Análise LéxicaAnálise Léxica
André Luis Meneses SilvaAndré Luis Meneses Silva
[email protected]@ufs.br
1
Núcleo de Sistemas de InformaçãoUniversidade Federal de Sergipe
Linguagens Formais e Tradutores
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)
2
analisadorlexico
analisadorlexico
parserparser
TokensTokens
Programa fontePrograma fonte
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
3
<ID> x, taxa, i_0<Int> 235, 0<Real> 235E-23<If> if<COMMA> ,<ASSIGN> :=<LPAR> (<GE> >=
4
Token Lexema
Alguns Tokens possuem atributos:<Int,235><ID,”taxa”>
Análise LéxicaVantagens
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)5
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
6
DO: palavra chave ou parte de ID?
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
7
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*, RS Precedência
• > concatenação > |
• Não Permitem Recursão
8
Definições regulares
Açúcar sintático das e.r.d_1 r_1d_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
9
Exemplo
letra A | ... | Z | a | ... | zdigito 0 | 1 | 2 | ... | 9id 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)?
10
Exemplo
11
letra A | ... | Z | a | ... | zdigito 0 | 1 | 2 | ... | 9
if ifid letra(letra|digito)*relop < | <= | = | > | >= | <>num digito+(.digito+)?(E(+|-)?digito+)?
Lexemas podem estar separados por espaços em branco.
delim branco | tab | nlws delim+
toke
ns
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
12
13
1 32i f
1 2
letraletradigito
1
2
5
<4
=
=
3
>
6 = 7>
1 23
4
5
67
dd.
d
d
E
E
+,-
d
d
d
1 2
delim
delim
d=digito
14
1 32i f
14 15
letraletrad
16
17
20
<19
=
=
18
>
21 = 22>
23 2425
26
27
2829
dd.
dd
E
E
+,-
d
d
0
d
ε
ε
ε
ε
28 29
delim
delim
ε
Autômato combinadoIF
ID
LELT
EQNE
GT GE
NUM
NUMNUM
15
21
i
f
3
letra-{i}
letrad
4
6
<
7
=
=5
>
8 = 9
>
1011
12
13
1415d
d.
dd
E
E
+,-
d
d
0
d
29
delim
delim
AFD combinado (construído usando o aprendido em LFA)
IF
ID
LELT
EQNE
GT GE
NUM
NUMNUM
letradID
letra-{f}d
Implementação
Duas Opções
AFD com uma matrizint[][] delta, tal que:delta[q][c] = p sse
Diretamente no códigoswitch(estado)case q: if (caracterCorrente==c) estado=p; return RespectivoToken // se q for final
Qual mais eficiente?
16
q pc
Implementação
Critério para escolha do token Reconhecer menor ou maior token?
17
Implementação
Critério para escolha do token Reconhecer menor ou maior token?
Como reconhecer o maior token possível?
18
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
19
Implementação
Faz uso de Buffer. 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
20
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}
21
O tipo TokenO tipo Token
22
classs Token {classs Token { public final int codigo; public final int codigo; public Object valor;public Object valor; Token (int c, Obejct v) {Token (int c, Obejct v) { codigo=c; valor=v}codigo=c; valor=v} Token (int c) {Token (int c) { this(c, null) }this(c, null) }}}
class sym {class sym { public final static int IF = 0;public final static int IF = 0; public final static int ID = 1;public final static int ID = 1; ...... public final static int GE = 8;public final static int GE = 8;}}
23
class Lexer {Buffer buffer = new Buffer(....); Token proximoToken( ) { int estado = 0; int ultimoFinal=-1; buffer.marcarInicio( );
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; buffer.marcarUltimo(); } else if ... else throw Erro(); // ou ignorar
break;
24
case 29: if (!delim(c)) { buffer.retrair(1); buffer.marcarInicio(); estado=0; } } //switch}//while scan
case 1: if (c=='f') { ultimoFinal = estado = 2; buffer.marcarUltimo(); } else if (letra(c)||digito(c)) { ultimoFinal = estado=3; buffer.marcarUltimo(); } else break scan; break;
case 2: ... ...
25
switch (ultimoFinal) { case -1: throw new Erro(); case 1: buffer.retrairAoUltimo(); return ( new Token ( sym.ID, buffer.lexema( ) ); case 2: … }} // proximoToken
Atividades
Codificar autômato dos slides. Codificar a classe Buffer.
26
Referências
Capítulo 2 (Livro do Tigre) Capítulo 3 (Livro do Dragão). Slides de Aula Prof. Giovanny
27