Gramáticas Livres de Contexto Análise...

Click here to load reader

  • date post

    09-Dec-2018
  • Category

    Documents

  • view

    219
  • download

    0

Embed Size (px)

Transcript of Gramáticas Livres de Contexto Análise...

1

Compiladores

Anlise sinttica (2)

Anlise Top-Down

2

Gramticas Livres de Contexto Anlise Top-Down

S AB cB ccbB ccbca

Top-Down

S ABA cB cbBB ca

Gramtica: S A B A c | B cbB | ca

String: ccbca

3

Transformaes de GLCs

Eliminao de produes vazias

Eliminao da recurso esquerda:

Recurso diretaA produo: A Aa | b Se torna: A bA A aA|

Fatorao de uma gramticaA produo: A 1 | 2 Se torna:A X e X 1 |2

4

Plano da aula

Implementao de um reconhecedor de sentenas

Top-Down Lookahead.

Primitivas First e Follow.

5

Anlise Top-Down

Como implementar um reconhecedor para uma GLC?

Constri-se a rvore de derivao, lendo a sentena de esquerda para a direita, e substituindo sempre o no-terminal mais esquerda.

Existem trs tipos principais de parser top-down: Recursivo com retrocesso

Recursivo preditivo

Tabular preditivo.

6

Anlise Top-Down Exemplo

S A BA c | B cbB | ca

S cbca tentar SABAB cbca tentar AccB cbca casar c

B bca sem-sada, tentar AB cbca tentar BcbBcbB cbca casar c

bB bca casar b

B ca tentar BcbBcbB ca casar c

bB a sem-sada, tentar Bcaca ca casar c

a a casar a -> Fim!

Gera S * cbca?

7

Anlise Recursiva com Retrocesso Cria-se um procedimento por no-terminal

Testa-se aplicao de cada produo associada ao no-terminal;

L no texto de entrada o prximo token

Invoca o analisador lexical (yylex())

necessrio lembrar onde se fez uma escolha de uma alternativa, para poder retroceder neste ponto.

Operao de retrocesso (backtracking)

8

Anlise Recursiva com Retrocesso

[ a ] $

S

[ L ]

[ a ] $

S

[ L ]

Sucesso S ; L

Expandir S

[ a ] $

S

[ L ]

S ; L

Sucesso

a

[ a ] $

S

[ L ]

S ; L

Falhaa

[ a ] $

S

[ L ]

Expandir

[ a ] $

S

[ L ]

SucessoS

a

Exemplo (Price e Toscani, Seo 3.2.1)Gramtica: Entrada:

S a | [ L ] [ a ] $ L S ; L | S

9

Anlise Recursiva com Retrocessotoken tok;

main() {

tok = lexyy();

if( S() )

if( token == $ )

printf(Sucesso!!!);

else printf(Erro.);

}

boolean S() {

if( tok == a ) {

tok = lexyy();

return true; }

else if( tok == ] ) {

tok = lexyy();

if( L() )

if( tok = ] ) { tok = lexyy(); return true; }

else return false;

else return false;

}

boolean L() {

MARCA_PONTO;

if( S() )

if( tok == ; ) {

tok = lexyy();

if( L() ) return true;

else return false;

}

else {

RETROCEDE; //o cabeote de leitura

if( S() ) return true;

else return false;

}

else return false;

}

10

Anlise Recursiva com Retrocesso Este mtodo ineficiente:

Vrias leituras para a mesma entrada.

Difcil de de indicar local onde foi encontrado um erro, devido a tentativa de aplicao de produes alternativas.

Como em algumas situaes o reconhecimento acompanhado de aes semnticas que modificam a tabela de smbolos retrocessos implicam em desfazer estas modificaes.

No um mtodo comumente aplicado.

11

Anlise Recursiva Preditiva

Analisadores recursivos sem retrocesso.

Chamados de preditivos pois o smbolo sob o cabeote de leitura determina qual produo a ser aplicada a cada no terminal.

Mais eficientes.

12

Anlise Recursiva Preditiva

fcil de implementar.

necessrio:1. Que a gramtica no seja recursiva esquerda

Pois: A Aa Implica na funo: reconheceA() {

(recurso infinita) reconheceA(); ...

}

2. Que a gramtica seja fatorada esquerda

Seno deve se fazer retrocesso.

3. Que os primeiros terminais derivveis possibilitem a deciso de uma produo a aplicar!

No h retrocesso sobre no-terminais...

13

Anlise Recursiva Preditiva Exemplo:

TYPE SIMPLE | ^ id | array [ SIMPLE ] of TYPESIMPLE integer | char | num dotdot num

Aho, Seo 2.4

array [ num dotdot num ] of integer

14

Anlise Recursiva Preditiva

array [ num dotdot num ] of integer

15

Anlise Recursiva Preditiva

array [ num dotdot num ] of integer

16

Anlise Recursiva Preditivatoken lookahead;

token nexttoken;

void match( token t ) {

if( lookahead == t )

lookahead = nexttoken;

else error();

}

void type() {

switch( lookahead )

case integer :

case char :

case num : simple(); break;

case ^ : match(^); match( id ); break;

case array : match(array); match([);

simple();

match(]); match(of); type();

break;

default : error();

}

}

void simple() {

switch( lookahead )

case integer : match(integer);

break;

case char : match(char);

break;

case num : match(num);

match(dotdot);

match(num);

break;

default: error();

}

}

17

Analisador recursivo preditivo

Conjunto First(): Definio formal:

Se existe um t T e um V* tal que * t ento t First()

Se * ento First()

Definio informal: Conjunto de todos os terminais que comeam

qualquer seqncia derivvel de .

A B | C | DB bC cD d

First(A)={b,c,d}First(B)={b}First(C)={c}First(D)={d}

18

Analisador recursivo preditivo No caso que os First() so simpticos, no ter

retrocesso.

Isso supe que para qualquer produo

A 1 | 2 | ... | n

se tenha

First( 1) First( 2) ... First( n) =

19

proc First(: string de smbolos)// seja = X1 X2 X3 Xn

if( X1 T ) // caso simples onde X1 um terminal First() := {X1}else { // X1 no um terminal

i := 0; First() = First{X1} \ {};

for( i = 1 ; i

25

O que acontece se First(A)?S ACEA a | b | C c | d | E e

Consegue derivar ? ace bde ce de e

A () {switch {case a:

matchToken(a); break;case b:

matchToken(b); break;case ??:

break;default:

abort(syntax_error);}

26

Exerccio

Escrever um reconhecedor recursivo para: G=({+,*,id,(,)} {E,T,F}, P, E)

E E+T | T

T T*F | F

F (E) | id

27

Exerccio

Escrever um reconhecedor recursivo para: G=({+,*,id,(,)} {E,T,F}, P, E)

E E+T | T

T T*F | F

F (E) | id

P1

Retirar recurso esquerda

Transformar produes do tipo A

1 |

2 ... |

n |

1 |

2 ... |

m

Em produes do tipo A

1X |

2X ... |

mX

X 1X |

2X ... |

nX |

28

Exerccio

Escrever um reconhecedor recursivo para: G=({+,*,id,(,)} {E,T,F}, P, E)

E E+T | T A : E

1 : +

1 :

T T*F | F A : T

1 : F

1 : F

F (E) | id

P1

Retirar recurso esquerda

Transformar produes do tipo A

1 |

2 ... |

n |

1 |

2 ... |

m

Em produes do tipo A

1X |

2X ... |

mX

X 1X |

2X ... |

nX |

29

Exerccio

Escrever um reconhecedor recursivo para: G=({+,*,id,(,)} {E,T,F}, P, E)

E E+T | T A : E

1 : +

1 :

T T*F | F A : T

1 : F

1 : F

F (E) | id

P1

Retirar recurso esquerda

E TEE +TE| T FTT *FT | F (E) | id

30

Para melhorar: o conjunto Follow

Follow(A): Conjunto de terminais que podem aparecer direita

de um no-terminal A em uma sentena vlida.

$ passa a denotar um terminal virtual que marca o fim da entrada (EOF, CTRL-D,)

Formalmente: Se existe um t T e , V* tal que S * A t

ento t Follow(A) Se S * A ento $ Follow(A)

31

Exemplo First/Follow

S A BA c | B cbB | ca

First(A) = {c, } Follow(A) = {c}First(B) = {c} Follow(B) = {$}

First(S) = {c} Follow(S) = {$}

32

Algoritmo: proc Follow(A N)Follow(S) := {$};Repeat foreach p P do {

// Varre as produes case p == A B {

Follow(B) := Follow(B) First()\{}; if First() then Follow(B) := Follow(B) Follow(A); end

} case p == A B

Follow(B) := Follow(B) Follow(A);} until no change in any Follow(N)

33

Exerccio First/Follow

P: S XYZ

X aXb | Y cYZcX | d Z eZYe | f

Para: G = (T,N,P,S)

T = {a,b,c,d,e,f}

N = {S,X,Y,Z}

34

Exerccio First/Follow

P: S XYZ

X aXb | Y cYZcX | d Z eZYe | f

First(X) = {a, } Follow(X) = {c, d, b, e, f}

First(Y) = {c, d} Follow(Y) = {e, f}

First(Z) = {e, f} Follow(Z) = {$, c, d}

First(S) = {a, c, d} Follow(S) = {$}

Para: G = (T,N,P,S)

T = {a,b,c,d,e,f}

N = {S,X,Y,Z}

35

Gramtica LL(1)Condies necessrias:

Sem ambigidade Sem recurso a esquerda

Uma gramtica G LL(1) sse Para quaisquer duas produes de G

A | * t1. First() First() = 2. * implies !( * )3. * implies First() Follow(A) =

(2) Significa que pertence no mximo ao First de um smbolo.

LL(1) = leitura Left -> right + derivao mais a esquerda (Left) + + uso de 1 token lookahead.

36

Sumrio

Gramticas LL(1) podem ser analisadas por um simples parser descentente recursivo Sem recurso a esquerda Fatorada a esquerda 1 smbolo de look-ahead

Nem todas as linguagens podem ser tornadas LL(1).

Ainda se pode usar um mecanismo mais poderoso para reconhecer tais gramticas. Eliminar a recursividade.

37

BibliografiaLeituras:

A. M. A. Price, S. S. Toscani. Implementao de Linguagens de Programao: Compiladores. 3 ed. Porto Alegre: Sagra-Luzzatto. 2005. Cap 3, at Seo 3.2.2.

A. V. Aho, R. Sethi, J. D. Ullman. Compilers: Principles, Techniques and Tools. Reading: Addison-Wesley. 1985. Seo 4.4.