1 linguagens formais e tradutores análise sintática - 1 prof. andré luis meneses silva...

34
1 Linguagens Formais e Tradutores Análise Sintática - 1 Prof. André Luis Meneses Silva [email protected] www.dsi.ufs.br

Upload: internet

Post on 17-Apr-2015

115 views

Category:

Documents


8 download

TRANSCRIPT

Page 1: 1 Linguagens Formais e Tradutores Análise Sintática - 1 Prof. André Luis Meneses Silva alms@ufs.br

1

Linguagens Formais e Tradutores

Análise Sintática - 1

Prof. André Luis Meneses [email protected]

www.dsi.ufs.br

Page 2: 1 Linguagens Formais e Tradutores Análise Sintática - 1 Prof. André Luis Meneses Silva alms@ufs.br

2

Análise Sintática (parsing) Verificar se um programa é

sintaticamente válido Reconhecer a estrutura

sintática do programa Produzir uma representação

abstrata dos programas (sintaxe abstrata)

Produzir mensagens de erros. Se recuperar.

analisadorléxico

parser

Tokens

Programa fonte

AnalisadorSemântico

Árvore Abstrata

Page 3: 1 Linguagens Formais e Tradutores Análise Sintática - 1 Prof. André Luis Meneses Silva alms@ufs.br

3

Especificação da Sintaxe Definições regulares não têm o poder de expressão

suficiente Gramáticas livres de contexto = def. regulares

+ recursão Uma GLC G é definida por

um conjunto de produções (ou regras) simbolo → simbolo simbolo ....

simbolo Cada símbolo pode ser terminal ou não terminal O símbolo à esquerda de → é um não terminal Existe um símbolo destacado: símbolo inicial

Page 4: 1 Linguagens Formais e Tradutores Análise Sintática - 1 Prof. André Luis Meneses Silva alms@ufs.br

4

Especificação da Sintaxe ExemploE → E+E ouE → E+EE → E*E | E*EE → num | num

E → (E) | (E) Derivação

E E+E E + E + E num + E + E num + E + num num + num + num

Page 5: 1 Linguagens Formais e Tradutores Análise Sintática - 1 Prof. André Luis Meneses Silva alms@ufs.br

5

Árvore de derivação

E

E E+

E E+

num num

num

yield

Page 6: 1 Linguagens Formais e Tradutores Análise Sintática - 1 Prof. André Luis Meneses Silva alms@ufs.br

6

Derivação mais à esquerdaE E+E E + E + E num + E + E num + num + E num + num + num Gramática é ambígua

sse

existe mais de uma árvore de derivação para uma mesma sentença (yield)sseexiste mais de uma derivação mais à esquerda

Page 7: 1 Linguagens Formais e Tradutores Análise Sintática - 1 Prof. André Luis Meneses Silva alms@ufs.br

7

E

E E+

E E+

num num

E

E E+

E E+

num num

num

num

Page 8: 1 Linguagens Formais e Tradutores Análise Sintática - 1 Prof. André Luis Meneses Silva alms@ufs.br

8

Gramáticas ambíguas

Problemáticas para compilação Qual é a estrutura gramatical escolhida?

Como lidar Adicionar regras extra-gramaticais

precedência de operadores, associatividade, else opcional, ...; ou

Usar GLC não ambígua equivalente com a original

Page 9: 1 Linguagens Formais e Tradutores Análise Sintática - 1 Prof. André Luis Meneses Silva alms@ufs.br

9

Gramáticas ambíguas Precedência e associatividade podem ser

codificadas dentro da GLC

E → E+T | E-T | TT → T*F | T/F | FF → id | num | (E)

Regras recursivas à esq. associatividade à

esquerda Camada mais alta precedência mais baixa

Page 10: 1 Linguagens Formais e Tradutores Análise Sintática - 1 Prof. André Luis Meneses Silva alms@ufs.br

10

Gramática por camadas - exemplo

E → E + T | E - T | TT → T * F | T / F | FF → -F | +F | VV → V . id | V [ E ] | AA → id | num | (E)

Page 11: 1 Linguagens Formais e Tradutores Análise Sintática - 1 Prof. André Luis Meneses Silva alms@ufs.br

11

else opcionalS if E then S else S | if E then S | outro

Qual é a árvore deif E1 then if E2 then S1 else S2 ?

Page 12: 1 Linguagens Formais e Tradutores Análise Sintática - 1 Prof. André Luis Meneses Silva alms@ufs.br

12

else opcionalS if E then S else S | if E then S | outro

Qual é a árvore deif E1 then if E2 then S1 else S2 ?

LPs adotam: else sempre casa com o if mais próximo.Podemos codificar isto numa GLC, assim:

S S' | S"S' if E then S' else S' | outroS" if E then S | if E then S' else S"

Page 13: 1 Linguagens Formais e Tradutores Análise Sintática - 1 Prof. André Luis Meneses Silva alms@ufs.br

13

Métodos de Análise Métodos universais são ineficientes (CYK e outros) Top Down (recursivos-descendentes)

Constroem a árvore de deriv. em pré-ordem Caso particular: parser preditivos (LL(n))

Decidem que produção usar olhando n tokens de lookahead

LL(1) são adequados para implementação manual Servem para a maioria das linguagens Exigem transformações na gramática original

Bottom Up (pós-ordem) Cobrem uma classe mais ampla de gramáticas Menos transformações Usualmente construídos com ferramentas

Page 14: 1 Linguagens Formais e Tradutores Análise Sintática - 1 Prof. André Luis Meneses Silva alms@ufs.br

14

Parser Recursivo Descendente Pode envolver retrocesso (Backtracking)

L → c A d

A → ab | a

O parser de cad exige retrocesso

Ineficiente para ser usado na prática Em geral, LPs não precisam de retrocesso

Page 15: 1 Linguagens Formais e Tradutores Análise Sintática - 1 Prof. André Luis Meneses Silva alms@ufs.br

15

Análise preditivo Não precisam de retrocesso Porém, só servem para um tipo de gramáticas -- LL(n)

não permitem recursão à esquerda LL(1): Se queremos expandir A e temos a na entrada

Só deve ser possível usar uma única produção a é chamado de lookahead

Exemplo: Sintaxes com palavras reservadas como

S if E then S else S | while E do S | begin L end

Em gramáticas LL(n) usa-se n símbolos de lookahead

Page 16: 1 Linguagens Formais e Tradutores Análise Sintática - 1 Prof. André Luis Meneses Silva alms@ufs.br

16

Parser preditivo

S if E then S else S | begin S L | print E

L end | ; S LE num = num

void S( ) { switch(tok) { case IF: proxToken( ); E( ); reconhecer(THEN); S( ); reconhecer(else); S( ); break; case BEGIN: proxToken( ); S( ); L( ); break; case PRINT: proxToken( ); E( ); break; default: erro( ); } }

Um procedimento para cada não terminal Um switch com um caso para cada produção

Page 17: 1 Linguagens Formais e Tradutores Análise Sintática - 1 Prof. André Luis Meneses Silva alms@ufs.br

17

void L( ) { switch(tok) { case END: proxToken( ); break; case SEMICOLON: proxToken( ); S( ); L( ); break; default: erro( ); } }

void E( ) { switch(tok) { case NUM: proxToken( ); reconhecer(EQ); reconhecer(NUM); break; default : erro( ); } }

void proxToken( ) { tok = scanner.proximoToken( ).codigo; }

void reconhecer(int t) { if (t!=tok) erro( ); else tok = scanner.proximoToken( ).codigo; }

Page 18: 1 Linguagens Formais e Tradutores Análise Sintática - 1 Prof. André Luis Meneses Silva alms@ufs.br

18

Gramáticas não LLV V [ E ] | id

O procedimento V( ) chama recursivamente V( ) sem consumir nenhum token. Entra em loop.

E num + E | num * E | num | (E)Com num inicialmente scaneado, que produção escolho?Porém, ela é LL(2).

E T + E | T T F * T | FF num | (E)

Não é LL(2). (num)+(num)

“( num” não determina a produção a escolher

Page 19: 1 Linguagens Formais e Tradutores Análise Sintática - 1 Prof. André Luis Meneses Silva alms@ufs.br

19

Primeiro e Seguinte Primeiro()={a | * a} { | * } Seguinte(A)={a | S * Aa}

Permitem ver se a gramática é LL(1) Permitem construir a tabela sintática preditiva

c/entrada contém a produção a ser aplicada para um par lookahead – terminal

ExemploZ d Y X Y W b | X Y W Z | c | a

Primeiro(Z)=?

Page 20: 1 Linguagens Formais e Tradutores Análise Sintática - 1 Prof. André Luis Meneses Silva alms@ufs.br

20

Algoritmo para Primeiro Inicializar Primeiro(a)={a}, para todo terminal a

Se X , adicionar a Primeiro(X)Repetir até não poder adicionar mais

Se X Y1Y2...Yk, Primeiro(Y1), ... , Primeiro(Yi-1)

(i.e., Y1Y2..Yi-1 ), ea Primeiro(Yi)então adicionar a a Primeiro(X)

Primeiro(X1X2...Xn) = Primeiro(X1), se Primeiro(X1);Primeiro(X1X2...Xn) = Primeiro(X1)...Primeiro(Xi+1) - {} se Primeiro(Xk), para k =1...i , e Primeiro(Xi+1); ePrimeiro(X1X2...Xn) = Primeiro(X1) ... Primeiro(Xn) se Primeiro(Xk), para k = 1...n

Page 21: 1 Linguagens Formais e Tradutores Análise Sintática - 1 Prof. André Luis Meneses Silva alms@ufs.br

21

Z d Y X Y W b | X Y W Z | c | a

abcdXYZW

a

b

c

d

, a, c

, c

a, b, c, d

b

Primeiro

Page 22: 1 Linguagens Formais e Tradutores Análise Sintática - 1 Prof. André Luis Meneses Silva alms@ufs.br

22

Seguinte - Algoritmo Seguinte(A)={a | S * Aa} Colocar $ em Seguinte(S)

Repetir até não poder adicionar mais Se existir AB

adicionar Primeiro()-{ε} a Seguinte(B)

Se existir AB ouAB e Primeiro()

adicionar Seguinte(A) a Seguinte(B)

Page 23: 1 Linguagens Formais e Tradutores Análise Sintática - 1 Prof. André Luis Meneses Silva alms@ufs.br

23

Z d Y X Y W b | X Y W Z | c | a

XYZW

c, b

c, b

$

a, b, c, d

Seguinte

S Z $

Page 24: 1 Linguagens Formais e Tradutores Análise Sintática - 1 Prof. André Luis Meneses Silva alms@ufs.br

24

Tabela sintática preditiva

Z d Y X Y W b | X Y W Z | c | a

X a X Y X Y

Y Y cY

W b

Z X Y W Z Z X Y W Z Z X Y W ZZ d

Z X Y W Z

X

Y

WZ

a b c d

A é uma entrada para (A,a) na tabela sse:– Se A e a Primeiro() – Se A, Primeiro() e a Seguinte(A)

Page 25: 1 Linguagens Formais e Tradutores Análise Sintática - 1 Prof. André Luis Meneses Silva alms@ufs.br

25

G é LL(1) sse a sua tabela sintática preditiva é determinística

LL(n): Com n lookaheads as entradas para as colunas serão cadeias de tamanho n

Gramáticas não LL: Nenhuma G ambígua é LL Nenhuma G com recursão à esquerda é LL

V V [ E ] | idid Primeiro(V[E])

Page 26: 1 Linguagens Formais e Tradutores Análise Sintática - 1 Prof. André Luis Meneses Silva alms@ufs.br

26

Eliminando recursão à Esquerda• E → E+T | E-T | T

Podemos escrever sem recursão à esquerda, assimE → T E'E'→ + T E' |

Em geral, se temosA → A1 | A2 |...| An

| 1 | 2 |...| m

EscrevemosA → 1A' | 2A' |...| mA'A' → 1A' | 2A' |...| nA' |

Dificuldades futuras Árvore de derivação associativa à direita Geração de árvore abstrata exige tratamento especial

Page 27: 1 Linguagens Formais e Tradutores Análise Sintática - 1 Prof. André Luis Meneses Silva alms@ufs.br

27

Tabela preditiva da gramática de expressões anterior

S → E $E → T E'E'→ + T E' |

Page 28: 1 Linguagens Formais e Tradutores Análise Sintática - 1 Prof. André Luis Meneses Silva alms@ufs.br

28

Tirando em evidência (fatoração) à esquerda

• A → | |...podemos escrever

A → A' |... A' → |

Por exemploD → int Id ; | int Id ( A ) ; | outro

pode ser re-escrito comoD → int Id D' | outroD' → ; | ( A ) ;

Pequena dificuldade: A estrutura gramatical foi mudada

Page 29: 1 Linguagens Formais e Tradutores Análise Sintática - 1 Prof. André Luis Meneses Silva alms@ufs.br

29

Exemplos de fatoração

E id E' | num

E' (E) | [e] |

E id(E) |id[e] |id |num

Page 30: 1 Linguagens Formais e Tradutores Análise Sintática - 1 Prof. André Luis Meneses Silva alms@ufs.br

30

• S if E then S else S | if E then S | outro

Pode ser escrito comoS if E then S X

| outroX else S |

Porém, neste caso, a fatoração não é suficiente pois a nova gramática ainda é ambígua

Em (X,else), a tabela vai ter duas entradas:

Xelse S e X Solução ad-hoc: (adotada pela javacc, por ex.)

Escolher sempre a primeira regra (neste caso, o else associa com o if mais próximo, como esperado).

Não há prescrição geral.

Page 31: 1 Linguagens Formais e Tradutores Análise Sintática - 1 Prof. André Luis Meneses Silva alms@ufs.br

31

Recuperação de erros em Parsers preditivos

Quando acontecem?– A( ) foi chamado com o lookahead a e a entrada (A,a)

na tabela preditiva é vazia; ou Ao reconhecer(a) o lookahead é diferente de a

Desespero trabalha bem Pular todos os tokens até achar um de sincronização Heurísticas para o conjunto de sincronização Ajustes por tentativa e erro

Outros métodos Substituir o token. Exemplo:

lookahead = "," e Reconhecer(";") falha Inserindo tokens (inseguro, pode entrar em loop)

Inserir ";” quando detectar sua falta

Page 32: 1 Linguagens Formais e Tradutores Análise Sintática - 1 Prof. André Luis Meneses Silva alms@ufs.br

32

Modalidade de despero -- Heurísticas

• A( ) foi chamado com lookahead a Ponto de partida: sincronização = Seguinte(A) e A( )

é resumido Acrescentar como sincronização as palavras chaves de

construções mais altas ou da mesma altura (se houver seqüências). Por ex.

Se faltar “;” e começar depois um while, o while poderia ser ignorado sem esta heurística

Expressões estão dentro de comandos Usar produção vazia (ou que gera vazio) como default

Ao reconhecer token Ignorar token (apagar) – sincroniza com todos

Page 33: 1 Linguagens Formais e Tradutores Análise Sintática - 1 Prof. André Luis Meneses Silva alms@ufs.br

33

Resumo Análise Sintática Gramáticas

Ambigüidade Classificação dos métodos de análise Análise top-down

Análise preditivo – Gramáticas LL Tabela sintática preditiva Fatoração e eliminação da recursão á esquerda Recuperação de erros

Page 34: 1 Linguagens Formais e Tradutores Análise Sintática - 1 Prof. André Luis Meneses Silva alms@ufs.br

34

Bibliografia Seções 4.1-4.6 do livro do Dragão Seções 3.1 e 3.2 do livro do Tigre