DCC063
Linguagens Formais
e Autômatos
Conjunto FIRST
Seja
uma sequência qualquer gerada por G.
Definimos como sendo
FIRST
(
) o conjunto de
símbolos terminais que iniciam
ou sequências
derivadas (direta ou indiretamente) de
.
Se = ou
* , então FIRST().
Para computar FIRST(
) para todos os símbolos
X de uma GLC G, aplique as seguintes regras até
que nenhum símbolo terminal ou
passa ser
adicionado a qualquer conjunto FIRST.
Análise Sintática Descendente
Baseadas em AP
Conjunto FIRST
1.Se X for um terminal, então FIRST(X) = {X}
2.Se X → for uma produção, adicionar a FIRST(X)
3.Se X for um não terminal e X → Y1Y2...Yk uma produção, colocar a em FIRST(X) se, para algum i, a estiver em
FIRST(Yi) e estiver em todos os FIRST(Y1),..., FIRST(Yi-1); isto é, se Y1...Yi-1 *.
4.Se X → 1|2|...|n| forem produções de G, então
FIRST(X) = FIRST(1) FIRST(2) ... FIRST(n)
Análise Sintática Descendente
Baseadas em AP
Conjunto FIRST
Assim podemos computar FIRST para qualquer
cadeia X
1X
2...X
n. Adicionar a FIRST(X
1X
2...X
n) :
todos os símbolos não- de FIRST(X1); todos os símbolos não- de FIRST(X2) se estiver em FIRST(X1);
todos os símbolos não- de FIRST(X3) se estiver em ambos: FIRST(X1) e FIRST(X2); e assim por diante.
o símbolo se, para todo i, FIRST(Xi)
Análise Sintática Descendente
Baseadas em AP
Conjunto FIRST
Para determinar manualmente o conjunto FIRST
dos não terminais de uma GLC:
1.Crie uma tabela TABFIRST cujas linhas são rotuladas com os não terminais da gramática e com uma coluna rotulada como FIRST que irá conter os símbolos pertencentes ao FIRST de cada não-terminal. Inicialize cada célula com .
2.Para cada um dos não-terminais, calcule o seu conjunto FIRST utilizando as regras anteriores.
3.Repita o passo 2 até que não ocorra mais nenhuma modificação na tabela
Análise Sintática Descendente
Baseadas em AP
Conjunto FIRST
Exemplo: calcular o conjunto FIRST para cada
não terminal da gramática
S → ABS | aA A → | a
B → Bb | cd
Inicialmente, construir a tabela:
Análise Sintática Descendente
Baseadas em AP
6
NT FIRST
S
A
Conjunto FIRST
Exemplo:
Pelas regras, FIRST(S) = FIRST(ABS) FIRST(aA). Como FIRST(A) = , então FIRST(S) = {a}. A tabela fica:
Análise Sintática Descendente
Baseadas em AP
7
N FIRST
S a
A
B
S → ABS | aA A → | a
Conjunto FIRST
Exemplo:
FIRST(A) = {, a}. A tabela fica:
Análise Sintática Descendente
Baseadas em AP
8
N FIRST
S a
A {, a}
B
S → ABS | aA A → | a
Conjunto FIRST
Exemplo:
FIRST(B) = FIRST(Bb) FIRST(cd) =
{c}
. A tabela fica:Análise Sintática Descendente
Baseadas em AP
9
N FIRST
S a
A {, a}
B {c}
S → ABS | aA A → | a
Conjunto FIRST
Exemplo:
A tabela foi modificada, logo o passo 2 deve ser repetido.
FIRST(S) = FIRST(ABS) FIRST(aC) = {a} FIRST(BS) {a} =
{a} {c} {a} = {a, c}. Assim, a tabela fica:
Análise Sintática Descendente
Baseadas em AP
10
N FIRST
S {a, c}
A {, a}
B {c}
S → ABS | aA A → | a
B → Bb | cd
N FIRST
S a
A {, a}
Conjunto FIRST
Exemplo:
O cálculo do FIRST de A e B não modifica a tabela. Mas como houve uma modificação no FIRST de S, o passo 2 deve ser novamente executado. Como desta vez não haverá modificações, a última tabela será, de fato, a definitiva.
Análise Sintática Descendente
Baseadas em AP
11
N FIRST
S {a, c}
A {, a}
B {c}
S → ABS | aA A → | a
Conjunto FOLLOW
Define-se FOLLOW(A), para o não terminal A,
como sendo o conjunto de terminais
a
que
podem figurar imediatamente à direita de A em
alguma forma sentencial.
Isto é, FOLLOW(A) é o conjunto de terminais
a
tais que exista uma derivação da forma
S
*
Aa
, para algum
e
.
Se A puder ser o símbolo mais à direita em
alguma forma sentencial (
S
*
A
), então $ está
em FOLLOW(A).
Análise Sintática Descendente
Baseadas em AP
Conjunto FOLLOW
Note que podem ter existido, em algum tempo
durante a derivação, símbolos entre A e
a
, mas,
se assim o foi, os mesmos derivam
e
desaparecem.
Para Computar FOLLOW(A) para todos os
não-terminais A da gramática G, aplicar as seguintes
regras até que nada mais possa ser adicionado a
qualquer conjunto FOLLOW.
Análise Sintática Descendente
Baseadas em AP
Conjunto FOLLOW
Algoritmo
1. Colocar $ em FOLLOW(S), onde S é o símbolo de partida de G e $ o marcador de fim de entrada
2. Se existir a produção A →B, com , então tudo em FIRST(), exceto , é colocado em FOLLOW(B).
3. Se existir uma produção A →B ou A →B tal que
e FIRST(), então tudo em FOLLOW(A) está em FOLLOW(B).
Análise Sintática Descendente
Baseadas em AP
Conjunto FOLLOW
Observações
a) A função FIRST é definida para cadeias de símbolos;
b) A função FOLLOW só é definida para não-terminais;
c) Os elementos de um conjunto FIRST pertencem ao conjunto T{};
d) Os elementos de um conjunto FOLLOW pertencem ao conjunto T{$}.
Análise Sintática Descendente
Baseadas em AP
Conjunto FOLLOW
Exemplo. Calcular o conjunto FOLLOW para
todos os não-terminais da gramática
Análise Sintática Descendente
Baseadas em AP
16
E → TE’
E’ → +TE’ | T → FT’
Conjunto FOLLOW
Exemplo. 1º) Calcular o FIRST:
Análise Sintática Descendente
Baseadas em AP
17
E → TE’
E’ → +TE’ | T → FT’
T’ → *FT’ | F → (E) | id N FIRST
E {(, id}
E’ {+, } T {(, id}
Conjunto FOLLOW
Exemplo. 2º) Calcular o FOLLOW:
Análise Sintática Descendente
Baseadas em AP
18
E → TE’
E’ → +TE’ | T → FT’
T’ → *FT’ | F → (E) | id
N FOLLOW
E {$, )}
E’ {$, )} T {+, $, )}
T’ {+, $, )} F {*, +, $, )}
N FIRST
E {(, id}
E’ {+, } T {(, id}
Conjunto FOLLOW
Para computar os conjuntos FOLLOW, colocamos $ em
FOLLOW(E) pela regra (1). Pela regra (2), aplicada à produção F → (E), o parênteses à direita etá em FOLLOW(E). Pela regra (3), aplicada à produção E →
TE’, o $ e o parênteses direito estão em FOLLOW(E’). Como E’→ , também estão em FOLLOW(T). Como um último exemplo de como as regras podem ser aplicadas, a produção E→ TE’ implica, pela regra (2) que tudo que não for em FIRST(E’) precisa ser colocado em FOLLOW(T). Já vimos que $ está em FOLLOW(T).
Análise Sintática Descendente
Baseadas em AP
Exercício. Calcular os conjuntos FIRST e FOLLOW para a gramática
S
→
XYZ
X
→
aXb |
Y
→
cYZcX | d
Z
→
eZYe | f
Análise Sintática Descendente
Baseadas em AP
20
Resposta:
FIRST(S) = {a, c, d} FOLLOW(S) = {$}
FIRST(X) = {a,
}
FOLLOW(X) = {c, d, b, e, f}
FIRST(Y) = {c, d}
FOLLOW(Y) = {e, f}
Algoritmo para construir a tabela
sintática preditiva
Reescrever a gramática G para satisfazer as condições
de LL(1) (sem recursão à esquerda e fatorada);
Calcular os conjuntos FIRST e FOLLOW de G e criar
uma tabela, onde as linhas são rotulados por
não-terminais e as colunas por não-terminais
{$}. Colocar em
cada M[A
i, a
j] uma produção de G.
Análise Sintática Descendente
Baseadas em AP
Algoritmo para construir a tabela
sintática preditiva
Para cada produção A
→
α
de uma GLC G
Para cada a FIRST(α), exceto
◼ incluir a produção A → α em M[A, a]
Se FISRT(α)
◼ incluir a produção A → α em M[A, b] para cada b em FOLLOW(A)
Se FISRT(α) e $FOLLOW(A)
◼ incluir A → α a M[A,$]
Análise Sintática Descendente
Baseadas em AP
Algoritmo para construir a tabela
sintática preditiva
A tabela preditiva deve possuir a propriedade de que,
para cada entrada da tabela M, exista no máximo uma
produção.
Isto viabiliza a análise determinística da sentença de
entrada.
Se uma gramática G possuir esta propriedade, diz-se
que ela é LL(1).
Análise Sintática Descendente
Baseadas em AP
Exemplo: tabela
sintática preditiva
Construir a tabela sintática para a gramática abaixo:
Análise Sintática Descendente
Baseadas em AP
24
S
→
cAa
A
→
cB | B
B
→
bcB |
Onde:
FIRST(S) = {c}
FOLLOW(S) = {$}
FIRST(A) = {b, c,
}
FOLLOW(A) = {a}
Exemplo: tabela
sintática preditiva
Construir a tabela sintática para a gramática abaixo:
Linhas: não-terminais.
Colunas: terminais
{$}
Análise Sintática Descendente
Baseadas em AP
25
S → cAa FIRST(S) = {c} FOLLOW(S) = {$} A → cB | B FIRST(A) = {b, c, } FOLLOW(A) = {a} B → bcB | FIRST(B) = {b, } FOLLOW(B) = {a}
a b c $
S
A
B
S → cAa A → cB A → B
B → bcB A → B
Linguagens LL
Para que esta propriedade se verifique, a gramática
considerada deverá satisfazer as seguintes condições
(LL(1)):
a. Não possuir recursão à esquerda;
b. Estar fatorada;
c. Para todo A∈N tal que A *ε:
FIRST(A)∩FOLLOW(A) = ∅
Se estas condições forem satisfeitas, então é possível
construir um APD para a linguagem subjacente.
Análise Sintática Descendente
Baseadas em AP
Construção de AP a partir da tabela sintática
AP por meio da tabela sintática:
o alfabeto de entrada = T; o alfabeto da pilha = TN;
o conjunto de estados Q = {p, q} {qa| aT {$}}; o estado inicial p;
o conjunto de estados finais F = {q$};
27
Construção de AP a partir da tabela sintática
a função de transição
é definida da seguinte forma:
28
Autômatos de Pilha
(
)
(
)
(
)
*:Q T T N →Q T N
Construção de AP a partir da tabela sintática
Exemplo. APD para a gramática de expressões
aritméticas (gramática a esquerda):
Análise Sintática Descendente
Baseadas em AP
29
E → TE’
E’ → +TE’ | T → FT’
T’ → *FT’ | F → (E) | id
N FIRST
E {(, id}
E’ {+, } T {(, id}
T’ {*, } F {(, id}
N FOLLOW
E { $,) }
E’ { $,) }
T { +, $,) }
Construção de AP a partir da tabela sintática
Exemplo. Tabela sintática:
(APD no quadro)
Análise Sintática Descendente
Baseadas em AP
30
N Símbolo de entrada
id + * ( ) $
E E→TE’ E→TE’
E’ E’→+TE’ E’→ E’→
T T→FT’ T→FT’
T’ T’→ T’→*FT’ T’→ T’→