• Nem Talált Eredményt

Nyelvtanok normálalakjai

In document Formális nyelvek (Pldal 95-102)

3. Környezetfüggetlen nyelvek

3.3. Nyelvtanok normálalakjai

A (3.12.) szabályt elhagyva, és helyette a fenti két új levezetési szabályt beiktatva látható, hogy az első rögtön kielégíti a követelményeket, míg a második szabály jobboldalának hossza eggyel rövidebb, mint elődjéé volt.

Az a tény, hogy a módosítás nem érinti a generált nyelvet, nem igényel magyarázatot.

A fenti vagy ezzel egyenértékű felbontással tehát csökkenteni lehet a jobboldalak hosszát. Ezt kellő kitartással folytatva a leghosszabb jobboldalt is kettőre tudjuk redukálni. Ezzel viszont a kijelölt célt teljesítettük is, létrehoztunk egy az eredeti nyelvtannal egyenértékű Chomsky normálalakot.

Megjegyzem, hogy az S → ε alakú szabály, ahol S a mondatszimbólum, mint egyetlen olyan ε-szabály, amely jólfésült nyelvtanokban előfordulhat, szintén Chomsky szabálynak minősül. Nélküle ugyanis nem lehetne olyan nyelv nyelvtanát Chomsky alakra hozni, amely az üres jelsorozatot tartalmazza.

A fenti konstruktív bizonyítás alapján rögzíthető, hogy minden környezetfüggetlen nyelvtannak van egyenértékű Chomsky normálalakja. Ez a normálforma nem unikális, hiszen az átalakításnál leválaszthattuk volna, például az utolsó két nemterminálist, vagyis a szalámit nem az elején, hanem a végén kezdtük volna szeletelni. De ez csak két lehetőség a sok közül.

Példaképpen hozzuk Chomsky normálalakra az alábbi nyelvtant:

S → aSb S → ab A nyelvtan nyilvánvalóan az

aibi i > 0 nyelvet generálja.

Írjuk át a terminális szimbólumokat nemterminálisokká. Szerencsére itt nem kell jelölési konfliktustól tartani, így a vesszőzés elmaradhat.

S → ASB S → AB A → a B → b

Szerencsére a négy új szabály közül három rögtön megfelel a követelmé-nyeknek. Egyedül az első helyen álló szabályt kell tovább bontanunk:

S → AC C → SB Ezzel a nyelv teljes Chomsky nyelvtana:

S → AC C → SB S → AB A → a B → b

Mielőtt az itt tárgyalt másik normálalak, a Greibach normálalak részleteiben elmerülnénk, szólnunk kell néhány szót a balrekurzióról, illetve annak megszüntetéséről.

Már korábban tisztáztuk, mikor mondjuk egy nyelvtanról, hogy rekurzív.

Az is kiderült, hogy a rekurzivitás a nyelv és nem a nyelvtan sajátja. Ebből következik, hogy ha egy nyelvet generáló nyelvtan rekurzív, akkor minden, ezt a nyelvet generáló nyelvtan is szükségképpen rekurzív lesz. A rekurzivitást tehát nem lehet megszüntetni, egy rekurzív nyelvtannal csakis egy rekurzív nyelvtan lehet egyenértékű.

Balrekurzívnak mondunk egy nyelvtant akkor, ha van olyan a rekurzi-vitásért felelős nemterminális szimbólum, amelyből kiinduló levezetés során a szóban forgó nemterminális a legbaloldalibb pozícióban jelenik meg újból.

A baloldali rekurzióra tehát a következő összefüggés írható fel:

*

A ⇒ Aα (3.14.) A balrekurzivitást alkalmas átalakításokkal meg lehet szüntetni.

Természetesen a nyelvtan továbbra is rekurzív marad, csak ez a tulajdonság nem a baloldali rekurzió formájában jelentkezik.

Itt rögtön felmerül az a kérdés, miért van erre szükség? Ha egyszer a rekurzió nem küszöbölhető ki, akkor nem mindegy, hogy ez milyen formában, hol jelentkezik?

Messzemenően nem mindegy! Mint látni fogjuk, bizonyos egyszerű szintaktikus elemző módszerek nem alkalmazhatóak, ha a nyelvtan balrekurzív.

Így ennek megszüntetése nagyon is lényeges.

Elöljáróban az úgynevezett közvetlen balrekurzió megszüntetését ismer-tetem. Közvetlen balrekurzióról beszélünk akkor, ha van a nyelvtanban

A → Aα (3.15.)

alakú szabály, vagyis a balrekurzió már egyetlen helyettesítési lépés után jelent-kezik. A (3.15.) alakú szabályok léte szembeszökővé teszi a balrekurzió tényét, hiányuk azonban nem biztosíték arra, hogy nincsen balrekurzió.

Legyen A egy közvetlen balrekurziót okozó nemterminális. Soroljuk az A levezetési szabályait két halmazba aszerint, hogy közvetlen balrekurziót okoznak-e vagy sem.

A → Aα1 Aα2  . . .  Aαn (3.16.) A → β1  β2  . . .  βm (3.17.) Itt persze a β jelsorozatok nem kezdődhetnek az A nemterminálissal. Sem n sem m nem lehet zérus, hiszen akkor vagy az A szimbólum nem okozna közvet-len balrekurziót, vagy az álrekurziónak nevezett badarsággal volna dolgunk.

Vezessük be a reguláris halmazoknál már alkalmazott jelöléseket, és legyen

α = α1 + α2 + . . . + αn (3.18.) β = β1 + β2 + . . . + βm (3.19.) Ezzel a (3.16.) és (3.17.) egyenlet a következő alakot ölti:

A = Aα + β (3.20.)

Könnyen belátható, hogy ebből a kifejezésből levezethető

*

A ⇒ βα* (3.21.)

Az A nemterminális ugyanis csak akkor tűnik el a jobboldal első helyéről, ha az A → β szabályt alkalmazzuk. Előtte viszont tetszőlegesen sokszor

beleértve a nullaszoros lehetőséget is, felhasználhattuk az A → Aα szabályt. Ezt fejezi ki az α* faktor.

Alakítsuk át nyelvtanunkat a következők szerint:

A = β + β   = α + α (3.22.) A második egyenletből  = α+ és ebből már következik, hogy a (3.22.) egyenletek ugyanazt az eredményt adják, mint a (3.20.) egyenlet. A két egyenlet tehát egyenértékű, és mivel a (3.22.) kifejezés nem tartalmaz közvetlen balrekurziót, feladatunkat megoldottuk, a közvetlen balrekurziót sikerült kiküszö-bölnünk.

Térjünk most át a környezetfüggetlen nyelvtanok másik nevezetes normálalakjára, a Greibach-féle normálalakra. Az irodalom GNF néven is emlegeti (Greibach Normal Form). A Greibach normálalakban a helyettesítési szabályok engedélyezett alakja:

A → aW (3.23.) ahol W tetszőleges, csak nemterminálisokból álló sorozat. A tetszőleges számban természetesen a zérus is beleértendő, hiszen ellenkező esetben egyetlen mondatot sem lehetne levezetni, mindig maradna a mondatszerű formában nemterminális.

Az S → ε alakú ε-szabály ugyanúgy, ahogy a Chomsky normálalaknál, itt is engedélyezett Greibach szabály.

Vegyük észre, hogy a Greibach normálalakban felírt nyelvtanok nem balrekurzívak. Ez magától értetődő, ha meggondoljuk, hogy minden helyettesí-tési szabály jobboldalának első szimbóluma terminális.

A következőkben a Greibach normálalak előállítását megoldva, elvégezzük a balrekurzió kiküszöbölését is. Azt kell elérnünk, hogy csak olyan levezetési szabályok legyenek a nyelvtanban, amelyek terminálissal kezdődnek.

Ha ezt megvalósítottuk, akkor már nyert ügyünk van, hiszen a levezetési szabályok belsejében található terminális szimbólumok eltávolításában már a Chomsky normálalak szerkesztésekor bizonyos gyakorlatra tettünk szert.

Legyen adott egy jólfésült nyelvtan. Definiáljunk a nyelvtan nemterminális szimbólumai között egy szigorú, de egyébként teljesen tetszőleges rendezést.

Ennek szemléltetésére valamennyi nemterminális szimbólumot egyetlen betűvel és egy indexszel jelöljük, ahol az index sorszáma határozza meg a rendezést.

A rendezés tetszőleges abban az értelemben, hogy semmiféle feltételezést nem teszünk majd a sorrend mikéntjére, így például azt sem kötjük ki, hogy a mondatszimbólum hányadik – első vagy utolsó – legyen ebben a sorban.

A sorrend tehát elvben tetszőleges, a gyakorlatban persze lehet, hogy egy ügyetlenül megválasztott sorrend az átalakítási munkát megnöveli, ez azonban a megvalósíthatóságot nem érinti.

Első lépésben azt kívánjuk elérni, hogy az Ai nemterminálishoz tartozó valamennyi levezetési szabály vagy terminálissal kezdődjék, vagy első karaktere magasabb sorszámú nemterminális legyen.

Formálisan:

Ai → aX vagy Ai → Aj Y j > i (3.24.) ahol X és Y tetszőleges szimbólumokat tartalmazhat.

Ezt a műveletet a legalacsonyabb indexű nemterminális szimbólumnál kezdjük el, és innen haladunk felfelé a nagyobb indexek felé.

Az A1 nemterminális esetében, minthogy ennél alacsonyabb sorszámú nem-terminális nincsen, csak az okozhat problémát, ha a jobboldal első szimbóluma szintén A1. Ez viszont a közvetlen balrekurzió esete, amelynek kiküszöbölésére már van algoritmusunk. Ezt alkalmazva elérhetjük, hogy a (3.24.) feltételei erre a nem-terminálisra teljesüljenek.

Ha most áttérünk az A2 nemterminális szimbólumra, akkor először azokat a levezetési szabályokat keressük meg, amelyek jobboldala az A1 nemterminálissal kezdődik. Ha vannak ilyen szabályok, akkor ezekben az élen álló A1 szimbólumot levezetési szabályainak jobboldalával kell helyettesíteni, mégpedig minden lehetséges kombinációban.

Így ha az A2 levezetési szabályai között k olyan van, amelynek jobboldala az A1 szimbólummal kezdődik, és az A1 szimbólumhoz tartozó levezetési szabályok száma j, akkor az eredeti k szabály helyébe k∗j szabályt kell írni.

Ezzel garantáljuk, hogy A2 szabályai között nem lesz olyan, amelyiknek a jobboldala az A1 szimbólummal, vagyis a baloldalinál alacsonyabb sorszámú nem-terminálissal kezdődne. Ennek következtében itt most csakis azok a szabályok okozhatnak problémát, amelyeknek első jobboldali szimbóluma A2, függetlenül attól, hogy az ilyen szabályok eredetileg is benne voltak a nyelvtanban, vagy az átalakítások során kerültek bele. Ez viszont megint a közvetlen balrekurzió esete, így az annak megszüntetésére szolgáló algoritmusunkat kell mozgósítanunk. Így elérjük, hogy csak vagy terminálissal, vagy nagyobb sorszámú nemterminálissal kezdődő szabályaink lesznek, a (3.24.) követelmények teljesülnek.

Általánosságban, ha fenti célunkat az Ai nemterminális szimbólumnál kívánjuk elérni, akkor feltételezhetjük, hogy ezt az algoritmust az i−1 indexig bezáróan már sikerrel alkalmaztuk.

Először itt is az A1 kezdetű levezetési szabályokat – ha vannak ilyenek – szüntetjük meg helyettesítéssel. Ezzel a minimális kezdeti sorszámot eggyel feljebb vittük. Ekkor jön a következő sorszámú nemterminális, ismét csak helyettesítés, és ezt alkalmazzuk mindaddig, amíg az i indexhez nem érünk. Itt, ha szükséges, ismét a közvetlen balrekurzió elhárítására bevezetett módszert vetjük be.

Már a leírásból is látszik, hogy ez az algoritmus, bár biztosan célhoz ér, meglehetősen hosszadalmas.

Vegyük észre, ha átrágtuk magunkat az összes indexen, akkor az utolsó nemterminális szimbólum esetében a Greibach normálalak előírásainak megfelelő levezetési szabályokat kapunk, amennyiben valamennyi szabály jobboldala termi-nális szimbólummal kezdődik. Ez abból következik, hogy az utolsó nemterminális esetében, az utolsónál nem lévén magasabb sorszámú nemterminális, csak az a lehetőség marad, hogy a levezetési szabályok terminálissal kezdődnek. Itt persze feltételeztük, hogy az esetleges belső terminális szimbólumokat a szokott módon

„nemterminálosítottuk”.

Ezekkel az átalakításokkal elértük, hogy a nyelvtan nem lehet balrekurzív.

Minden szabály ugyanis vagy terminálissal, vagy magasabb sorszámú nemterminá-lissal kezdődik, így nincs lehetőség arra, hogy egy nemterminális a jobboldal legelső pozíciójába visszatérjen, hiszen nem lehet önmagánál magasabb indexe.

Most viszont visszafordulhatunk, és az átalakítás második lépéseként fá-radságos utunkat nem kevésbé fáfá-radságos módon lefelé is végigjárjuk.

Az utolsó előtti nemterminálisról ugyanis tudjuk, hogy ha vannak is nem-terminálissal kezdődő levezetési szabályai, akkor azok csakis az utolsó nemtermi-nálissal kezdődhetnek. Ezen szabályoknál az utolsó nemterminális helyébe levezetési szabályainak jobboldalát helyettesítve elérhetjük, hogy az utolsó előtti nemterminális valamennyi szabályának jobboldala terminálissal kezdődjék. Ezek szerint ez a nemterminális is ki fogja elégíteni a Greibach-féle szabályokat.

Ezt az algoritmust a sorszámok csökkenő sorrendjében folytatva, mire az első nemterminálist is túlhaladtuk, az egész nyelvtanban nem lesz olyan leveze-tési szabály, amely ne terminális szimbólummal kezdődne.

Minthogy a fent ismertetett algoritmus bármely jólfésült nyelvtanra alkalmazható, igazoltuk, hogy minden környezetfüggetlen nyelvnek létezik Greibach normálalakja.

Lássunk erre is egy példát. Legyen a nyelvtan:

A → BC B → CA  b C → AB  a

Válasszuk a három nemterminális sorrendjének az A – B – C sorrendet.

Először azt az állapotot kell előállítanunk, amikor az egyes nemterminálisokhoz tartozó levezetési szabályok csak vagy terminálissal, vagy sorrendben későbbi nemterminálissal kezdődnek.

Szerencsére az A és B nemterminális szimbólumokra ez eleve teljesül. A C levezetési szabályainál a kezdő A szimbólumot helyettesítéssel el kell távolítani. Sajnos erre az új szabály jobboldalának elején megjelenik a B nemterminális, így újabb helyettesítésre van szükség.

C → AB a ⇒ BCBa ⇒ CACB  bCB a

Ezzel sajnos nem vagyunk készen, hiszen a C nemterminális levezetési szabályaiban önmaga sem szerepelhet a jobboldal első helyén. Most a közvetlen balrekurzivitást megszüntető algoritmust kell alkalmaznunk.

C → bCB  a  bCBĈ  aĈ Ĉ → ABC  ACBĈ

Ezzel megkaptuk azt az egyenértékes nyelvtant, amelynek levezetési szabályai vagy terminálissal, vagy magasabb sorszámú nemterminálissal kezdődnek:

A → BC

B → CA  b

C → bCB  a  bCBĈ  aĈ Ĉ → ACB  ACBĈ

Ami a kalapos szimbólumokat illeti, azokat úgy kezelhetjük, mintha sorrendben megelőznék az összes eredeti szimbólumot. Példánkban csak egy ilyen szimbólum van Ĉ. Ha több ilyen volna egymás közötti sorrendjük közömbös.

Most visszafelé kell az utat bejárnunk. A sorrendben legutolsó nemtermi-nális esetünkben C volt. Ennek levezetési szabályai már teljesítik a Greibach feltételeket, amennyiben terminális szimbólummal kezdődnek. Azokba a levezetési szabályokba, ahol C a kezdőszimbólum a jobboldalakat behelyettesítjük. Ezt kell tennünk a B nemterminális egyik levezetési szabályánál. Ezzel a B szimbólum valamennyi levezetési szabálya is terminálissal fog kezdődni.

Ezután a B szimbólumot kell az A egyetlen szabályában átírnunk, végül az A szimbólumra kapott eredményt a Ĉ szabályaiba beírnunk.

Mindezek után a nyelvtan a következő lesz. A szabályokat célszerűen a származtatás sorrendjében adom meg.

C → bCB  a  bCBĈ  aĈ

B → bCBA  aA  bCBĈA  aĈA  b A → bCBAC  aAC  bCBĈAC aĈAC  bC

Ĉ → bCBACCB  aACCB  bCBĈACCB aĈACCB bCCB  bCBACCBĈ  aACCBĈ  bCBĈACCBĈ  aĈACCBĈ  bCCBĈ Itt említem meg, hogy más rendezés például a C–A–B sorrend esetén talán még szövevényesebb, de mindenesetre más nyelvtant kaptunk volna.

Természetesen bárhogyan is származtatjuk a Greibach normálalakot a kapott nyelvtanok egyenértékűek.

Mint látható az eredeti egyszerűnek tűnő nyelvtanból készített Greibach normálalak ijesztő bonyolultságú. Felmerülhet ezzel kapcsolatban a kérdés, van-e a normálalakoknak az esetleges elvi jelentőségen túlmenően gyakorlati fontossága.

Gyakran az áttekinthető nyelvtan alapján nehéz elemzőt szerkeszteni. A normálalakok erre sokkal jobb kiindulást adhatnak. Minthogy az elemzést a fordítóprogramot futtató számítógép végzi, ez esetben az elemezhetőség szem-pontja nagyobb prioritású, mint az olvashatóságé.

In document Formális nyelvek (Pldal 95-102)