Licenciatura em Engenharia Informática DEI/ISEP Linguagens de Programação 2006/07. Tópicos avançados

Documentos relacionados
Processamento de Linguagens I LESI + LMCC (3 o ano)

Introdução ao FLEX e expressões regulares

Questão Aula Tipo - Flex+Bison

Introdução. Flex e uma ferramenta para gerar scanners programas que reconhecem padrões lexicais em texto

Linguagens e Programação BISON. Paulo Proença

Compiladores I Prof. Ricardo Santos (cap 3 Análise Léxica: Introdução, Revisão LFA)

Como construir um compilador utilizando ferramentas Java

Compiladores. Lex e Yacc / Flex e Bison. Ferramentas Flex/Bison

Compiladores. Bruno Lopes. Bruno Lopes Compiladores 1 / 31. Instituto de C

Compiladores - JFlex. Fabio Mascarenhas

Compiladores - JFlex. Fabio Mascarenhas Monday, April 15, 13

Programação 5374 : Engenharia Informática 6638 : Tecnologias e Sistemas de Informação. Cap. 7 Arrays. Arrays

Universidade Estadual da Paraíba - UEPB Curso de Licenciatura em Computação

1 d=

Linguagem C Princípios Básicos (parte 1)

Mestrado em Engenharia Física Tecnológica

13 a Aula - Instruções Condicionais. Ciclos. Pré-processador. Variáveis de ambiente. Mestrado em Engenharia Física Tecnológica

O que faz/o que é Como usar Como funciona Formato geral do Arquivo Submetido ao Lex ER estendidas Exemplos The Lex & YACC page:

Utiliza Expressões Regulares (ER) Estendidas para definir a especificação da análise léxica desejada

Processamento de Linguagens I LESI + LMCC (3Âo ano)

Construção de Compiladores Aula 3 - Analisador Sintático

JavaScript (Elementos de Programação e Programação Básica)

Folha 3 - Análise léxica

Licenciatura em Engenharia Informática DEI/ISEP Linguagens de Programação 2006/07

PROGRAMAÇÃO E ALGORITMOS (LEII) Universidade da Beira Interior, Departamento de Informática Hugo Pedro Proença, 2016/2017

3. Linguagem de Programação C

COMPILAÇÃO. Ricardo José Cabeça de Souza

Teoria e Implementação de Linguagens Computacionais. Especificação do projeto da disciplina (2006.1) Versão de 23/08/2006.

V.2 Especificação Sintática de Linguagens de Programação

Análise Sintática Introdução

Folha 4.2 Análise sintática ascendente

Fundamentos de Programação

TASM DEFINIÇÃO DE UMA NOVA TABELA DE CONVERSÃO

Revisão. Profa Marina Gomes

Linguagem C Introdução. Contexto Histórico Principais diferenças do Java Funções em C Compilar programas em C no Linux

Identificadores Nome de variáveis, constantes, métodos, etc...

Folha 4.1 Análise sintática descendente

Linguagens de Domínio Específico

C/C++; biblioteca stdio

Compilação da linguagem Panda

Construção de Compiladores Aula 2 - Analisador Léxico

A Linguagem C. A forma de um programa em C

Escrever scripts de PHP com HTML

Trabalho de Linguagens Formais e Compilação

Fundamentos de Programação

1. Lex & YACC. 2. Lex. O que podem fazer por você. O que cada programa faz. Casando expressões regulares

3.1 - Funções para manipular dados de entrada e saída padrão

COMPILADORES. Análise sintática. Prof. Geovane Griesang Universidade de Santa Cruz do Sul UNISC Departamento de informática

Preprocessador. Macros. #include. #define

Compiladores - Análise Léxica

Programação 5374 : Engenharia Informática 6638 : Tecnologias e Sistemas de Informação. Cap. 11 Estruturas (Structs) Structs

Compiladores - Análise Léxica

IV.2 Aspectos Léxicos Convencionais

Conceitos Básicos de C

1 Da aula teórica ao Java

Compiladores. Bruno Lopes. Bruno Lopes Compiladores 1 / 32. Instituto de C

Programação de Computadores I Introdução ao C PROFESSORA CINTIA CAETANO

Ponteiros. Ponteiros. Ponteiros. Ponteiros. Ponteiros. Introdução a Programação. Profa. Roseli Romero

Compiladores. Análise Léxica

Programa fonte token padrões lexema Tokens

Análise Léxica I. Eduardo Ferreira dos Santos. Março, Ciência da Computação Centro Universitário de Brasília UniCEUB 1 / 31

Programação Dicas e Outras Coisas

Revisão. Fases da dacompilação

Linguagem C: diretivas, compilação separada. Prof. Críston Algoritmos e Programação

LEX & YACC / FLEX & BISON. Uso prático... LEX: Tokenizer LEX & YACC / FLEX & BISON. Uso do Flex:

DEP. INFORMÁTICA - UNIVERSIDADE DA BEIRA INTERIOR

Computação e Programação Exame Época de recurso

Introdução à Programação

Compiladores I Prof. Ricardo Santos (cap 1)

Vetores e Matrizes. Prof. Fabrício Olivetti de França Charles Henrique

Sub-rotinas em C. Disciplina de Programação de Computadores I Universidade Federal de Ouro Preto

Descrição da Linguagem DECAF

Compiladores. Conceitos Básicos

Rui Carneiro, Rui Pereira, Tiago Orfão

Linguagens Formais e Autómatos

Construção de um compilador para a linguagem Panda

Noção de estrutura de dados

Lex Adaptação da obra original de Tom Niemann

Compiladores - Autômatos

Informática para as Ciências e Engenharias - 2º semestre 2015/2016

( ) LEIA ATENTAMENTE as instruções para a resolução do p-fólio: 1. O tempo de resolução do p-fólio é de uma hora e trinta minutos.

Estruturas de Dados. Módulo 4 Funções. 9/8/2005 (c) Dept. Informática - PUC-Rio 1

Copiar para o ficheiro ArvoreBinaria.h e adaptar as funções associadas às operações sobre árvores binárias (3.1 a 3.12)

LINGUAGEM C: FUNÇÕES FUNÇÃO 08/01/2018. Funções são blocos de código que podem ser nomeados e chamados de dentro de um programa.

Métodos Computacionais

Mestrado em Engenharia Física Tecnológica

XML. Prof. Júlio Machado

Linguagens e Programação FLEX. Paulo Proença

Identificação do discente: Matrícula: Nome completo: Douglas Godeguez Nunes. Curso: Ciência da Computação

Conceitos básicos de programação

Computação L2. Linguagem C++ Observação: Material Baseado na Disciplina Computação Eletrônica.

Elementos de Linguagem C

Funções de Entrada e Saída

Linguagens de Domínio Específico

Introdução à linguagem C

Hello World. Linguagem C. Tipos de Dados. Palavras Reservadas. Operadores Aritméticos. Pré e pós incremento e pré e pós decremento

Ponteiros. um ponteiro é uma variável que contém o endereço um dado declaração: * indica que a variável é um ponteiro. Ex: tipo_dado *nome_ponteiro;

Programação de Computadores II Aula 03. Linguagem C I

Transcrição:

Licenciatura em Engenharia Informática DEI/ISEP Linguagens de Programação 2006/07 Tópicos avançados Este documento apresenta alguns métodos para a resolução de problemas, susceptíveis de ocorrer na resolução do trabalho prático de LPROG. No final deste documento, é indicado o URL dum arquivo, contendo alguns dos exemplos apresentados. 1 Contextos do FLEX (start conditions) O FLEX permite estabelecer contextos, para a aplicação das expressões regulares. Um contexto, é um estado especial, no qual só está activo um conjunto restrito de expressões regulares. Um dos exemplos mais conhecidos, implementado recorrendo a contextos, é o processamento de comentários multi-linha da linguagem de programação C. O contexto em que o FLEX se encontra por omissão, é o contexto 0 ou INITIAL. Neste contexto todas as expressões regulares que não pertencem a nenhum contexto e as marcadas como INITIAL são usadas. Para definir novos contextos são usadas as directivas %s e %x na primeira secção do ficheiro FLEX, em que: A directiva %s define um contexto inclusivo, em que são aplicadas as expressões regulares desse contexto e as que não têm contexto; A directiva %x define um contexto exclusivo, isto é, quando o FLEX está nesse contexto, somente as expressões regulares marcadas com esse contexto estão activas. A indicação dos contextos a que se aplica uma expressão regular é realizada, colocando um estado ou uma lista de estados, delimitado pelos símbolos < e >, antes da expressão regular. Para expressões activas em todos os contextos, pode-se usar a notação <*>. A mudança de contextos é realizada nas acções com a macro BEGIN, indicando o contexto para o qual queremos mudar. De seguida é apresentado um exemplo que ignora os comentários da linguagem C, continuando a contar as mudanças de linha. 1

1 %x coment 2 3 %% 4 5 "/ " BEGIN coment ; / inicia comentário / 6 <coment>[^ \n] / ignorar tudo até um ou \n / 7 <coment>" /" BEGIN INITIAL ; / f i n a l i z a comentário / 8 <coment>" " / ignorar sozinho / 9 10 / a regra seguinte está activa nos dois contextos / 11 <INITIAL, coment>\n numlinhas++; // equivante a < > 12 13 [0 9]+ return INTEIRO; 14 [0 9] \.[0 9]+ return REAL; 15 16 < >[ \t\r ] / ignorar em todos os contextos / 17 <<EOF>> return 0; 18 %% O processamento de um comentário HTML é semelhante, sendo somente necessário substituir as expressões regulares de início e fim de comentário, pelas expressões regulares "<!--" e "-->" respectivamente, e fazer algumas alterações às restantes expressões regulares. No caso de processamento das linguagens XML e HTML, pode ser necessária a criação de contextos FLEX, para garantir que tudo que se situa fora das etiquetas é tratado como um único token. É necessário também permitir que apareçam palavras reservadas fora das etiquetas, e sejam tratadas como texto normal. No exemplo de código seguinte é apresentado o extracto dum ficheiro XML com alguns problemas de análise com o FLEX e o BISON, sem recorrer à utilização de contextos no FLEX. 1 <?xml version=" 1.0 "?> 2 <language> 3 <extension>xml</ extension> 4 <name>extensible markup language</name> 5 <update>2005 04 12 12 : 1 0: 2 2</ update> 6 </language> 7 <language> 8 <extension>html</ extension> 9 <name>hypertext markup language</name> 10 <update>2003 09 24 19 : 4 4: 0 1</ update> 11 </language> No exemplo anterior a palavra xml aparece como etiqueta e como texto, é necessário identificar esta diferença recorrendo a dois contextos no FLEX, um quando se está dentro duma etiqueta, e outro quando se está fora. Também fora duma etiqueta é necessário diferençar vários casos, dependendo da etiqueta a tratar. Por exemplo na etiqueta extension existe 2

somente uma palavra, já na etiqueta name existe qualquer coisa (até encontrar o < seguinte) e na etiqueta update existe uma data que tem de ser validada do lado do BISON, necessitando dum contexto especial FLEX que identifique os inteiros e os símbolos - e : até encontrar o símbolo <. De seguida apresenta-se uma maneira de identificar a etiqueta name e update no FLEX e no BISON 1... 2 language : < LANGUAGE > 3 dados_ language 4 TAG_FIM LANGUAGE > { printf ("language... \ n") ;} 5 ; 6 dados_language : extension name update 7 error { yyerror ("unrecognized language") ; yynerrs++;} 8 ; 9... 10 name : < NAME > beginstrxml 11 strxml 12 TAG_FIM NAME > { printf ("name...% s\n", $5 ) ;} 13 ; 14 beginstrxml : { printf ("begin stringxml... \ n") ; 15 BEGIN stringxml ;} 16 ; 17 update : < UPDATE > begindata 18 dataerr 19 TAG_FIM UPDATE > { printf ("data... \ n") ;} 20 ; 21 begindata : { printf ("begin data... \ n") ;BEGIN data ;} 22 ; 23 dataerr : data hora 24 error hora { yyerror ("malformed data... ") ; yynerrs++;} 25 data error { yyerror ("malformed hora... ") ; yynerrs++;} 26 ; 27 data : INTEIRO INTEIRO INTEIRO { printf ("dia...%d %d %d\n",$1, $3, $5 ) ;} 28 ; 29 hora : INTEIRO : INTEIRO : INTEIRO { printf ("hora...% d:%d:%d\n",$1, $3, $5 ) ;} 30 ; 31... Sempre que é necessário usar a macro BEGIN no BISON para mudar o contexto do FLEX, deve ser criada uma regra vazia com a respectiva acção semântica, para esse fim (neste exemplo, são usadas as regras beginstrxml e begindata). Este motivo deve-se à necessidade do FLEX mudar imediatamente para este contexto, o que pode não acontecer com a inclusão de acções semânticas no meio de regras, tal como foi descrito na Ficha 6. 3

Para poder usar a macro BEGIN e os contextos dentro do BISON, torna-se necessário ao correr o comando flex, usar a opção header-file=nome.h para gerar um ficheiro header que será incluído no BISON. Quem utilizar o FLEX para Windows, não tem a opção de criar o ficheiro header, pelo que terá de incluir o ficheiro C gerado pelo FLEX no BISON e compilar somente o ficheiro BISON. Um analisador léxico para esta gramática seria: 1 2 %{ 3 extern int coluna, linha ; 4 %} 5 6 %x tag data stringxml 7 8 ID [ a za Z]+ 9 INTEIRO [0 9]+ 10 REAL [0 9] \.[0 9]+ 11 12 %% 13 14 < >"<" BEGIN tag ; coluna+=yyleng ; return yytext [ 0 ] ; 15 < >"</" BEGIN tag ; coluna+=yyleng ; return TAG_FIM; 16 <tag>">" BEGIN INITIAL ; coluna+=yyleng ; return yytext [ 0 ] ; 17 <tag>xml coluna+=yyleng ; return XML; 18 <tag>extension coluna+=yyleng ; return EXTENSION; 19 <tag>language coluna+=yyleng ; return LANGUAGE; 20 <tag>name coluna+=yyleng ; return NAME; 21 <tag>update coluna+=yyleng ; return UPDATE; 22 <tag >[=?/] coluna+=yyleng ; return yytext [ 0 ] ; 23 <tag>\"{real}\" 24 <tag > {REAL} coluna+=yyleng ; yylval. real=atof ( yytext+1) ; return REAL_STR; 25 26 <tag, data, INITIAL>[ \t\r ] coluna+=yyleng ; 27 <tag, data, INITIAL>\n coluna =0; linha++; 28 29 <data>{inteiro} coluna+=yyleng ; yylval. i n t e i r o=atoi ( yytext ) ; return INTEIRO; 30 <data >[: ] coluna+=yyleng ; return yytext [ 0 ] ; 31 32 <stringxml >[^>] BEGIN INITIAL ; coluna+=yyleng ; yylval. str=strdup ( yytext ) ; return STRING_XML; 33 34 < >[ \t\r ] coluna+=yyleng ; 35 < >\n coluna =1; linha++; 4

36 < >. coluna+=yyleng ; printf ("Erro lexico(%d %d) : simbolo desconhecido (%c )\n", linha, coluna, yytext [ 0 ] ) ; 37 <<EOF>> return 0; 2 Validação da existência de elementos por ordem arbitrária numa lista Para a validação da existência ou não de elementos numa lista e se eles estão repetidos, é necessário recorrer a acções semânticas para evitar a criação exponencial, de regras alternativas. O exemplo seguinte aceita dentro da etiqueta uma lista de três campos obrigatórios, mas que podem aparecer por qualquer ordem. Para a sua validação é necessário usar um vector (ou uma estrutura) com um elemento para cada campo. A regra lista é a regra que permite inserir os vários campos, sendo na acção da condição de paragem (a primeira acção a ser realizada) iniciado o vector. 1 regra : 2 < TAG l i s t a { 3 if (veccampos[0]==0) 4 yyerror ("Falta campo 0") ; 5 else 6 if (veccampos[0] >1) { 7 s printf ( str, "Campo 0 repetido %d vezes ",veccampos [ 0 ] ) ; 8 yyerror ( str ) ; 9 } 10 if (veccampos[1]==0) 11 yyerror ("Falta campo 1") ; 12 else 13... 14 } 15 / > 16 17 < TAG error / > { yyerror ("Erro dentro da tag") ;} 18 ; 19 20 l i s t a : / Vazio / {veccampos[0]= veccampos[1]= veccampos [2]=0;} 21 l i s t a campo 22 ; 23 24 campo :CAMPO_0 { 25 if (veccampos[0] >0) yyerror ("Campo 0 repetido ") ; 26 veccampos[0]++; 5

27 } 28 CAMPO_1 { 29 if (veccampos[1] >0) yyerror ("Campo 1 repetido ") ; 30 veccampos[1]++; 31 } 32 CAMPO_2 { 33 if (veccampos[2] >0) yyerror ("Campo 2 repetido ") ; 34 veccampos[2]++; 35 } 36 ; 3 Passagem de strings entre o FLEX e o BI- SON Na passagem de strings entre o FLEX e o BISON deve-se ter o cuidado de reservar espaço e copiar a string no FLEX (por exemplo usando a função strdup). No BISON deve ser libertado o espaço quando o token já não é utilizado. Isto pode ser realizado de duas maneiras diferentes, a primeira é incluindo a instrução free directamente nas acções semânticas, a outra é incluindo a instrução free na directiva do BISON %destructor (somente disponível a partir da versão 1.9 do BISON). De seguida são apresentados dois pequenos exemplos do FLEX e do BI- SON que utilizam este mecanismo. 1... 2 %% 3... 4 [ a za Z_] [ a za Z0 9_] yylval. str=strdup ( yytext ) ; return ID ; 5... 6 %% 1 2 %union{ 3 int i n t e i r o ; 4 double real ; 5 char str ; 6 } 7 8 %token <str> ID 9 10 %type <str> id 11 12 %destructor { free ( $$ ) ;} ID id 13 14 %% 6

15 i n i c i o : / vazio / 16 i n i c i o id { printf (" id:%s\n", $2 ) ; 17 / se não usar %destructor, fazer free ($2) ; aqui /} 18 ; 19 20 id : ID {$$=$1 ;} 21 ; 22 23 %% Os dois exemplos usados neste documento, estão disponíveis no endereço http://www.dei.isep.ipp.pt/~matos/lprog/topicos.zip 7