Você está na página 1de 34

Anlise Sinttica I:

Analisadores
Descendentes com
Retrocesso

Definio

A anlise sinttica o processo de determinar


se

uma cadeia de tomos (tokens), isto , o


programa j analisado pelo analisador lxico, pode
ser gerado por uma gramtica

Seu objetivo a construo da rvore sinttica


ou apenas a deciso se a cadeia fornecida ou
no uma sentena da gramtica que define a
linguagem

Papel da Anlise Sinttica na


Estrutura de um Compilador

Prog. fonte

Anlise
lxica

pede token
token

Anlise
sinttica

rvore
sinttica

Aceita/No
aceita

Anlise
semntica

Formas de anlise sinttica

A anlise sinttica pode ser:


Top-down

(A.S. Descendente), na qual a


construo da rvore de derivao/sinttica
(explicitamente ou no) da raiz para as
folhas

Bottom-up

(A.S. Ascendente), que comea


das folhas para o smbolo inicial

Mtodos de anlise
Existem mtodos universais de anlise sinttica,
como o algoritmo de Cocke-Younger-Kasami e o
de Earley,

que

trabalham com qualquer tipo de gramtica livre


de contexto,

Mas so ineficientes para se usar na produo


de compiladores,

so de ordem de O(n3), com n sendo o tamanho


da cadeia de tokens.

pois

Mtodos de anlise
Earley, em 1970, apresentou um mtodo de A.S.
Top-Down sem Backtracking que reconhece todas
as GLCs com O(n3);

- mas se elas forem no ambguas, o tempo O(n2) e


chega a ser O(n) para muitas linguagens.

Mais detalhes em:


www.cs.uiowa.edu/~RVS/Courses/Compiler/Notes
/earley.pdf

Mtodos de anlise
Os mtodos Top-Down e Bottom-Up mais eficientes e
interessantes so determinsticos (O(n)).

Eles trabalham somente com subclasses de GLCs,


por exemplo, as gramticas LL(k) e LR(k), que so bastante
expressivas para descrever a maioria das linguagens de
programao.
LR(k)

Duas delas so de interesse imediato:

LL(k)

LL(1): Left to right scan, Left-most derivation, 1 token look-ahead

LR(1): Left to right scan, Right-most derivation, 1 token look-ahead

Mtodos de anlise
Veremos 3 tipos de A.S.D. e suas vantagens e desvantagens:
A.S.D. Recursiva com Retrocesso/Backtracking (tentativa e
erro na escolha de produo)

Parsers Preditivos:

Com procedimentos recursivos: so mais adequados para serem


escritos manualmente; um smbolo look-ahead determina a produo
a ser escolhida

JavaCC, no entanto, cai neste tipo, mesmo sendo um compiler compiler. Ele
tambm permite que certas regras possam ser analisadas com um K maior que 1

Dirigidos por tabela/Tabular: fazem uso de uma pilha explcita para


guardar o lado direito das produes;

mais adequado para serem implementados automaticamente pela prcomputao da Tabela de Anlise

A.S.D. com Retrocesso


Ineficiente
Foi usada em implementaes pioneiras
Ainda utilizada em aplicaes
especficas
Usada em muitos compilers-compilers
com backtracking;

Funcionamento
cadeia a ser analisada
D rvore formada apenas pelo smbolo
reservado S
folha corrente S

Repita:

{Seja X a folha corrente}


Se X no terminal ento
[ escolha uma produo X::=X1X2...Xr; substitua na rvore D a folha corrente
por uma rvore com raiz de rtulo X e descendentes diretos com rtulos
X1, X2, ... Xr;
folha corrente X1]
seno {X terminal}
[Se =X ento
;
folha corrente prxima folha em D no percurso das folhas da
esquerda para a direita]
seno {= ou 1o smbolo de no X}
[retroceder, ou seja, restaurar os valores de D e de folha corrente,
antes da ltima aplicao de produo;
Se existe outra produo
ento aplicao da produo
seno retroceder novamente {repete-se at que uma
produo seja encontrada}]
at que (= e folha corrente aponta para fora da rvore -> ACEITAR) ou (D=S e no
h alternativa -> ERRO)

Cdigo pode refletir a gramtica

Em Price & Toscani (2001), pgs. 40 e 41,


vemos uma implementao de um ASD
recursivo com retrocesso:
Cada

no terminal uma funo para tratar o


trecho de cdigo da gramtica

Price, A.M.A. e Toscani, S.S. (2001). Implementao de Linguagens de


Programao: Compilador. Editora Sagra Luzzatto.

Exemplo de ASD com retrocesso em cdigo


genrico
Seja a gramtica
E::=E+T | T
T::=T*F | F
F::= a | b | (E)

elimina-se a recurso a esquerda, para evitar que o


algoritmo entre numa repetio infinita
E::=T+E | T
T::=F*T | F
F::=a | b | (E)

ateno: mudar a recursividade muda o significado


atribudo s expresses

a eliminao da recursividade feita no resolveu o problema,


pois mudou a associao dos operadores
Anlise de a+b

Seja a sentena a*b


(1)

(2)

(3)

(4)

(5)

(6)

(7)

(8)

a*b

a*b

a*b

a*b

*b

T+E

T+E

T+E

T+E

T+E

T+E

T+E

F*T

F*T

F*T

F*T

F* T

F* T

a F*T

a F*T
a

(9)

(10)

(11)

(12)

(13)

(14)

T+E

T+E

T+E

T+E

T+E

T+E

F* T

F* T

F* T

F*T

F*T

F*T

a F*T

a F*T

a F*T

( E ) 67

F
a 12

F
b

(15)

(16)

(17)

(18)

(19)

a*b

a*b

*b

T+E

T+E

T+E

T+E

T+E

F*T
a

F*T
a

12

F*T
3612

F*T
3

( E ) 23

( E)

(20)

(21)

(22)

(23)

(24)

(25)

(26)

a*b

a*b

a*b

a*b

a*b

a*b

a*b

T+E

T+E

T+E

T+E

F*T

F*T

19

19

( E)

1219

(27)

(28)

(29)

(30)

(31)

(32)

*b

F*T

F*T

F* T

F* T

F* T

F* T

a F*T

a F*T

29

a
(33)
b
E
T
F* T
a F*T
( E)

2829

a F*T

a F*T

(34)

(35)

(36)

(37)

F*T

F*T

F*T

F*T

a F

a F

a F

a F

29

A.S.D. com retrocesso

A utilizao de retrocesso far com que as aes de


modificaes da tabela de smbolos e possvel gerao de
cdigo em compiladores de 1 passo sejam anulados.
Geralmente esta no uma tarefa simples.

O nmero de derivaes pode ser uma funo exponencial


do tamanho da cadeia

Este algoritmo caracteriza derivaes esquerdas de


cadeias (substitui o terminal mais a esquerda)

A recursividade a esquerda no permitida nos mtodos


de A.S.D. em geral.

Pela ineficincia e problemas, a anlise descendente s


usada quando se elimina retrocesso

Exemplo
E ::= E op T | T
T ::= a

recursiva a esquerda
Associa /resolve os operadores da mesma classe da
esquerda para a direita
E

E
a op a op a

op

E op T
T
a

T
a

Exemplo
E ::= T op E | T
T ::= a

recursiva a direita
Associa /resolve os operadores da mesma classe da
direita para a esquerda
E

T
a op a op a

op

E
T op E
a

T
a

Eliminao de retrocessos e de
recurso a esquerda
Para eliminar retrocessos:
fazer com que o algoritmo tome a deciso
correta quanto produo a ser aplicada.

Uma classe de gramtica para as quais isso


pode ser feito pode ser descrita por:
1. Toda produo da forma AX, X terminal
2. Se AX11 | X22 | ... | Xmm, ento X1X2
... Xm

No algoritmo de anlise, a escolha de


expanses resolvida consultando-se o 1o
smbolo de entrada

Ex.: Seja a gramtica E a | b | * EE | + EE


que satisfaz 1 e 2.

Na anlise da sentena + a * b a
(1)

(2)

(3)

(4)

(5)

(6)

+a*ba

+a*ba

a*ba

a*ba

*ba

*ba

+ E E

+ E E

+ E E

+ E E

+ E E

a * E E

(7)

(8)

(9)

(10)

ba

ba

+ E E

+ E E

+ E E

+ E E

+ E E

a * E E

a * E E
b

a * E E
b

(11)

a * E E

a * E E

b a

b a

Essas restries so muito severas ( muito difcil


encontrar uma gramtica que satisfaa essas
condies para uma determinada linguagem).

Vamos obter uma classe mais ampla de gramticas.

Seja a relao FIRST


First(X) = {Y T | X *p Y } {primeiro_smbolo}
isto , First(X) = {X} se X T
= {Y T | X =>* Y} se X N

A restrio passa a ser:


- para todo smbolo A N com as regras:
A X11 | X22 | ... | Xnn
onde X V, temos que:
- First(Xi) so disjuntos dois a dois:
-

First(Xk) First(Xj) = { } para k,j {1, 2...n} com kj

Agora, o algoritmo de anlise deve verificar a


qual dos conjuntos First pertence o 1o smbolo
da cadeia de entrada .

Como os conjuntos devem ser disjuntos, haver


no mximo 1 alternativa possvel

Seja a gramtica:
S AS | BA
A aB | C
B bA | d
Cc

Gerem o conjunto
dos FIRST para
todos os smbolos

S AS | BA
A aB | C
B bA | d
Cc

S
A
B
C
a
b
c
d

p
A, B
a, C
b, d
c
-

*p
First
A,B,a,C,b,d,c,S a,b,d,c
a,C,c,A
a,c
b,d,B
b,d
c,C
c
a
b
c
d

Passos da anlise para a sentena abcdad


(1)

(2)

(3)

(4)

(5)

(6)

(7)

(8)

abcdad

abcdad

abcdad

bcdad

bcdad

cdad

cdad

cdad

A S

A S

A S

A S

A S

A S

A S

a B

a B

a B
b A

a B
b A

a B

a B

b A

b A

(9)

(10)

(11)

(12)

dad

dad

dad

ad

a B

a B

B A

a B

B A

a B

B A

b A

b A

b A

b A

(13)

(14)

(15)

ad

a B

b A

A
A

d a B

a B

b A

A
A

d a B

a B
b A

a B

A classe de gramtica que satisfaz esta restrio chamada LL(1)


analisa uma cadeia da esquerda para a direita produzindo uma
derivao esquerda, verificando apenas 1 smbolo da cadeia de
entrada para decidir qual a produo aplicada.
S AS ABS abAS abCS abcS abcBA abcdA
abcdAB abcdaB abcdad

Como definido, LL(1) = Left to right, Left-most


derivation, 1 smbolo look-ahead
Ex.:
S aAB | aBA
A b | cS
B d | eS
No LL(1), mas como A comea com b ou c e B
comea com d ou e, a escolha de S pode se
basear no segundo caractere LL(2).

A gramtica de expresses abaixo no LL(1), pois os


conjuntos First no so disjuntos dois a dois. Na verdade,
no LL(K).
ET+E|T
TF*T|F
F a | b | (E)
A gramtica equivalente abaixo pode resolver o problema:
E T E
E + E |
T F T
T * T |
F a | b | (E)

Quando uma regra gera h


uma segunda checagem a ser
feita: veremos logo mais

Agora, os conjuntos First so disjuntos dois a dois.

Problema: aumento do comprimento das


derivaes e conseqente aumento do nmero de
operaes para realizar a anlise.
Para minimizar esse problema, podemos aplicar
outros recursos, isto , adotar uma notao
estendida para gramtica (EBNF) e modificar o
algoritmo de anlise.
1) Fatorao
E T+E | T

E T (+E | )

De uma forma geral, se:


A 1 | 2 | ... | n, com
podemos fator-la em:
A (1 | 2 | ... | n)
Dessa forma, a escolha da alternativa pode ser retardada.
Ex.:
E T (+E | )
T F (*T | )
F a | b | (E)

2) Substituio da notao recursiva por uma


notao iterativa
EE+T|T
por

E T {+ T}
3) Combinao de Fatorao e Substituio

fatora:
substitui:

EE+T|E-T|T
E E (+ T | - T) | T
E T { +T | - T} ou E T {(+|-) T}