análise léxica andré luis meneses silva alms@ufs.br 1 núcleo de sistemas de informação...

Post on 17-Apr-2015

105 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Análise LéxicaAnálise Léxica

André Luis Meneses SilvaAndré Luis Meneses Silva

alms@ufs.bralms@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

top related