Języki, automaty i obliczenia/Wykład 9: Języki bezkontekstowe i ich gramatyki

Z Studia Informatyczne
Przejdź do nawigacjiPrzejdź do wyszukiwania

W tym wykładzie rozpoczniemy omawianie drugiej w hierarchii Chomsky'ego rodziny języków formalnych, a mianowicie języków bezkontekstowych. Przedstawimy gramatyki bezkontekstowe i ich prostsze, a zarazem równoważne, postacie.

Gramatyki języków bezkontekstowych

Języki typu (2), zwane językami bezkontekstowymi, są rodziną szerszą niż omówione wcześniej języki regularne. Jak stwierdziliśmy w poprzednich wykładach gramatyki regularne generują poprawne napisy poprzez ciąg przepisywań metodą "od lewej do prawej". Natomiast gramatyki bezkontekstowe, zwane w lingwistyce gramatykami bezkontekstowych struktur frazowych, generują poprawne napisy poprzez sekwencję przepisywań, która ma strukturę drzewa. Ze względu na tę właśnie strukturę, gramatyki bezkontekstowe nadają się bardzo dobrze do opisu syntaktyki języków programowania. Z tego też powodu nastąpił szybki rozwój teorii gramatyk i języków bezkontekstowych.

Na wstępie przypomnijmy, że każda produkcja jakiejkolwiek gramatyki bezkontekstowej G=(VN,VT,v0,P) ma postać vx1.xk lub v1, gdzie vVN,xi(VNVT). Często korzystać będziemy z możliwości przedstawienia graficznego takiej produkcji. Mianowicie każdej produkcji odpowiada etykietowane drzewo z wyróżnionym wierzchołkiem początkowym.

Rysunek 1

Drzewo odpowiadające pojedynczej produkcji z gramatyki G nazywane jest drzewem elementarnym. Mając dowolne wyprowadzenie w gramatyce G, można przedstawić je graficznie w postaci etykietowanego drzewa. Niech

v0w1..wn=w

będzie wyprowadzeniem słowa w w gramatyce G. Drzewo reprezentujące to wyprowadzenie powstaje z połączenia drzew elementarnych odpowiadających pojedynczym produkcjom występującym w wyprowadzeniu słowa w w taki sposób, aby spełnić poniższe warunki:

  • wierzchołek początkowy jest etykietowany przez v0,
  • każdy wierzchołek nie będący liściem, czyli wierzchołkiem maksymalnym w drzewie, jest oznaczony przez elementy z VN,
  • jeśli vVN jest symbolem nieterminalnym występującym w słowie wi w wyprowadzeniu w, to bezpośrednie następniki wierzchołka etykietowanego przez v są oznaczone przez symbole x1,,xk (porządek od lewej do prawej), gdzie vx1xkP i ta

właśnie produkcja została wykorzystana w bezpośrednim wyprowadzeniu wiwi+1, to znaczy we fragmencie wyprowadzenia v0*wn=w,

  • wierzchołki maksymalne drzewa (ciąg liści "od lewej strony") to słowo w, przy czym, jeśli wszystkie wierzchołki maksymalne są etykietowane przez 1, to w=1, a w przeciwnym razie wierzchołki oznaczone przez 1 pomijamy.

Przykład 1.1

Niech G=(VN,VT,v0,P), gdzie VN={v0,v1},VT={a,b,c},
P={v0av0c,v0bv1c,v1bv1c,v1bc}.

Wówczas wyprowadzeniu
v0av0cabv1ccabbccc
odpowiada drzewo
Rysunek 2

W poniższym przykładzie, jak i w dalszych wykładach symbolem A oznaczamy kopię alfabetu A, o której zakładać będziemy, że jest to zbiór rozłączny z oryginalnym alfabetem.

Przykład 1.2

  1. Język Dycka.
    Określamy bezkontekstową gramatykę G=(VN,VT,v0,P), w której VN={v0,v1},VT=AA, ;A={a}, ;A={a},P=
    {v01,v0v1v0,v1av0a}.
    Język generowany przez tę gramatykę, nazywany językiem Dycka, oznaczany jest przez DA*. Język Dycka zwany jest też językiem "poprawnych nawiasów" przy interpretacji symboli a,a jako lewego i prawego nawiasu.
    L(G)={1,aa,aaaa,aaaa,aaaaaa,}
    Język Dycka można zdefiniować także dla alfabetu A={a1,,an} mającego więcej niż dwa symbole. Do zbioru praw gramatyki G wprowadza się wszystkie możliwe prawa postaci v1aiv0ai. W tym przypadku dla języka Dycka używa się oznaczenia Dn*, aby zaznaczyć liczbę elementów alfabetu A.
  2. Język Łukasiewicza.
    Język Łukasiewicza jest generowany przez gramatykę bezkontekstową G=(VN,VT,v0,P), gdzie VN={v0}, VT={a,b,+,*},v0=v oraz P={va,vb,v+vv,v*vv}. Język Łukasiewicza jest więc zbiorem
    L(G)={a, :b,+ab,*b+ab,*+ab+ab,}

    Używając tego języka, możemy zapisywać wyrażenia algebraiczne bez użycia nawiasów (notacja polska, prefiksowa), interpretując + jako operator dodawania, * jako operator mnożenia oraz a i b jako argumenty. Używając nawiasów, przy powyżej interpretacji, możemy ten język zapisać następująco:
L(G)={a, :b, :a+b, :b*(a+b), :(a+b)*(a+b),}

Wprost z definicji gramatyk - regularnej i bezkontekstowej - wynika, że rodzina języków regularnych jest podrodziną rodziny języków bezkontekstowych. Z lematu o pompowaniu dla języków regularnych wiemy, że język L={anbn:n=1,2,} nie jest regularny. Łatwo uzasadnić, że język ten jest bezkontekstowy, bo jest generowany przez gramatykę:

G=({v0,v1},{a,b},v0,{v0av1b,v11,v1av1b}).

Zatem rodzina języków regularnych jest właściwą podrodziną rodziny języków bezkontekstowych, czyli 3/2

Przejdziemy teraz do omówienia pewnych własności gramatyk bezkontekstowych, które prowadzą do ich uproszczenia. Występujące w poniższym twierdzeniu sformułowanie "produkcja wymazująca" oznacza produkcję v1 .

Twierdzenie 1.1

Niech G=(VN,VT,v0,P) będzie dowolną gramatyką bezkontekstową.

  1. Istnieje gramatyka bezkontekstowa G bez produkcji wymazującej taka, że
    L(G)=L(G){1}.
  2. Jeśli 1L(G), to istnieje równoważna G gramatyka bezkontekstowa G=(V'N,VT,v0,P) taka,

że jedyną produkcją wymazującą w P jest produkcja v01 i symbol v0 nie występuje po prawej stronie żadnej produkcji z P.

Dowód

Dowód podaje konstrukcję odpowiednich gramatyk. Dla dowodu punktu 1 rozważmy ciąg zbiorów

U1={vVN:v1P},Ui+1=Ui{vVN:vxP,xUi*}

określony dla i=1,2 . Jest to ciąg podzbiorów VN taki, że U1U2VN. Ponieważ zbiór symboli nieterminalnych VN jest skończony, więc istnieje indeks k taki, że Uk=Uk+1. Zatem ciąg Ui jest skończony. Stąd równoważność

vG*1vUk.(*)

Zatem 1L(G) wtedy i tylko wtedy, gdy v0Uk. Konstruujemy teraz gramatykę G=(VN,VT,v0,P), przyjmując VN,VT i v0 jak w gramatyce G . Natomiast nowy zbiór praw P zawiera zmodyfikowane prawa gramatyki G . Jeśli prawo vxP , to do zbioru P wprowadzamy prawa vx , gdzie x1 i x powstaje z x przez wymazanie dowolnej liczby (także 0 ) symboli ze zbioru Uk . Pozostaje teraz uzasadnienie równości

L(G)=L(G){1}

Dowód inkluzji
Zauważmy, że dla każdego prawa vxP istnieje prawo vxP takie, że x różni się od x wyłącznie pewną ilością symboli z Uk . Z równoważności (*) wynika, że symbole ze zbioru Uk prowadzą w dalszym ciągu generowania do słowa pustego. A więc dla każdego wyprowadzenia niepustego słowa w gramatyce G istnieje w gramatyce G wyprowadzenie tego samego słowa. Wystarczy w wyprowadzeniu w gramatyce G w miejsce praw postaci vxP wprowadzić prawa vxP by otrzymać wyprowadzenie tego samego słowa w G .

Dowód inkluzji
Określamy gramatykę pomocniczą G=(VN,VT,vo,PP) . Zbiór praw tej gramatyki rozszerza P o wszystkie prawa wymazujące ze zbioru P . Z definicji wynika, że L(G)L(G) , więc L(G){1}L(G){1} . Dla dowodu wystarczy więc pokazać, że

L(G){1}L(G).

Niech wL(G){1} i niech v0G....Gw będzie wyprowadzeniem słowa w w G . Jeśli w tym wyprowadzeniu wszystkie prawa należą do P , to oczywiście słowo wL(G) . Jeśli w wyprowadzeniu słowa w występuje prawo wymazujące, to oznacza, że dla pewnego yiUk,xpv1v2P oraz xpv1yiv2P wyprowadzenie ma postać

xpv1yiv2yi1v0x1xpxnx1v1yiv2ym
x1v1v2xnw

Jednak, jak łatwo zauważyć, słowo w można także wygenerować, pomijając to prawo wymazujące i wykorzystując wyłącznie prawa z P

xpv1v2v0x1xpxnx1v1v2xnw,

co kończy dowód punktu 1.

Przechodząc do dowodu punktu 2, załóżmy, że 1L(G) i niech G będzie gramatyką taką jak w punkcie 1. Definiujemy teraz gramatykę

G=(VN{v0},VT,v0,P{v01, :v0v0}),

która spełnia żądane w twierdzeniu warunki i L(G)=L(G) .

Z udowodnionego powyżej twierdzenia i z definicji gramatyk bezkontekstowych i kontekstowych (definicja 2.1. z wykładu 2) wynika następujące stwierdzenie

Wniosek 1.1

Rodzina języków bezkontekstowych (typu (2)) zawiera się w rodzinie jezyków kontekstowych (typu (1))

21.

Przejdziemy teraz do zagadnienia upraszczania gramatyki bezkontekstowej. Wprowadzimy następującą definicję.

Definicja 1.1

Mówimy, że gramatyka bezkontekstowa G jest właściwa, jeśli zbiór praw nie zawiera produkcji wymazującej oraz produkcji typu v1v2, gdzie v1,v2VN .

Lemat 1.1

Dla każdej gramatyki bezkontekstowej G generującej język bez słowa pustego istnieje równoważna jej gramatyka bezkontekstowa H właściwa.

Dowód

W dowodzie przedstawimy konstrukcję gramatyki o żądanych własnościach. Na podstawie udowodnionego powyżej twierdzenia możemy przyjąć, że G=(VN,VT,v0,P) jest bez produkcji wymazującej. Dla usunięcia produkcji w postaci v1v2 określamy ciąg zbiorów Ui(x) dla xVNVT, przyjmując U1(x)={x} oraz dla i=1,2Ui+1(x)=Ui(x){yVNVT:uUi(x),uyP}

Ciąg Ui(x) jest skończony (stabilizuje się), a więc Uk(x)=Uk+1(x) dla pewnego k i dla każdego l>k mamy równość Ul(x)=Uk(x). Dla dowolnego vVN oraz zVNVT prawdziwa jest równoważność

v*zzUk(v),

która w szczególności dla symbolu terminalnego aVT oznacza, że aL(G) wtedy i tylko wtedy, gdy aUk(v0).

Określamy teraz gramatykę H=(VN,VT,v0,P) , w której zbiór P zawiera produkcje postaci:

  1. v0a dla każdego aVTUk(v0),
  2. vz1...zn dla vVN, n2 oraz dla

każdego zjVNVT, j=1,,n takiego, że istnieje prawo vx1...xnP, vUk(v) i zjUk(xj).

W gramatyce H nie występują prawa postaci v1v2. Gramatyka H nie zawiera praw wymazujących oraz L(G)=L(H), co kończy dowód lematu.

Dalsze rozważania prezentują mozliwości upraszczania gramatyk bezkontekstowych poprzez usunięcie pewnych nieistotnych symboli nieterminalnych, a także poprzez zastąpienie danej gramatyki przez równoważną o prostszej strukturze.

Niech G=(VN,VT,v0,P) będzie gramatyką bezkontekstową, generującą niepusty język. Mówimy, że symbol nieterminalny vVN jest użyteczny, jeśli istnieje słowo wL(G) i wyprowadzenie tego słowa takie, że

v0*xvy*w

dla pewnych x,y(VNVT)* . W przeciwnym wypadku mówimy, że symbol v jest bezużyteczny. Symbole nieużyteczne można usunąć z gramatyki bez uszczerbku dla generowanego przez tę gramatykę języka. Przekonuje o tym następujące twierdzenie.

Twierdzenie 1.2

Dla dowolnego niepustego języka bezkontekstowego L istnieje gramatyka bezkontekstowa bez bezużytecznych symboli nieterminalnych, która generuje ten język.

Konstrukcja takiej gramatyki, a więc i dowód tego twierdzenia wynika bezpośrednio z następujących dwóch lematów.

Lemat 1.2

Dla każdej gramatyki bezkontekstowej G=(VN,VT,v0,P) istnieje równoważna gramatyka bezkontekstowa G=(VN,VT,v0,P) taka, że dla dowolnego vVN istnieje wVT* oraz

vG*w

Dowód

Określamy rekurencyjnie ciąg podzbiorów zbioru symboli nieterminalnych VN :
U1={vVN :: :vwP, :wVT*} oraz dla i=1,2,
Ui+1=Ui{vVN :: : :vxP, :x(UiVT)*} . Zbiory te tworzą ciąg wstępujący i stabilizujący się dla pewnego p . Oznacza to, że U1U2Up=Up+1 . Przyjmujemy z definicji VN=Up oraz

P={vxP, :vVN, :x(VTVN)*}

Tak określona gramatyka G=(VN,VT,v0,P) ma własności gramatyki postulowanej w tezie lematu. Pozostaje udowodnić równoważność określonej gramatyki G i gramatyki G . W tym celu wystarczy pokazać dla dowolnego vVN i wVT* , że jeśli vG*w , to vVN . Udowodnimy tę implikację indukcyjnie ze względu na długość wyprowadzenia. Dla n=1 istnienie wyprowadzenia vG*w oznacza, że vwP . Stąd zaś wynika, że vU1VN . Dla dalszej części rozumowania załóżmy, że implikacja jest prawdziwa dla wyprowadzenia o długości nie większej od n i niech

vGzG*w

będzie wyprowadzeniem o długości n+1 dla słowa wVT* . Niech z=y1v1y2v2vkyk+1 dla pewnych v1,,vkVN oraz y1,,yk+1VT* . Oznaczmy dla słowa z symbolem N(z) słowo otrzymane przez wymazanie wszystkich symboli terminalnych, a symbolem T(z) słowo otrzymane przez wymazanie wszystkich symboli nieterminalnych. Wtedy N(z)=v1vk,T(z)=y1yk+1 . Wówczas istnieją słowa w1,,wkVT* takie, że w=y1w1y2ykwkyk+1 i dla każdego i=1,,k istnieją wyprowadzenia viG*wi o długości mniejszej lub równej od n . Korzystając z założenia indukcyjnego, wnioskujemy, że dla każdego i=1,,k, : :viVN , a to oznacza z definicji VN , że istnieje j takie, że dla każdego i=1,,k, : :viUj . Ostatecznie więc vVN .

Lemat 1.3

Dla każdej gramatyki bezkontekstowej G=(VN,VT,v0,P) istnieje równoważna gramatyka bezkontekstowa G=(VN,VT,v0,P) taka, że dla dowolnego xVNVT istnieją słowa u1,u2(VNVT)* oraz

v0G*u1xu2.

Dowód

Dla rekurencyjnego określenia ciągu podzbiorów zbioru VNVT przyjmujemy:

U1={v0} oraz dla k=1,2,Uk+1=Uk{xalph(VNVT)y :: :vyP, :vUk}

gdzie alph(VNVT)y oznacza zbiór symboli terminalnych i nieterminalnych występujących w słowie y . Zbiory te tworzą stabilizujący się dla pewnego p ciąg wstępujący U1U2Up=Up+1 . Przyjmijmy

VN=UPVN, : : :VT=UPVT.

Zbiór P definiujemy jako zawierający te i tylko te prawa z P , w których wszystkie symbole tworzące słowa należą do VNVT . Łatwo zauważyć, że tak określona gramatyka G=(VN,VT,v0,P) spełnia tezę lematu.

W świetle uzyskanych rezultatów dowolną gramatykę bezkontekstową generującą niepusty język można przekształcić w oparciu o Lemat 1.2 na równoważną, a następnie raz jeszcze przekształcić uzyskaną gramatykę stosując konstrukcję opisaną w dowodzie Lematu 1.3, uzyskując ostatecznie gramatykę bez bezużytecznych symboli nieterminalnych, czyli spełniającą tezę powyższego twierdzenia.

Warto podkreślić, iż istotna jest kolejność przekształcania gramatyk. Zmiana kolejności może sprawić, iż nie uzyskamy pożądanego efektu. Załóżmy, dla ilustracji, że w gramatyce G=(VN,VT,v0,P) istnieje wyprowadzenie v0G*u1v1u2v2u3 dla pewnych v1,v2VN oraz u1,u2,u3(VNVT)* i jest to jedyna możliwość wygenerowania z v0 słowa, w którym występuje v1 . Istnieje także słowo wVT* i wyprowadzenie v1G*w . Z symbolu v2 nie da się natomiast w gramatyce G wyprowadzić żadnego słowa terminalnego. Zastosowanie drugiego z powyższych lematów, uzasadniających twierdzenie, nie usunie symboli v1 i v2 z alfabetu nieterminalnego. Lemat pierwszy usunie tylko v2 . Symbol v1 pozostanie, pomimo iż jest bezużyteczny.

Gramatyki w postaci Chomsky'ego i Greibach

Wprowadzimy teraz określenia dwóch szczególnych postaci gramatyk bezkontekstowych, a mianowicie gramatyki w postaci normalnej Chomsky'ego oraz gramatyki w postaci normalnej Greibach.

Definicja 2.1

Gramatyka bezkontekstowa G=(VN,VT,v0,P) jest

  1. w postaci normalnej Chomsky'ego, jeśli wszystkie prawa są w formie:
    vv1v2 lub va,
    gdzie v,v1,v2VN, aVT.
  2. w postaci normalnej Greibach, jeśli wszystkie prawa są w formie:
vax,

gdzie aVT, :xVN* .

Sheila Greibach (1939-)
Zobacz biografię

Łatwo zaobserwować, że gramatyka zarówno w postaci normalnej Chomsky'ego, jak i w postaci

Greibach jest gramatyką właściwą oraz że język generowany przez te gramatyki nie zawiera słowa pustego. Ponadto drzewo wywodu dowolnego słowa w gramatyce w postaci normalnej Chomsky'ego jest binarne.

Twierdzenie 2.1

Dla każdej gramatyki bezkontekstowej G, generującej język bez słowa pustego, istnieje równoważna gramatyka H w postaci normalnej Chomsky' ego.

Dowód

Zakładamy, że gramatyka G=(VN,VT,v0,P) jest właściwa. Konstruujemy gramatykę H1=(VNVT,VT,v0,P1) , gdzie VT={va:aVT} jest kopią alfabetu terminalnego. Zbiór produkcji P1 powstaje z P przez zamianę w każdej produkcji, której prawa strona nie jest pojedynczą literą terminalną, symbolu a na va oraz dodaniu produkcji vaa dla każdego aVT . Prawdziwa jest równość L(G)=L(H1) i w gramatyce H1 nie występują produkcje typu vv.

Aby uzyskać równoważną gramatykę H w postaci normalnej Chomsky' ego, produkcje typu vv1...vn dla n2 i viVN występujące ewentualnie w H1 zastępujemy

produkcjami:
vv1u1,u1v2u2,...,un2vn1vn,

dodając do zbioru symboli nieterminalnych nowe elementy u1,,un2 . Skonstruowana w ten sposób gramatyka H jest w normalnej postaci Chomsky'ego oraz L(G)=L(H) .

Przedstawiamy poniżej algorytm przekształcający gramatykę bezkontekstową właściwą w gramatykę mającą postać normalną Chomsky'ego.

Algorytm PostaćNormalnaChomsky'ego - buduje gramatykę bezkontekstową w postaci normalnej Chomsky'ego



  1  Wejście: G=(VN,VT,v0,P) - gramatyka bezkontekstowa właściwa.
  2  Wyjście: G=(VN,VT,v0,P) - gramatyka bezkontekstowa w postaci
normalnej Chomsky'ego. 3 P; nowy zbiór produkcji budujemy sukcesywnie 4 VNVN; tak jak i nowe symbole nieterminalne 5 VTVT; symbole terminalne pozostają takie same 6 v0v0; podobnie jak symbol startowy 7 for each aVT do 8 VNVN{va} dodaj nowy symbol nieterminalny 9 end for 10 k1 licznik produkcji 11 for (vx1x2...xm)P do 12 if m=1 and x1VT then 13 PP{vx1}; takie produkcje są dopuszczone 14 else 15 for i1 to m do 16 if xiVT then 17 PP{vxixi}; 18 xivxi; zmień (vx1x2...xm) na parę produkcji 19 end if 20 end for 21 VNVN{u1k,u2k,,um2k}; nowe symbole nieterminalne 22 PP{vx1u1k} nowe produkcje w miejsce (vx1x2...xm) 23 PP{um2xm1xm} 24 for i1 to m3 do 25 PP{uixi+1ui+1}; 26 end for 27 end if 28 end for 29 return G=(VN,VT,v0,P);

Przykład 2.1

Gramatykę G=(VN,VT,v0,P) , dla której VN={v0,u,w}, VT={a,b}, a zbiór praw dany jest poniżej

v0bu | awubuu | av0b | awaaww | b

sprowadzimy do postaci normalnej Chomsky'ego.

Do zbioru P od razu włączamy produkcje ua oraz wb. Poniżej, dla każdej z pozostałych produkcji wypisane są (po dwukropku) produkcje dodawane do P:

v0bu:vbb;  v0vbuv0aw:vaa;  v0vawubuu:uvbd1;  d1uuuav0b:uvad2;  d2v0vbwaaww:wvad3;  d3vad4;  d4ww

Ostatecznie gramtyka ma postać:

v0vbu | vawuvbd1 | vad2 | awvad3 | bd1uud2v0vbd3vad4d4wwvaavbb
Uwaga 2.1

Rozumowanie z dowodu twierdzenia o postaci Chomsky'ego można zastosować do gramatyk regularnych prawoliniowych. W wyniku tego uzyskujemy łatwo fakt, że postać normalna Chomsky'ego oznacza tu gramatykę o prawach typu:

{ vav lub va lub v1. }

Podobne twierdzenie, w którym mowa o postaci normalnej Greibach podamy poniżej. Przypomnijmy następujące oznaczenie. Dla dowolnego symbolu nieterminalnego vVN w gramatyce G przez P(v) oznaczamy podzbiór zbioru produkcji P zawierający wyłącznie takie produkcje, które po lewej stronie mają symbol v . Twierdzenie poprzedzimy dwoma lematami. Obserwacja sformułowana w pierwszym lemacie jest oczywista

Lemat 2.1

Niech G=(VN,VT,v0,P) będzie gramatyką bezkontekstową, a  vxuy  prawem tej gramatyki dla pewnych v,uVN,x,y(VNVT)* . Gramatyka G=(VN,VT,v0,P) , w której

P=(P{vxuy}){vxzy:uzP}

jest równoważna G .

Usuniętą produkcję vxuy nazywać będziemy niekońcową v-produkcją.

Definicja 2.2

Niech G=(VN,VT,v0,P) będzie gramatyką bezkontekstową.

Produkcję
vvx,

gdzie vVN, x(VNVT)* nazywamy lewostronnie rekursywną.

Kolejny lemat wskazuje możliwość wyeliminowania lewostronnej rekursji z gramatyki generującej język bezkontekstowy.

Lemat 2.2

Niech G=(VN,VT,v0,P) będzie gramatyką bezkontekstową oraz vVN . Zakładając niepustość zbioru P1(v)={vvxP(v):x(VNVT)*} niech

P2(v)=P(v)P1(v) . Gramatyka G=(VN{u},VT,v0,P) , gdzie uVN ,

P=(PP1(v)){vxu:vxP2(v)}{ux:vvxP1(v)}{uxu:vvxP1(v)}

jest równoważna gramatyce G .

Dowód

Zaobserwujmy, że w gramatyce G każdy ciąg produkcji ze zbioru P1(v) musi zakończyć produkcja z P2(v) . Zatem wyprowadzenie

vGvx1Gvx2x1GGvxkx1Gxxkx1

można w gramatyce G przeprowadzić następująco:

vGxuGxxkuGGxxkx2uGxxkx1

W podobny sposób można każde wyprowadzenie w G przeprowadzić w G .

Udowodnimy teraz twierdzenie o postaci normalnej Greibach.

Twierdzenie 2.2

Dla każdej gramatyki bezkontekstowej G, generującej język bez słowa pustego, istnieje równoważna gramatyka bezkontekstowa H w postaci normalnej Greibach.

Dowód

Załóżmy, że gramatyka G jest w postaci normalnej Chomsky'ego. W alfabecie nieterminalnym VN={v0,,vn} wprowadzamy porządek zadany przez indeksy symboli nieterminalnych. Gramatykę G przekształcimy teraz na równoważną taką, że jeśli vivjx jest prawem nowej gramatyki, to j>i Efekt taki uzyskamy, przekształcając prawa kolejno, zgodnie z porządkiem wprowadzonym w zbiorze VN i symbolem nieterminalnym występującym po lewej stronie prawa. Załóżmy, że dla pewnego k, wszystkich i=0,,k1 , gdzie 1kn jest:

jeśli vivjxjest prawem,toj>i

oraz istnieje j<k takie, że

vkvjxjest prawem.

W oparciu o lemat 2.1 prawo vkvjx zastępujemy prawami vkvlyx , gdzie vjvlyP lub vkayx , gdzie vjayP . Stąd, że j<k , to l>j . Powtarzamy to postępowanie (co najwyżej k1 razy), aż uzyskamy nierówność lk lub prawo vkax , gdzie aVT . W przypadku, gdy otrzymamy l=k , czyli lewą rekursję vkvkx , stosujemy Lemat 2.2, wprowadzając nowy symbol nieterminalny vn+k+1 . Analogicznie postępujemy, gdy w gramatyce G występuje lewa rekursja vkvkx dla k=0,,n.

W wyniku wprowadzonych przekształceń uzyskamy, równoważną wyjściowej, gramatykę ze zbiorem produkcji P , w którym

vivjxorazj>i,i=0,,n1,j=1,,nviax,gdziei=0,,n,aVTvix,gdziei=n+1,,2n+1,

gdzie pierwszą literą słowa x, które występuje w trzecim typie produkcji, jest symbol nieterminalny różny od vi (nie jest to lewa rekursja). Zauważmy, że każda produkcja z P(vn) ma postać vnax oraz każda produkcja z P(vn1) ma postać vn1vnx lub vn1ax . A więc dla i=0,,n każda produkcja z P(vi) jest postaci vivjx, :j>i lub viax .

Stosujemy teraz Lemat 2.1 do praw ze zbioru P(vn) i P(vn1) , tak by prawe strony otrzymanych produkcji zaczynały się symbolem terminalnym. Następnie stosujemy Lemat 2.1 do praw ze zbioru P(vn2),,P(v1) . Po tych zmianach prawe strony produkcji zaczynają się symbolem terminalnym. Natomiast żadna z produkcji należących do P(vi) dla i=n+1,,2n+1 nie jest lewą rekursją, co wynika z konstrukcji gramatyki G i z Lematu 2.2. Produkcje te zaczynają się symbolem nieterminalnym i w związku z tym stosujemy kolejny raz Lemat 2.1. W rezultacie uzyskujemy bezkontekstową gramatykę H w postaci normalnej Greibach równoważną wyjściowej gramatyce G .

Prezentowany teraz algorytm PrzekształćDlaGreibach przekształca gramatykę bezkontekstową, realizując powyższe dwa lematy, czyli usuwając v-produkcje niekońcowe i eliminując lewostronną rekursję. Zakładamy, bez utraty ogólności, że na wejściu algorytm otrzymuje gramatykę w postaci normalnej Chomsky'ego.

Algorytm PrzekształćDlaGreibach - buduje gramatykę bezkontekstową taką, że każda produkcja jest postaci vkvjx, k<j lub jej prawa strona zaczyna się od symbolu terminalnego



  1  Wejście: G=(VN,VT,v0,P) - gramatyka bezkontekstowa w postaci Chomsky'ego.
  2  Wyjście: G=(VN,VT,v0,P) - gramatyka bezkontekstowa
bez niekońcowych v-produkcji i bez lewostronnej rekursji. 3 VNVN; VN={v0,,vn} 4 VTVT; 5 PP; 6 for k1 to n do 7 for r=1 to k do 8 for j=0 to k1 do 9 for each (vkvjx1xs)P do 10 PP{vkvjx1xs}; 11 for each (vjy1yl)P do 12 PP{vky1ylx1xs}; 13 end for 14 end for 15 end for 16 end for 17 for j=0 to k1 do 18 for each (vkvjx1xs)P do 19 PP{vkvjx1xs}; 20 end for 21 end for 22 end for 23 for k0 to n do 24 for each (vkvkx1xs)P do 25 VNVN{vn+k+1}; 26 PP{vkvkx1xs}; 27 PP{vn+k+1x1xs}; 28 PP{vn+k+1x1xsvn+k+1}; 29 end for 30 for each (vky1ys)P do 31 if y1vk then 32 PP{vky1ysvn+k+1}; 33 end if 34 end for 35 end for 36 return G=(VN,VT,v0,P);

Kolejny algorytm PostaćNormalnaGreibach przekształca gramatykę bezkontekstową do postaci normalnej Greibach. Zakładamy, że algorytm ten otrzymuje na wejściu gramatykę bezkontekstową właściwą.

Algorytm PostaćNormalnaGreibach - buduje gramatykę bezkontekstową w postaci normalnej Greibach



  1  Wejście: G=(VN,VT,v0,P) - gramatyka bezkontekstowa właściwa.
  2  Wyjście: G=(VN,VT,v0,P) - gramatyka bezkontekstowa w postaci normalnej Greibach.
  3  GPostaćNormalnaChomsky'ego(G);                            VN={v0,,vn}
  4  GPrzekształćDlaGreibach(G);                   VN{v0,,v2n+1},VT=VT
  5  for in1  downto  0 do
  6    for j1  to  ni do
  7      for each (vivi+jx1xs)P do
  8        PP{vivi+jx1xs}
  9        for each (vi+jz1zl)P do 
 10          if z1VT then
 11            PP{viz1zlx1xs};
 12          end if
 13        end for
 14      end for
 15    end for
 16  end for
 17  for in+1  to  2n+1 do
 18    for each  (vix1xs)P do
 19      PP{vix1xs}
 20      for each  (x1z1zl)P do
 21        PP{viz1zlx2xs}
 22      end for
 23    end for
 24  end for
 25  v0v0;
 26  return G=(VN,VT,v0,P);

Przykład 2.2

Gramatykę G=(VN,VT,v1,P) , dla której VN={v1,v2,v3}, VT={a,b}, a zbiór praw dany jest poniżej

v1v2v3v2v3v1 | bv3v1v2 | a,

sprowadzimy do postaci normalnej Greibach.

Stosujemy procedurę PrzekształćDlaGreibach, wykorzystującą lematy 2.1 oraz 2.2. Prawe strony produkcji rozpoczynających się od v1 i v2 rozpoczynają się symbolami terminalnymi lub nieterminalami o wyższych indeksach niż odpowiednio 1 i 2, zatem jedyna produkcja, do której zastosujemy lemat 2.1, to v3v1v2. Usuwamy ją, a ponieważ prawa jej strona rozpoczyna się nieterminalem v1, zastępujemy ten nieterminal prawą stroną produkcji v1v2v3 i nowo otrzymaną produkcję v3v2v3v2 dodajemy do P. Ponieważ pierwszy nieterminal po prawej stronie ma niższy indeks niż 3, znowu stosujemy tę samą operację: usuwamy produkcję v3v2v3v2 i na jej miejsce wstawiamy produkcje powstałe w wyniku zastąpienia pierwszego v2 z prawej jej strony łańcuchami v3v1 oraz b, czyli prawymi stronami produkcji, po których lewej stronie jest v2. Otrzymujemy zatem dwie nowe produkcje: v3v3v1v3v2 oraz v3bv3v2. Teraz każda produkcja jest następującej postaci: albo prawa jej strona zaczyna się terminalem, albo nieterminalem o indeksie większym lub równym indeksowi nieterminala stojącego z lewej strony.

Następny krok to wyeliminowanie lewostronnej rekursji. Stosujemy lemat 2.2 do produkcji v3v3v1v3v2. Usuwamy ją z P i w jej miejsce wstawiamy produkcje v3bv3v2w3, v3aw3, w3v1v3v2w3.

Po zakończeniu działania procedury PrzekształćDlaGreibach otrzymujemy następującą gramatykę:

v1v2v3v2v3v1 | bv3bv3v2w3 | aw3 | bv3v2 | aw3v1v3v2 | v1v3v2w3

Wszystkie prawe strony produkcji mających po lewej stronie v3 zaczynają się od terminala. W pętli (linie 5. - 16.) zastępujemy tymi prawymi stronami nieterminale v3 stojące jako pierwsze nieterminale po prawej stronie produkcji postaci v2v3x; w naszym przypadku jedyną taką produkcją jest produkcja v2v3v1; teraz zarówno produkcje postaci v3x jak i v2x rozpoczynają się terminalami. Po tym przekształceniu gramatyka ma postać:

v1v2v3v2bv3v2w3v1 | aw3v1 | bv3v2v1 | av1 | bv3bv3v2w3 | aw3 | bv3v2 | aw3v1v3v2 | v1v3v2w3

Prawymi stronami produkcji postaci v2x zastępujemy teraz nieterminale v2 stojące jako pierwsze nieterminale po prawej stronie produkcji postaci v1v2x. W naszym przypadku jedyną taką produkcją jest produkcja v1v2v3. Gramatyka wygląda teraz tak:

v1bv3v2w3v1v3 | aw3v1v3 | bv3v2v1v3 | av1v3 | bv3v2bv3v2w3v1 | aw3v1 | bv3v2v1 | av1 | bv3bv3v2w3 | aw3 | bv3v2 | aw3v1v3v2 | v1v3v2w3

Ostatecznie, po ukończeniu pętli, każda produkcja mająca po lewej stronie v1, v2 lub v3 zaczyna się terminalem, po którym następuje ciąg nieterminali. Te produkcje są więc w postaci normalnej Greibach.

W ostatnim kroku sprowadzamy do żądanej postaci nieterminale wi. Obie w3-produkcje przekształcamy, zastępując pierwszy nieterminal stojący po ich prawych stronach (czyli v1) prawymi stronami produkcji postaci v1x. Obie w3-produkcje zostaną z P usunięte, a na ich miejsce dodane zostaną produkcje

w3bv3v2w3v1v3v3v2 | aw3v1v3v3v2 | bv3v2v1v3v3v2  | av1v3v3v2 | bv3v3v2

oraz

w3bv3v2w3v1v3v3v2w3 |aw3v1v3v3v2w3 | bv3v2v1v3v3v2w3  | av1v3v3v2w3 | bv3v3v2w3

Ostatecznie, gramatyka w postaci Greibach ma postać:

v1bv3v2w3v1v3 | aw3v1v3 | bv3v2v1v3 | av1v3 | bv3v2bv3v2w3v1 | aw3v1 | bv3v2v1 | av1 | bv3bv3v2w3 | aw3 | bv3v2 | aw3bv3v2w3v1v3v3v2 |aw3v1v3v3v2 | bv3v2v1v3v3v2  | av1v3v3v2 | bv3v3v2bv3v2w3v1v3v3v2w3  | aw3v1v3v3v2w3 | bv3v2v1v3v3v2w3   | av1v3v3v2w3 | bv3v3v2w3