Está en la página 1de 12

LINGUAGGI LL(1)

Ricorsione sinistra

In generale se esiste la regola con ricorsione sinistra

Y  Y x1 | Y x2 | … | Y xn | v1 | v2 | … | vm

questa può essere sostituita con le regole equivalenti:

Y  (v1 | v2 | … | vm)Y’
Y’  (x1 | x2 | … | xn )Y ’ | ε

Fattorizzazione sinistra

La fattorizzazione sinistra serve ad eliminare un eventuale prefisso comune a due parti destre
di regole associate allo stesso simbolo non terminale

– Se una regola della grammatica ha la forma

A  y v | y w,

con y ∈ V+, v ∈ V* e w ∈ V+ e le stringhe v e w non hanno prefissi


comuni,

– è necessario fattorizzare a sinistra sostituendo la regola con:

A  yA’
A’  v | w

dove A’ è un nuovo simbolo non terminale.

Insiemi FIRST

Se x ∈ V*, si definisce FIRST(x) l’insieme di simboli terminali a tale che x ⇒+ a y. Se x ⇒+ ε


allora anche ε è in FIRST(x).

-Se t ∈ VT allora FIRST(t) = { t }; (per completezza si pone FIRST(ε) = ∅)

-Se X ∈ VN allora FIRST(X)= { t | t ∈ VT, X ⇒+ tu, u ∈ V*};

-Se X  x1 | x2 | … | xn , FIRST(X) = ∪n i=1 FIRST(xi).

- Se y  y1 y2… yn con yi ∈ V:

1. se y1 non deriva ε, FIRST(y) = FIRST(y1);


2. se yi ⇒+ ε, per i = 1, …, k e k < n, e y k+1 non deriva ε,
FIRST(y) è l’unione dei FIRST(yi);
3. Se tutti gli yi derivano ε allora FIRST(y) contiene ε.

Grammatiche LL(1)

Una grammatica si dice LL(1) se, per ogni regola

X  x1 | x2 | … | xn , con xi ∈ V*, i=1,…,n,

sono soddisfatte le condizioni seguenti (dette condizioni LL(1)):

1. gli insiemi FIRST(xi) sono a due a due disgiunti;


2. Esiste un solo xj tale che xj ⇒+ ε e, se esiste, allora devono essere disgiunti gli insiemi
FOLLOW(X) e FIRST(X).
ESERCIZIO 1

Data la seguente grammatica, stabilire se è LL(1):


S → aBbE | b | Db
B → BcA | A
A → d | df | dfCg
C → Ch | i | ε
D → Ah | ε
E → Ch | a

Fattorizzazione:

S → aBbE | b | Db
B → BcA | A
A → dA’
A’ → fA’’ | ε
A’’ → Cg | ε
C → Ch | i | ε
D → Ah | ε
E → Ch | a

Eliminazione ricorsione sinistra

S → aBbE | b | Db
B → AB’
B’ → cAB’ | ε
A → dA’
A’ → fA’’ | ε
A’’ → Cg | ε
C → iC’ | C’
C’ → hC’ | ε
D → Ah | ε
E → Ch | a

Insiemi FIRST:

FIRST(S) ⊇ {a, b} ∪ FIRST(D) = {a, b, d, ε}


FIRST(B) ⊇ FIRST(A) = {d}
FIRST(B’) = {c, ε}
FIRST(A) = {d}
FIRST(A’) = {f, ε}
FIRST(A’’) ⊇ FIRST(C) ∪ {ε} = {g, i, h, ε}
FIRST(C) ⊇ {i} ∪ FIRST(C’) = {i, h, ε}
FIRST(C’) = {h, ε}
FIRST(D) ⊇ FIRST(A) ∪ {ε} = {d, ε}
FIRST(E) ⊇ FIRST(C) ∪ {a} = {a, i, h, ε}
Insiemi FOLLOWS:
FOLLOWS(S) = {$}
FOLLOWS(B) = {b}
FOLLOWS(B’) = {b}
FOLLOWS(A) =FIRST(B’) ∪ FOLLOWS(B) ∪ {h}={c, b, h}
FOLLOWS(A’) = {c, b, h}
FOLLOWS(A’’) = {c, b, h}
FOLLOWS(C) = {g, h}
FOLLOWS(C’) = {g, h}
FOLLOWS(D) = {b}
FOLLOWS(E) = {$}

La grammatica non è LL(1) perché:

1. In A’’ → Cg | ε FIRST(A’’) ∩ FOLLOWS(A’’)={h} (violazione regola 2)


2. C’ → hC’ | ε FIRST(C’) ∩ FOLLOWS(C’)={h} (violazione regola 2)

ESERCIZIO 2

Scrivere un parser discendente per il linguaggio definito dalla grammatica le cui produzioni
sono di seguito riportate:
Risoluzione :

INSIEME dei FIRST:


INSIEMI dei FOLLOW:
L’unico conflitto nella tabella di parsing è per la regola:
TABELLA di PARSING

La grammatica non è LL(1) a causa dell’ambiguità presente nella cella a sfondo grigio. Nella scrittura
del parser discendente in Java sceglieremo di considerare in corrispondenza di un’ambiguità una sola
regola, in particolare la prima, ottenendo così un parser di un sottoinsieme del linguaggio originario.

También podría gustarte