Professor: Gabriel Soares Baptista
Na aula anterior, o parser era descendente.
FIRST, FOLLOW e um símbolo de lookaheadHoje o parser será ascendente.
LR(0) lê da esquerda para a direita e reconstrói uma derivação mais à direita ao contrário.
Considere:
$$ S \to aS \mid b $$
Essa gramática gera:
babaabaaab$$ FIRST(S)=\{a,b\} $$
$$ FOLLOW(S)=\{\$\} $$
| Não terminal | a |
b |
$ |
|---|---|---|---|
S |
$S \to aS$ | $S \to b$ | erro |
Entrada: aab$
| Pilha | Entrada | Ação |
|---|---|---|
$ S |
a a b $ |
usa $S \to aS$ |
$ S a |
a a b $ |
casa a |
$ S |
a b $ |
usa $S \to aS$ |
$ S a |
a b $ |
casa a |
$ S |
b $ |
usa $S \to b$ |
$ b |
b $ |
casa b |
$ |
$ |
aceita |
O LR(0) faz o movimento oposto.
LR(0) é simples, mas restritivo. Muitas gramáticas precisam de SLR, LR(1) ou LALR.
| Operação | Notação | Ideia |
|---|---|---|
| Shift | sN |
consome um terminal e vai para o estado N |
| Reduce | rK |
reduz pelo corpo da produção K |
| Goto | N |
desvia após reconhecer um não terminal |
| Accept | acc |
aceita a entrada |
Se a pilha guardasse apenas símbolos, o parser não saberia em que ponto da gramática está.
Antes de construir o autômato, adicionamos uma nova produção inicial.
Gramática original:
$$ S \to a $$
Gramática aumentada:
$$ S' \to S $$
A produção aumentada cria o estado de aceitação.
O parser reconheceu um S completo e não sobrou entrada real.
Um item LR(0) é uma produção com um ponto.
$$ A \to XYZ $$
| Item | Leitura |
|---|---|
| $A \to \cdot XYZ$ | ainda não reconheci nada |
| $A \to X \cdot YZ$ | reconheci X, falta YZ |
| $A \to XY \cdot Z$ | reconheci XY, falta Z |
| $A \to XYZ \cdot$ | reconheci tudo, posso reduzir |
Closure completa um conjunto de itens.
Regra:
Se existe $A \to \alpha \cdot B \beta$ e
Bé não terminal, adicionamos todos os itens $B \to \cdot \gamma$.
B, preciso considerar todas as formas pelas quais B pode começar.
Gramática aumentada:
$$ \begin{split} S' &\to S \\ S &\to aS \mid b \end{split} $$
Começamos com:
$$ S' \to \cdot S $$
Como o ponto está antes de S, adicionamos as produções de S com ponto no início.
$$ I_0 = \left\{ \begin{array}{l} S' \to \cdot S \\ S \to \cdot aS \\ S \to \cdot b \end{array} \right\} $$
Goto(I, X) responde:
se estou no estado
Ie reconheço o símboloX, para onde vou?
Procedimento:
XClosure ao resultadoEstado inicial:
$$ I_0 = \left\{ \begin{array}{l} S' \to \cdot S \\ S \to \cdot aS \\ S \to \cdot b \end{array} \right\} $$
O item com a depois do ponto é:
$$ S \to \cdot aS $$
Depois de reconhecer a:
$$ S \to a \cdot S $$
Agora o ponto ficou antes de S.
S é não terminal, entram todas as produções de S com ponto no início.
A tabela tem duas partes.
| Parte | Colunas | Conteúdo |
|---|---|---|
ACTION |
terminais e $ |
shift, reduce, accept, erro |
GOTO |
não terminais | próximo estado |
shiftgotoreduceaccept em $Reduções comuns entram em todas as colunas de ACTION.
$$ S \to a $$
Gramática aumentada:
$$ \begin{array}{rcl} (0) & S' & \to S \\ (1) & S & \to a \end{array} $$
$$ I_0 = \left\{ \begin{array}{l} S' \to \cdot S \\ S \to \cdot a \end{array} \right\} $$
| Origem | Símbolo | Destino |
|---|---|---|
I0 |
S |
I1 |
I0 |
a |
I2 |
| Estado | ACTION a |
ACTION $ |
GOTO S |
|---|---|---|---|
0 |
s2 |
1 |
|
1 |
acc |
||
2 |
r1 |
r1 |
r1: $S \to a$
a$| Pilha | Entrada | Ação |
|---|---|---|
0 |
a $ |
s2 |
0 a 2 |
$ |
r1: $S \to a$ |
0 S 1 |
$ |
acc |
a antes de b$$ S \to aS \mid b $$
Gramática aumentada:
$$ \begin{array}{rcl} (0) & S' & \to S \\ (1) & S & \to aS \\ (2) & S & \to b \end{array} $$
$$ I_0 = \left\{ \begin{array}{l} S' \to \cdot S \\ S \to \cdot aS \\ S \to \cdot b \end{array} \right\} $$
| Origem | Símbolo | Destino |
|---|---|---|
I0 |
S |
I1 |
I0 |
a |
I2 |
I0 |
b |
I3 |
I2 |
S |
I4 |
I2 |
a |
I2 |
I2 |
b |
I3 |
$$ \begin{split} I_1 &= \{S' \to S \cdot\} \\ I_3 &= \{S \to b \cdot\} \\ I_4 &= \{S \to aS \cdot\} \end{split} $$
I3 reduz por $S \to b$.
I4 reduz por $S \to aS$.
| Estado | ACTION a |
ACTION b |
ACTION $ |
GOTO S |
|---|---|---|---|---|
0 |
s2 |
s3 |
1 |
|
1 |
acc |
|||
2 |
s2 |
s3 |
4 |
|
3 |
r2 |
r2 |
r2 |
|
4 |
r1 |
r1 |
r1 |
aab$| Pilha | Entrada | Ação |
|---|---|---|
0 |
a a b $ |
s2 |
0 a 2 |
a b $ |
s2 |
0 a 2 a 2 |
b $ |
s3 |
0 a 2 a 2 b 3 |
$ |
r2: $S \to b$ |
0 a 2 a 2 S 4 |
$ |
r1: $S \to aS$ |
0 a 2 S 4 |
$ |
r1: $S \to aS$ |
0 S 1 |
$ |
acc |
O parser reconstruiu a cadeia de baixo para cima.
$$ E \to E + n \mid n $$
n, depois reduz para E$$ \begin{array}{rcl} (0) & E' & \to E \\ (1) & E & \to E + n \\ (2) & E & \to n \end{array} $$
Estado inicial:
$$ I_0=\left\{ \begin{array}{l} E' \to \cdot E \\ E \to \cdot E + n \\ E \to \cdot n \end{array} \right\} $$
$$ \begin{split} I_1 &= \left\{ \begin{array}{l} E' \to E \cdot \\ E \to E \cdot + n \end{array} \right\} \\ I_2 &= \{E \to n \cdot\} \\ I_3 &= \{E \to E + \cdot n\} \\ I_4 &= \{E \to E + n \cdot\} \end{split} $$
| Origem | Símbolo | Destino |
|---|---|---|
I0 |
E |
I1 |
I0 |
n |
I2 |
I1 |
+ |
I3 |
I3 |
n |
I4 |
| Estado | ACTION n |
ACTION + |
ACTION $ |
GOTO E |
|---|---|---|---|---|
0 |
s2 |
1 |
||
1 |
s3 |
acc |
||
2 |
r2 |
r2 |
r2 |
|
3 |
s4 |
|||
4 |
r1 |
r1 |
r1 |
n+n$| Pilha | Entrada | Ação |
|---|---|---|
0 |
n + n $ |
s2 |
0 n 2 |
+ n $ |
r2: $E \to n$ |
0 E 1 |
+ n $ |
s3 |
0 E 1 + 3 |
n $ |
s4 |
0 E 1 + 3 n 4 |
$ |
r1: $E \to E + n$ |
0 E 1 |
$ |
acc |
Nem toda gramática é LR(0).
Conflitos comuns:
| Conflito | Significado |
|---|---|
shift/reduce |
o estado quer empilhar e reduzir |
reduce/reduce |
o estado quer reduzir por duas produções |
O conflito aparece quando um estado contém ao mesmo tempo:
ACTION.
| Aspecto | LL(1) | LR(0) |
|---|---|---|
| Direção | top-down | bottom-up |
| Derivação | mais à esquerda | mais à direita ao contrário |
| Pilha | símbolos esperados | estados e símbolos reconhecidos |
| Decisão | FIRST, FOLLOW, lookahead |
itens e estados |
| Recursão à esquerda | problema | natural |
Closure do item inicial.Goto até fechar os estados.ACTION e GOTO.Construa a tabela LR(0) para:
$$ S \to c $$
Depois simule:
$$ c\$ $$
Construa a tabela LR(0) para:
$$ S \to aS \mid c $$
Depois simule:
$$ aac\$ $$
Construa a tabela LR(0) para:
$$ E \to E * n \mid n $$
Depois simule:
$$ n*n\$ $$
Considere:
$$ \begin{split} S &\to A \\ A &\to aA \mid b \end{split} $$
Faça:
aab$Closure expande possibilidades antes de não terminaisGoto cria as transições entre estadosACTION decide shift, reduce e acceptGOTO move entre estados após uma reduçãoO mais importante é dominar a construção da tabela.
Depois que a tabela está pronta, a execução é mecânica: