Análise Sintática botton-up - Departamento de Informática
Análise Sintática botton-up - Departamento de Informática
Análise Sintática botton-up - Departamento de Informática
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
<strong>Análise</strong> <strong>Sintática</strong> <strong>botton</strong>-<strong>up</strong><br />
Magnos Martinello<br />
Universida<strong>de</strong> Fe<strong>de</strong>ral do Espírito Santo - UFES<br />
<strong>Departamento</strong> <strong>de</strong> <strong>Informática</strong> - DI<br />
Laboratório <strong>de</strong> Pesquisas em Re<strong>de</strong>s Multimidia - LPRM<br />
2009
<strong>Análise</strong> sintática Botton-<strong>up</strong><br />
Tenta construir a árvore gramatical começando pelas folhas e<br />
trabalhando em direção a raiz.<br />
Um bottom-<strong>up</strong> parser constroi uma <strong>de</strong>rivação da sentença <strong>de</strong><br />
entrada retornando ao simbolo inicial S<br />
S ⇒ γ 0 ⇒ γ 1 ⇒ γ 2 ⇒ … ⇒ γ n-1 ⇒ γ n ⇒ sentença<br />
Para <strong>de</strong>rivar γ i-1 a partir γ i, associa-se γ i = α β δ contra γ i,<br />
substitui-se β com sua parte correspon<strong>de</strong>nte lhs, N, para resultar γ<br />
1<br />
= α N δ . (assumindo N→β )<br />
Uma árvore sintática não precisa ser construída, mas po<strong>de</strong> ser<br />
simulada<br />
|parse tree no<strong>de</strong>s| = |words| + |reductions|
Encontrando reduções<br />
Consi<strong>de</strong>re a gramática a seguir<br />
1 Goal → a A B e<br />
2 A → A b c<br />
3 | b<br />
4 B → d<br />
String <strong>de</strong> entrada abbc<strong>de</strong><br />
Sentential Next Red’n<br />
Form Prod’n Pos’n<br />
abbc<strong>de</strong> 3 2<br />
a A bc<strong>de</strong> 2 4<br />
a A <strong>de</strong> 4 3<br />
a A B e 1 4<br />
Goal — —<br />
A idéia é percorrer a entrada encontrando a próxima redução
Encontrando Reduções<br />
Se G é não-ambígua, então toda a forma <strong>de</strong> sentença a<br />
direita tem uma única redução<br />
Se pu<strong>de</strong>rmos encontrar as reduções, então po<strong>de</strong>mos construir<br />
uma <strong>de</strong>rivação !<br />
Roteiro da Prova:<br />
1 G é não-ambígua ⇒ <strong>de</strong>rivação mais a direita é única<br />
2 ⇒ uma única produção N→ β aplicada para levar γ i-1 à γ i<br />
3 ⇒ uma única posição k na qual N→ β é aplicada<br />
4 ⇒ uma única redução
Botton-<strong>up</strong> parsers<br />
Handle é uma subca<strong>de</strong>ia que reconhece o lado direito <strong>de</strong> uma<br />
produção e cuja redução ao não-terminal representa um passo<br />
<strong>de</strong> uma <strong>de</strong>rivação mais a direita.<br />
O processo <strong>de</strong> <strong>de</strong>scrobrir um handle e reduzi-lo apropriadamente<br />
para o lado esquerdo é chamado <strong>de</strong> handle pruning (poda do<br />
handle)<br />
Forma a base para o método <strong>de</strong> parsing bottom-<strong>up</strong><br />
Para construir uma <strong>de</strong>rivação mais a direita<br />
S ⇒ γ 0 ⇒ γ 1 ⇒ γ 2 ⇒ … ⇒ γ n-1 ⇒ γ n ⇒ w<br />
Aplicar o seguinte algoritmo simples<br />
for i ← n to 1 by -1<br />
Encontrar o handle in γ i<br />
Substituir β i por N i para gerar γ i-1
Exemplo<br />
Prod’n. Sentential Form Handle<br />
1<br />
2<br />
3<br />
4<br />
5<br />
6<br />
7<br />
8<br />
Goal<br />
Expr<br />
Term<br />
Factor<br />
→<br />
→<br />
|<br />
|<br />
→<br />
|<br />
|<br />
→<br />
Expr<br />
Expr + Term<br />
Expr – Term<br />
Term<br />
Term *<br />
Factor<br />
Term / Factor<br />
Factor<br />
number<br />
—<br />
1<br />
3<br />
5<br />
9<br />
7<br />
8<br />
4<br />
Goal<br />
Expr<br />
Expr - Term<br />
Expr -Term * Factor<br />
Expr - Term * <br />
Expr - Factor * <br />
Expr - *<br />
<br />
Term - *<br />
—<br />
1,1<br />
3,3<br />
5,5<br />
9,5<br />
7,3<br />
8,3<br />
4,1<br />
9 | id<br />
<br />
7 Factor - *<br />
<br />
7,1<br />
9 - * 9,1<br />
Gramática Derivação mais a direita <strong>de</strong> x - 2 * y
Técnica <strong>de</strong> implementação<br />
Parser shift-reduce<br />
push INVALID<br />
token ← next_token( )<br />
repeat until (top of stack = Goal and token = EOF)<br />
if the top of the stack is a handle N→β<br />
then /* reduce β to N */<br />
pop |β | symbols off the stack<br />
push N onto the stack<br />
else if (token ≠ EOF)<br />
then /* shift */<br />
push token<br />
token ← next_token( )<br />
Como mostrar os erros?<br />
• Falha para encontrar<br />
um handle<br />
• Atingiu EOF & precisa<br />
executar o shift (else<br />
final)<br />
Gerar um erro
Avançar e reduzir<br />
Stack Input Handle Action<br />
$ id – num * id none shift<br />
$ id – num * id 9,1 red. 9<br />
$ Factor – num * id 7,1 red. 7<br />
$ Term – num * id 4,1 red. 4<br />
$ Expr – num * id none shift<br />
$ Expr – num * id none shift<br />
$ Expr – num * id 8,3 red. 8<br />
$ Expr – Factor * id 7,3 red. 7<br />
$ Expr – Term * id none shift<br />
$ Expr – Term * id none shift<br />
$ Expr – Term * id 9,5 red. 9<br />
$ Expr – Term *<br />
5,5 red. 5<br />
Factor<br />
$ Expr – Term 3,3 red. 3<br />
$ Expr 1,1 red. 1<br />
$ Goal none accept<br />
5 shifts +<br />
9 reduces<br />
+ 1 accept
Stack Input Action<br />
$ id – num * id shift<br />
$ id – num * id red. 9<br />
$ Factor – num * id red. 7<br />
$ Term – num * id red. 4<br />
$ Expr – num * id shift<br />
$ Expr – num * id shift<br />
$ Expr – num * id red. 8<br />
$ Expr – Factor * id red. 7<br />
$ Expr – Term * id shift<br />
$ Expr – Term * id shift<br />
$ Expr – Term * id red. 9<br />
$ Expr – Term *<br />
red. 5<br />
Factor<br />
$ Expr – Term red. 3<br />
$ Expr red. 1<br />
$ Goal accept<br />
Exemplo<br />
Term<br />
Fact.<br />
Goal<br />
Expr<br />
Expr -<br />
Term<br />
Fact.<br />
<br />
Term<br />
*<br />
Fact.<br />
Avançar e Reduzir<br />
Shift reduce parsers são mais simples <strong>de</strong> ser construídos e<br />
facilmente entendidos<br />
Um shift-reduce parser tem apenas quatro ações<br />
• Shift — próxima palavra é avançada e empilhada<br />
• Reduce — lado direito do handle está no topo da pilha<br />
Localiza o lado esquerda do handle <strong>de</strong>ntro da pilha<br />
Desempilha o handle & empilha apropriadamente lhs<br />
• Accept — parar o parsing & reportar sucesso<br />
• Error — chamar um relato <strong>de</strong> erro /rotina <strong>de</strong> rec<strong>up</strong>eração<br />
Shift executa apenas empilhar e uma chamada para o léxico<br />
Reduce toma |rhs| <strong>de</strong>sempilha & 1 empilha