A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

André Luis Meneses Silva

Apresentações semelhantes


Apresentação em tema: "André Luis Meneses Silva"— Transcrição da apresentação:

1 André Luis Meneses Silva alms@ufs.br
Análise Léxica Núcleo de Sistemas de Informação Universidade Federal de Sergipe Linguagens Formais e Tradutores André Luis Meneses Silva

2 Análise Léxica Objetivos:
Produzir tokens a partir de uma seqüência de caracteres Ignorar comentários e espaços em branco Correlacionar mensagens de erro com o programa fonte Sub-rotina ou co-rotina do analisador sintático (parser) Programa fonte analisador lexico Tokens parser

3 Análise Léxica Alguns Conceitos
Token: saída do an. léxico. (símbolo terminal do parser) Lexema: seqüência de caracteres Padrão: descrição dos possíveis lexemas de um token

4 x, taxa, i_0 235, 0 235E-23 if , := ( >= Token Lexema <ID>
<Int> 235, 0 <Real> 235E-23 <If> if <COMMA> , <ASSIGN> := <LPAR> ( <GE> >= Alguns Tokens possuem atributos: <Int,235> <ID,”taxa”>

5 Análise Léxica Vantagens Projeto de Linguagem mais simples
O módulo do parser fica mais simples. (Ex. não lida mais com comentários, Trata palavras reservadas como símbolos terminais, etc.) Eficiência Métodos eficientes para análise léxica. Leitura de arquivo fonte, só aqui. Um caracte é lido só uma vez ... Portabilidade Alfabeto de entrada é restrito ao analisador léxico (characters encodings, here) Vantagens

6 Análise Léxica Dificuldades Alinhamento dos lexemas (Fortran antigo)
Espaços não são significativos (Fortran - Algol 68) DO 5 I = 1.25 DO 5 I = 1,25 Palavras chaves não são reservadas (PL/I) if then then = else else else = then DO: palavra chave ou parte de ID?

7 Erros Léxicos Poucos erros são detectados nesta etapa Como atuar?
Desespero (Panic mode): pular até encontrar Apagar caractere estranho Substituir caractere incorreto Transpor dois caracteres Ex. fi (x==3) ... (se o correto for “if”, o erro só é detectado no parser)

8 Especificação dos tokens
Em geral, emprega-se expressões regulares:  é uma e.r. que denota {} ε é uma e.r. que denota {ε} Se aΣ, a é uma e.r. Denota {a} Se r e s são e.r. que denotam R e S rs, r*, r|s são e.r. que denotam RS, R*, RS Precedência > concatenação > | Não Permitem Recursão Obs.: Defns. Regulares: não permitem recursão

9 Definições regulares Açúcar sintático das e.r.
d_1  r_1 d_2  r_2 ... d_n  r_n onde os r_i são e.r. sobre Σ {d_1,..., d_n} e em r_k não aparece nenhum d_j com j≥k. Obs. Não é possível usar recursão

10 Exemplo Notação: r+ ≡ rr* r? ≡ r | ε Ex.: digitos  digito+
letra  A | ... | Z | a | ... | z digito  0 | 1 | 2 | ... | 9 id  letra( letra | digito )* digitos  digito digito* fraçao_op  . digitos | ε expoente_op  E(+|-|ε)digitos | ε num  digitos fraçao_op expoente_op Notação: r+ ≡ rr* r? ≡ r | ε Ex.: digitos  digito+ fraçao_op  (.digitos)?

11 Exemplo letra  A | ... | Z | a | ... | z digito  0 | 1 | 2 | ... | 9
if  if id  letra(letra|digito)* relop  < | <= | = | > | >= | <> num  digito+(.digito+)?(E(+|-)?digito+)? tokens Lexemas podem estar separados por espaços em branco. delim  branco | tab | nl ws  delim+

12 Construindo um analisador léxico
Construir um AFD (ou AFND) para cada token (e delimitadores) Combinar num único AFND Transformar para AFD (opcional) Implementar o autômato combinado

13 d i f d . 1 2 1 2 3 3 d letra E d d letra digito 4 7 6 1 2 +,- E 5 d =
d=digito < 2 > 4 Obs. ws (delimitadores) não devolve token 1 5 = delim > 6 7 = delim 1 2

14 i f Autômato combinado 1 2 3 IF ε letra d letra d d . 14 15 23 24 ε ID
NUM 25 d E d ε d 26 NUM NUM 29 28 E +,- ε 27 d d = LT LE ε 18 esta < 17 > delim 19 NE 16 20 EQ = 28 29 delim > 21 = 22 GT GE

15 AFD combinado (construído usando o aprendido em LFA)
letra ID d 1 2 IF d d letra d letra-{f} . 3 10 i ID NUM 11 letra-{i} d E d d d 12 NUM NUM 15 14 E +,- 13 d < d = delim LT 5 LE Eliminação das transições vazias. Transformação de AFND para AFD Minimização de estados = 4 > 7 NE 29 delim > 6 EQ 8 = 9 GT GE

16 Implementação Duas Opções AFD com uma matriz int[][] delta, tal que:
delta[q][c] = p sse Diretamente no código switch(estado) case q: if (caracterCorrente==c) estado=p; return RespectivoToken // se q for final Qual mais eficiente? c q p Switchs são mais eficientes.

17 Implementação Critério para escolha do token
Reconhecer menor ou maior token?

18 Implementação Critério para escolha do token
Reconhecer menor ou maior token? Como reconhecer o maior token possível?

19 Implementação Critério para escolha do token
Reconhecer menor ou maior token? Como reconhecer o maior token possível? Analisar até chegar num estado sem possibilidade de sair Ir salvando o último Token reconhecido

20 Implementação Faz uso de Buffer. Bufferização deve ser eficiente
Armazena em memória um bloco de dados para posterior armazenamento. Bufferização deve ser eficiente Única fase a ler caractere por caractere Usa-se um sentinela para eof

21 Buffer Duas marcas no buffer para delimitar o lexema
A Interface (assinatura) do Buffer: class Buffer { char proximo(); // devolve o c.c. e avança um marcarInicio(); marcarUltimo(); retrair(int); // retrai o apontador do c.c. retrairAoUltimo(); String lexema(); // seq. entre as marcas }

22 O tipo Token classs Token { public final int codigo;
public Object valor; Token (int c, Obejct v) { codigo=c; valor=v} Token (int c) { this(c, null) } } class sym { public final static int IF = 0; public final static int ID = 1; ... public final static int GE = 8;

23 if delimitador(c) estado = 29; else if (c=='i') {
scan: while (true) { c=buffer.proximo(); switch (estado) { case 0: if delimitador(c) estado = 29; else if (c=='i') { ultimoFinal = estado = 1; buffer.marcarUltimo(); } else if (isLetra(c)) { ultimoFinal = estado = 3; else if ... else throw Erro(); // ou ignorar break; class Lexer { Buffer buffer = new Buffer(....); Token proximoToken( ) { int estado = 0; int ultimoFinal=-1; buffer.marcarInicio( ); Falta tratar o final de arquivo .... Obs. Quando for para um estado não final, não é preciso Marcar Ultimo

24 ultimoFinal = estado = 2; buffer.marcarUltimo(); }
case 1: if (c=='f') { ultimoFinal = estado = 2; buffer.marcarUltimo(); } else if (letra(c)||digito(c)) { ultimoFinal = estado=3; else break scan; break; case 2: ... ... case 29: if (!delim(c)) { buffer.retrair(1); buffer.marcarInicio(); estado=0; } } //switch }//while scan ***TODO** Desenvolver o case 10 (tem diferenças com os outros casos)

25 switch (ultimoFinal) { case -1: throw new Erro();
case 1: buffer.retrairAoUltimo(); return ( new Token ( sym.ID, buffer.lexema( ) ); case 2: … } } // proximoToken ***TODO*** Desenvolver outros casos: por exemplo 5 e 10.

26 Atividades Codificar autômato dos slides. Codificar a classe Buffer.

27 Referências Capítulo 2 (Livro do Tigre) Capítulo 3 (Livro do Dragão).
Slides de Aula Prof. Giovanny


Carregar ppt "André Luis Meneses Silva"

Apresentações semelhantes


Anúncios Google