Gramatyki LL(k)

Transkrypt

Gramatyki LL(k)
Gramatyki LL(k)
Odtwarzanie wywodu lewostronnego metodą top-down
wyprowadzenie
lewostronne
już terminale
pierwszy od lewej
nieterminal, którym
zastępujemy prawą stronę
pewnej produkcji
G = < N, T, P, Z > ∈ GBK
v = a1...an
- analizowane słowo
Załóżmy, że v∈L(G).
Wówczas:
Z = uo ⇒Lp1 u1 ⇒ Lp2 u2 ⇒L ... ⇒Lpm um = v
pi – numery produkcji
p1 ... pm – rozkład lewostronny słowa v
Poszukujemy tego rozkładu!
Przypuśćmy, że :
Szukamy:
ui = a1 ... aj Aα
(wyprowadzono już poprawnie pierwsze symbole)
ui+1 i pi+1 takich, że:
ui ⇒Lp i+1 ui+1
Znamy:
(1) a1 ... aj – wyprowadzona, początkowa część słowa
(2) aj+1 ... aj+k – następnych k symboli słowa wejściowego
(3) nieterminal A
Pytamy:
którą produkcję A → β należy zastosować w wyprowadzeniu. Jeśli odpowiedź na to
pytanie jest jednoznaczna (∀i) to G jest klasy LL(k)
a1
a1
A
aj b
aj aj+1
a
aj+kaj+k+1
an
Niech:
ω, x, y ∈ T*
β, γ ∈ (N∪T)*
A
∈N
G = < N, T, P, Z > ∈ GBK jest klasy LL(k) ⇔ gdy dla każdej pary wywodów lewostronnych:
(1) Z ⇒L* ωAα ⇒L ωβα ⇒L* ωx
(2) Z ⇒L* ωAα ⇒L ωγα ⇒L* ωy
jeżeli FIRSTk(x) = FIRSTk(y) to β = γ
Z
ω
α
A
ω
α
β
ω
x
k
Przykład:
G = < { S, D }, { a, b }, P, S >
(1)
(2)
(3)
(4)
S→aDS
S→b
D→a
D→bSD
Pytanie: czy G jest klasy LL(1) ?
S ⇒L* a D S
ω Aα
Z
⇒L(3) a a S
ωβ α
⇒L* a a b
ωx
⇒L(3) a a S
ωγα
⇒L* a a a a b
ω y
Jeśli FIRST(x) = FIRST(y) = a
to produkcja (3)
⇒L(4) a bSD S ⇒L* a b b a b
ω β α
ω x
Jeśli FIRST(x) = FIRST(y) = b
to produkcja (4)
⇒L(4) a bSD S ⇒L* a b a a b a b
ω γ α
ω y
Takie rozumowanie można uogólnić na wszystkie możliwe wywody
S ⇒L* ωSα ⇒ ...
oraz S ⇒L* ωDα ⇒ ...
Więc gramatyka jest LL(1) !
Przykład:
G = < { S, D, E }, { 0, 1, a, b }, P, S >
(1) S → D
(2) S → E
(3) D → a D b
(4) D → 0
(5) E → a E b b
(6) E → 1
L(G) = { an 0 bn : n ≥ 0 } ∪ { an 1 b2n : n ≥ 0 }
S ⇒L* S
Z
ωA α
⇒L(1) D ⇒L* ak 0 bk
ωβα
ω x
⇒L(2) E ⇒L* ak 0 b2k
ωγα
ω y
(ω=ε;α=ε;)
Dla dowolnego k FIRSTk(x) = FIRSTk(y) = ak, ale β ≠ γ ( D ≠ E ).
Ponieważ k było dowolne – gramatyka G nie jest LL(k) dla żadnego k !
Tw.
pozwalające stwierdzić (w oparciu o zbiór produkcji), czy gramatyka jest klasy LL(k)
dla danego k
G ∈ GBK jest klasy LL(k) ⇔ ∀ ( A → β ) ∈ P , ( A → γ ) ∈ P : β ≠ γ
∀ α : Z ⇒L* ωAα
zachodzi: FIRSTk(βα) ∩ FIRSTk(γα) = ∅
Przykład:
(1) S → S a
(2) S → b
Rozważamy: wyprowadzenia
produkcje
S ⇒Li S ai
S→Sa
S→b
*
A→β
A→γ
Z ⇒L ωAα
Dla k ≤ i mamy
FIRSTk( βα ) = FIRSTk(Saai )
= { bak-1 }
FIRSTk( γα ) = FIRSTk(bai )
= { bak-1 }
Ponieważ i – dowolne, k ≤ i, więc G nie może być klasy LL(k) dla żadnego k.
Uwaga: żadna gramatyka z lewostronną rekursją nie jest klasy LL(k) dla żadnego k.
Tw.
G ∈ GBK jest klasy LL(1) ⇔ ∀ ( A → α1 | α2 | ... | αn ) ∈ P zachodzi:
(1) FIRST1( α1 ), FIRST1( α2 ), ... , FIRST1( αn ) są parami rozłączne, oraz
(2) jeżeli αi ⇒* ε to
FIRST1( αj ) ∩ FOLLOW1( A ) = ∅ (pusty) dla 1 ≤ j ≤ n ∧ i ≠ j
Przykład:
Poprzednia gramatyka
S→Sa|b
po przekształceniu ma postać:
S → b S′
S′ → a S′ | ε
i jest klasy LL(1) bo:
(1)
FIRST1( α1 ) = FIRST1( aS′ ) = { a }
FIRST1( α2 ) = FIRST1( ε ) = { ε }
FIRST1( α1 ) ∩ FIRST1( α2 ) = ∅
(2)
ε ⇒* ε
FIRST1( α1 ) = FIRST1( aS′ )
FOLLOW1( A ) = FOLLOW1( S′ )
={a}
={$}
FIRST1( α1 ) ∩ FOLLOW1( A ) = FIRST1( aS′ ) ∩ FOLLOW1( S′ ) = ∅
Tw.
(1) G ∈ GBK jest klasy LL(k) ⇒ ∃ G′ ∈ GBK :
(a) G′ - jest klasy LL( k+1 )
(b) G′ - nie zawiera ε-produkcji
(c) L(G′) = L(G)
(2) G ∈ GBK jest klasy LL(k), gdzie k≥2,
oraz G nie zawiera ε-produkcji ⇒ ∃ G′∈GBK :
(a) G′ - jest klasy LL( k-1 )
(b) L( G′ ) = L(G)
Przekształceniem obniżającym stopień gramatyki LL kosztem wprowadzenia ε-produkcji jest
lewostronna faktoryzacja. Polega ona na zamianie produkcji postaci:
A → αβ1 | ... | αβk
na produkcje:
A → αA′
A′ → β1 | ... | βk
Przykład:
Gramatyka:
S→aS|a
A → α β1 | α β2
Po lewostronnej faktoryzacji jest klasy LL(1), ale zawiera ε-produkcje
S → a S′
S′ → S | ε
A → α A′
A′ → β1 | β2