Informatik IC2 Balazs Simon
Inhaltsverzeichnis 1 Contextfreie Sprachen 3 1.1 Ableitungsbaum..................................... 3 1.2 Schönheit........................................ 4 1.3 Normalformen...................................... 6 1.3.1 Chomsky Normal Form (CNF)......................... 6 1.3.2 Greibach Normal Form (GNF)......................... 7 1.3.3 Beispiel..................................... 7 1.4 LL(k) Parser....................................... 7 1.5 LR(k) Parser....................................... 8 1.6 Pumpen......................................... 9 1.6.1 Reguläre Sprachen............................... 9 1.6.2 CF Sprachen.................................. 9 1.7 Geschlossenheit der CF Sprachen........................... 10 1.8 Geschlossenheit der reguläre und CF Sprachen.................... 10 1.9 Aufgaben........................................ 10 2
Kapitel 1 Contextfreie Sprachen 1.1 Ableitungsbaum Betrachten wir den folgenden Grammatik: E E + T T T T F F F (E) a Konstruieren wir die Links- und Rechtsableitung, und die zugehörige Ableitungsbäume. Linksableitung: immer die linkste Nichtterminalzeichen zu ersetzen. Rechtsableitung: immer die rechteste Nichtterminalzeichen zu ersetzen. Auch für die folgende Grammatik: E E + E E E (E) a Für Computers müssen alle Ableitungsbäume dieselbe sein, also jede Ableitungs soll eindeutig sein. Die obige Grammatik ist eindeutig, die untere nicht. Eine andere nicht eindeutige Sprache: a i b i c j a j b i c i S XC AY X axb ab C cc c A aa a Y by c bc a i b i c i kann nicht eindeutig abgeleitet werden. Die Sprache ist nicht eindeutig, es hat kein eindeutige zugehörige Grammatik. 3
4 KAPITEL 1. CONTEXTFREIE SPRACHEN 1.2 Schönheit Eine Grammatik ist schön (proper grammar, jólfésült nyelvtan), wenn es kein Hässlichkeit hat. Die 3 Grundhässlichkeiten: Unnötige Zeichen. Ein Nichtterminalzeichen ist nötig, wenn wir solche gültige Ableitungen haben, die dieses Nichtterminalzeichen enthalten. Ein Terminalzeichen ist unnötig, falls es in kein Satzform vorkommt. Wenn ein Zeichen unnötig ist, wir sollen die Regeln, die dieses Zeichen enthalten, weglassen. ɛ-regeln sind hässlich, weil sie verkürzende Regeln sind. Einfache Ableitungsregeln sind hässlich, weil die Ableitung ein Zyklus enthalten kann. (A B B C C A) Eliminierung der hässliche Regeln (kemmen): Unnötige Zeichen: Bottom-up kemmen: Konstruieren wir eine Folge von Mengen. B i+1 = B i {A A α, α B i } Wir konstruieren die neue Menge so, dass wir solche Nichtterminalzeichen zunehmen, die solche Ableitungsregeln hat, dessen rechte Seite nur solche Charakters enthält, die in der vorige Menge sind. Die nullte Menge wird die Alphabet der Sprache: B 0 = Σ. B wird die grösste Menge sein, wir können es so bekommen, falls B i B i+1 kein neue Hinzufügen hat. Dann wird B = B i = B i+1 sein, und wird nur die Terminalsymbolen und nur solche Nichtterminalsymbolen enthalten, die ein solche Satzform generieren können, die nur aus Terminalzeichen besteht. Top-down kemmen: Wieder eine Folge von Mengen. T i+1 = T i {X A αxβ, A T i } T i enthält solche Zeichen, die von der Satzsymbol in i Schritten ableitbar sind. T 0 = S und T wird die grösste Menge sein, wir können es so bekommen, falls T i T i+1 kein neue Hinzufügen hat. Dann wird T = T i = T i+1 sein, und wird nur die Terminalsymbolen und nur solche Nichtterminalsymbolen enthalten, die von der Satzsymbol eigentlich ableitbar sind. Wir müssen immer erstmal von unten, danach von oben kemmen! Beispiel: S a aa A AB Ab B bb b Von oben: B 0 = {a, b} B 1 = {a, b, B, S} B 2 = {a, b, B, S}
1.2. SCHÖNHEIT 5 also A ist unnötig: S a B bb b Von unten: T 0 = {S} T 1 = {S, a} T 2 = {S, a} also B ist auch unnötig: S a ɛ-regeln: Von unten nach oben kemmen mit B 0 = {ɛ} anfangen. Wenn S B, die Sprache enthält die leere Zeichenkette, sonst nicht. Falls ɛ Element der Sprache ist, das Ergebnis wird die Vereinigung von L 1 = {ɛ} und L 2 = {alle Sätze, die die originale Sprache enthält}. L 1 generiert die leere Zeichenkette, L 2 generiert alle andere Zeichenketten der Sprache. Die Grammatik von L 2 wird ohne ɛ-regeln eine solche Grammatik, die wir so bekommen, dass in der originale Grammatik jede Nichtterminalzeichen von B in alle Kombinationen in alle rechte Seiten einschreiben oder weglassen. Die direkte ɛ-regeln sollen weggelassen werden. Beispiel: Nach kemmen: B = {ɛ, S} Das Ergebnis: S ɛ S S S SaSb ɛ S SaSb asb Sab ab Einfache Ableitungsregeln: Suchen wir erstmal alle einfache Regeln, und wir sammeln alle Nichtterminalsymbolen aus diese Regeln. Wir kemmen von oben nach unten aus jede solche Nichtterminalzeichen. Die T Menge, die zu eine solche Nichtterminalsymbol gehört, enthält alle Nichtterminalsymbolen, die aus diese Nichtterminalsymbol durch einfache Ableitungsregeln erreichtbar sind. Wir werden statt die einfache Regeln solche Regeln aufnehmen, dessen linke Seite diese Nichtterminalsymbol wird, und die rechte Seite wird alle Rechte seiten solcher Regeln enthalten, dessen linke seite eine Nichtterminalsymbol aus der Menge T stammt. Beispiel: infix arithmetik E E + T T T T F F F (E) a
6 KAPITEL 1. CONTEXTFREIE SPRACHEN Die einfache Regeln: E T T F Die Nichtterminalsymbolen, die in die Regeln vorkommen: E, T und F. Nach kemmen: T E = {E, T, F } T T = {T, F } T F = {F } Wenn wir die einfache Regeln weglassen: E E + T T T F F (E) a Mit den neuen Regeln anhand T E, T T und T F : E E + T T F (E) a T T F (E) a F (E) a Also wir können die hässliche Regeln immer eliminieren. 1.3 Normalformen Wir müssen immer erstmal die Grammatik kemmen, wenn wir die Normalformen konstuieren möchten! 1.3.1 Chomsky Normal Form (CNF) Diese Normalform kann nur solche Regeln enthalten: A BC und A a. Gegeben ist eine Grammatik. Konstruieren die CNF von dieser Grammatik! Regeln schon in CNF vertig. Regeln nicht in CNF: aus der Terminalzeichen sollen neue Nichtterminalzeichen konstruiert. Statt eine Regel C BaD nehmen wir zwei neue Regeln auf: C BÂD und  a. Aus die lange"n N 1 N 2...N n Regeln (n > 2) neue Regeln: N N 1 N 1 N 1 N 2 N 3...N n usw.
1.4. LL(K) PARSER 7 1.3.2 Greibach Normal Form (GNF) Die Greibach Normal Form enthält nur Regeln in der Form A aw, wo W eine beliebig lange Nichtterminalzeichenkette ist. Aus jede schönen Grammatik können wir die GNF konstruieren, aber wir werden es nicht lernen. 1.3.3 Beispiel Konstruieren wir die CNF der folgenden Grammatik: S asb ab. Diese Grammatik generiert die Sprache a i b i. Die neue Regeln mit die neuen Nichtterminalsymbolen: S ASB S AB, A a, B b. Die erste Regel soll modifiziert werden: S AC, C SB. Die CNF der Grammatik: S AC C SB S AB A a B b 1.4 LL(k) Parser Ein Parser ist für Bestimmung der Ableitungsbaum. Es analysiert immer eindeutig und deterministich die Sätze. Bei der Linksableitung fangen wir mit dem Satzsymbol an, und wir eliminieren immer die linkste Nichtterminalsymbol. Im allgemein hat ein Nichtterminalsymbol mehr als 1 rechte Seiten, und wir sollten entscheiden, welche aus diesen anzuwenden. Es soll eindeutig sein, weil der Sprache eindeutig ist. Damit der LL(k) Parser entscheiden kann, macht es ein Vorblick: er liest k Charakters vor, und aus diese Charakters wird er entscheiden, welche Regel zu benutzen. Erste L: wir lesen von links nach rechts Zweite L: wir machen eine Linksableitung k: wir lesen soviele Charakters vor Wenn wir bei einer Satzform waβ haben: wir haben w schon abgeleitet das linkste Nichtterminalsymbol A ist β ist der Rest des Satzes Falls die k Symbols, die w folgen, genug Information geben, dass wir entscheiden können, welche Ableitungsregel zu benutzen, dann sagen wir, dass die Grammatik LL(k) analysierbar ist. Beispiel: prefix polish Notation 1 E +EE 2 E EE 3 E a
8 KAPITEL 1. CONTEXTFREIE SPRACHEN Diese Grammatik ist LL(1) analysierbar: der erste Charakter ist unterschiedlich für alle Regeln. Die sogenannte Parser Tabelle: in dem horizontalen Kopf sind die höchstens k lange Zeichenketten, die wir vorblicken können. In dem vertikalen kopf stehen die Symbolen, die in der Keller vorkommen können. + a ɛ E +EE, 1 EE, 2 a, 3 + pop pop a pop ɛ acc Falls der Terminalzeichen am Dach des Kellers gleich mit dem gelesene Symbol, dann nehmen wir dieses Symbol aus den Keller (pop). Der k lange Vorblick bedeutet das k lange Prefix der noch nicht gelesene Zeichenkette. Wir können ɛ nur dann vorblicken, falls wir das ganze Zeichenkette durchgelesen haben. Wir akzeptieren mit leerem Keller, also falls ɛ ist in dem Keller und wir haben die ganze Zeichenkette durchgelesen (der Vorblick ɛ ist), dann akzeptieren wir den Satz (acc). Die leere Stellen in der Tabelle kann nie vorkommen, falls der Satz ein gültiger Satz ist. Die wichtigste Informationen kann man in der erste Zeile finden. Die Felder sagen, was statt das Nichtterminalzeichen schreiben soll, und welche Zahl als Ergebnis ausgegeben soll. Die Konfiguration der Ableitung: noch zu lesen, im Keller: linkste Symbol ist das Dach, Ergebnis: die Reihenfolge der Regeln Analysieren wir den folgenden Satz: +a aa {+a aa, E, ɛ} {+a aa, +EE, 1} {a aa, EE, 1} {a aa, ae, 13} { aa, E, 13} { aa, EE, 132} {aa, EE, 132} {aa, ae, 1323} {a, E, 1323} {a, a, 13233} {ɛ, ɛ, 13233} acc 1.5 LR(k) Parser Wir lesen die Symbolen des Satzes, und plazieren sie im Keller. Falls am Dach des Kellers eine rechte Seite eines Regels vorkommt, es ist ein potentialer Griff. Wenn dieser Griff ein echter Griff ist, sollen wir es abbrechen, falls nicht, dann ein neues Charakter einlesen. Das ist die Rechtsaufleitung. Wir schieben ein Charakter in den Keller, und falls sich ein echte Griff am Dach befindet, abbrechen wir es, sonst nehmen wir das nächste Charakter. Deshalb ist diese Methode als shift-reduce genannt. Der kritisher Punkt ist zu entscheiden, ob wir abbrechen oder schieben sollen. Eine Zustimmung mit eine der rechte Seiten bedeutet nicht, dass wir abbrechen können. Es kann auch vorkommen, das mehrere Nichtterminalsymbolen die gleiche Rechte seiten haben, und wir sollten entscheiden, welche Regel zu benutzen. In dieser Entscheidung hilft uns der LR(k) Parser. L: wir lesen von links nach rechts R: wir machen Rechtssufleitung k: wir lesen soviele Charakters vor Wenn wir eine Ableitung S γax γαx wx haben, und bei der Rechtsaufleitung bei der Satzform γα sind, und x ist noch yu lesen, dann: wir haben γα schon abgeleitet α ist ein lebhafte Prefix x ist der Rest des Satzes Falls die erste k Symbols von x genug Information geben, dass wir entscheiden können, ob wir α abbrechen sollen, oder nicht, und welche Ableitungsregel im fall von Abbrechen zu benutzen, dann sagen wir, dass die Grammatik LR(k) analysierbar ist.
1.6. PUMPEN 9 Die Parser Tabelle hat zwei Teilen: Aktionstabelle und Gototabelle. Die Aktionstabelle sagt, dass in einem gegebenen Situation bei einem gegebenen lebhaften Prefix und bei einem gegebenen Vorblick was zu tun. Es gibt 4 Operatitionen: schieben(s), akzeptieren(a), abbrechen(zahlen), Fehler(leere Stelle). Die Goto Tabelle sagt, dass wenn wir zu die aktuelle lebhafte Prefix ein neues Symbol hinzufügen, welche Prefix wir bekommen. Das nächste Schritt wird von dieser neuen Zustand gemacht. Sei der Grammatik: S S, S SaSb ɛ a b ɛ S a b T 0 2 2 T 1 T 1 S A T 2 T 2 2 2 T 3 T 3 S S T 5 T 4 T 4 1 1 T 5 2 2 T 6 T 6 S S T 5 T 7 T 7 1 1 Analysieren wir den folgende Sätze: aababb, abba 1.6 Pumpen 1.6.1 Reguläre Sprachen Eine genügend lange Satz w einer regulärer Sprache kann auf 3 Teilen xyz aufgeteilt werden so, dass wenn wir die mittlere Teil beliebig vielmal wiederholen, bekommen wir wieder einen Satz der Sprache. Falls xyz L, dann xy i z L (i 0). Ein endliche Automat bewegt sich sovielmal, wieviele Charakters der gelesene Satz beinhaltet. Falls der Automat n Zustände hat, dann macht er n Schritten, falls er einen Satz mit n Charakters einliest, und inzwischen geht er durch n + 1 Zuständen. Das bedeutet, dass es eine solche Zustand existieren muss, an der der Automat zweimal durchgegangen hat, also gibt es eine Schleife in dem Weg, den der Automat gemacht hat. Wenn die y Teil der Satz dieser Schleife verursacht, dann können wir durch diese Schleife beliebig vielmal durchgehen, wenn wir y genug vielmal wiederholen. Aufgabe: a i b i keine reguäre Sprache ist. 1.6.2 CF Sprachen Die CF Sprachen können auch pumpen, diese ist als zweifache Pumpen genannt. Wenn wir eine CF Grammatik haben, und wir können eine genügend lange q = vwxyz Satz generieren können, dann vw i xy i z ist auch Element der Sprache. Beweis. Nehmen wir an, dass die Anzahl der Nichtterminalsymbolen n ist. Nehmen wir einen solchen Satz, in dessen Ableitungsbaum eine solche Weg von der Wurzel bis einem Blatt existitert, der n Knotenpunkten beinhaltet. Diese bedeutet die "genügend langäusdruck. In den Knotenpunkten sind Nichtterminalsymbolen, also muss es eine solche Nichtterminalsymbol existieren, die an dieser Weg zweimal vorkommt. (S vaz vwayz vwxyz, also: A way und A x). Wir könnten aber aus A beliebig vielmal wieder eine way Satzform ableiten, dann wird w und y immer wiederholt, aber genauso vielmal. Eine von w und y kann auch ɛ sein, aber nicht beide. Aufgabe: a i b i CF Sprache ist. (es kann zweimal pumpen, und S asb ab generiert diese Sprache) Aufgabe: a i b i c i kein CF Sprache ist.
10 KAPITEL 1. CONTEXTFREIE SPRACHEN 1.7 Geschlossenheit der CF Sprachen Aufgabe: a i b i c j CF Sprache ist. (S XC, X axb ab, C cc c) Aufgabe: a i b j c j CF Sprache ist. (S AX, X bxc bc, A aa a) Diese zwei Sprachen sind deterministisch. Eine CF Sprache deterministisch ist, falls es eine deterministische Kellerautomat konstruiert werden kann so, dass dieser Automat die Sätze der Sprache akzeptiert. Durchschnitt von a i b i c j und a i b j c j ist a i b i c i, es ist keine CF Sprache. Die CF Sprachen sind nicht geschlossen für Durchschnitt Operation. Für die deterministiche CF Sprachen ist die Komplementbildung geschlossen, aber wir werden es nicht beweisen. Vereinigung: die deterministiche CF Sprachen sind nicht geschlossen für Vereinigung. Beweis: indirekt, mit De-Morgan Indentitäten. Die Durchschnitt würde auch geschlossen. Konkatenation: die CF Sprachen sind geschlossen für Konkatenation, aber wir wissen es nicht für deterministische CF Sprachen. Transitive Hülle: die CF Sprachen sind geschlossen für Transitive Hülle. 1.8 Geschlossenheit der reguläre und CF Sprachen regulär CF = CF regulär CF = CF regulär CF = CF!!! 1.9 Aufgaben 1. Geben wir CF Grammatik für die folgende Sprachen! (a) a i b j 0 i j 3i (b) a i+j b i c j i, j 0 (c) a i b i+j c j i, j 0 (d) a i b j c i+j i, j 0 2. Eliminieren Sie die ε-regeln! S ABC A BB ε B CC a C AA b 3. Eliminieren Sie die überflüssige Symbole! 4. Kämmen wir die folgende Grammatik: S A B A ab bs b B AB Ba C AS b S Ba Cab A A ab ac a B b BC C Cb CA
1.9. AUFGABEN 11 5. Geben wir den folgenden Grammatik in Chomsky Normal Form! S ABB a ba A BaS abs B b bs