Você está na página 1de 6

proc First(: string of symbols)

Repeat {

Compiladores
Anlise sinttica (3)
Anlise LL(1) com tabela preditiva.

X1 X2 X3 Xn
// seja
if X1 T
then // caso simples onde X1 um terminal
First() := {X1}
else { // X1 um no-terminal
First() = First{X1} \ {};
for (i=1 ; i<=n ; i++) {
if is in First(X1) and in First(X2) and in First(Xi-1)
First() := First() First(Xi) \ {}
}
}
if ( =>* )
then First() := First() {}
} until no change in any First()

proc Follow(B 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)

Exemplo First/Follow
S XYZ
X aXb |
Y cYZcX | d
Z eZYe | f
First(X) = {a, }
First(Y) = {c, d}
First(Z) = {e, f}

trivial quando um terminal t.


varre as produes X t quando um no-terminal X;
chato quando o incio de ume derivao de X deriva em .
Inclui apenas quando X pode derivar em .

O algoritmo de clculo de Follow(X)

reservado aos no-terminais X


Inclui o $ em alguns casos triviais (X == o start S)
Varre as produes onde X aparece direita (A X )
chato quando X aparece no fim (ou logo antes de algo que
deriva em )
NUNCA inclui

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

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

Gramtica LL(1)

Observaes First/Follow
S terminais entram em First e Follow.
O algoritmo de clculo de First():

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

Condies necessrias:

sem ambigidade
sem recurso a esquerda

Uma gramtica G LL(1) sse


A | * t

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

LL(1) = leitura Left -> right + derivao mais a


esquerda (Left) + uso de 1 token lookahead.

Anlise top-down com


tabela preditiva

Reconhecedor preditivo com Pilha

Os dois mtodos apresentados at agora para


fazer anlise descendente usam recursividade.
Cada no-terminal tem um procedimento associado;
Chamadas com ou sem retrocesso.
Para gramticas LL1 no tem retrocesso.

Tem um buffer em entrada;


$ marca seu fim.

Tem um fluxo de sada;


Uma pilha cujo fundo marcado por $
Inicializada com S (Start)

Chamadas recursivas usam uma pilha implcita

Uma tabela sinttica preditiva M


0

A pilha das chamadas!


Sobrecusto!
Pilha S

Funcionamento do parser

1. Se X = $ e a = $ : para e reconheceu uma


sentencia.
2. Se X = a != $ : desempilha X e avana de um
smbolo na entrada.
3. Se X no-terminal: Consulta a tabela M(X, a)
Se for vazia: ERRO
Se contm X -> UVW, ento substitui na pilha X por UVW
(U no topo).

Buffer de entrada

Sada

Tabela

Re-escrever a gramtica para satisfazer condies de


LL(1)
Calcular os conjuntos First e Follow
Para cada produo A
1. Para cada a First()
incluir a produo A em M[A,a]
2. Se First()
incluir a produo A em M[A,b] para cada b
em Follow(A)
3. Se First() e $ Follow(A)
incluir A to M[A,$]
Todas entradas no definidas so erros

Exemplo de tabela M(X, t)

A tabela preditiva M(X, t)


Tabela Bi-dimensional:

Tabela Bi-dimensional:

Dimenso 1: No-terminal X
Dimenso 2: Caractere da entrada (terminal) t
A entrada (X,t) contm a regra de produo a aplicar

Dimenso 1: No-terminal X
Dimenso 2: Caractere da entrada (terminal) t
A entrada (X,t) contm a regra de produo a aplicar

S
A
B

S
A
B
S cAa
A cB | B
B bcB |

Algoritmo para construir a tabela

Seja X o smbolo no topo da pilha


Seja a o smbolo de entrada (terminal!) a
analisar

Parser preditivo top-down

Usa-se uma pilha para armazenar os no-terminais


encontrados;
Usa-se uma tabela para orientar as derivaes.

Idia: de-recursificar o procedimento:

First(A) = {b, c, }
First(B) = {b, }
First(S) = {c}

Follow(S) = {$}
Follow(A) = {a}
Follow(B) = {a}

S cAa
A cB | B
B bcB |

c
S cAa

First(A) = {b, c, }
First(B) = {b, }
First(S) = {c}

Follow(S) = {$}
Follow(A) = {a}
Follow(B) = {a}

Exemplo de tabela M(X, t)

Exemplo de tabela M(X, t)

Tabela Bi-dimensional:

Tabela Bi-dimensional:

Dimenso 1: No-terminal X
Dimenso 2: Caractere da entrada (terminal) t
A entrada (X,t) contm a regra de produo a aplicar

a
S
A
B
S
A
B

AB

cAa
cB | B
bcB |

c
S cAa

S
A
B

AB

First(A) = {b, c, }
First(B) = {b, }
First(S) = {c}

Follow(S) = {$}
Follow(A) = {a}
Follow(B) = {a}

AB
B

AB

c
S cAa
A cB

First(A) = {b, c, }
First(B) = {b, }
First(S) = {c}

S
A
B

cAa
cB | B
bcB |

First(A) = {b, c, }
First(B) = {b, }
First(S) = {c}

Follow(S) = {$}
Follow(A) = {a}
Follow(B) = {a}

Follow(S) = {$}
Follow(A) = {a}
Follow(B) = {a}

b
c
ERRO S cAa
A B A cB
B bcB ERRO

First(A) = {b, c, }
First(S) = {c}

AB
B

AB
B bcB

S cAa
A cB | B
B bcB |

c
S cAa
A cB

First(A) = {b, c, }
First(B) = {b, }
First(S) = {c}

Follow(S) = {$}
Follow(A) = {a}
Follow(B) = {a}

Usando a tabela
String: cbca

Dimenso 1: No-terminal X
Dimenso 2: Caractere da entrada (terminal) t
A entrada (X,t) contm a regra de produo a aplicar

First(B) = {b, }

Dimenso 1: No-terminal X
Dimenso 2: Caractere da entrada (terminal) t
A entrada (X,t) contm a regra de produo a aplicar

S
A
B

Tabela Bi-dimensional:

S cAa
A cB | B
B bcB |

AB

Exemplo de tabela M(X, t)

a
ERRO
AB
B

AB

c
S cAa
A cB

Tabela Bi-dimensional:

Dimenso 1: No-terminal X
Dimenso 2: Caractere da entrada (terminal) t
A entrada (X,t) contm a regra de produo a aplicar

S
A
B

Exemplo de tabela M(X, t)

Tabela Bi-dimensional:

S cAa
A cB | B
B bcB |

Exemplo de tabela M(X, t)

S
A
B

Dimenso 1: No-terminal X
Dimenso 2: Caractere da entrada (terminal) t
A entrada (X,t) contm a regra de produo a aplicar

$
ERRO
ERRO
ERRO

Follow(S) = {$}
Follow(A) = {a}
Follow(B) = {a}

Pilha
S$
cAa$
Aa$
Ba$
bcBa$
cBa$
Ba$
a$
$

Entrada

Ao

cbca$
cbca$
bca$
bca$
bca$
ca$
a$
a$
$

S->cAa
casar c
A->B
B->bcB
casar b
casar c
B->
casar a
casar $, sucesso

Mais um exemplo...

TE
+TE|
T FT
T *FT |
F (E)| Id
E

Smbolo

First

Follow

E
E
T
T
F

{(, id}
{+, }
{(, id}
{*, }
{(, id}

{$, )}
{$, )}
{+, $, )}
{+, $, )}
{*, +, $, )}

Exemplo LL(1)
S XYZ
X aXb |
Y cYZcX | d
Z eZYe | f
First(X) = {a, }
First(Y) = {c, d}
First(Z) = {e, f}

Construir Tabela
Analisar abcdfcf

Follow(X) = {c, d, b, e, f}
Follow(Y) = {e, f}
Follow(Z) = {$, c, d}

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

Observao sobre a Tabela


A tabela indica se h ambigidade!
Mais de uma regra numa entrada!

Solues?
Tornar a gramtica LL(1)
Eliminar ambiguidade, recursividade... Ver os slides
seguintes.

Usar uma heurstica para desempatar as regras


Qual?

Transformaes de GLCs
Eliminao de produes vazias
Eliminao de recursividade esquerda:
recurso direta
recurso indireta
Fatorao de uma gramtica

Usar outros algoritmos do que os top-down!

Exemplo total: if... Then... Else:


SiEtS|iEtSeS|a
Eb

Eliminao de produes vazias (1)


Objetivo:
eliminar produes da forma A .
Algoritmo: seja G = (N,T,P,S) uma GLC
Etapa 1:
construir N , o conjunto de no-terminais que
geram a palavra vazia:

N = {A | A };
Repita
N = N {X | X X1...Xn P tq X1,...,Xn
N}
At que o cardinal de N no aumente.

Eliminao de produes vazias (2)


Etapa 2:
construir o conjunto de produes sem produes
vazias:
gera G1 = (N,T,P1,S), onde P1 construdo como
segue:
P1 = {A | };
Repita
Para toda A P1 e X N tal que
= 1X2 e 12
Faa P1 = P1 {A 12}
At que o cardinal de P1 no aumente

Eliminao de produes vazias (3)


Etapa 3:
incluir gerao da palavra vazia, se
necessrio.
Se a palavra vazia pertence linguagem,
ento a gramtica resultante
G2 = (N,T,P2,S), onde P2 = P1 {S }

Eliminao de recursividade esquerda

Exemplo
A Aa | b
Com a palavra vazia
A bX
X aX |

Sem a palavra vazia


A b | bX
X a | aX

Obs: pode ainda haver recurso indireta!

Exemplo
E -> E+T | T
T -> T*F | F
F -> (E)| Id
A regra E -> E+T | T se torna:
E -> TE
E -> +TE|

Convertendo recurso a esquerda para


recurso a direita

X Xb | Xc | AB | C
Introduzir Y
X ABY | CY
Y bY | cY |

A regra T- > T*F | F se torna:


T -> FT
T-> *FT |

Fatorao de uma gramtica

Exemplo de Fatorao a Esquerda

Elimina indeciso de qual produo


aplicar quando duas ou mais produes
iniciam com a mesma forma sentencial

Cmd if Expr then Cmd else Cmd


Cmd if Expr then Cmd
Cmd Outro

A 1 | 2
Se torna:

A X
X 1 |2

Fatorando a esquerda:

Cmd if Expr then Cmd ElseOpc


Cmd Outro
ElseOpc else Cmd |

Gerenciamento de Erros
Relatar erros & recuperar

Relatar erros assim que possvel


Mensagens de erro adequadas
Continua aps o erro
Evitar a cascata de erros

Nvel-Frase (local) x Modo-Pnico


Nvel frase: tenta-se alterar UM smbolo para
recuperar.
Modo pnico: pula x tokens de entrada at poder
voltar a fazer a anlise.

Recuperao em Modo Pnico


Pula tokens at que um conjunto de
sincronizao encontrado
Follow(A) (A sendo no topo da pilha)
Smbolos de alta hierarquia na gramtica
{ , for, while, if

First(A)
Epsilon produo
Pop/Insert um terminal no topo da pilha.

Adicione aes de sincronia para a tabela

= at encontrar um token de sincronizao.

Sumrio
Anlise top-down possibilita o reconhecimento
eficiente e simples de gramticas LL(1):
Implementao preditiva com tabela.
Baseada nos clculos dos conjuntos First/Follow
Obs: tm casos que no foram tratados (e.g. o +)

Limitao:
Quando a gramtica no LL(1) !

Por isso: usa-se tambm anlise ascendente


(bottom-up).

Você também pode gostar