Automaten und Formale Sprachen Skript zur Vorlesung WS 2010/11 Teil 2 (Kap. 4+5) Lesender: Prof. D. Kuske Autor: Prof. M. Dietzfelbinger Fassung vom 24.11.2010 Technische Universität Ilmenau Fakultät für Informatik und Automatisierung Fachgebiet Komplexitätsheorie und Effiziente Algorithmen i Inhaltsverzeichnis 0 Vorbemerkungen 2 0.1 Einleitung und Überblick . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 0.2 Zur Arbeitstechnik . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 0.3 Literatur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 1 Grundbegriffe 1.1 9 Alphabete und Sprachen . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 Endliche Automaten und reguläre Sprachen 2.1 9 18 Deterministische endliche Automaten . . . . . . . . . . . . . . . . . . . . . 18 2.1.1 Endliche Automaten mit Ausgabe . . . . . . . . . . . . . . . . . . . 30 2.2 Nichtdeterministische endliche Automaten . . . . . . . . . . . . . . . . . . 31 2.3 Reguläre Ausdrücke . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 2.4 Das Pumping-Lemma für reguläre Sprachen . . . . . . . . . . . . . . . . . 60 2.5 Abschlusseigenschaften für reguläre Sprachen . . . . . . . . . . . . . . . . . 63 2.6 Entscheidbarkeitsfragen für reguläre Sprachen . . . . . . . . . . . . . . . . 68 2.7 Die Minimierung deterministischer endlicher Automaten . . . . . . . . . . 71 2.7.1 Unerreichbare Zustände . . . . . . . . . . . . . . . . . . . . . . . . 71 2.7.2 Äquivalente und nicht-äquivalente Zustände . . . . . . . . . . . . . 74 2.7.3 Minimalautomaten . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 3 Grammatiken und die Chomsky-Hierarchie 87 3.1 Grammatiken . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87 3.2 Rechtslineare Grammatiken und reguläre Sprachen . . . . . . . . . . . . . 99 3.2.1 Rechtslineare Grammatiken . . . . . . . . . . . . . . . . . . . . . . 99 3.2.2 Äquivalenz zu regulären Sprachen . . . . . . . . . . . . . . . . . . . 100 ii 3.2.3 Linkslineare Grammatiken . . . . . . . . . . . . . . . . . . . . . . . 102 4 Kontextfreie Grammatiken und kontextfreie Sprachen 105 4.1 Beispiele und Ableitungen . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 4.2 Ableitungsbäume, Linksableitungen, Rechtsableitungen . . . . . . . . . . . 111 4.3 Die Chomsky-Normalform . . . . . . . . . . . . . . . . . . . . . . . . . . . 122 4.3.1 Separierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125 4.3.2 Verkürzung rechter Seiten . . . . . . . . . . . . . . . . . . . . . . . 127 4.3.3 Bearbeitung von ε-Produktionen . . . . . . . . . . . . . . . . . . . 129 4.3.4 Elimination von Kettenregeln . . . . . . . . . . . . . . . . . . . . . 137 4.4 Das Pumping-Lemma für kontextfreie Sprachen . . . . . . . . . . . . . . . 141 4.5 Der Cocke-Younger-Kasami-Algorithmus . . . . . . . . . . . . . . . . . . . 157 4.6 Abschlusseigenschaften kontextfreier Sprachen I . . . . . . . . . . . . . . . 162 5 Kellerautomaten 167 5.1 Nichtdeterministische Kellerautomaten . . . . . . . . . . . . . . . . . . . . 167 5.2 Top-Down-Parsing, LL-Parsing . . . . . . . . . . . . . . . . . . . . . . . . 180 5.3 Bottom-Up-Parsing, LR-Parsing . . . . . . . . . . . . . . . . . . . . . . . . 191 5.4 Akzeptierungsmodi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196 5.5 Kellerautomaten und Grammatiken . . . . . . . . . . . . . . . . . . . . . . 198 5.6 Abschlusseigenschaften II . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201 5.7 Deterministische Kellerautomaten und ihre Sprachen . . . . . . . . . . . . 202 5.8 Entscheidungsfragen für kontextfreie Sprachen . . . . . . . . . . . . . . . . 209 A 214 A.1 Zahldarstellungen und Abzählungen . . . . . . . . . . . . . . . . . . . . . . 214 A.1.1 Die b-äre Zahldarstellung . . . . . . . . . . . . . . . . . . . . . . . 214 A.1.2 Die b-adische Zahldarstellung . . . . . . . . . . . . . . . . . . . . . 218 A.2 Induktive Definitionen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222 A.2.1 Beispiel: Aussagenlogische Formeln . . . . . . . . . . . . . . . . . . 222 A.2.2 Beispiel: Korrekte Klammerausdrücke . . . . . . . . . . . . . . . . . 225 A.2.3 Induktive Definitionen: Formaler Rahmen . . . . . . . . . . . . . . 228 1 Kapitel 4 Kontextfreie Grammatiken und kontextfreie Sprachen In diesem Kapitel untersuchen wir die im vorigen Kapitel definierte Sprachklasse L2 genauer. Diese Klasse (und besonders noch engere Teilklassen davon) spielt eine zentrale Rolle bei der Spezifikation von Programmiersprachen und der Konstruktion von Compilern für Programmiersprachen. 4.1 Beispiele und Ableitungen Wir wiederholen Definition 3.1.10: Eine kontextfreie Grammatik G besteht aus der Menge V der (syntaktischen) Variablen, einem Terminalzeichen-Alphabet Σ, einem Startsymbol S ∈ V und der Menge P der Produktionen, wobei jede Produktion in P die Form A → X1 · · · Xr , A ∈ V, X1 , . . . , Xr ∈ V ∪ Σ hat. (Elemente von V ∪ Σ bezeichnen wir mit X, Y, Z, Xi , Yi , Zi , usw.) Man erinnere sich auch an die Konvention, statt A → β1 , A → β2 , . . . , A → βs kurz A → β1 | β2 | · · · | βs zu schreiben. Wir haben schon mehrere Beispiele für kontextfreie Grammatiken gesehen: (a) Beispiel 3.1.1 sollte arithmetische Ausdrücke mit den vier Grundoperationen, Klammerung und der Prioritätsregel Punkt vor Strich“ beschreiben. ” 105 (b) Bei Beispiel 3.1.11 sollte, so wurde behauptet, mit den drei Produktionen S → ε | SS | 0S1 die Menge kKA der korrekten Klammerausdrücke beschrieben werden. (Diese Sprache wird in Definition A.2.4 im Anhang definiert.) (c) In Beispiel 3.1.12 sollten die beiden Produktionen S → ε | 0S1 die Sprache {0n 1n | n ≥ 0} beschreiben. Wir erinnern uns weiter an den Ableitungs-Kalkül. (Siehe Definition 3.1.3(c).) Wenn α = Y1 · · · Ys A Z1 · · · Zt (mit Y1 , . . . , Ys , Z1 , . . . , Zt ∈ V ∪ Σ), und A → X1 · · · Xr eine Produktion in P ist, dann kann man aus α in einem Schritt α′ = Y1 · · · Ys X1 · · · Xr Z1 · · · Zt ableiten; man schreibt α ⇒ α′ . ∗ Dann betrachtet man Ketten von Ableitungsschritten und schreibt α ⇒ α′ , wenn es eine Folge α = α0 ⇒ α1 ⇒ · · · ⇒ αt , t ≥ 0 , von Ableitungsschritten gibt. Die Wörter α ∈ (V ∪ Σ)∗ , die man auf diese Weise aus S erzeugen kann, heißen Satzformen in G. D. h.: α ∈ (V ∪ Σ)∗ ist Satzform in G ⇔ es existiert eine Folge S = α0 ⇒ α1 ⇒ · · · ⇒ αt = α, mit t ≥ 0. Satzformen in Beispiel 3.1.1 sind z. B. die Zwischenwörter“, die in der in diesem Beispiel ” angegebenen Ableitung auftreten, also hexpr i , htermi , htermi / hfactor i , htermi / (hexpr i) , htermi / (hexpr i - htermi) , hfactor i / (hexpr i - htermi) , num / (hexpr i - htermi) und so weiter. Keine Satzformen sind (hexpr i / hexpr i)(htermi / hexpr i) und -htermi . In Beispiel 3.1.11 sind z. B. die folgenden Wörter Satzformen (prüfen!): S , 0S1 , 01 , SS , 0S1S , 01S , 01SS , 01S0S1 , 010S1S , 0101S , 0101 , 01S01 , 0100S110S1 , 0100110S1 , 01001101 . 106 Keine Satzformen sind 1S0 , S0S , 0S0S1, und so weiter. Sehr nützlich für den Nachweis, dass etwas keine Satzform ist, ist der Umstand, dass man das Konzept der Satzformen auch als induktive Definition fassen kann, vgl. Anhang A.2: (i) S ist Satzform in G; (ii) wenn α = Y1 · · · Ys A Z1 · · · Zt Satzform in G ist und A → X1 · · · Xr eine Produktion in P , dann ist auch α′ = Y1 · · · Ys X1 · · · Xr Z1 · · · Zt eine Satzform in G. (iii) Nichts sonst ist Satzform in G. Die Äquivalenz der beiden Formulierungen ist nicht schwer nachzuweisen. (Der Leser ist eingeladen, dies als Übung zu beweisen.) Wir benutzen diejenige der beiden Formulierungen, die bequemer ist. Induktion über den Aufbau von Satzformen“ ist oft hilfreich, um ” nachzuweisen, dass alle Satzformen eine bestimmte Eigenschaft haben. In Beispiel 3.1.1 kann man z. B. mit einer solchen Induktion leicht zeigen, dass keine Satzform mit -“ ” beginnt. Daher kann - htermi keine Satzform sein. Mit derselben Methode kann man beweisen, dass in keiner Satzform eines der Wörter )hexpr i , )htermi , )hfactor i oder )( als Teilwort vorkommen kann. Daher kann (hexpr i / hexpr i)(htermi / hexpr i) keine Satzform sein. Unter den Satzformen zu einer Grammatik G interessieren uns besonders diejenigen, die keine Variable enthalten. In Beispiel 3.1.11 sind dies z. B. 01, 0101 und 01001101. Die Menge L(G) = {w ∈ Σ∗ | w ist Satzform von G} ist die von G erzeugte Sprache. Also: w ist in L(G) ⇔ w ∈ Σ∗ und es gibt eine Ableitung S = α0 ⇒ α1 ⇒ · · · ⇒ αt = w. Achtung: Wenn die Grammatik G mehr als eine Variable benutzt, hat die Menge L(G) normalerweise keine einfache induktive Definition. 4.1.1 Beispiel Sei G = (V, Σ, S, P ), wo V = {S}, Σ = {0, 1}, und P enthält die Produktionen S → 0S0, S → 1S1, S → 0, S → 1, S → ε, oder kürzer: S → 0S0 | 1S1 | 0 | 1 | ε. 107 Ableitungen in der Grammatik G sehen beispielsweise so aus: S ⇒ ε ; S ⇒ 0S0 ⇒ 01S10 ⇒ 01110 ; S ⇒ 1S1 ⇒ 11S11 ⇒ 110S011 ⇒ 110011 . 4.1.2 Proposition Für die Grammatik G aus Beispiel 4.1.1 gilt L(G) = {w ∈ {0, 1}∗ | w = wR }. D. h.: L(G) ist die Sprache der Spiegelwörter ( Palindrome“) über {0, 1}. ” Ein Palindrom sieht von vorne und hinten gelesen gleich aus. Palindrome über dem 26buchstabigen lateinischen Alphabet sind zum Beispiel ara, elle, hannah, reliefpfeiler, sinnlosolnnis, ε . (Wie sieht eine kontextfreie Grammatik für die Menge der Palindrome über {a, . . . , z} aus? Wie die für die Palindrome über einem beliebigen vorgegebenen Alphabet Σ?) Beweis von Proposition 4.1.2: (Dieser Beweis ist als (Übungs-)Beispiel dafür zu verstehen, wie man das intuitiv Naheliegende formal exakt fassen kann.) ⊆“: (Typisch: Durch Induktion über den Aufbau der Satzformen beweist man eine Eigen” schaft aller Satzformen. Diese wird dann benutzt, um eine Eigenschaft aller ableitbaren Wörter w ∈ Σ∗ zu zeigen.) Behauptung: Ist α eine Satzform in G, so gilt entweder (I) α = wSwR für ein w ∈ Σ∗ oder (II) α = w ∈ Σ∗ mit w = wR . (Aus dieser Behauptung folgt sofort, dass jedes in G ableitbare Wort w ∈ Σ∗ die Eigenschaft w = wR hat.) I.A.: α = S: S = εSεR , also Format (I). I.V.: Die Behauptung gilt für α. I.S.: Sei α′ aus der Satzform α durch einen Ableitungsschritt gewonnen. Dann muss α mindestens eine Variable enthalten, also gilt nach der I.V.: α = wSwR für ein w ∈ Σ∗ . Nun gibt es drei Fälle. 1. Fall : Es wird die Produktion S → ε angewendet, um von α nach α′ zu kommen. Dann ist α′ = wwR , und es gilt (wwR )R = (wR )R wR = wwR . Also gilt (II) für α′ . 108 2. Fall : Es wird eine Produktion S → a, a ∈ {0, 1} angewendet, um von α nach α′ zu kommen. Dann ist α′ = wawR , und es gilt (wawR )R = (wR )R aR wR = wawR . Also gilt (II) für α′ . 3. Fall : Es wird eine Produktion S → aSa, a ∈ {0, 1}, angewendet, um von α nach α′ zu kommen. Dann ist α′ = waSawR , und es gilt (waSawR )R = (wR )R aSawR = waSawR . Also gilt (I) für α′ . In jedem Fall hat auch α′ Format (I) oder (II). ⊇“: (Typisch: Durch Induktion über die Wortlänge zeigt man, dass gewisse Wörter über ” Σ Satzformen darstellen, also in L(G) liegen.) Durch Induktion über die Wortlänge |w| zeigen wir: (+) Ist w = wR , so ist w ∈ L(G), für alle w ∈ Σ∗ . I.A.: w = ε, 0, oder 1. Dann gilt w ∈ L(G), weil S ⇒ ε, S ⇒ 0, S ⇒ 1 Ableitungen sind. I.V.: k ≥ 2, und für alle w′ mit |w′ | < k gilt (+). I.S.: Sei w ein Palindrom mit |w| = k. Weil |w| ≥ 2, ist w = aw′ a für ein a ∈ {0, 1} und ein w′ ∈ Σ∗ . Offenbar gilt w′ = (w′ )R und |w′ | < k. Nach I.V. ist also w′ eine Satzform in G. Das heißt: Es existiert eine Ableitung S ⇒ α1 ⇒ · · · ⇒ αr ⇒ w′ für w′ , mit r ≥ 0. Damit ist S ⇒ aSa ⇒ aα1 a ⇒ · · · ⇒ aαr a = aw′ a Ableitung für aw′ a, also w = aw′ a ∈ L(G). Damit ist Proposition 4.1.2 bewiesen. Wir bemerken, dass nach einer Übungsaufgabe die Sprache {w ∈ Σ∗ | w = wR } nicht regulär ist. Also sehen wir hier nochmals, dass L3 6= L2 ist. Nun wollen wir mit derselben Methode nachweisen, dass die Grammatik G = (V, Σ, S, P ) aus Beispiel 3.1.11, mit V = {S}, Σ = {0, 1}, und Produktionen S → ε | SS | 0S1, die Menge kKA der korrekten Klammerausdrücke erzeugt, siehe Definition A.2.4. Als Vorbereitung notieren wir eine nichtrekursive Charakterisierung der Elemente von kKA: Ein 0-1-Wort w ist ein korrekter Klammerausdruck genau dann wenn w ebenso viele Nullen wie Einsen hat und wenn beim Lesen von w von links nach rechts es niemals vorkommt, dass man mehr Einsen als Nullen gesehen hat. Formal: 4.1.3 Proposition (∗) Ein Wort w ∈ {0, 1}∗ ist in kKA genau dann wenn |w|0 = |w|1 und für jedes Präfix u von w gilt |u|0 ≥ |u|1 . 109 Beweis: Siehe Sätze A.2.5, A.2.6, A.2.7 in Anhang A.2. 4.1.4 Proposition Für die Grammatik G aus Beispiel 3.1.11 gilt: kKA = L(G). Beweis: ⊆“: Wir zeigen durch Induktion über die Struktur von kKA, dass alle Elemente ” w von kKA in L(G) sind, d. h., eine Ableitung haben. (i) Ist w = ε, so ist S ⇒ ε eine Ableitung von w. Also ist w ∈ L(G). (ii) Ist w = 0u1v, mit u, v ∈ kKA, so gibt es nach I.V. Ableitungen S = α0 ⇒ · · · ⇒ αt = u , , S = β0 ⇒ · · · ⇒ βs = v. Diese können wir mit den Anfangsschritten S ⇒ SS ⇒ 0S1S kombinieren, um eine Ableitung S ⇒ SS ⇒ 0S1S = 0α0 1β0 ⇒ · · · ⇒ 0αt 1β0 ⇒ · · · ⇒ 0αt 1βs = 0u1v = w für w zu erhalten. Also ist w ∈ L(G). (Übung: Man benutze diese Strategie, um für das Wort 010010101011 eine Ableitung in G zu finden.) ⊇“: Wir beweisen die folgende Hilfsbehauptung (HB) über Satzformen α in G: ” (HBα ) |α|0 = |α|1 und jedes Präfix γ von α erfüllt |γ|0 ≥ |γ|1 . Der Beweis erfolgt durch Induktion über den Aufbau von Satzformen. I.A.: Wenn α = S, so ist (HBα ) erfüllt, weil S keine Nullen oder Einsen enthält. I.V.: α = β S ζ erfüllt (HBα ). I.S.: Betrachte die Satzformen, die aus α in einem Schritt erzeugt werden können, indem man auf das S zwischen β und ζ eine Produktion anwendet. Es gibt zwei Fälle: 1. Fall : α′ = β SS ζ. (HBα′ ) folgt unmittelbar aus (HBα ), da sich an der Verteilung von Nullen und Einsen nichts ändert. 2. Fall : α′ = β 0S1 ζ. Hier erhöht sich die Gesamtzahl von Nullen und Einsen um jeweils 1, also folgt |α′ |0 = |α′ |1 aus der I.V. Nun betrachten wir Präfixe: Für ein Präfix γ ′ von α′ gibt es verschiedene Möglichkeiten. Wenn γ ′ Präfix von β ist, besagt die I.V. direkt, dass |γ ′ |0 ≥ |γ ′ |1 . Weil nach I.V. |β|0 ≥ |β|1 , folgt auch |β0|0 ≥ |β0|1 , |β0S|0 ≥ |β0S|1 und |β0S1|0 ≥ |β0S1|1 . Schließlich könnte γ ′ = β0S1ζ ′ für ein Präfix ζ ′ von ζ sein. Dann liefert die I.V., dass |βζ ′ |0 ≥ |βζ ′ |1 gilt; daraus folgt sofort |β0S1ζ ′ |0 ≥ |β0S1ζ ′ |1 , weil sich auf beiden Seiten die Anzahl der Nullen und Einsen um 1 erhöht. Nach dem Prinzip der Induktion über den Aufbau von der Satzformen in G folgt, dass (HBα ) für alle Satzformen in G gilt. Da jedes Wort w ∈ L(G) (auch) Satzform ist, erfüllt jedes w ∈ L(G) Bedingung (∗) in Proposition 4.1.3, ist also in kKA. 110 4.2 Ableitungsbäume, Linksableitungen, Rechtsableitungen Wir haben bislang Ableitungen als Folgen S ⇒ α1 ⇒ · · · ⇒ αr in (V ∪ Σ)∗ dargestellt. Im Fall der kontextfreien Grammatiken bietet es sich jedoch an, Ableitungen als Bäume darzustellen. Diese Syntaxbäume“ oder Ableitungsbäume“ sind wichtiges Hilfmittel ” ” und Zwischenergebnis bei der Analyse von Programmtexten durch einen Compiler. 4.2.1 Beispiel Wir betrachten wieder die Grammatik G mit Produktionen S → ε | SS | 0S1 aus Beispiel 3.1.11. Folgendes ist eine Ableitung in dieser Grammatik: S ⇒ SS ⇒ SSS ⇒ S0S1S ⇒ S01S ⇒ 0S101S ⇒ 0S101S ⇒ 0101S ⇒ 0101 . (In jedem Schritt haben wir die Kopie von S, auf die eine Produktion angewandt wird, T : 2 T : 1 T : 0 T : 4 T : 3 S S S S_ S_ S S S_ T : 5 S S S_ 1 0 T : 6 S S S 1 0 S 1 0 S ε S 0 ε S S S_ S 1 S 1 S S S S ε T : 7 S S S S 0 S_ S_ S S S 0 S S 1 0 S S ε ε S S 1 0 S 1 ε ε Abbildung 4.1: Schrittweiser Aufbau eines Ableitungsbaums unterstrichen.) Aus einer solchen Ableitung α0 ⇒ · · · ⇒ αt bauen wir schrittweise Bäume 111 T0 , . . . , Tt , wie folgt. Baum T0 ist ein Knoten, der mit S beschriftet ist. Nach Abarbeiten der Ableitungsschritte α0 ⇒ · · · ⇒ αs , s ≤ t, haben wir einen Baum Ts , an dessen Blättern, von links nach rechts gelesen, die Buchstaben der Satzform αs stehen. Im Schritt αs ⇒ αs+1 wird eine der Produktionen S → ε, S → SS, S → 0S1 auf eine der Variablen angewendet, die in einem Blatt steht. An dieses Blatt hängen wir einen, zwei oder drei neue Knoten, die mit ε oder den Buchstaben in der rechten Seite der benutzten Produktion beschriftet werden. Wenn s = t, sind wir fertig, und Tt ist der Ableitungsbaum“ zu ” α0 ⇒ · · · ⇒ αt . Aus der Beispielableitung ergibt sich die in Abb. 4.1 dargestellte Folge von Ableitungsbäumen. Aus der Ableitung S ⇒ SS ⇒ SSS ⇒ 0S1SS ⇒ 0S1S ⇒ 01S ⇒ 010S1 ⇒ 0101 für dasselbe Terminalzeichenwort erhalten wir am Ende denselben Baum wie in Abb. 4.1. (Der Leser/die Leserin ist eingeladen, die entsprechende Folge aufzuzeichnen und sich zu überzeugen, dass eigentlich dieselben Ableitungsschritte vorgenommen werden, nur in einer anderen Reihenfolge.) Dagegen ergibt die Ableitung S ⇒ SS ⇒ SSS ⇒ SS ⇒ 0S1S ⇒ 01S ⇒ 010S1 ⇒ 0101 , die dasselbe Wort erzeugt, den in Abb. 4.2 dargestellten Baum, der eine andere Struktur hat. S S S S ε S 0 0 S 1 S 1 ε ε Abbildung 4.2: Ein zweiter Ableitungsbaum für 0101 Als weiteres Beispiel betrachten wir Ableitungsbäume zur Grammatik aus Beispiel 3.1.1. In den Abbildungen haben wir die Knoten, die syntaktischen Variablen entsprechen, einfach durch den Namen der Variablen dargestellt; nur Terminalzeichen sind als Kreis dargestellt. Abbildung 4.3 zeigt einen Ableitungsbaum für das Wort ( num - num * num / num ) / num + num * num / num - num 112 <expr> + <term> <factor> ( <term> <expr> − <factor> num / <term> ) <factor> <factor> num num <expr> num − <term> <term> * <factor> num <term> <factor> <expr> <term> * <factor> / num / <expr> <term> <term> <factor> <factor> num num <term> <factor> num Abbildung 4.3: Ableitungsbaum für ( num - num * num / num ) / num + num * num / num - num Abbildung 4.4 einen für num - num - num - num * num. In Abbildung 4.5 sieht man einen Ableitungsbaum, in dem manche Blätter mit Variablen beschriftet sind, der also eine Satzform liefert und noch weiter ausgebaut werden könnte. Wir definieren nun formal, was Ableitungsbäume sein sollen. 4.2.2 Definition Sei G = (V, Σ, S, P ) eine kontextfreie Grammatik. (a) Ein Ableitungsbaum (auch: Syntaxbaum) T ist ein gerichteter, geordneter1 Baum mit Wurzel, dessen Knoten mit je einem Buchstaben aus V ∪ Σ oder mit ε beschriftet sind, wobei folgendes gilt: (I) Die Wurzel ist mit S beschriftet, (II) Ist v ein Knoten, der mit a ∈ Σ oder mit ε beschriftet ist, so ist v ein Blatt, hat also keine Nachfolgerknoten. 1 Ein Baum heißt geordnet, wenn die unmittelbaren Nachfolgerknoten eines Knotens eine Reihenfolge von links nach rechts“ haben. ” 113 <expr> <term> <factor> num − <expr> <term> − <expr> <factor> <term> num <factor> num − <expr> <term> <factor> num * <term> <factor> num Abbildung 4.4: Ableitungsbaum für num - num - num - num * num (III) Ist v ein Knoten, der mit A ∈ V beschriftet ist, und ist v kein Blatt, so gilt: (i) die Nachfolgerknoten v1 , . . . , vr von v sind mit X1 , . . . , Xr ∈ Σ ∪ V beschriftet, und A → X1 · · · Xr ist Produktion in P oder (ii) v hat genau einen Nachfolger v ′ , der mit ε beschriftet ist, und A → ε ist Produktion in P . (b) Ist T ein Ableitungsbaum, so bezeichnen wir mit α(T ) das Wort über V ∪ Σ, das sich beim Lesen der Blätter von T von links nach rechts ergibt. (Das Wort α(T ) heißt das Ergebnis“ oder Resultat“ von T (engl. yield ), manchmal ” ” auch das Blattwort“ von T .) ” In den Bäumen in Abb. 4.1 sind die Wörter α(T0 ), . . . , α(T7 ) einfach die Satzformen in der zugrunde liegenden Ableitung. Im Baum in Abb. 4.2 ist α(T ) = 0101. Bei der Bestimmung von α(T ) werden ε’s natürlich einfach verschluckt. Im Extremfall sind alle Blätter von T 114 <expr> + <term> <factor> / <expr> <term> − <term> <factor> <factor> <term> * <factor> num / <term> <expr> <term> <factor> num Abbildung 4.5: Ableitungsbaum für eine Satzform mit ε beschriftet; dann ist α(T ) = ε. Ein Beispiel für diese Situation ist für die Grammatik aus Beispiel 4.2.1 in Abb. 4.6 angegeben. S S S ε S S S S ε ε S S ε ε Abbildung 4.6: Ein Ableitungsbaum für ε Wenn X ∈ V ∪ Σ beliebig ist, ist ein X-Ableitungsbaum genauso definiert wie in Definition 4.2.2, außer dass man verlangt, dass die Beschriftung der Wurzel X ist. Zum Beispiel ist in Abb. 4.3 der linke Unterbaum der Wurzel ein htermi-Ableitungsbaum T ′ mit Ergebnis α(T ′ ) = ( num - num * num / num ) / num. X-Ableitungsbäume werden schematisch so gezeichnet: 115 X T α(T ) Wir halten fest, dass Ableitungsbäume tatsächlich dasselbe leisten wie Ableitungsfolgen. 4.2.3 Lemma Sei G kontextfreie Grammatik. Dann sind für X ∈ V ∪ Σ und α ∈ (V ∪ Σ)∗ die folgenden beiden Aussagen äquivalent: ∗ (i) X ⇒ α; (ii) α = α(T ) für einen X-Ableitungsbaum T . Insbesondere gilt: α ist Satzform von G genau dann wenn es einen (S-)Ableitungsbaum T mit α(T ) = α gibt; und w ∈ L(G) ⇔ w ∈ Σ∗ und es gibt einen Ableitungsbaum T mit α(T ) = w. Beweis (i) ⇒ (ii)“: Sei X = α0 ⇒ · · · ⇒ αr = α Ableitung in G. Wir formulieren ” die in 4.2.1 angewandte induktive Methode, aus einer Ableitung schrittweise einen Baum zu konstruieren, allgemein. Die Wurzel ist ein Knoten, der mit X = α0 beschriftet ist. Sei nun 0 ≤ s < r. Als Induktionsvoraussetzung nehmen wir an, wir hätten schon einen X-Ableitungsbaum Ts für αs = X1 · · · Xt , d. h. X1 , . . . , Xt sind die von ε verschiedenen Einträge an den Blättern von Ts . Es gibt dann t′ ∈ {1, . . . , t} und Y1 · · · Yu derart, dass Xt′ → Y1 · · · Yu eine Produktion ist und αs = X1 · · · Xt′ · · · Xt ⇒ X1 · · · Xt′ −1 Y1 · · · Yu Xt′ +1 · · · Xt = αs+1 der nächste Ableitungsschritt ist. Der Knoten zu Xt′ in Ts erhält u Nachfolgerknoten, die mit Y1 , . . . , Yu beschriftet werden. Offenbar ist der resultierende Baum Ts+1 wieder ein X-Ableitungsbaum, und α(Ts+1 ) = αs+1 . Ist u = 0, erhält der Knoten zu Xt′ einen Nachfolger mit Markierung ε. Das Konstruktionsschema ist in Abb. 4.7 wiedergegeben. 116 Ts : Ts + 1: X X1 ... X t’ ... X t X X1 ... X t’ ... X t ... Y1 ... ... Yu Abbildung 4.7: Konstruktion eines Ableitungsbaumes, ein Schritt Nach r Schritten ergibt sich ein Baum Tr mit α(Tr ) = αr = α. (ii) ⇒ (i)“: Es sei ein X-Ableitungsbaum T gegeben. Durch Induktion nach der Tiefe k ” ∗ von T zeigen wir, dass X ⇒ α(T ) gilt. 0 k = 0: Hat T nur einen Knoten, die Wurzel, so ist α(T ) = X, und X ⇒ X ist Ableitung. k > 0: Ist T ein Baum, der nicht nur aus der Wurzel besteht, so muss die Wurzelbeschriftung X eine Variable A ∈ V sein. Falls die Wurzel nur einen, mit ε beschrifteten, Nachfolger besitzt, ist α(T ) = ε; dann muss aber A → ε Produktion sein, also A ⇒ ε Ableitung. Sonst hat die Wurzel r ≥ 1 Nachfolger v1 , . . . , vr , die mit X1 , . . . , Xr ∈ V ∪ Σ beschriftet sind. Der i-te Unterbaum Ti (mit Wurzel vi ) ist Xi -Ableitungsbaum, für 1 ≤ i ≤ r, jeweils mit Tiefe kleiner als k. Nach Induktionsvoraussetzung gilt ∗ Xi ⇒ α(Ti ) , für 1 ≤ i ≤ r . Durch Zusammensetzen dieser r Ableitungen erhalten wir die Ableitung ∗ ∗ ∗ X ⇒ X1 X2 · · · Xr ⇒ α(T1 )X2 · · · Xr ⇒ α(T1 )α(T2 )X3 · · · Xr ⇒ · · · ∗ ⇒ α(T1 ) · · · α(Tr ) = α(T ) . Beispiel: Wir wollen aus dem Baum S S S S ε S 0 S 0 1 ε 0 S S ε 117 1 1 zu der Grammatik aus 4.2.1 eine Ableitung bauen. Zuerst behandeln wir den linken Unterbaum und finden (notfalls durch Anwenden derselben Prozedur auf diesen Unterbaum) die Ableitungsfolge S ⇒ SS ⇒ S ⇒ 0S1 ⇒ 01. Der rechte Unterbaum liefert die Ableitungsfolge S ⇒ 0S1 ⇒ 00S11 ⇒ 0011. Diese beiden Ableitungen werden hintereinandergesetzt“ an den Startschritt S ⇒ SS ” angefügt – mit der ersten Ableitung wird das erste S“ bearbeitet, mit der zweiten das ” zweite. Dies liefert: S ⇒ SS ⇒ SSS ⇒ SS ⇒ 0S1S ⇒ 01S ⇒ 010S1 ⇒ 0100S11 ⇒ 010011. Folgende Beobachtung ist für später wichtig: Ableitungsschritte, die zum rechten Unterbaum gehören, werden erst durchgeführt, wenn der linke Unterbaum komplett abgearbeitet ist. Dies führt dazu, dass immer die am weitesten links stehende Variable bearbeitet wird. Der Ableitungsbaum T enthält vollständige Information darüber, durch welche Ableitungsschritte die Satzform α(T ) abgeleitet wird, also auch noch jede Menge Strukturinformation. Einzig von der Reihenfolge der Anwendung der Produktionen wird abgesehen. Deshalb heißen Ableitungsbäume auch Syntaxbäume oder Strukturbäume – sie geben über die Struktur“ oder den Satzbau“ des Wortes α(T ) bezüglich der Grammatik G Aus” ” kunft. Diese Eindeutigkeit der verwendeten Produktionen ist bei Ableitungsfolgen nicht unbedingt gegeben; z. B. können zur Folge S ⇒ SS ⇒ SSS in der Grammatik von Beispiel 4.2.1 die beiden verschiedenen Bäume S S S S S S S S S S gehören. Daher zieht man meist Ableitungsbäume als Darstellung für Ableitungen vor. Oft ist es jedoch nützlich, eindimensionale (zeigerfreie) Notationen für Ableitungsbäume zu haben. Diesem Zweck dienen Linksableitungen (bzw. Rechtsableitungen). 4.2.4 Definition Eine Ableitung S = α0 ⇒ α1 ⇒ · · · ⇒ αr = w ∈ Σ∗ (NB: w besteht aus Terminalzeichen) ist eine Linksableitung , wenn für 0 ≤ s < r beim Übergang von αs zu αs+1 auf die am weitesten links stehende Variable in αs eine Produktion angewendet wird. Mit anderen Worten: In einer Linksableitung gilt für jeden Ableitungsschritt Y1 · · · Ys A Z1 · · · Zt ⇒ Y1 · · · Ys X1 · · · Xr Z1 · · · Zt , 118 dass Y1 , . . . , Ys ∈ Σ sind. Rechtsableitungen werden analog definiert: Produktionen werden immer auf die am weitesten rechts stehende Variable angewendet. Beispiel: (Zu Grammatik aus Beispiel 4.2.1 ) S ⇒ SS ⇒ 0S1S ⇒ 00S11S ⇒ 0011S ⇒ 00110S1 ⇒ 001101 ist Linksableitung, S ⇒ SS ⇒ S0S1 ⇒ S01 ⇒ 0S101 ⇒ 00S1101 ⇒ 001101 ist Rechtsableitung. Die Ableitung S ⇒ SS ⇒ SSS ⇒ S0S1S ⇒ 0S1S ⇒ 0S10S1 ⇒ 010S1 ⇒ 0101 ist weder Links- noch Rechtsableitung. Wenn man weiß, dass eine Ableitung eine Linksableitung (bzw. eine Rechtsableitung) ist, erübrigt es sich, in αs die Variable zu markieren, auf die eine Produktion angewendet wird – es ist immer die am weitesten links (bzw. rechts) stehende. 4.2.5 Proposition Sei G kontextfreie Grammatik, w ∈ Σ∗ . Dann gilt: Ableitungsbäume und Linksableitungen für w entsprechen einander eineindeutig. Die entsprechende Aussage gilt für Ableitungsbäume und Rechtsableitungen. Beispiel: Das Wort 010101 besitzt in der Grammatik aus 4.2.1 die beiden Linksableitungen S ⇒ SS ⇒ 0S1S ⇒ 01S ⇒ 01SS ⇒ 010S1S ⇒ 0101S ⇒ 01010S1 ⇒ 010101, S ⇒ SS ⇒ SSS ⇒ 0S1SS ⇒ 01SS ⇒ 010S1S ⇒ 0101S ⇒ 01010S1 ⇒ 010101, entsprechend den beiden in Abb. 4.8 angegebenen Ableitungsbäumen. (Man suche die entsprechenden Rechtsableitungen!) S S S S 0 S ε S S 1 0 S ε S 1 0 S S S S 1 0 ε S ε 1 0 S 0 1 S 1 ε ε Abbildung 4.8: Zwei verschiedene Ableitungsbäume für das Wort 010101 119 Beweis von Proposition 4.2.5: Sei w ∈ L(G) fest. Wenn eine beliebige Linksableitung LA für w ∈ Σ∗ gegeben ist, so können wir wie im Beweisteil (i) ⇒ (ii)“ von Lemma 4.2.3 daraus einen Ableitungsbaum TLA für w erzeugen. ” Sind zwei verschiedene Linksableitungen LA1 und LA2 für w gegeben, so führen diese zu zwei verschiedenen Ableitungsbäumen TLA1 und TLA2 . (Man betrachte den ersten Ableitungsschritt, in dem sich LA1 und LA2 unterscheiden. Dabei müssen auf dieselbe Variable an derselben Position verschiedene Produktionen angewendet werden; dies schlägt sich direkt in einem Unterschied in den Syntaxbäumen nieder.) Die Abbildung Φ : LA 7→ TLA ist also injektiv. Wenn man nun einen beliebigen Ableitungsbaum T für w gegeben hat, so liefert die Konstruktion aus Lemma 4.2.3 (ii) ⇒ (i)“ eine Linksableitung LA(T ) für w, und es gilt ” TLA(T ) = T . Damit ist die Abbildung Φ auch surjektiv; sie stellt also eine Bijektion dar. Um diesen Beweis zu illustrieren, wende man die Konstruktionen aus 4.2.3 auf das nach Bemerkung 4.2.5 angegebene Beispiel an. 4.2.6 Definition (a) Eine kontextfreie Grammatik G heißt mehrdeutig , wenn es ein Wort w ∈ L(G) gibt, das (mindestens) zwei verschiedene Ableitungsbäume besitzt. Sie heißt eindeutig , wenn jedes Wort w ∈ L(G) genau einen Ableitungsbaum besitzt. (b) Eine Sprache L ∈ L2 heißt inhärent mehrdeutig , wenn jede kontextfreie Grammatik G mit L = L(G) mehrdeutig ist. Es ist für die Syntaxanalyse (Konstruktion eines Ableitungs- oder Syntaxbaumes zu einem vorgelegten Wort w ∈ L(G)), wie sie z. B. in Compilern geleistet wird, sehr wichtig, dass jedes Wort w ∈ L(G) nur einen Syntaxbaum, also auch nur eine Linksableitung besitzt. Beim Entwurf von Programmiersprachen ist es also wichtig, eine eindeutige Grammatik für die Sprache zu haben. Insbesondere ist es ungünstig, wenn die Programmiersprache selbst inhärent mehrdeutig ist. 4.2.7 Beispiel (a) Die Grammatik aus Beispiel 4.2.1 für kKA ist mehrdeutig, wie wir an den in Abb. 4.1 und 4.2 dargestellten verschiedenen Ableitungsbäumen für das Wort 0101 erkennen können. Dennoch ist die Sprache kKA nicht inhärent mehrdeutig, da sie auch eine eindeutige Grammatik besitzt. Wir behaupten nämlich, und beweisen gleich, dass folgendes eine eindeutige Grammatik für die Sprache kKA ist: G = ({S}, {0, 1}, S, P ), wo P die Produktionen S → ε , S → 0S1S enthält. (Man baue Ableitungsbäume in dieser Grammatik für einige Wörter w ∈ kKA!) (b) Ohne Beweis bemerken wir, dass die Sprache L := {an bn cm | n, m ∈ N} ∪ {am bn cn | n, m ∈ N} 120 eine inhärent mehrdeutige kontextfreie Sprache ist. Die Aussage L ∈ L2 ist dabei nicht schwer zu zeigen. Folgendes ist eine naheliegende Grammatik für L: G = ({S, A, B}, {a, b, c}, S, P ), wobei P die folgenden Produktionen enthält: S A D C E → → → → → AD | EC aA | ε bDc | ε cC | ε aEb | ε . Zum Beispiel gibt es für das Wort aabbcc die beiden folgenden verschiedenen Linksableitungen, anhand derer man auch die Idee hinter der Grammatik studieren kann: S ⇒ AD ⇒ aAD ⇒ aaAD ⇒ aaD ⇒ aabDc ⇒ aabbDcc ⇒ aabbcc ; S ⇒ EC ⇒ aEbC ⇒ aaEbbC ⇒ aabbC ⇒ aabbcC ⇒ aabbccC ⇒ aabbcc . Der Nachweis der inhärenten Mehrdeutigkeit ist aufwendiger und wird hier ausgelassen. Intuitiv benötigt jede Grammatik G′ mit L(G′ ) = L für die beiden Teile der Sprache unabhängige Abteilungen“; die Wörter an bn cn für große n müssen Ableitungen in beiden ” Abteilungen“ besitzen, die dann notwendig verschieden sind. ” 4.2.8 Proposition gilt: Es sei G = ({S}, {0, 1}, S, P ) mit P = {S → ε, S → 0S1S}. Dann (a) L(G) = kKA, (b) G ist eindeutig. Beweis: (a) ⊆“: Durch Induktion über die Länge t einer Ableitungsfolge ” S = α0 ⇒ α1 ⇒ · · · ⇒ αt beweist man, dass jede Satzform in der Grammatik G die Hilfsbehauptung (HBα ) aus dem Beweis von Prop. 4.1.4 erfüllt. Das geht praktisch genau so wie dort vorgeführt. Daraus folgt dann, dass jedes w ∈ L(G) die Eigenschaft (∗) aus Prop. 4.1.3 hat, also ein korrekter Klammerausdruck ist. ⊇“: Wir beweisen durch Induktion über den Aufbau von korrekten Klammerausdrücken, ” dass jeder korrekte Klammerausdruck w eine Ableitung in G besitzt. I.A.: Wenn w = ε, ist S ⇒ ε eine Ableitung. I.S.: Nun sei w 6= ε ein korrekter Klammerausdruck. Nach der Definition ist w = 0w′ 1w′′ 121 ∗ für korrekte Klammerausdrücke w′ und w′′ . Nach I.V. gibt es Ableitungsfolgen S ⇒ w′ ∗ und S ⇒ w′′ . Wenn wir diese Folgen mit dem Ableitungsschritt S ⇒ 0S1S kombinieren, erhalten wir eine Ableitung ∗ ∗ S ⇒ 0S1S ⇒ 0w′ 1S ⇒ 0w′ 1w′′ = w, wie gewünscht. (b) Wir zeigen durch Induktion über |w|, dass jedes Wort w ∈ L(G) genau eine Linksableitung hat. I.A.: Wenn w = ε, ist S ⇒ ε die einzige Ableitung für w. I.V.: Es sei k ≥ 1, und für jedes w′ ∈ L(G) gebe es genau eine Linksableitung. I.S.: Nun sei w ∈ L(G), w 6= ε, mit einer Linksableitung S = α0 ⇒ 0S1S = α1 ⇒ · · · ⇒ αt = 0w′ 1w′′ = w. Man denkt sich die 0 und die 1 in α1 = 0S1S permanent markiert (unterstrichen). Diese Terminalzeichen werden ja nach dem ersten Ableitungsschritt nie mehr verändert. Da wir es mit einer Linksableitung von w zu tun haben, werden in einem ersten Teil α0 ⇒ · · · ⇒ αs der Ableitung Produktionen nur auf Variable zwischen 0 und 1 angewendet, und αs = 0w′ 1S. Da man aus S nur Wörter in L(G) erzeugen kann, ist w′ ∈ L(G) und der Teil der Ableitung α1 ⇒ · · · ⇒ αs , der sich zwischen 0 und 1 abspielt, bildet eine Linksableitung für w′ . Nun ist |w′ | < |w|, und daher ist nach der I.V. diese Ableitung eindeutig bestimmt; daher sind α1 , . . . , αs eindeutig bestimmt. Genauso argumentiert man, dass sich im zweiten Teil der Ableitung αs ⇒ · · · ⇒ αt im Teil rechts von 1 eine Linksableitung für das Wort w′′ abspielen muss. Wieder wegen der Eindeutigkeit dieser Linksableitung (nach I.V.) kann es auch nur eine Möglichkeit für diesen zweiten Teil der Ableitung geben. Schließlich bemerkt man, dass 0w′ 1 das kürzeste Präfix von w ist, das gleich viele Nullen wie Einsen enthält. Damit sind die Teilwörter w′ und w′′ durch w, nicht durch die spezielle Ableitung α0 ⇒ 0S1S ⇒ · · · ⇒ αt = w, festgelegt. Also kann es für w nur diese eine Linksableitung geben; das ist die Induktionsbehauptung. Wir bemerken noch (ohne formalen Beweis), dass die Grammatik für arithmetische Ausdrücke aus Beispiel 3.1.1 eindeutig ist. In den Übungen wird eine mehrdeutige Grammatik für klammerfreie arithmetische Ausdrücke besprochen. 4.3 Die Chomsky-Normalform Sowohl für theoretische Zwecke als auch für praktische Anwendungen ist es günstig, kontextfreie Grammatiken zu haben, deren Produktionen noch engere Anforderungen erfüllen als die bloße Kontextfreiheit. In diesem Abschnitt geben wir eine solche Normalform an und besprechen einen Konstruktionsalgorithmus dafür. Anwendungen werden in späteren Abschnitten angegeben. 122 4.3.1 Definition Eine kontextfreie Grammatik G = (V, Σ, S, P ) ist in ChomskyNormalform, falls • entweder alle Produktionen von G die Form A → BC (A, B, C ∈ V ) oder A → a (A ∈ V, a ∈ Σ) haben • oder alle Produktionen von G die Form A → BC oder A → a oder S → ε haben, und S nie auf der rechten Seite einer Produktion vorkommt. 4.3.2 Beispiel (a) Die Grammatik G = (V, Σ, S, P ) mit V = {S, R, A, B, F, H}, Σ = {0, 1}, Startsymbol S und Produktionen S R F H A B → → → → → → ε | AF AF BR | RH | 1 BR | 1 0 1 erfüllt die Anforderungen der Definition. Die Produktion S → ε kommt vor; S kommt nicht auf der rechten Seite irgendeiner Produktion vor. Die einzige Möglichkeit, das Wort ε zu erzeugen, ist mit der 1-Schritt-Ableitung S ⇒ ε. An der Beispiel-Linksableitung S ⇒ AF ⇒ 0F ⇒ 0RH ⇒ 0AF H ⇒ 00F H ⇒ 00BRH ⇒ 001RH ⇒ 001AF H ⇒ 0010F H ⇒ 00101H ⇒ 00101BR ⇒ 001011R ⇒ 001011AF ⇒ 0010110F ⇒ 00101101 für ein Wort 6= ε erkennt man, dass in jedem Ableitungsschritt entweder die Zahl der Zeichen um 1 steigt oder eine Variable in ein Terminalzeichen umgewandelt wird. Daraus sieht man sofort, auch allgemein, dass die Zahl der Ableitungsschritte in einer Grammatik in Chomsky-Normalform für ein Wort w mit n Buchstaben genau 2n − 1 beträgt. Eine Satzform besteht immer aus 0 oder mehr Terminalzeichen, gefolgt von 0 oder mehr Variablen. Der Ableitungsbaum, der der Beispiel-Linksableitung entspricht, sieht folgendermaßen aus: Wieder erkennt man schon am Beispiel, dass Ableitungsbäume für n-buchstabige Wörter genau n Blätter haben, die mit Terminalzeichen beschriftet sind, und dass der Teil des Baums, dessen Knoten mit Variablen beschriftet sind, einen vollen“ Binärbaum ” 123 S F A 0 H R A F B 0 R 1 B R 1 A F 0 1 A F 0 1 Abbildung 4.9: Ein Ableitungsbaum zu einer Grammatik in Chomsky-Normalform mit n Blättern darstellt.2 Man weiß, dass solche Bäume 2n − 1 Knoten haben (die genau den Ableitungsschritten entsprechen). Wie im Beispiel gilt allgemein, dass Ableitungen und Ableitungsbäume in Grammatiken in Chomsky-Normalform sehr stark standardisiert und übersichtlich sind. (b) Die Grammatik G = (V, Σ, S, P ) mit V = {S, A, B, F, H}, Σ = {0, 1}, Startsymbol S und Produktionen S F H A B → → → → → AF BS | SH | 1 BS | 1 0 1 erfüllt ebenfalls die Anforderungen der Definition. Die Startvariable erscheint auf der rechten Seite von Produktionen, aber es gibt überhaupt keine ε-Produktion. 2 Ein Binärbaum heißt voll“, wenn jeder Knoten, der kein Blatt ist, genau zwei Nachfolger hat. ” 124 Der Leser/die Leserin ist eingeladen, einige Ableitungen und Ableitungsbäume für diese Grammatik zu entwickeln und zu spekulieren, welche Sprache zu G gehört. 4.3.3 Definition L(G′ ) gilt. Zwei Grammatiken G und G′ heißen äquivalent, wenn L(G) = Am Ende dieses Abschnitts werden wir folgenden Satz bewiesen haben: 4.3.4 Satz Jede kontextfreie Grammatik G kann in eine äquivalente Grammatik G′ in Chomsky-Normalform umgebaut werden. Hierfür gehen wir in vier Schritten vor: 1. Separieren der Terminalzeichen-Produktionen 2. Verkürzen der rechten Seiten 3. Elimination der ε-Produktionen A → ε 4. Elimination von Kettenregeln A → B 4.3.1 Separierung Zunächst wollen wir Produktionen, die Terminalzeichen erzeugen, von solchen trennen, die Variable erzeugen. Es soll also niemals auf einer rechten Seite eine Mischung von Terminalzeichen und Variablen stehen; zudem sollen niemals Blöcke von mehreren Terminalzeichen erzeugt werden. Es gibt keinen Grund, sich für diese Überlegung auf kontextfreie Grammatiken zu beschränken. 4.3.5 Definition Eine Grammatik G = (V, Σ, S, P ) (im Sinn von Definition 3.1.2) heißt separiert, wenn Terminalzeichen nur in Produktionen der Form A → a (A ∈ V , a ∈ Σ) vorkommen. (Alle anderen Produktionen haben die Form X1 · · · Xs → Y1 · · · Yt , mit s ≥ 1, t ≥ 0, X1 , . . . , Xs , Y1 , . . . , Yt Variable.) 4.3.6 Lemma Jede Grammatik G = (V, Σ, S, P ) kann in eine äquivalente separierte Grammatik G′ = (V ′ , Σ, S, P ′ ) umgebaut werden. 125 Beweis: Für jedes a ∈ Σ wird eine neue Variable Da eingeführt. In allen Produktionen in P wird auf der linken und auf der rechten Seite a durch Da ersetzt. Weiterhin werden neue Regeln Da → a, für a ∈ Σ, hinzugefügt. Offenbar gilt für die resultierende Grammatik G′ := (V ∪ {Da | a ∈ Σ}, Σ, S, P ′ ), dass L(G) = L(G′ ). 4.3.7 Beispiel Wenn man die angegebene Konstruktion auf G = ({S}, {0, 1}, S, P ) mit P = {S → ε | 0S1S} anwendet, braucht man zwei neue Variable, etwa A (als D0 ) und B (als D1 ). Die Produktionen der neuen Grammatik G′ sind dann: S → ε | ASBS A → 0 B → 1 4.3.8 Beispiel Weiter wenden wir die Konstruktion aus Lemma 4.3.6 auf die Grammatik aus Beispiel 3.1.1 an, die die folgenden Produktionen hat: hfactor i → num | (hexpr i) htermi → htermi * hfactor i | htermi / hfactor i | hfactor i hexpr i → hexpr i + htermi | hexpr i - htermi | htermi Wir führen für jedes Terminalzeichen eine neue Variable und eine Produktion ein, zum Beispiel wie folgt: hnumi hliklai hreklai hplusi hminusi htimesi hover i → → → → → → → 126 num ( ) + * / Die alten Produktionen sehen nach der Änderung wie folgt aus: hfactor i → hnumi | hliklaihexpr ihreklai htermi → htermi htimesi hfactor i | htermi hover i hfactor i | hfactor i hexpr i → hexpr i hplusi htermi | hexpr i hminusi htermi | htermi 4.3.2 Verkürzung rechter Seiten Als nächsten Schritt möchten wir erreichen, dass unsere Grammatiken keine Produktionen mehr haben, bei denen auf der rechten Seite mehr als zwei Variable stehen. Das ist ganz leicht. 4.3.9 Lemma Jede separierte kontextfreie Grammatik G = (V, Σ, S, P ) kann in eine äquivalente separierte kontextfreie Grammatik G′ = (V ′ , Σ, S, P ′ ) umgebaut werden, die nur noch Produktionen der folgenden Form hat: • A → ε, • A → a, mit A ∈ V , a ∈ Σ, • A → B, mit A, B ∈ V , • A → BC, mit A, B, C ∈ V . Beweis: Wir bearbeiten jede Produktion A → C1 C2 · · · Cr in P mit r ≥ 3 separat. Es werden r − 2 neue Variable Y2 , . . . , Yr−1 (die nur für diese Produktion verwendet werden) zu V hinzugenommen; die folgenden Produktionen werden zu P hinzugefügt: A → C1 Y2 Y2 → C2 Y3 .. . Yr−1 → Cr−1 Cr . Schließlich wird die Produktion A → C1 C2 · · · Cr gestrichen. Die neue Variablenmenge heißt V ′ ; die neue Produktionenmenge P ′ . 127 Es ist offensichtlich, dass in der neuen Grammatik G′ gilt: A ⇒ C1 Y2 ⇒ C1 C2 Y3 ⇒ · · · ⇒ C1 C2 · · · Yr−1 ⇒ C1 C2 · · · Cr−1 Cr . Daher sind in G′ mindestens alle Wörter von L(G) ableitbar. Umgekehrt kann man sich überlegen, dass die neuen Variablen zu nichts anderem verwendet werden können, als in einer Teilableitung oder in einem Teil des Ableitungsbaums A in C1 · · · Cr zu transformieren. In der Notation der Ableitungsbäume sieht die Übersetzung so aus: ersetze A A C1 α1 ... ... Cr αr durch ^ D 2 C1 α1 ^ D r-1 C2 α2 Cr-1 α r-1 Cr αr und umgekehrt. 4.3.10 Beispiel Wenn wir mit der separierten Grammatik G = ({S, A, B}, {0, 1}, S, P ) aus Beispiel 4.3.7 beginnen, die die Produktionen S → ε | ASBS A → 0 B → 1 hat, benötigen wir zwei neue Variable, etwa F und H, und die neuen Produktionen S → AF F → SH H → BS . Die Produktion S → ASBS wird gestrichen. 128 4.3.3 Bearbeitung von ε-Produktionen Der erste ernsthafte Schritt in der Konstruktion der Chomsky-Normalform ist die Elimination der ε-Regeln aus der Grammatik. Hier gehen wir in zwei Teilschritten vor: Zunächst lösen wir (für eine beliebige kontextfreie Grammatik G) das Problem herauszufinden, aus welchen Variablen man das leere Wort ableiten kann: wir bestimmen die Menge ∗ Vε = {A ∈ V | A ⇒ ε} . In einem zweiten Schritt bauen wir eine separierte Grammatik G mit kurzen rechten Seiten zu einer Grammatik G′ für L(G) − {ε} um, so dass in G′ überhaupt keine ε-Produktionen vorkommen. Teilschritt 1: Ermittlung von Vε . Dies geschieht mit einem Markierungsalgorithmus. Eingabe ist eine kontextfreie Grammatik G = (V, Σ, S, P ). Markierungsalgorithmus für Vε Auszuführen auf einer Tabelle aller Produktionen in P Runde 0: Markiere alle (Vorkommen von) A, wo A → ε Produktion Runde t: (t = 1, 2, . . .) Wenn A → C1 C2 · · · Cr Produktion, r ≥ 1, und C1 , . . . , Cr sind alle markiert und A ist unmarkiert dann markiere (alle Vorkommen von) A . Ausgabe: Menge der markierten Variablen . 4.3.11 Beispiel Die Liste der Produktionen könnte wie folgt aussehen: S S A A B B C T T T → → → → → → → → → → BB ABC aA a bB ε SBT A BT B In Runde 0 wird B markiert (unterstrichen), und zwar alle neun Exemplare, die vorkommen. In den Runden 1, 2 und 3 folgen S, T und C. Schließlich sieht die Tabelle so 129 aus: S S A A B B C T T T → → → → → → → → → → BB ABC aA a bB ε SBT A BT B Die Variable A kann nicht markiert werden, was der intuitiven Beobachtung entspricht, dass aus A das leere Wort nicht ableitbar ist. Für diese Grammatik ergibt sich also Vε = {B, S, T, C}. 4.3.12 Proposition (a) (b) (c) Für das Resultat des Markierungsalgorithmus gilt: ∗ A wird markiert ⇔ A ⇒ ε. A wird markiert ⇔ es gibt einen A-Ableitungsbaum T mit α(T ) = ε. ε ∈ L(G) ⇔ S wird markiert. Beweis: Nach Lemma 4.2.3 sind (a) und (b) äquivalent. Weiter ist es klar, dass (c) aus (a) folgt. Es genügt also, (b) zu beweisen. (b) ⇒“: Man zeigt durch eine einfache Induktion über Markierungsschritte, dass es zu ” jeder markierten Variablen A einen A-Ableitungsbaum TA,ε mit α(TA,ε ) = ε gibt. I.A.: Wenn A in Runde 0 markiert wird, gibt es die Produktion A → ε und daher den A-Ableitungsbaum A ε I.S.: Nun betrachte eine Variable A, die in Runde t ≥ 1 markiert wird. Dies passiert, weil es eine Produktion A → C1 · · · Cr gibt, wobei die Variablen C1 , . . . , Cr in früheren Runden markiert wurden. Nach der I.V. gibt es also für jedes i, 1 ≤ i ≤ r, einen Ci -Ableitungsbaum TCi ,ε mit Ergebnis α(TCi ,ε ) = ε. Diese Bäume können wir wie in Abb. 4.10 angegeben zu einem A-Ableitungsbaum TA,ε zusammenbauen. Dies liefert die Induktionsbehauptung. 130 T A,ε : A Cr C1 TC ,ε r T C ,ε 1 ε ε Abbildung 4.10: Struktur eines A-Ableitungsbaums mit Ergebnis ε (b) ⇐“: ” Wir zeigen: Falls es einen A-Ableitungsbaum TA gibt, der Tiefe d hat und α(TA ) = ε erfüllt, so wird A markiert. (Man sollte sich überlegen, dass dies keineswegs offensichtlich ist. Der Baum TA könnte im Prinzip sehr groß sein, und es ist nicht klar, wieso der Markierungsalgorithmus, der ja höchstens |V | Runden ausführt, feststellt, dass ε aus A ableitbar ist. Der Beweis zeigt aber, dass es in diesem Fall auch einen kleinen A-Ableitungsbaum mit Ergebnis ε geben muss, den der Algorithmus finden kann.) Wir benutzen Induktion über d. I.A.: d = 1: Dann sieht TA wie folgt aus: A ε Es muss also A → ε Produktion in P sein; also wird A in Runde 0 markiert. I.V.: d ≥ 2, und die Aussage stimmt für d′ < d. I.S.: Es sei d ≥ 2 und ein Baum TA der Tiefe d gegeben. Dann gibt es Variable C1 , . . . , Cr , r ≥ 1, und eine Produktion A → C1 · · · Cr derart, dass TA folgendermaßen aussieht: 131 T : A A Cr C1 TC TC r 1 ε ε Die Unterbäume TC1 , . . . , TCr haben alle Tiefe kleiner als d, und jeder liefert als Ergebnis ε. Nach I.V. werden also die Variablen C1 , . . . , Cr alle markiert. Daraus folgt, nach der Formulierung des Algorithmus, und weil A → C1 · · · Cr Produktion ist, dass auch die Variable A irgendwann einmal markiert werden muss. Damit ist die Induktionsbehauptung gezeigt. Mit den vorangegangenen Überlegungen können wir für jede kontextfreie Grammatik G die Menge Vε ermitteln und auch feststellen, ob ε ∈ L(G) ist oder nicht. Ausflug: Produktive und überflüssige Variable Mit den eben für Vε entwickelten Techniken lässt sich auch eine andere fundamentale Frage über eine gegebene kontextfreie Grammatik G lösen, nämlich ob L(G) = ∅ ist, oder ∗ äquivalent, ob S ⇒ w für mindestens ein Wort w ∈ Σ∗ ist. Allgemeiner betrachtet man folgende Eigenschaft von Variablen: 4.3.13 Definition Eine Variable A in einer kontextfreien Grammatik G = (V, Σ, S, P ) ∗ heißt produktiv , wenn es ein Terminalzeichenwort w mit A ⇒ w gibt. (Äquivalent: . . . wenn es einen A-Ableitungsbaum T mit α(T ) ∈ Σ∗ gibt.) Die Menge der produktiven Variablen heißt Vprod . Eine Variable A, die nicht produktiv ist, heißt überflüssig . Man kann sich leicht überlegen, dass eine überflüssige Variable in keinem Ableitungsbaum zur Grammatik G vorkommen kann, der als Ergebnis ein Terminalzeichenwort hat. Produktionen, in denen solche Variablen vorkommen, können also weggelassen werden, ohne die Sprache zu verändern. Die Sprache L(G) ist leer genau dann wenn S überflüssig ist. Wenn G = (V, Σ, S, P ) gegeben ist, ermitteln wir die Menge der produktiven Variablen durch einen Markierungsalgorithmus, der dem für Vε sehr ähnelt. 132 Markierungsalgorithmus für Vprod Auszuführen auf einer Tabelle aller Produktionen in P Runde 0: Markiere alle (Vorkommen von) A, wo A → w Produktion für ein w ∈ Σ∗ Runde t: (t = 1, 2, . . .) Wenn A → X1 X2 · · · Xr Produktion, r ≥ 1, und X1 X2 · · · Xr sind markierte Variable oder Terminalzeichen, und A ist unmarkiert dann markiere (alle Vorkommen von) A . Ausgabe: Menge der markierten Variablen . 4.3.14 Proposition (a) (b) (c) Für das Resultat des Markierungsalgorithmus gilt: ∗ A wird markiert ⇔ A ⇒ w für ein w ∈ Σ∗ . A wird markiert ⇔ es gibt einen A-Ableitungsbaum T mit α(T ) ∈ Σ∗ . L(G) 6= ∅ ⇔ S wird markiert. Der Beweis dieser Behauptung verläuft ganz genau so wie der für Proposition 4.3.12. (Eine gute Übung!) 4.3.15 Beispiel Betrachte folgende Produktionen: S A B C D E F → → → → → → → ABC | ADC | AF aA | a bB cC | ε S | Eabc AE | AaE | ACA F B | abB | F F In Runde 0 werden die Variablen A und C markiert, wegen der Produktionen A → a und C → ε. In Runde 1 wird E markiert (wegen der Produktion E → ACA), in Runde 2 D (wegen der Produktion D → Eabc) und in Runde 3 schließlich S (wegen der Produktion S → ADC). Es ergibt sich die Tabelle S A B C D E F → → → → → → → ABC | ADC | AF aA | a bB cC | ε S | Eabc AE | AaE | ACA F B | abB | F F. 133 Keine weitere Variable kann mehr markiert werden. Als produktiv stellen sich also A, C, E, D und S heraus Weil S produktiv ist, erzeugt die Grammatik auch mindestens ein Terminalzeichenwort. Als überflüssig ergeben sich B und F . (In diesem konkreten Beispiel ist auch intuitiv zu sehen, dass man die Variable B nie loswerden“ kann, auch ” wenn man noch so viele Ableitungsschritte durchführt, und dass sich dies dann auch auf F überträgt.) Dies beendet unsere kurze Diskussion von produktiven und überflüssigen Variablen. Wir kehren zurück zur Konstruktion der Chomsky-Normalform, und hier konkret zur Elimination von ε-Produktionen. Teilschritt 2: Gegeben sei eine kontextfreie Grammatik G = (V, Σ, S, P ), in der es nur Produktionen der Form • A → ε, • A → a, mit A ∈ V , a ∈ Σ, • A → B, mit A, B ∈ V , • A → BC, mit A, B, C ∈ V . gibt. Auf diese Grammatik wenden wir den Markierungsalgorithmus für ε-produzierende Variable an, und erhalten Vε . P ′ entsteht aus P durch folgende Änderungen: • Wenn A → BC Produktion und B ∈ Vε , füge A → C hinzu • Wenn A → BC Produktion und C ∈ Vε , füge A → B hinzu • Streiche alle Produktionen A → ε 4.3.16 Lemma Die Grammatik G′ = (V, Σ, S, P ′ ) erfüllt L(G′ ) = L(G) − {ε}. Bevor wir das Lemma beweisen, geben wir ein Beispiel an. 4.3.17 Beispiel In der Grammatik G = ({S, A, B, F, H}, {0, 1}, S, P ) aus Beispiel 4.3.10 mit den Produktionen: S F H A B → → → → → ε | AF SH BS 0 1 134 ergibt sich: Vε = {S}. Die folgenden Produktionen werden hinzugefügt: F → H H → B die Produktion S → ε wird gestrichen. Damit ergibt sich als neue Produktionenmenge P ′: S F H A B → → → → → AF H | SH B | BS 0 1 Die Grammatik G′ = ({S, A, B, F, H}, {0, 1}, S, P ′ ) erzeugt L(G) − {ε}, das ist die Menge aller korrekten Klammerausdrücke ohne ε. Beweis von Lemma 4.3.16: Wir müssen zeigen, dass man einen Ableitungsbaum für w ∈ Σ+ in G in einen in G′ umbauen kann und umgekehrt. ⊇“: Gegeben ist ein Ableitungsbaum T für das Wort w 6= ε in der alten Grammatik ” G. Wenn dieser Baum keine ε-Produktionen benutzt, sind wir fertig, weil dann T selbst ein Baum für die neue Grammatik G′ ist. Andernfalls suchen wir in T einen maximalen Unterbaum T0 mit α(T0 ) = ε. Maximal“ heißt hier, dass jeder Unterbaum, der T0 echt ” T: T’ : S A A B T B ε S C C T C T’ C =/ ε =/ ε Abbildung 4.11: Links: G-Baum, mit Produktion A → BC, der C-Unterbaum liefert ε. Rechts: entsprechender G′ -Baum, mit Produktion A → B, keine ε-Produktionen enthält, Ergebnis 6= ε hat. Es ist klar, dass T0 nicht der ganze Baum T ist (denn α(T ) 6= ε). Also hat die Wurzel von T0 , die etwa mit B beschriftet ist, einen Vorgänger (mit A 135 beschriftet). Der Teilbaum unter dem A-Knoten kann nicht Ergebnis ε haben (da T0 maximal groß ist). Also hat der B-Knoten einen Bruder, etwa mit C beschriftet, und der Unterbaum unter dem C-Knoten liefert ein Ergebnis 6= ε. Dies liefert den ersten Baum in Abbildung 4.11. Wir ersetzen die Produktion A → BC im Baum T durch die Produktion A → C aus der neuen Grammatik G′ , ohne dass sich das Ergebnis des Baums ändert. Diesen Schritt führen wir gleichzeitig für alle maximalen ε-erzeugenden Unterbäume aus. Dadurch ändert sich eventuell auch der Baum TC unter dem C-Knoten in einen neuen Baum TC′ . Das Resultat ist als zweiter Baum in Abb. 4.11 angegeben. Insgesamt erhalten wir einen Baum zur Grammatik G′ mit Ergebnis w. ⊆“: Gegeben ist ein Ableitungsbaum T ′ für das Wort w in der neuen Grammatik G′ . Diese ” benutzt Produktionen, die in G nicht vorkommen. Betrachte zum Beispiel die Produktion A → C, die in P ′ ist, weil P die Produktion A → BC enthält und B ∈ Vε ist. Das bedeutet, dass es in G einen B-Ableitungsbaum TB,ε , gibt, der als Ergebnis ε liefert. Nun ersetzen wir in T ′ einfach jedes Knotenpaar, das der Produktion A → C entspricht, durch eine Unterstruktur für die Produktion A → BC und hängen unter den B-Knoten den Unterbaum TB,ε . Diese Transformation ist in Abb. 4.12 skizziert. T’ : T: S A S A B C T C T B, ε =/ ε ε C T C =/ ε Abbildung 4.12: Links: G′ -Baum mit neuer Produktion A → C. Rechts: G-Baum für dasselbe Wort, mit Produktion A → BC und B-Ableitungsbaum TB,ε mit Ergebnis ε Durch eine solche Änderung ändert sich das Ergebnis des Gesamtbaums nicht. Wenn wir diesen Umbau für alle in T ′ verwendeten neuen Produktionen durchführen, erhalten wir einen Ableitungsbaum für w in der alten Grammatik G. Damit ist Lemma 4.3.16 bewiesen. 4.3.18 Lemma Jede separierte kontextfreie Grammatik G = (V, Σ, S, P ) mit Produk136 tionen der Form A → ε, A → a, A → B, A → BC, mit A, B, C ∈ V , a ∈ Σ, kann in eine äquivalente separierte kontextfreie Grammatik G′ = (V ′ , Σ, S, P ′ ) umgebaut werden, die folgendes erfüllt: • entweder sind alle Produktionen von der Form A → a, A → B oder A → BC, • oder alle Produktionen sind von der Form A → a, A → B, A → BC oder S → ε und S kommt nicht auf der rechten Seite einer Produktion vor. Diese Grammatik G′ ist kontextsensitiv im Sinn von Definition 3.1.6(b). Beweis: Sei L ∈ L2 , also L = L(G) für eine kontextfreie Grammatik G. Nach 4.3.9 und 4.3.16 existiert eine kontextfreie Grammatik G1 = (V1 , Σ, S, P1 ) mit L(G1 ) = L(G) − {ε}, wobei P1 nur Produktionen der Form A → a, A → B und A → BC hat. Demnach besteht P1 nur aus kontextsensitiven Produktionen (Definition 3.1.6(a)). 1. Fall : ε 6∈ L. Dann ist L = L(G1 ), und wir können G′ = G1 wählen. 2. Fall : ε ∈ L. Dann ist L = L(G′ ) für die Grammatik G′ = (V1 ∪ {S ′ }, Σ, S ′ , P1 ∪ {S ′ → S, S ′ → ε}). Diese erfüllt die aufgeführten Anforderungen, ist also insbesondere kontextsensitiv. Wir notieren, dass wir mit Lemma 4.3.18 einen entscheidenden Schritt in Richtung ChomskyHierarchie getan haben. (Siehe hierzu die Bemerkungen zur Chomsky-Hierarchie am Ende von Abschnitt 3.2.) 4.3.19 Korollar Jede kontextfreie Sprache ist kontextsensitiv, in Zeichen: L2 ⊆ L1 Beweis: Nach Lemma 4.3.9 kann jede kontextfreie Grammatik G in eine äquivalente kontextsensitive Grammatik G′ umgebaut werden. 4.3.4 Elimination von Kettenregeln Mit der kontextsensitiven Form aus Lemma 4.3.18 sind wir noch immer nicht ganz zufrieden. Wir wollen auch noch die Kettenregeln“, das sind Produktionen der Form A → B ” für A, B ∈ V , eliminieren. Wir starten hierzu mit einer Grammatik G = (V, Σ, S, P ) mit Produktionen der Form wie in Lemma 4.3.18 für G′ angegeben. 137 Zunächst können wir alle Produktionen der Form A → A weglassen, da Ableitungsschritte, die diese Produktion benutzen, nichts ändern. Die verbleibende Menge aller Kettenregeln in P nennen wir P1 . Die Idee für das Weitere ist, Ableitungsfolgen der Form A = A0 ⇒ A1 ⇒ · · · ⇒ At = B ⇒ CD bzw. A = A0 ⇒ A1 ⇒ · · · ⇒ At = B ⇒ a durch Hinzufügen von Produktionen A → CD bzw. A → a kurzzuschließen“. Dadurch ” entstehen natürlich keine Ableitungen für Wörter, die nicht schon vorher in L(G) waren. Nun werden alle Kettenregeln A → B weggelassen, und man muss sich überlegen, dass dadurch die Menge der ableitbaren Wörter nicht schrumpft. 4.3.20 Beispiel (a) Wir betrachten die Grammatik G = ({S, A, B, F, H}, {0, 1}, S, P ) aus Beispiel 4.3.17 mit Produktionen: S F H A B → → → → → AF SH | H BS | B 0 1 Hier gibt es die Ableitungsfolgen F ⇒ H ⇒ B ⇒ 1, F ⇒ H ⇒ BS und H ⇒ B ⇒ 1. Entsprechend fügen wir die neuen Produktionen F → 1 F → BS H → 1 hinzu. Die Kettenregeln F → H und H → B fallen weg. Dies liefert die folgende Liste von Produktionen: S F H A B → → → → → AF SH | BS | 1 BS | 1 0 1 Diese Grammatik in Chomsky-Normalform haben wir schon in Beispiel 4.3.2(b) gesehen. Aus dem Erzeugungsprozess folgt, dass sie die Klammersprache ohne ε erzeugt. 138 (b) Weiter betrachten wir die Grammatik Gε = ({Sε , S, A, B, F, H}, {0, 1}, Sε , P ∪ {Sε → ε | S}), die aus der Grammatik aus Beispiel 4.3.17 durch Hinzufügen eines speziellen neuen Startsymbols Sε hervorgeht. Wenn man hier alle Ketten überbrückt und die Kettenregeln weglässt, ergibt sich die folgende Produktionenmenge für die volle Klammersprache in Chomsky-Normalform: Sε S F H A B → → → → → → ε | AF AF SH | BS | 1 BS | 1 0 1 Wenn wir hier S in R und dann Sε in S umbenennen, erhalten wir die Grammatik aus Beispiel 4.3.2(a). Die formale Konstruktion besteht aus zwei Phasen. Phase (a): Für jedes A ∈ V ermittle die Menge ∗ VA = {B ∈ V | A ⇒ B und A 6= B}. Das heißt, B ∈ VA genau dann wenn A = A0 ⇒ A1 ⇒ · · · ⇒ At = B für eine Variablenfolge A0 , . . . , At , t ≥ 0, und A 6= B. Algorithmisch gehen wir dazu folgendermaßen vor: Wir fassen V als Knotenmenge und E = P1 als Kantenmenge eines Graphen H = (V, E) auf. Nun ermitteln wir für jedes A ∈ V durch Breitensuche die Menge VA = {B ∈ V | B ist von A aus erreichbar}. Der Zeitaufwand hierfür ist O(|V | · (|V | + |P1 |)), also polynomiell. Phase (b): Für jede Kombination A ∈ V, B ∈ VA , B → a in P fügen wir die Produktion A → a zu P hinzu; für jede Kombination A ∈ V, B ∈ VA , B → CD in P fügen wir die Produktion A → CD zu P hinzu. Alle Kettenregeln A → B werden aus P entfernt. Die neue Produktionenmenge heißt dann P ′ ; die neue Grammatik G′ . Man sieht sofort, dass in der neuen Grammatik G′ = (V, Σ, S, P ′ ) nicht mehr Wörter ableitbar sind als in G. Umgekehrt kann man einen Ableitungsbaum T für ein Wort w in der Grammatik G immer zu einem in der Grammatik G′ umbauen, indem man in T maximal 139 lange Ketten von Knoten mit jeweils einem Nachfolger sucht, die dann Teilableitungen A = A0 ⇒ A1 ⇒ · · · ⇒ At = B ⇒ a bzw. . . . At = B ⇒ CD entsprechen, und diese Ketten durch die Unterstrukturen zur Grammatik G′ ersetzt, die den Teilableitungen A ⇒ a bzw. A ⇒ CD entsprechen. Wir ersetzen also A A A1 A1 A2 bzw. B C A2 B D a im Ableitungsbaum durch A C A bzw. D a und umgekehrt. 140 4.4 Das Pumping-Lemma für kontextfreie Sprachen Wir benutzen die Chomsky-Normalform, um ein Pumping-Lemma ähnlich dem für reguläre Sprachen (Satz 2.4.1) zu beweisen. Dieses Lemma, das eine grundlegende Struktureigenschaft kontextfreier Sprachen formuliert, wird gewöhnlich dafür benutzt (in ähnlicher Weise wie in Abschnitt 2.4 das für reguläre Sprachen), um nachzuweisen, dass gewisse Sprachen nicht kontextfrei sind. 4.4.1 Satz (Pumping-Lemma für kontextfreie Sprachen) Wenn L eine kontextfreie Sprache über Σ ist, dann gibt es eine Zahl n ≥ 1, für die folgendes gilt: Für jedes z ∈ L mit |z| ≥ n gibt es Wörter u, v, w, x, y ∈ Σ∗ , derart dass: (i) z = uvwxy, (ii) |vwx| ≤ n, (iii) |v| + |x| ≥ 1, (iv) ∀i ∈ N : uv i wxi y ∈ L. Beweis: Weil L kontextfrei ist, gibt es für L eine Grammatik G = (V, Σ, S, P ) in ChomskyNormalform (Definition 4.3.1 und Satz 4.3.4). – Wir definieren n := 2|V | und zeigen, dass diese Zahl die verlangten Eigenschaften hat. Sei dazu z ∈ L = L(G) mit |z| ≥ n. Dann gibt es einen Ableitungsbaum T für z in G. Weil n ≥ 1 ist und G in Chomsky-Normalform ist, kann in diesem Baum keine ε-Produktion benutzt werden. Beispielsweise (Abb. 4.13) betrachte man nochmals den Ableitungsbaum aus Abb. 4.9 zur Grammatik aus Beispiel 4.3.2. Da in der Grammatik G Terminalzeichen a ∈ Σ nur durch Produktionen A → a erzeugt werden, hat T genau |z| viele Variablenknoten, die als Nachfolger ein (mit einem Terminalzeichen beschriftetes) Blatt haben; alle anderen Knoten haben genau zwei Nachfolger. Anders ausgedrückt: Der Variablenteil des Ableitungsbaumes bildet einen vollen ” Binärbaum“. Behauptung: Ein voller Binärbaum, in dem auf dem längsten Weg von der Wurzel zu einem Blatt genau d Knoten liegen, hat maximal 2d−1 viele Blätter. (Dies beweist man durch Induktion über d. I.A.: Wenn der längste Weg einen Knoten hat, besteht der Baum nur aus der Wurzel und hat 20 Blätter. I.S.: Sei nun d > 1. Im linken Teilbaum hat der längste Weg maximal d − 1 Knoten, also hat der linke Teilbaum nach I.V. höchstens 2d−2 Blätter. Dasselbe gilt für den rechten Teilbaum. Insgesamt gibt es also höchstens 2 · 2d−2 = 2d−1 Blätter.) 141 S F A 0 H R A F B 0 R 1 B R 1 A F 0 1 A F 0 1 Abbildung 4.13: Ein Ableitungsbaum zu einer Chomsky-Normalform-Grammatik Wir wählen nun im Ableitungsbaum T für z einen Wurzel-Blatt-Weg mit maximaler Knotenzahl; diese sei l. Nach der Behauptung“ gilt ” 2|V | = n ≤ |z| ≤ 2l−1 , also |V | < l. (Diese kleine Rechnung ist der Grund dafür, dass wir n = 2|V | gewählt haben.) 142 T: S A¦V | A2 | V |+1 Knoten A1 A0 z a Abbildung 4.14: Ein maximal langer Weg in Ableitungsbaum T Wir nennen die Variablen auf diesem Weg, vom Blatt her zählend, A0 , A1 , . . . , Al−1 . (Siehe Abb. 4.14.) Nach dem Schubfachprinzip muss in der Folge A0 , . . . , A|V | eine Variable wiederholt vorkommen. Wir können also i, j wählen mit 0 ≤ i < j ≤ |V | und Ai = Aj . Die doppelt vorkommende Variable wird A genannt. Damit haben wir die in Abb. 4.15 skizzierte Situation. T: S A A <| V |+1 Knoten A0 z a Abbildung 4.15: Eine Variablenwiederholung 143 Die beiden ausgewählten Positionen in der Folge A0 , . . . , A|V | bestimmen die Wurzeln von zwei Unterbäumen T1 (Knoten zu Aj ) und T2 (Knoten zu Ai ) von T . Beide Knoten sind mit A beschriftet, siehe Abb. 4.16. T: S T1: A T2 : u v A w x y Abbildung 4.16: Ineinander geschachtelte Teilbäume, beide Wurzeln mit A beschriftet Die Teilbäume T1 und T2 teilen z = α(T ) in 5 Teile (von denen manche leer sein können): u := der Inhalt der Blätter von T links von T1 v := der Inhalt der Blätter von T1 links von T2 w := α(T2 ) x := der Inhalt der Blätter von T1 rechts von T2 y := der Inhalt der Blätter von T rechts von T1 . Im Beispielbaum aus Abb. 4.13 könnten diese Unterbäume und die zugehörigen Teilwörter zum Beispiel aussehen wie in Abb. 4.17. Hier wiederholt sich die Variable F . Folgende Eigenschaften der Teilwörter liest man aus der Konstruktion ab. (i) z = uvwxy. (ii) |vwx| ≤ n. Dies sieht man so: vwx = α(T1 ), also ist |vwx| gerade die Anzahl der Blätter in T1 . Weil die zu A0 , A1 , . . . , A|V | gehörende Knotenfolge zu einem Weg maximaler Länge in T gehört, hat der längste Weg in T1 höchstens |V | + 1 Variablenknoten. Nach der obigen Behauptung“ hat T1 höchstens 2|V | Blätter, also ist |vwx| ≤ 2|V | = n. ” (iii) |v| + |x| ≥ 1. Dies gilt, weil nach der Konstruktion T2 echter Teilbaum von T1 ist, und weil es bei Chomsky-Normalform-Grammatiken im Inneren eines Ableitungsbaumes nur Knoten von 144 Grad 2 und keine ε-Produktionen gibt. Also muss auf dem Weg von der Wurzel von T1 zur Wurzel von T2 rechts oder links oder beidseitig von T2 ein nichtleeres Teilwort entstehen. Es bleibt (iv) zu zeigen. Weil T1 und T2 im Wurzelknoten dieselbe Variable A als Inschrift haben, kann man den Teil von T1 , der nicht auch in T2 ist, beliebig oft, d.h., 0-mal, 1-mal, 2-mal usw., zwischen den Baum T (ohne T1 ) und T2 einfügen und daraus stets einen legalen Ableitungsbaum zur Grammatik G erhalten. Diese Idee sieht man am besten anhand der in Abbildungen 4.18 und 4.19 wiedergegebenen Skizzen ein. T: T2: S A w y u Abbildung 4.18: T2 anstelle von T1 eingehängt. In Abb. 4.18 nimmt T2 die Stelle von T1 ein; das Resultat ist ein Ableitungsbaum für uv 0 wx0 y. Daher ist uwy = uv 0 wx0 y in L = L(G). In Abb. 4.19 wird der Teil von T1 , der nicht auch in T2 ist, zweimal benutzt; es ergibt sich ein Ableitungsbaum für uv 2 wx2 w. Damit liegt auch dieses Wort in L = L(G). 145 T: T1: S A T1 : u v A T2 : x A w v y x Abbildung 4.19: Verdopplung eines Teils von T1 Es sollte zumindest anschaulich klar sein, dass man ebenso Ableitungsbäume für uv 3 wx3 y, uv 4 wx4 y usw. konstruieren kann. – Also gilt {uv 0 wx0 y, uvwxy = z, uv 2 wx2 y, uv 3 wx3 y, . . . } ⊆ L, wie in (iv) behauptet. 4.4.2 Beispiel Aus der Grammatik in Beispiel 4.2.1 erhält man durch Anwendung der Schritte Separierung“ und Verkürzung der rechten Seiten“ und durch Weglassen ” ” der ε-Produktion eine Grammatik G = ({S, D, A, B}, {0, 1}, S, P ), wobei P die folgenden Produktionen enthält: S → SS | AD | AB , D → SB , A → 0, B → 1 . Diese Grammatik G ist in Chomsky-Normalform. Es ist klar, dass L(G) die Sprache der korrekten Klammerausdrücke ohne ε ist. Betrachte z. B. den folgenden Ableitungsbaum für z = 00101101 in dieser Grammatik: 146 S S S D A 0 B S S S A B 0 1 1 T1 A B A B 0 1 0 1 T2 Wir haben einen längsten Pfad markiert; auf ihm wiederholt sich die Variable S (doppelt umrandet). Auch die resultierenden Teilbäume T1 und T2 sind markiert. Man überprüfe, dass hier u = 0, v = 01, w = 01, x = ε und y = 101 gilt, und die Aussagen (i), (ii), (iii) aus 4.4.1! Durch Herausschneiden und Verdoppeln des Baumteils T1 ohne T2“ ergeben sich die ” folgenden Ableitungsbäume: S S S D A 0 S B A B 1 0 1 T2 147 A B 0 1 S S S D A 0 S B A B 0 1 B 0 1 1 S S A S S A B A B 0 1 0 1 T1 T1 ohne T2 Zur Übung erstelle man einen Ableitungsbaum für uv 3 wx3 y! Genau wie im Fall des Pumping-Lemmas für reguläre Sprachen wollen wir das PumpingLemma 4.4.1 für den Beweis nutzen, dass gewisse Sprachen nicht kontextfrei sind. Dabei gehen wir nach demselben Schema vor wie in Kapitel 2 (vor 2.4.2). L sei die Sprache, deren Nichtregularität bewiesen werden soll. Schema für Nicht-Kontextfreiheits-Beweise: [1] (Wörtlich) Beweis indirekt. Annahme: L ist kontextfrei. [2] (Wörtlich) Dann gibt es ein n ≥ 1 mit den im Pumping-Lemma für kontextfreie Sprachen (PL-kfS, Satz 4.4.1) behaupteten Eigenschaften. [3] (Problemspezifisch) Wir wählen z ∈ L, mit |z| ≥ n. (z muss man geschickt wählen, so dass Schritt [5] ausführbar ist.) [4] (Wörtlich) Gemäß (PL-kfS) gibt es u, v, w, x, y derart dass (i) z = uvwxy; (ii) |vwx| ≤ n; (iii) |v| + |x| ≥ 1 und 148 (iv) uv i wxi y ∈ L für alle i ≥ 0. [5] (Problemspezifisch) Zeige nun, dass man für jede mögliche Position der Teilwörter u, v, w, x, y in z ein i angeben kann, so dass uv i wxi y ∈ / L ist. (Hierfür muss man oft mehrere Fälle betrachten. Eventuell sind in verschiedenen Fällen die benötigten i’s unterschiedlich.) (Wörtlich) Dies ist der gewünschte Widerspruch. Wir wenden dieses Beweisschema auf einige Beispiele an. Nur im ersten Beispiel markieren wir die Teilschritte. Die behandelten Sprachen sind auch charakteristisch für Sprachen, die nicht kontextfrei sind. 4.4.3 Behauptung Die Sprache L1 = {am bm cm | m ≥ 1} ist nicht kontextfrei. Beweis: [1] Indirekt. Angenommen, L1 wäre kontextfrei. [2] Dann gibt es ein n ≥ 1 mit den Eigenschaften wie in (PL-kfS). [3] Wir wählen z = an bn cn ∈ L1 . Offenbar ist |z| = 3n ≥ n. [4] Nach (PL-kfS) gibt es u, v, w, x, y ∈ Σ∗ derart dass (i) an bn cn = uvwxy, (ii) |vwx| ≤ n, (iii) |v| + |x| ≥ 1, (iv) ∀i ∈ N : uv i wxi y ∈ L1 . [5] Das Teilwort vwx von z kann nicht sowohl a’s als auch c’s enthalten. (Sonst müsste vwx mindestens n + 2 Buchstaben haben, was (ii) widerspricht.) 1. Fall: vwx enthält kein c. Dann betrachten wir uv 0 wx0 y = uwy. Dieses Wort enthält (immer noch) genau n c’s, aber die Zahl der a’s und b’s zusammen ist gleich 2n−|v|−|x| < 2n (wegen (iii)). Also ist uv 0 wx0 y 6∈ L1 , im Widerspruch zu (iv). 2. Fall: vwx enthält kein a. Dann betrachten wir uv 0 wx0 y = uwy. Dieses Wort enthält (immer noch) genau n a’s, aber die Zahl der b’s und c’s zusammen ist gleich 2n−|v|−|x| < 2n (wegen (iii)). Also ist uv 0 wx0 y 6∈ L1 , im Widerspruch zu (iv). (Hinweis: Der zweite Fall ist so ähnlich zum ersten, dass man hier normalerweise analog“ ” schreiben würde.) 149 4.4.4 Bemerkung (a) Es ist unwichtig, ob das leere Wort in der Sprache enthalten ist oder nicht; allgemeiner kann man immer eine endliche Anzahl von Wörtern hinzufügen oder entfernen, ohne die Eigenschaft der Kontextfreiheit zu verändern. (Technisch werden wir dies erst weiter unten sehen, siehe Abschnitt 5.6.) Also sind auch die Sprachen {am bm cm | m ≥ 0} und {am bm cm | m ≥ 5} (und so weiter) nicht kontextfrei. (b) Auch Sprachen wie {am b2m cm | m ≥ 0} und {a4m bm c3m | m ≥ 1} oder {0m 10m 10m | m ≥ 0} und {0m 1m 0m | m ≥ 0} sind nicht kontextfrei, was sich mit leichten Variationen des Beweises für Behauptung 4.4.3 zeigen lässt. (Siehe Übung.) (c) In Beispiel 3.1.9 haben wir eine monotone Grammatik für {am bm cm | m ≥ 1} angegeben, also ist dies eine Chomsky-1-Sprache. Wenn wir das mit Korollar 4.3.19 kombinieren, erhalten wir, dass L2 ( L1 gilt. Dies beweist einen weiteren Teil unserer früher aufgestellten Behauptung, dass die Chomsky-Hierarchie eine echte Hierarchie ist. 4.4.5 Behauptung Die Sprache L2 = {am bk cm dk | m, k ≥ 1} ist nicht kontextfrei. Beweis: Indirekt. Angenommen, L2 wäre kontextfrei. Dann gibt es ein n ≥ 1 mit den Eigenschaften wie in (PL-kfS). Wähle nun z = an bn cn dn ∈ L2 . Offenbar ist |z| = 4n ≥ n. Nach (PL-kfS) gibt es u, v, w, x, y ∈ Σ∗ derart dass (i) an bn cn dn = uvwxy, (ii) |vwx| ≤ n, (iii) |v| + |x| ≥ 1, (iv) ∀i ∈ N : uv i wxi y ∈ L2 . 150 Das Teilwort vwx von z kann nicht sowohl a’s als auch c’s enthalten, und auch nicht sowohl b’s als auch d’s. (Sonst müsste vwx mindestens n + 2 Buchstaben haben, was (ii) widerspricht.) Also ist vwx entweder Teilwort von an bn oder Teilwort von bn cn oder Teilwort von cn dn . 1. Fall: vwx ist Teilwort von an bn . Dann ist im Wort uv 0 wx0 y die Zahl der a’s und b’s zusammen gleich 2n−|v|−|x| < 2n (wegen (iii)), aber die Zahl der c’s und d’s zusammmen gleich 2n. Jedes Wort t ∈ L2 erfüllt aber |t|a + |t|b = |t|c + |t|d . Also ist uv 0 wx0 y 6∈ L2 . Dies widerspricht (iv). 2. Fall: vwx ist Teilwort von bn cn . Dann ist im Wort uv 0 wx0 y die Zahl der b’s und c’s zusammen gleich 2n−|v|−|x| < 2n (wegen (iii)), aber die Zahl der a’s und d’s zusammmen gleich 2n. Jedes Wort t ∈ L2 erfüllt aber |t|a + |t|d = |t|b + |t|c . Also ist uv 0 wx0 y 6∈ L2 . Dies widerspricht (iv). 3. Fall: vwx ist Teilwort von cn dn . Hier erhält man analog zum 1. Fall einen Widerspruch. 4.4.6 Bemerkung (a) Auch Sprachen wie {am b2k c3m d4k | m ≥ 0} und {am bm am bm | m ≥ 0} erweisen sich mit ähnlichen Beweisen als nicht kontextfrei. Man versuche, das Muster zu erkennen: Kontextfreie Grammatiken können nicht beschreiben, dass in vier Teilwörtern w1 , w2 , w3 , w4 von w, die voneinander abgegrenzt sind, die Längenbeziehung |w1 | = |w3 | und |w2 | = |w4 | gilt. Intuitiv gesagt liegt das daran, dass die Anordnung der Paare (w1 , w3 ) und (w2 , w4 ) einander entsprechender Teilwörter nicht einer korrekten Klammerung entspricht. (b) Im Gegensatz zu (a) bemerken wir, dass die Sprache L′2 = {am bk ck dm | m, k ≥ 1}, die auf den ersten Blick sehr ähnlich zu L2 aussieht, kontextfrei ist. (Man kann eine Grammatik mit Variablen S und A und Produktionen S → aSd | aAd und A → bAc | bc benutzen.) Es ist also kein Problem, mit einer kontextfreien Grammatik zu spezifizieren, dass in vier Teilwörtern w1 , w2 , w3 , w4 von w, die voneinander abgegrenzt sind, die Längenbeziehung |w1 | = |w4 | und |w2 | = |w3 | gilt. Hier sind die einander entsprechenden Teilwortpaare wie in korrekten Klammerausdrücken angeordnet. 151 (c) Auch L2 und die in (a) genannten Sprachen sind Chomsky-1-Sprachen. (Hier ohne Beweis.) 4.4.7 Behauptung Die Sprache L3 = {w2w | w ∈ {0, 1}∗ } über Σ = {0, 1, 2} ist nicht kontextfrei. Beweis: Indirekt. Angenommen, L3 wäre kontextfrei. Dann gibt es ein n ≥ 1 mit den Eigenschaften wie in (PL-kfS). Wähle nun z = 0n 1n 20n 1n ∈ L3 . Offenbar ist |z| = 4n+1 > n. Nach (PL-kfS) gibt es u, v, w, x, y ∈ Σ∗ derart dass (i) 0n 1n 20n 1n = uvwxy, (ii) |vwx| ≤ n, (iii) |v| + |x| ≥ 1, (iv) ∀i ∈ N : uv i wxi y ∈ L3 . 1. Fall: v oder x enthält die 2“ aus z. Dann enthält uv 0 wx0 y überhaupt keine 2“, ist ” ” also nicht in L3 . 2. Fall: Die 2“ liegt im Teilwort u. D. h.: vwx liegt in z komplett rechts von der 2“. ” ” Dann befinden sich in uv 0 wx0 y rechts von der 2“ weniger Buchstaben als links von der ” 2“, also ist uv 0 wx0 y nicht in L3 . ” 3. Fall: Die 2“ liegt im Teilwort y. Analog zum 2. Fall ist dann uv 0 wx0 y nicht in L3 . ” 4. Fall: Die 2“ liegt im Teilwort w. D. h.: v liegt komplett links von der 2“ und x ” ” liegt komplett rechts von der 2“. Nach (ii) gilt |vwx| ≤ n, also ist v ein Teilwort des ” Einserblocks links von der 2“ und x ein Teilwort des Nullerblocks rechts von der 2“. ” ” Damit ist uv 0 wx0 y = 0n 1n−|v| 20n−|x| 1n . Nach (iii) sind nicht |x| und |v| beide 0. Daher ist uv 0 wx0 y ∈ / L3 . In allen vier Fällen ergibt sich ein Widerspruch zu (iv). 4.4.8 Bemerkung Die in der letzten Behauptung notierte Eigenschaft, dass kontextfreie Grammatiken nicht erzwingen können, dass zwei Teilwörter identisch sind, kann verallgemeinert werden, zum Beispiel folgendermaßen: Die Sprache {w1 3 · · · 3wr 2v1 3 · · · 3vs | s ≥ r ≥ 1, w1 , . . . , wr , v1 , . . . , vr ∈ {0, 1}∗ , jedes vi kommt in {w1 , . . . , wr } vor} 152 ist nicht kontextfrei. Dies hat zur Folge, dass eine grundlegende Eigenschaft korrekter Pascal- und Java-Programme nicht durch kontextfreie Grammatiken ausgedrückt werden kann, nämlich das Prinzip, dass die Namen von Variablen, die benutzt werden, zuvor deklariert worden sein müssen. Bedingungen dieser Art werden daher stets zusätzlich zu der formalen Grammatik angegeben. 4.4.9 Behauptung Die Sprache 2 L4 = {0n | n ≥ 1} ist nicht kontextfrei. Beweis: Indirekt. Angenommen, L4 wäre kontextfrei. Dann gibt es ein n ≥ 1 mit den Ei2 genschaften wie in (PL-kfS). Wähle nun z = 0n ∈ L4 . Nach (PL-kfS) gibt es u, v, w, x, y ∈ Σ∗ derart dass für z (i)–(iv) erfüllt sind. Nun ist aber 2 +|v|+|x| uv 2 wx2 y = 0n 2 +k = 0n für ein k mit 1 ≤ k ≤ n (nach (ii) und (iii)). Jedoch ist n2 < n2 + k < (n + 1)2 , also n2 + k keine Quadratzahl und damit uv 2 wx2 y 6∈ L4 . Dies widerspricht (iv). 4.4.10 Bemerkung (a) Der Beweis von Behauptung 4.4.9 verläuft genauso wie der Beweis von Behauptung 2.4.2(b), wo wir gesehen haben, dass L3 nicht regulär ist. Dies ist charakteristisch für Sprachen über einem einelementigen Alphabet: Ein Nichtregularitätsbeweis mit dem Pumping-Lemma für reguläre Sprachen führt sofort zu einem fast gleichlautenden Beweis der Nicht-Kontextfreiheit, wenn wir das Pumping-Lemma für kontextfreie Sprachen benutzen. (b) Tatsächlich gilt: L ⊆ Σ∗ , |Σ| = 1, L ∈ L2 ⇒ L ∈ L3 . Es gibt also überhaupt keine kontextfreien Sprachen über einem einelementigen Alphabet, die nicht regulär sind. Der Beweis dieser Aussage ist etwas aufwendiger – er benutzt übrigens das Pumping-Lemma 4.4.1 – und nicht Stoff der Vorlesung. Zum Schluss dieses Abschnittes formulieren wir eine verstärkte Version des PumpingLemmas für kontextfreie Sprachen, das in Beweisen für Nicht-Kontextfreiheit oft zum Ziel führt, wenn die Anwendung des einfachen Pumping-Lemmas mühsam oder nicht möglich ist. Diese Aussage nennt man nach seinem Urheber das Lemma von Ogden“. ” Bei der Anwendung dieses Lemmas per Schema dürfen wir in Schritt [3] nicht nur z wählen, sondern in z auch n uns günstig erscheinende Buchstaben in z markieren“ (unterstrei” chen, rot einfärben). Die Zerlegung in u, v, w, x, y, die wir in Schritt [5] bearbeiten 153 müssen, hat die Eigenschaft, dass entweder v oder x mindestens einen der markierten Buchstaben enthält. Wir formulieren das Lemma und das resultierende Beweisschema. Auf einen Beweis des Lemmas von Ogden verzichten wir hier. Dieser Beweis ist sehr ähnlich zu dem für das Pumping-Lemma für kontextfreie Sprachen (Satz 4.4.1). 4.4.11 Satz (Lemma von Ogden) Wenn L eine kontextfreie Sprache über Σ ist, dann gibt es eine Zahl n ≥ 1, für die folgendes gilt: Wenn z ein Wort in L ist, in dem n Buchstabenpositionen markiert“ sind, dann gibt es Wörter u, v, w, x, y ∈ Σ∗ , derart dass ” folgendes gilt: (i) z = uvwxy, (ii) v und x zusammen enthalten mindestens ein markierte Buchstabenposition, (iii) ∀i ∈ N : uv i wxi y ∈ L. Schema für Nicht-Kontextfreiheits-Beweise mit dem Lemma von Ogden: [1] (Wörtlich) Beweis indirekt. Annahme: L ist kontextfrei. [2] (Wörtlich) Dann gibt es ein n ≥ 1 mit den im Lemma von Ogden (Satz 4.4.11) behaupteten Eigenschaften. [3] (Problemspezifisch) Wähle z ∈ L, mit |z| ≥ n, und markiere n Buchstaben in z. (z und die Markierungspunkte werden so gewählt, dass Schritt [5] gut ausführbar ist.) [4] (Wörtlich) Gemäß (PL-kfS) gibt es u, v, w, x, y derart dass folgendes gilt: (i) z = uvwxy; (ii) v und x enthalten mindestens eine markierte Position; und (iii) uv i wxi y ∈ L für alle i ≥ 0. [5] (Problemspezifisch) Zeige nun, dass man für jede nach (ii) noch mögliche Position der Teilwörter u, v, w, x, y in z ein i angeben kann, so dass uv i wxi y ∈ /L ist. (Wörtlich) Dies ist der gewünschte Widerspruch. 4.4.12 Behauptung Die Sprache L4 = {ak bl cm | k ≥ l ≥ m ≥ 0} ist nicht kontextfrei. 154 Beweis: Indirekt. Angenommen, L4 wäre kontextfrei. Dann gibt es ein n ≥ 1 mit den Eigenschaften wie im Lemma von Ogden. Wähle nun z = an bn cn ∈ L4 und markiere die n a’s. Nach dem Lemma von Ogden gibt es u, v, w, x, y ∈ Σ∗ derart dass (i) an bn cn = uvwxy, ; (ii) v und x zusammen enthalten mindestens einen markierten Buchstaben, also mindestens ein a; (iii) ∀i ∈ N : uv i wxi y ∈ L4 . 1. Fall: v enthält zwei verschiedene Buchstaben. Dann sieht man sofort, dass in uv 2 wx2 y die Buchstabenreihenfolge ak bl cm nicht eingehalten ist, was der Aussage aus (iii) widerspricht. 2. Fall: x enthält zwei verschiedene Buchstaben. Das führt ebenso wie in Fall 1 zu einem Widerspruch. Von hier an nehmen wir an, dass v und x jeweils nur eine Sorte von Buchstaben enthält. 3. Fall: x besteht aus a’s. Dann besteht vx nur aus a’s, und uv 0 wx0 y enthält weniger a’s als b’s, also ist uv 0 wx0 y nicht in L4 , Widerspruch. 4. Fall: x besteht aus b’s. Wegen (ii) ist dann v eine nichtleere Folge von a’s, und uv 0 wx0 y enthält weniger a’s als c’s, also ist uv 0 wx0 y nicht in L4 , Widerspruch. 5. Fall: x besteht aus c’s. Führt analog zum 4. Fall zu einem Widerspruch. Eine alternative Sicht auf Beweise mit dem Pumping-Lemma: Ein Spiel-Schema Es gibt eine Formulierung für Beweise mit dem Pumping-Lemma, die es vermeidet, die Stichwörter Annahme“ und Widerspruch“ zu benutzen, die zu unserem Beweisschema ” ” gehören. Diese Formulierung formuliert den Beweis als ein Spiel, das wir (die Beweiser“, ” Spieler B), gegen einen Gegner (Spieler G) spielen. Auch hier sind die Züge zum Teil mechanisch, zum Teil erfordern sie etwas Einfallsreichtum. Gegeben ist eine Sprache L. Die zu beweisende Behauptung ist: L ist nicht kontextfrei. Spiel-Schema Runde 1: G gibt uns eine Zahl n ≥ 1. Runde 2: (B) Wir wählen (geschickt) ein z ∈ L mit |z| ≥ n (∗ so dass wir in Runde 4 immer gewinnen ∗) 155 Runde 3: G gibt uns u, v, w, x, y mit (i) z = uvwxy, (ii) |vwx| ≤ n und (iii) |v| + |x| ≥ 1 . (∗ Wir wissen nicht genau, wie u, v, w, x, y in z liegen. ∗) Runde 4: (B) Wir wählen, abhängig von u, v, w, x, y, ein i und zeigen, dass uv i wxi y ∈ / L. (∗ Normalerweise muss man hier einige Fälle betrachten. ∗) Wenn man sich das Spiel-Schema ansieht, erkennt man, dass keine Komponenten eines indirekten Beweises (wie Annahme“ und Dies ist ein Widerspruch“) mehr vorkommen. ” ” Allerdings hat sich die Schwierigkeit, die darin liegt, ein gutes z zu wählen und in Runde 4 für alle Möglichkeiten von u, v, w, x, y zu zeigen, dass man ein passendes i finden kann, gegenüber dem gewöhnlichen Schema nicht verändert. Wir demonstrieren die Benutzung des Spielschemas an einem Beispiel. Beh.: Die Sprache L = {0n 12n 23n | n ≥ 0} ist nicht kontextfrei. Wir beweisen dies mit dem Spielschema. Runde 1: G gibt uns eine Zahl n ≥ 1. Runde 2: Wir (B) wählen z = 0n 12n 23n . Es ist klar, dass |z| = 6n ≥ n ist. Runde 3: G gibt uns u, v, w, x, y mit (i) x = uvwxy, (ii) |vwx| ≤ n und (iii) |v| + |x| ≥ 1 . Runde 4: Unsere (B) Aufgabe ist es, nun zu zeigen, dass es ein i ∈ N gibt derart dass uv i wxi y ∈ / L ist. Da wir nicht wissen, wie u, v, w, x, y in z liegen, müssen wir mehrere Möglichkeiten betrachten. Zuerst benutzen wir, dass |vwx| ≤ n ist und folgern, dass vwx entweder den Buchstaben 0 nicht enthält oder den Buchstaben 2 nicht enthält. (Sonst müsste vwx alle 1en und zudem eine 0 und eine 2 enthalten, hätte also Länge mindestens 2n+2 > n.) 1. Fall: vwx enthält keine 2. – Setze i = 0. Dann gilt für uv 0 wx0 y = uwz folgendes: |uwy|0 + |uwy|1 = 3n − (|v| + |x|) < 3n, aber |uwy|2 = 3n. Daher kann uwy kein Element von L sein. 2. Fall: vwx enthält keine 0. – Setze i = 0. Dann gilt für uv 0 wx0 y = uwz folgendes: |uwy|0 = n, aber |uwy|1 + |uwy|2 = 5n − (|v| + |x|) < 5n. Daher kann uwy kein Element von L sein. Wir verzichten auf den formalen Beweis dafür, dass die korrekte Vervollständigung des Spielschemas in Runden 2 und 4 für eine Sprache L hinreichend dafür ist, zu zeigen, dass L nicht kontextfrei ist. Man sieht aber, dass man im Spielschema eigentlich nichts anderes macht als in den gewöhnlichen Beweisen nach dem Schema mit den indirekten Beweisen: 156 wähle (geschickt) ein z und beweise dann für eine beliebige Zerlegung von z in u, v, w, x, y, die (i), (ii), (iii) erfüllt, dass es ein i mit uv i wxi y ∈ / L geben muss. Bemerkung: Entsprechend modifizierte Spiel-Schemata sind auch geeignet, Nicht-Kontextfreiheits-Beweise mit dem Lemma von Ogden und Nicht-Regularitäts-Beweise mit dem Pumping-Lemma für reguläre Sprachen durchzuführen. 4.5 Der Cocke-Younger-Kasami-Algorithmus In diesem Abschnitt betrachten wir das Wortproblem für kontextfreie Grammatiken, d. h. das Problem, für eine vorgelegte kontextfreie Grammatik G = (V, Σ, S, P ) und ein Wort w ∈ Σ∗ zu entscheiden, ob w ∈ L(G) gilt oder nicht. Wir können annehmen, dass G in Chomsky-Normalform vorliegt (andernfalls wenden wir den Umbau-Algorithmus aus Abschnitt 4.3 an). Falls w = ε, müssen wir nur prüfen, ob S → ε eine Produktion in P ist. Also interessieren uns nur Wörter w 6= ε. In Ableitungen für ein solches w können keine ε-Produktionen vorkommen. Wir beschränken uns also auf die Produktionen in P , die die Form A → BC oder A → a haben, mit A, B, C ∈ V , a ∈ Σ. Wir benutzen das Prinzip der dynamischen Programmierung , das in der Vorlesung Effiziente Algorithmen“ genauer behandelt wird. ” Es sei w = a1 · · · an ∈ Σ∗ gegeben, n ≥ 1. Wir wollen für jedes Teilwort ai · · · ai+d−1 , 1 ≤ d ≤ n, 1 ≤ i ≤ n − d + 1, von w wissen, aus welchen Variablen dieses Wort herleitbar ist. Dazu definieren wir Mengen ∗ Ud,i := {A ∈ V | A ⇒ ai · · · ai+d−1 }, für 1 ≤ d ≤ n, 1 ≤ i ≤ n − d + 1. Offenbar ist w ∈ L(G) genau dann wenn S ∈ Un,1 . Wir überlegen nun, wie die Ud,i durch Induktion über d = 1, 2, . . . , n berechnet werden können. ∗ Induktionsanfang d = 1: Weil G in Chomsky-Normalform ist, gilt A ⇒ a für A ∈ V , a ∈ Σ genau dann wenn A → a in P ist. Also: U1,i = {A ∈ V | A → ai }, für 1 ≤ i ≤ n. ∗ Induktionsschritt d > 1: Setze v := ai · · · ai+d−1 . Ist A ⇒ v, so gibt es einen AAbleitungsbaum T mit α(T ) = v. Die Wurzel von T ist also mit A beschriftet, und T hat d Blätter. Die Wurzel muss zwei Nachfolger haben, die mit Variablen (etwa C und D) beschriftet sind. Schematisch sieht das so aus: 157 A C D TD TC w’’ w’ Die beiden Teilbäume von T heißen TC und TD , und wir setzen w′ := α(TC ), w′′ := α(TD ). Offenbar gilt: ∗ ∗ C ⇒ w′ , D ⇒ w′′ , v = w′ w′′ , und 1 ≤ |w′ |, |w′′ | < d , und A → CD ist Produktion. (4.1) Umgekehrt überlegt man sich leicht, anhand desselben Bildes, dass aus der Situation (4.1) ∗ folgt, dass A ⇒ v. – Wir haben also, für A ∈ V : ∗ A ⇒ ai · · · ai+d−1 ⇔ ∃C, D ∈ V ∃d′ : 1 ≤ d′ < d − 1 und ∗ ∗ C ⇒ ai · · · ai+d′ −1 , D ⇒ ai+d′ · · · ai+d−1 und A → CD ist Produktion . Damit erhalten wir folgende Rekursionsformel für die Mengen Ud,i : Ud,i = {A ∈ V | ∃C, D ∈ V ∃d′ : 1 ≤ d′ < d und A → CD ist Produktion und C ∈ Ud′ ,i und D ∈ Ud−d′ ,i+d′ }. Aus der Rekursionsformel ergibt sich der folgende iterative Algorithmus zur Lösung des Wortproblems für eine Grammatik G in Chomsky-Normalform. Eingabe: Grammatik G = (V, Σ, S, P ) in Chomsky-Normalform, w = a1 · · · an ∈ Σ∗ . Falls w = ε, prüfe, ob S → ε Produktion ist. Falls ja, gib JA“ aus, sonst NEIN“. ” ” Ab hier wird n ≥ 1 vorausgesetzt. Datenstruktur: Ein Array U [1..n, 1..n], wo jeder Eintrag eine Teilmenge von V ist. Initialisierung: U [d, i] := ∅, für 1 ≤ d ≤ n, 1 ≤ i ≤ n − d + 1. (Nur diese Einträge in U werden benutzt. d ist die Länge des betrachteten Teilworts, i die Position des ersten Buchstabens.) Methode: 1. U [1, i] := {A | A → ai ist Produktion }, für 1 ≤ i ≤ n. 158 2. for d := 2 to n do for i := 1 to n − d + 1 do for d′ := 1 to d − 1 do U [d, i] := U [d, i] ∪ {A ∈ V | es gibt eine Produktion A → CD und C ∈ U [d′ , i], D ∈ U [d − d′ , i + d′ ]} . 3. Falls S ∈ U [n, 1], gib JA“ aus, sonst NEIN“. ” ” Die Korrektheit des Algorithmus folgt aus den vorher angestellten Überlegungen. Die Laufzeit ist O(n3 ) – dabei geht die Größe der Grammatik G in die in dem O“ versteckte ” Konstante ein. Wenn man den CYK-Algorithmus von Hand ausführt, verwendet man ein dreieckiges Schema, dessen Felder den relevanten Einträgen des Arrays U entsprechen. In Feld (d, i), 1 ≤ d ≤ n, 1 ≤ i ≤ n − d + 1, werden die Variablen A ∈ Dd,i eingetragen, also die Variablen, aus denen ai · · · ai+d−1 ableitbar ist. i= w= 1 a1 2 a2 . . . . . n an d =1 2 ... ... ... n Die Einträge werden zeilenweise berechnet. Die Einträge in Zeile d = 1 ergeben sich direkt aus den Produktionen der Form A → a. Um die Variablen in Zelle (d, i) für d > 1 zu berechnen, betrachtet man Paare von schon ausgefüllten Zellen nach folgendem Muster, etwa für d = 5, i = 2: 159 i= w= 1 a1 2 a2 d =1 1 2 2 3 3 4 4 5 * n an . . . . . 4 3 2 1 n= 6 Abbildung 4.20: Ein Schritt im CYK-Algorithmus, zu bearbeitende Zellen Für d′ = 1, . . . , d − 1 prüft man für jede Produktion A → CD der Grammatik, ob C in Zelle (i, d′ ) und D in Zelle (i + d′ , d − d′ ) vorkommt. (Falls dies so ist, wird A in die Zelle (d, i) eingetragen.) In Abb. 4.20 wird die Zelle (2, 5) ausgefüllt. Zusammengehörige Zellen (i, d′ ) und (i + d′ , d − d′ ) sind mit den gleichen eingekreisten Zahlen markiert. Die Zellen (i, d′ ) bilden im Schema eine Teil-Spalte, die Zellen (i + d′ , d − d′ ) eine Teil-Diagonale. Zum Beispiel muss man testen, ob es eine Produktion A → CD gibt, derart dass C in Zelle (3, 2) und D in Zelle (2, 5) steht (mit eingekreister 3“ markiertes Zellenpaar). Die ” schraffierten Dreiecke deuten an, welche Teilwörter betroffen sind, wenn die Zellen (2, 3) und (5, 2) (Nummer 3) untersucht werden. Beispiel : Betrachte die Grammatik aus Beispiel 4.4.2. Anwenden des Verfahrens auf die Eingaben w1 = 00100111 und w2 = 01011100 liefert die in Abb. 4.21 angegebenen Ergebnisse. (Ist die Menge Ud,i leer, deuten wir dies durch Freilassen des entsprechenden Kästchens an.) 160 d=1 0 0 1 0 0 1 1 1 0 1 0 1 1 0 1 0 A A B A A B B B A B A B B A B A S 2 S D 3 4 S 5 D 6 S 7 D 8 S S S D S S Abbildung 4.21: Anwendung des CYK-Algorithmus auf zwei Wörter Es ergibt sich, dass w1 in L(G) ist, w2 dagegen nicht. Durch eine leichte Erweiterung der Datenstruktur ist es auch möglich, den Algorithmus so auszubauen, dass im Falle w ∈ L(G) eine Ableitungsfolge oder ein Ableitungsbaum für w ausgegeben wird: Dazu notiert man für jede eingetragene Variable A die Produktion A → BC, die zum Eintrag geführt hat, und den Wert d′ , der zu diesem Eintrag gehört. Mit diesen Informationen lässt sich, von dem S in Kästchen (d, 1) beginnend, ein Ableitungsbaum aufbauen. Ebenso ist leicht feststellbar, ob das Wort w mehrere Ableitungen besitzt: Wenn in ein Kästchen (i, d) dieselbe Variable A ein zweites Mal eingetragen wird, bedeu∗ tet dies, dass es zwei verschiedene Ableitungsbäume für die Ableitung A ⇒ ai · · · ai+d−1 gibt. Wenn ein solcher Eintrag im weiteren Verlauf dazu beiträgt, dass die Variable S in das Kästchen (n, 1) eingetragen wird, dann gibt es für das Eingabewort zwei verschiedene Ableitungen. Wir betrachten nochmals zwei Beispieleingaben für die Grammatik aus Beispiel 4.4.2: w3 = 01001101 und w4 = 01010111. Die entsprechenden Eintragungen im Schema finden sich in Abb. 4.22. 161 d=1 0 1 0 0 1 1 0 1 0 1 0 1 0 1 1 1 A B A A B B A B A B A B A B B B 1 2 S 2 S S S D 3 S D S 4 S S D 5 2 6 S 1 S S 7 8 S S D S S Abbildung 4.22: Mehrere Ableitungen im CYK-Algorithmus Es ergibt sich, dass w3 zwei verschiedene Ableitungsbäume besitzt. Die beiden Paare von Variablen S, die zu je einem Eintrag S“ in Kästchen (8, 1) führen, sind mit Indizes 1 ” bzw. 2 markiert. Das Schema für w4 weist ebenfalls eine Doppel-Eintragung auf, jedoch ist w4 nicht in L(G). Wir haben gezeigt: 4.5.1 Satz Es gibt einen Algorithmus, der zu einer vorgelegten kontextfreien Grammatik G = (V, Σ, S, P ) und w ∈ Σ∗ entscheidet, ob w ∈ L(G). Für festes G ist die Laufzeit des Algorithmus O(n3 ), für |w| = n. (Die Größe und Struktur der Grammatik G geht in die im O“ versteckte Konstante ein.) ” Es sei angemerkt, dass die Laufzeit O(n3 ) für die Analyse und Übersetzung von Programmen in einer durch eine kontextfreie Grammatik spezifizierten Programmiersprache indiskutabel langsam ist – schließlich gibt es Programme, die aus zigtausenden von Texteinheiten (Tokens) bestehen. In der Praxis benutzt man daher spezielle Grammatiken, die eine Syntaxanalyse in linearer Zeit erlauben. Weitere Erläuterungen hierzu finden sich im folgenden Kapitel 5, und Details in einer Vorlesung Übersetzerbau“. ” 4.6 Abschlusseigenschaften kontextfreier Sprachen I Wir diskutieren hier zunächst einige Operationen, unter denen die Klasse L2 der kontextfreien Sprachen abgeschlossen ist. Die Beweistechniken für diese positiven Abschlusseigen162 schaften können auch gut für den Entwurf von kontextfreien Grammatiken für komplexere Sprachen benutzt werden. Zum zweiten werden wir zeigen, dass L2 nicht unter der Durchschnittsoperation und unter Komplementbildung abgeschlossen ist. Weitere Abschlusseigenschaften der Klasse L2 und verwandter Klassen werden (nach der Besprechung von Kellerautomaten im folgenden Kapitel 5) in Abschnitt 5.6 diskutiert. 4.6.1 Satz Die Klasse L2 ist abgeschlossen unter Vereinigung, Konkatenation und Kleene-Abschluss. Beweis: Wir betrachten zunächst Vereinigung und Konkatenation. Es sei L1 = L(G1 ), L2 = L(G2 ) für kontextfreie Grammatiken G1 = (V1 , Σ1 , S1 , P1 ) und G2 = (V2 , Σ2 , S2 , P2 ). O. B. d. A. können wir annehmen, dass V1 ∩ V2 = ∅. (Gegebenenfalls benennt man Variablen um.) Dann definieren wir neue Grammatiken G′ und G′′ durch Zusammenwerfen von P1 und P2 und Verbinden der beiden Teile durch eine passend gewählte Startproduktion. Hierzu wählen wir eine neue Startvariable S 6∈ V1 ∪ V2 . G′ := (V1 ∪ V2 ∪ {S}, Σ1 ∪ Σ2 , S, P1 ∪ P2 ∪ {S → S1 | S2 }) G′′ := (V1 ∪ V2 ∪ {S}, Σ1 ∪ Σ2 , S, P1 ∪ P2 ∪ {S → S1 S2 }). Man überzeugt sich leicht, dass L(G′ ) = L1 ∪ L2 und L(G′′ ) = L1 L2 gilt. Nun betrachten wir den Kleene-Abschluss. Gegeben sei eine kontextfreien Grammatik G = (V, Σ, S, P ). Wir wählen eine neue Variable S ′ , S ′ 6∈ V , und definieren eine kontextfreie Grammatik G′′′ wie folgt: G′′′ := (V ∪ {S ′ }, Σ, S ′ , P ∪ {S ′ → S S ′ | ε}). Wieder ist leicht zu sehen, dass L(G′′′ ) = L(G)∗ gilt. 4.6.2 Beispiel Wir betrachten die Grammatiken G1 = ({A}, {0, 1}, A, P1 ) mit den Produktionen A → 0A1 | ε und G2 = ({B}, {0, 1}, B, P2 ) mit den Produktionen B → 1B0 | ε. Offenbar ist L(G1 ) = {0n 1n | n ≥ 0} und L(G2 ) = {1n 0n | n ≥ 0}. Eine Grammatik für die Sprache L(G1 ) ∪ L(G2 ) = {0n 1n | n ≥ 0} ∪ {1n 0n | n ≥ 0} hat Startvariable S und Produktionen S → A|B A → 0A1 | ε B → 1B0 | ε 163 Eine Grammatik für die Sprache L(G1 )L(G2 ) = {0n 1n 1m 0m | n, m ≥ 0} = {0n 1n+m 0m | n, m ≥ 0} hat Startvariable S und Produktionen S → AB A → 0A1 | ε B → 1B0 | ε Schließlich sieht eine Grammatik für die Sprache L(G1 )∗ = {0n1 1n1 · · · 0nr 1nr | r ≥ 0, n1 , . . . , nr ≥ 0} wie folgt aus: Startvariable S, Produktionen S → AS | ε A → 0A1 | ε Für den folgenden Satz rekapituliere man Definition 2.5.2, die die Substitution von Sprachen definiert. Es ist ziemlich klar, dass kontextfreie Sprachen unter dieser Operation abgeschlossen sind. 4.6.3 Satz Die Klasse L2 ist abgeschlossen unter Substitution. D. h.: Wenn f eine Substitution wie in Definition 2.5.2 ist und f (a1 ), . . . , f (an ) sowie L kontextfreie Sprachen sind, so ist auch f (L) kontextfrei. Beweis: Man wählt Grammatiken G1 , . . . , Gn (mit Startvariablen S1 , . . . , Sn ) und G für die Sprachen f (a1 ), . . . , f (an ) und L und sorgt dafür, dass die Variablenmengen in diesen Grammatiken disjunkt sind. Dann ersetzt man für 1 ≤ i ≤ n in G das Teminalzeichen ai durch eine neue Variable Di , vereinigt alle Produktionenmengen, und fügt die n Produktionen Di → Si zur Produktionenmenge hinzu. Die resultierende Grammatik erzeugt f (L). 4.6.4 Satz Die Klasse L2 ist nicht abgeschlossen unter Durchschnitt und Komplement. Beweis: Durchschnitt“: Wir müssen zeigen, dass es kontextfreie Sprachen L1 und L2 ” gibt, deren Durchschnitt nicht kontextfrei ist. Betrachte hierzu L1 = {ai bi cj | i, j ≥ 1} und L2 = {ai bj cj | i, j ≥ 1}. 164 Beide Sprachen sind kontextfrei. Zum Beispiel wird L1 von einer Grammatik mit den Produktionen S → AC A → aAb | ab C → cC | c erzeugt. Jedoch ist L1 ∩ L2 = {am bm cm | m ≥ 1}, eine Sprache, die sich in Behauptung 4.4.3 als nicht kontextfrei herausstellte. Komplement“: Wir untersuchen die Sprache ” L3 = {ai bj ck | i, j, k ≥ 0, i 6= j oder j 6= k}. Behauptung 1: L3 ist kontextfrei. – Dies sieht man folgendermaßen: L3 = L′1 ∪ L′2 ∪ L′3 ∪ L′4 , wobei L′1 L′2 L′3 L′4 = = = = {ai bj ck {ai bj ck {ai bj ck {ai bj ck | 0 ≤ i < j, k ≥ 0} | 0 ≤ j < i, k ≥ 0} | 0 ≤ j < k, i ≥ 0} | 0 ≤ k < j, i ≥ 0}. Die vier Sprachen L′1 , . . . , L′4 sind alle kontextfrei – zum Beispiel wird L′1 von einer Grammatik mit den folgenden Produktionen erzeugt: S → AbC A → aAb | Ab | ε C → cC | ε Nach Satz 4.6.1 ist also auch L3 kontextfrei. Behauptung 2: L4 := L3 ∪ (Σ∗ − L(a∗ b∗ c∗ )) ist kontextfrei. – Dies sieht man so ein: Die Sprache L(a∗ b∗ c∗ ) ist regulär. Da die regulären Sprachen unter Komplementbildung abgeschlossen sind, ist auch Σ∗ − L(a∗ b∗ c∗ ) regulär. Weil L3 ⊆ L2 , ist Σ∗ − L(a∗ b∗ c∗ ) auch kontextfrei. Daraus folgt, wieder mit Satz 4.6.1, dass L4 ebenfalls kontextfrei ist. Behauptung 3: L4 ist nicht kontextfrei. – In L4 sind alle Wörter, die weder in Σ∗ − L(a∗ b∗ c∗ ) noch in L3 sind. Dies sind also die Wörter der Form ai bj ck , die i = j und j = k erfüllen. Das heißt: L4 = {am bm cm | m ≥ 0}, die Sprache, die nach Behauptung 4.4.3 und Bemerkung 4.4.4 nicht kontextfrei ist. 165 S F A 0 H R A F B 0 R 1 B R 1 A F 0 1 A F 0 1 Abbildung 4.17: Zerlegung von α(T ) = 00101101: u = 00, v = 10, w = 1, x = ε, y = 101 166 Kapitel 5 Kellerautomaten In diesem Kapitel behandeln wir das Maschinenmodell, das den kontextfreien Grammatiken entspricht, nämlich die nichtdeterministischen Kellerautomaten. Anhand des Modells werden verschiedene Prinzipien für die Syntaxanalyse diskutiert, d. h. die Erstellung eines Ableitungsbaumes zu einem vorgelegten Wort aus L(G): Top-Down-Parsing und BottomUp-Parsing. Weiter wird auf die deterministische Variante des Kellerautomaten-Modells und die zugehörige Sprachklasse eingegangen. Schließlich werden wesentliche Abschlussund Entscheidbarkeitseigenschaften der entsprechenden Sprachklassen diskutiert. 5.1 Nichtdeterministische Kellerautomaten Was passiert mit der Berechnungsstärke von endlichen Automaten, wenn sie zusätzlich zur Steuereinheit mit einem weiteren (unendlichen) Speichermedium versehen werden? Wir betrachten hier eine ganz spezielle Form eines Speichers: einen Keller“ oder Stack“ ” ” (englisch auch: pushdown store“).1 ” Diese Datenstruktur lässt die Operationen empty, push und pop zu, wobei empty einen leeren Keller erzeugt, push a das Element a oben auf den Keller legt, und pop das oberste Kellerelement entfernt und ausliest. Im Zusammenhang mit Sprachen speichern wir Buchstaben eines (Keller-)Alphabets. 1 Synonym auch: Stapel, LIFO-Speicher, für last-in-first-out-Speicher. Diese Struktur wird im 1. Semester in der Lehrveranstaltung Algorithmen und Programmierung“ besprochen. ” 167 leer: push κ push λ push φ pop push π push κ κ λ κ φ λ π κ λ κ λ π κ λ κ κ push λ λ κ π λ κ pop pop push π pop pop pop κ π π π κ π λ κ π λ κ λ κ λ κ λ pop push λ λ κ Abbildung 5.1: Arbeitsweise eines Kellerspeichers Die Funktionsweise eines Kellers wird in Abbildung 5.1 veranschaulicht, die den Effekt der Operationsfolge empty; push κ; push λ; push φ; pop; push π; push κ; push λ; pop; pop; push π; pop; pop; pop; pop; push λ; auf einen anfangs leeren Keller zeigt. Keller sind sehr gut zur Bearbeitung von klammerartigen Strukturen geeignet; zum Beispiel kann man die Auswertung eines (auch geklammerten und nach der Punkt-vor-Strich168 Regel auszuwertenden) arithmetischen Ausdrucks sehr bequem mit einer solchen Datenstruktur durchführen. Wir werden hier sehen, dass alle von kontextfreien Grammatiken erzeugbaren Strukturen von Automaten mit einem Keller analysiert werden können. Anschaulich gesprochen besteht ein Kellerautomat aus einem Kellerspeicher (pushdown store), einer Steuereinheit, wie sie von den endlichen Automaten bekannt ist, und einem Eingabeband, das einfach von links nach rechts gelesen wird. Abbildung 5.2 gibt ein Beispiel. Eingabeband: c a c b b c # c b b c a c Lesekopf: Keller: B Steuereinheit: B C A C Abbildung 5.2: Anschauliches Bild eines Kellerautomaten Im Keller eines solchen Kellerautomaten können die Elemente eines Keller-Alphabets“ Γ ” gespeichert werden. Anfangs steht im Keller ein besonderes Zeichen, das Keller-Anfangs” Symbol“. Die Eingabe für den Kellerautomaten steht auf einem separaten Eingabeband, das mit Hilfe eines Lesekopfs“ einmal von links nach rechts gelesen wird. Anfangs steht ” der Kopf auf dem ersten Zeichen des Eingabewortes x ∈ Σ∗ . Die Steuereinheit des Kellerautomaten sieht aus wie bei einem DFA oder einem NFA: es gibt endlich viele Zustände, von denen einer als Startzustand ausgezeichnet ist. Der Kellerautomat rechnet in Schritten. In einem Schritt rückt der Kopf auf dem Eingabeband entweder um ein Feld nach rechts oder ändert seine Position nicht (letzteres nennen wir einen ε-Zug“). Wenn das Eingabewort vollständig gelesen worden ist, befindet sich ” der Lesekopf rechts von der Eingabe; dies ist also auch eine legale Position. Ein Schritt besteht dabei aus folgenden Teilschritten: 1. Das oberste Kellersymbol Z wird vom Keller entfernt und gemerkt (pop-Operation). 169 2. Es wird entweder das nächste Symbol ai des Eingabewortes gelesen (dann rückt der Lesekopf um ein Feld nach rechts) oder nichts vom Eingabeband gelesen (der Lesekopf bewegt sich nicht: ε-Zug). 3. Das Kellerzeichen Z, der gegenwärtige Zustand q und (falls kein ε-Zug vorliegt) das Zeichen ai zusammen legen fest, welche Züge ausführbar sind. Ein Zug besteht dabei aus – einem neuen Zustand q ′ ; – einer Folge γ = Z1 · · · Zr von Kellerzeichen, die auf den Keller gelegt werden: Der Keller verändert sich gemäß der Operationsfolge push(Zr ); push(Zr−1 ); . . . ; push(Z1 ). Einer der ausführbaren Züge wird durchgeführt. In einer gegebenen Situation können in Teilschritt 3. kein, ein, oder mehrere verschiedene Züge ausführbar sein. Die hier betrachteten Kellerautomaten sind also nichtdeterministisch. Daher sind, wie bei NFA’s, eventuell auf einer Eingabe viele verschiedene Berechnungen möglich. Per Konvention legen wir fest, dass der Kellerautomat mit leerem Keller akzeptiert“, ” d. h. eine Berechnung des Kellerautomaten auf einer Eingabe x = a1 · · · an akzeptiert, falls nach Lesen aller Zeichen der Eingabe und Durchführung entsprechender Züge der Keller völlig geleert ist. Man beachte, dass nach völligem Entleeren des Kellers kein weiterer Schritt möglich ist (Teilschritt 1. kann nicht durchgeführt werden) und dass nach Lesen des letzten Eingabezeichens an nur noch ε-Züge möglich sind. Die alternative Möglichkeit, über akzeptierende Zustände zu akzeptieren, wird später besprochen. 5.1.1 Beispiel Palindrome (Spiegelwörter) über {a, b, c} mit Mittezeichen. Wir beschreiben die Funktionsweise einen Kellerautomaten, der genau die Wörter der (nicht regulären) Sprache L = {w#wR | w ∈ {a, b, c}∗ } akzeptiert. Zunächst gehen wir informal vor. Der Automat arbeitet in zwei Phasen. Lesephase: Vor dem Auftauchen von #“ werden im Keller die bisher gelesenen Zeichen ” gespeichert. Kontrollphase: Nach dem #“ werden die gelesenen Zeichen der Reihe nach mit den ” Kellerzeichen verglichen. Die Steuereinheit wird benutzt, um zwischen den Phasen ( L“ für links“, R“ für rechts“) ” ” ” zu unterscheiden. Wenn in der Kontrollphase ein weiteres #“ auftaucht, bricht die Rech” nung ab; die Eingabe wird nicht akzeptiert. 170 Beginn: Eingabeband: c a c b b c # c Lesekopf b b c a c c a c c a c Keller: L R Nach dem Einlesen von 5 Buchstaben: Eingabeband: c a c b b c # c b b Keller: B B C A C L R Nach dem Entdecken des #: Eingabeband: c a c b b c # c b b Keller: C B B C A C L R 171 Nach dem Kontrollieren von 3 Buchstaben: Eingabeband: c a c b b c # c b b c a c c a c Keller: C A C L R Am Ende der Eingabe: Eingabeband: c a c b b c # c b b Keller: L R Wort zuende, Keller leer: akzeptieren! Wir setzen nun die obige informale Beschreibung in eine formale Definition um. 5.1.2 Definition Ein nichtdeterministischer Kellerautomat (englisch: nondeterministic pushdown automaton; Abk.: NPDA) ist ein 6-Tupel M = (Q, Σ, Γ, q0 , Z0 , δ), bestehend aus 6 Komponenten: • Q, einer endlichen, nichtleeren Menge von Zuständen, • Σ, dem Eingabe-Alphabet; • Γ, dem Keller-Alphabet (Stack-Alphabet) • q0 ∈ Q, dem Startzustand • Z0 ∈ Γ, dem Symbol, das anfangs im Keller steht 172 • δ : Q × (Σ ∪ {ε}) × Γ → P<∞ (Q × Γ∗ ), der (nichtdeterministischen) Übergangsfunktion. (Dabei steht P<∞ (R) für {T ⊆ R | T endlich}, für beliebige Mengen R.) Wir erläutern die Details und die Anwendung der Übergangsfunktion δ. Wenn q ein Zustand, a ein Buchstabe aus Σ und Z ein Buchstabe aus dem Kelleralphabet Γ ist, dann ist δ(q, a, Z) eine endliche Menge von Paaren (q ′ , Z1 · · · Zr ), q ′ Zustand, r ≥ 0, Z1 , . . . , Zr Buchstaben aus Γ. Jedes solche Paar beschreibt einen möglichen Zug , wenn auf dem Eingabeband a steht, der Automat in Zustand q ist und das oberste Kellerzeichen Z ist. Wenn δ(q, a, Z) = ∅ ist, ist in dieser Situation kein Zug möglich, der a liest. Wird der Zug (q ′ , Z1 · · · Zr ) angewendet, • geht der Automat in den neuen Zustand q ′ über, • das Eingabezeichen a wird gelesen, • der Lesekopf wird um ein Feld nach rechts gerückt, • das alte Kellerzeichen Z wird entfernt ( pop“) und ” • die Kellerzeichen Z1 , . . . , Zr werden auf den Keller gepackt, in der Art, dass Z1 oben liegt. Dies entspricht der Operationsfolge push(Zr ); push(Zr−1 ); . . . ; push(Z1 ). Bemerkung: Mit r = 0 wird das oberste Kellersymbol gestrichen. Mit r = 1 und Z1 = Z bleibt der Keller unverändert. Mit r ≥ 2 und Zr = Z werden Z1 , . . . , Zr−1 auf den Keller gestapelt. Neben den Zügen, die einen Buchstaben lesen, gibt es die ε-Züge, die durch die Werte δ(q, ε, Z) gegeben sind. Auch δ(q, ε, Z) ist jeweils eine endliche, möglicherweise leere, Menge von Zügen. Wenn der Automat in Zustand q ist und das oberste Kellerzeichen Z ist, kann einer der Züge aus δ(q, ε, Z) ausgeführt werden. Wenn der Zug (q ′ , Z1 · · · Zr ) ausgeführt wird, geht der Automat in den Zustand q ′ über und ersetzt das oberste Kellerzeichen Z durch Z1 · · · Zr . Der Lesekopf verändert seine Position nicht. Beachte: In einer Situation, in der M in Zustand q ist, das nächste Eingabezeichen a ist und das oberste Kellerzeichen Z ist, ist jeder der Züge aus δ(q, a, Z)∪δ(q, ε, Z) anwendbar. Wir sagen (vorerst informal), dass M ein Wort x akzeptiert, wenn es möglich ist, aus der Startsituation (Zustand q0 , Kellerinhalt Z0 , x als Inhalt des Eingabebands) durch Anwendung einer von δ erlaubten Folge von Zügen das Eingabewort vollständig zu lesen und dabei den Keller zu leeren. 5.1.3 Beispiel Wir setzen Beispiel 5.1.1 fort. Ein NPDA, der genau die Palindrome mit Mittezeichen akzeptiert, hat die folgenden Komponenten: • Q = {L, R} 173 • Σ = {a, b, c, #} • Γ = {A, B, C, ⊥} • q0 = L • Z0 = ⊥ • δ ist durch die folgende Tabelle gegeben: δ ⊥ A (L, a) (L, A) (L, AA) (L, b) (L, B) (L, BA) (L, c) (L, C) (L, CA) (L, #) (R, ε) (R, A) (R, a) – (R, ε) (R, b) – – – – (R, c) (R, #) – – B C (L, AB) (L, AC) (L, BB) (L, BC) (L, CB) (L, CC) (R, B) (R, C) – – (R, ε) – – (R, ε) – – In der Tabelle steht ein Paar (q ′ , γ) für die Einermenge {(q ′ , γ)}; der Strich – “ ” steht für ∅. Die Zeilen für die ε-Züge sind weggelassen, da δ(q, a, Z) = ∅ ist für alle a, q, Z, also überhaupt keine ε-Züge möglich sind. Man sieht, dass die Übergangsfunktion deterministisch ist in dem Sinn, dass in jeder Situation entweder ein oder kein Zug möglich ist. Dies ist von der Definition nicht verboten. Das Anfangs-Keller-Zeichen wird im ersten Leseschritt gelöscht. Man überzeuge sich durch Testen auf einigen Eingabewörtern, z. B. ε, #, a#a, a#, ac#ca und acc#ccab, dass der beschriebene Automat genau mit den Palindromen mit Mittezeichen als Input die beabsichtigte Berechnung absolviert (vollständiges Lesen des Eingabeworts, Leeren des Kellers). Situationen, die zu einem fehlerhaften Anhalten führen, sind: • Leeren des Kellers, bevor das Eingabewort vollständig gelesen ist; • Erreichen des Endes des Eingabewortes, ohne dass der Keller leer ist; • eine Situation mit Zustand q, oberstem Kellerzeichen Z, Eingabebuchstaben a, in der δ(q, a, Z) ∪ δ(q, ε, Z) = ∅ ist. Auch beachte man die Wirkung der Züge • (L, AB) ∈ δ(L, a, B) (Hinzufügen von A“ im Keller), ” • (L, A) ∈ δ(L, #, A) (Keller bleibt unverändert), • (R, ε) ∈ δ(L, a, A) (Löschen des Kellersymbols A“ nach Abgleich mit dem Einga” bezeichen a). 174 Alternativ zur Tabellendarstellung kann man für den Entwurf und für die Beschreibung der Übergangsfunktion für (kleine) NPDA’s auch eine graphische Darstellung benutzen. In Abb. 5.3 ist eine solche Darstellung für den NPDA aus Beispiel 5.1.3 angegeben. Start a, A b, B #, u u c, C #, a, u A u L ε a, A ε R b, B ε c ,C ε b, u B u c, u C u u steht für A, B oder C Abbildung 5.3: Graphische Darstellung eines NPDA In einer solchen graphischen Darstellung von M = (Q, Σ, Γ, q0 , Z0 , δ) gibt es für jeden Zustand q ∈ Q einen Knoten, der mit q beschriftet ist. Der Knoten für den Startzustand q0 ist mit einem Pfeil gekennzeichnet. Falls (q ′ , Z1 · · · Zr ) ∈ δ(q, a, Z), verläuft eine Kante von q nach q ′ , die mit a, Z | Z1 · · · Zr beschriftet ist. Dabei werden Mehrfachkanten zu einer zusammengefasst, die mit einer Liste von Beschriftungen versehen ist; weitere Abkürzungen für ähnliche Übergänge sind möglich. Um auch die Wirkung des Nichtdeterminismus zu sehen, betrachten wir ein weiteres Beispiel. 5.1.4 Beispiel Die Sprache L = {w wR | w ∈ {a, b, c}∗ } enthält genau die Palindrome (Spiegelwörter) über {a, b, c}, die gerade Länge haben. Zum Beispiel sind ε, aaaa und abbccbba in dieser Sprache, nicht hingegen aca und abca. Die Idee für einen NPDA, der die Wörter dieser Sprache akzeptiert, ist die folgende. Der Automat arbeitet in zwei Phasen. Lesephase: (Zustand L“) Die gelesenen Zeichen werden im Keller gespeichert. ” 175 Kontrollphase: (Zustand R“) Die gelesenen Zeichen werden mit den Kellerzeichen ver” glichen. Da das Eingabewort keine Markierung für das Umschalten von der Lese- zur Kontrollphase enthält, benutzen wir hierfür den Nichtdeterminismus: Jederzeit während der Lesephase kann der NPDA nichtdeterministisch wählen, ob das nächste Zeichen gelesen und im Keller gespeichert oder spontan (mit einem ε-Zug) in die Kontrollphase gewechselt werden soll. Der NPDA hat die folgenden Komponenten: • Q = {L, R} • Σ = {a, b, c} • Γ = {A, B, C, ⊥} • q0 = L • Z0 = ⊥ • δ ist durch die folgende Tabelle gegeben: δ ⊥ A (L, a) (L, A) (L, AA) (L, b) (L, B) (L, BA) (L, c) (L, C) (L, CA) (L, ε) (R, ε) (R, A) (R, a) – (R, ε) (R, b) – – (R, c) – – B C (L, AB) (L, AC) (L, BB) (L, BC) (L, CB) (L, CC) (R, B) (R, C) – – (R, ε) – – (R, ε) Die graphische Darstellung sieht aus wie in Abb. 5.4 angegeben. Start a, A b, B ε, u u c, C ε, a, u A u L ε a, A ε R b, B ε c ,C ε b, u B u c, u C u u steht für A, B oder C Abbildung 5.4: NPDA für Palindrome gerader Länge 176 Nun hat in dieser Tabelle jeder Eintrag δ(q, a, Z) und δ(q, ε, Z) Größe 1 oder Größe 0. Wo ist die nichtdeterministische Enscheidungsmöglichkeit? Wenn zum Beispiel der Zustand L und das oberste Kellerzeichen A ist, und der nächste Buchstabe auf dem Eingabeband das b, dann kann der NPDA zwischen den Zügen (L, BA) ∈ δ(L, b, A) und (R, A) ∈ δ(L, ε, A) wählen. Man finde für die Eingabe acca eine Berechnung des NPDA M , die das Wort liest und den Keller leert, sowie eine Berechnung, die eine Fehlentscheidung trifft und in eine Sackgasse gerät! Wie sieht die erfolgreiche Berechnung für die Eingabe ε aus? Um das Verhalten von NPDA’s formal zu erfassen, ohne nichtmathematische Gegenstände wie Leseköpfe oder Kellerspeicher zu erwähnen, benutzen wir das Konzept der Konfigurationen. Dieses Vorgehen ist typisch und beispielhaft für die exakte Beschreibung der Semantik von Systemen, die in Schritten rechnen und Speicher- oder Steuer-Zustände haben. 5.1.5 Definition Sei M = (Q, Σ, Γ, q0 , Z0 , δ) ein NPDA. (a) Eine Konfiguration von M ist ein Tripel (q, w, α) ∈ Q × Σ∗ × Γ∗ . Beispiel : Im NPDA aus Beispiel 5.1.4 sind (L, aabbc, BBC) oder (R, aabbc, CCC⊥AB) Konfigurationen. (q ist der gegenwärtige Zustand, w ist das noch nicht gelesene Suffix des Eingabewortes (w wird oft auch Restwort“ genannt), α = Y1 · · · Yr ∈ Γ∗ , r ≥ 0, ist der ” Kellerinhalt – Y1 ist das oberste Kellersymbol. Es ist nicht verlangt, dass das Wort α in einer Berechnung als Kellerinhalt auftreten kann.) Die Menge aller Konfigurationen von M nennen wir KM . (KM ist natürlich eine unendliche Menge.) (b) Wenn k = (q, au, Zγ) Konfiguration ist, mit q ∈ Q, a ∈ Σ, u ∈ Σ∗ , Z ∈ Γ und γ ∈ Γ∗ , und wenn zudem (q ′ , Z1 · · · Zr ) ∈ δ(q, a, Z) ist, dann nennen wir k ′ = (q ′ , u, Z1 · · · Zr γ) eine direkte Nachfolgekonfiguration von k und schreiben k ⊢M k ′ oder k ⊢ k ′ ; weiterhin: wenn k = (q, u, Zγ) Konfiguration ist, mit q ∈ Q, u ∈ Σ∗ , Z ∈ Γ und γ ∈ Γ∗ , und wenn zudem (q ′ , Z1 · · · Zr ) ∈ δ(q, ε, Z) ist, dann nennen wir k ′ = (q ′ , u, Z1 · · · Zr γ) eine direkte Nachfolgekonfiguration von k und schreiben k ⊢M k ′ oder k ⊢ k ′ . Damit ist ⊢M eine zweistellige Relation auf KM . 177 (c) Die Relation ⊢∗M , oder kurz ⊢∗ , ist die reflexive und transitive Hülle von ⊢ (siehe Beispiel A.2.14 im Anhang), das heißt: k ⊢∗M k ′ ⇔ es existiert eine Folge k0 = k, . . . , kl = k ′ , l ≥ 0, derart dass ki−1 ⊢ ki , für 1 ≤ i ≤ l. (Dies bedeutet, dass k = k ′ ist oder dass man in einer Reihe von legalen Schritten von der Konfiguration k zur Konfiguration k ′ kommen kann.) (d) M akzeptiert x ∈ Σ∗ , falls (q0 , x, Z0 ) ⊢∗M (q, ε, ε) für ein q ∈ Q. (Startend in Zustand q0 , mit Eingabe x und nur dem Zeichen Z0 im Keller, kann in einer Reihe von legalen Schritten das Eingabewort gelesen und der Keller geleert werden. Der erreichte Zustand ist irrelevant.) Die Konfiguration initM (x) := (q0 , x, Z0 ) heißt Startkonfiguration von M zu Eingabe x. Jede legale Konfigurationenfolge initM (x) = k0 ⊢M k1 ⊢M k2 ⊢M · · · ⊢M kt heißt eine Berechnung von M auf x. (e) LM := {x ∈ Σ∗ | M akzeptiert x} heißt die von M akzeptierte Sprache. Wir betrachten nochmals Beispiel 5.1.4. Die folgenden Paare liegen in der Relation ⊢M : (L, aabbc, BBC) ⊢M (L, abbc, ABBC) (L, aabbc, BBC) ⊢M (R, aabbc, BBC) (Auch dumme Übergänge können legal sein.) (L, abc, BBC⊥A) ⊢M (L, bc, ABBC⊥A) (Es kommt nicht darauf an, ob k und k ′ in echten Berechnungen vorkommen.) (R, aabbc, BBC) hat keine Nachfolgekonfiguration. (R, aabbc, ε) hat keine Nachfolgekonfiguration. (Allgemein gilt: Eine Konfiguration mit leerem Keller hat keine Nachfolgekonfiguration.) Eine legale Berechnung dieses NPDA, die zur gewünschten akzeptierenden Konfiguration führt, ist folgende: ⊢ ⊢ ⊢ ⊢ ⊢ (L, cbbc, ⊥) (L, bbc, C) (L, bc, BC) (R, bc, BC) (R, c, C) (R, ε, ε). 178 Eine legale, aber nicht akzeptierende Berechnung auf demselben Eingabewort: ⊢ ⊢ ⊢ ⊢ (L, cbbc, ⊥) (L, bbc, C) (L, bc, BC) (L, c, BBC) (R, c, BBC) Diese Berechnung führt in eine Sackgasse“, eine Konfiguration ohne Nachfolgekonfigura” tion. Obgleich solche Sackgassen existieren, gehört das Wort x = cbbc zur Sprache LM : eine akzeptierende Berechnung genügt uns. Startkonfiguration: (L,abbbba, ) (R,abbbba, ε ) (L,bbbba,A) (L,bbba,BA) (L,bba,BBA) (L,ba,BBBA) (L,a,BBBBA) (R,bbba,BA) (R,bba,BBA) (R,ba,BBBA) (L, ε,ABBBBA) (R,a,BBBBA) (R,bbbba,A) (R,a,BBA) (R,ε ,ABBBBA) (R,bba,A) (R,ba,BA) (R,a,A) (R, ε , ε ) Abbildung 5.5: Baum aller möglichen Berechnungen auf Eingabe abbbba Um dies zu verdeutlichen, geben wir in Abb. 5.5 den Baum aller möglichen legalen Berechnungen auf dem Eingabewort abbbba an. Sechs dieser Berechnungen enden in einer Sackgasse, aber eine erreicht die akzeptierende Konfiguration (R, ε, ε). Dies genügt, um abbbba ∈ LM zu folgern. Wenn ein Wort x nicht in LM ist, dann enthält der Baum aller möglichen Berechnungen keine einzige Berechnung, die in der akzeptierende Konfiguration (R, ε, ε) endet. (Man zeichne den entsprechenden Baum für die Eingabe abbb!) 5.1.6 Beispiel Zu guter Letzt wollen wir noch einen NPDA für die Sprache der korrekten Klammerausdrücke angeben. Zur Abwechslung benutzen wir nicht die Buchstaben 0 und 1, sondern ( und ). Es geht also um die Sprache L = {w | w ∈ {(, )}∗ ist korrekter Klammerausdruck} Die Idee für den NPDA ist ganz einfach: Wir merken uns im Keller (in Unärdarstellung) die Anzahl der gelesenen offenen“ Klammern, für die noch kein schließendes Gegenstück ” aufgetaucht ist. Das heißt: Beim Lesen eines (“ wird der Kellerstand um 1 erhöht, beim ” Lesen eines )“ wird der Kellerstand um 1 erniedrigt. Ein Fehler tritt ein, wenn der ” Keller leer ist und ein )“ gelesen wird. Hingegen ist es kein Fehler, wenn der Keller leer ” 179 wird und dann wieder ein (“ gelesen wird. (Man hat dann ein Präfix des Eingabewortes ” gesehen, das für sich ein korrekter Klammerausdruck ist.) Hierfür benutzen wir folgenden Trick: Das Kellerendezeichen ⊥ wird nicht gelöscht. Wenn es als oberstes Kellerzeichen auftaucht, wissen wir, dass der Keller eigentlich“ leer ist und dass kein )“ gelesen werden ” ” kann. Andererseits erlauben wir in dieser Situation einen ε-Übergang, der das ⊥ löscht, den Keller im technischen Sinn leert, und die Berechnung beendet. Der NPDA hat die folgenden Komponenten: • Q = {0} (|Q| = 1: Zustand ist irrelevant); • Σ = {(, )}; • Γ = {1, ⊥}; • q0 = 0; • Z0 = ⊥; • δ ist durch folgende Tabelle gegeben: ⊥ δ 1 (0, () (0, 1⊥) (0, 11) (0, )) − (0, ε) (0, ε) (0, ε) − (, Start 0 1 (, 1 11 ), 1 ε ε, ε Abbildung 5.6: NPDA für korrekte Klammerausdrücke 5.2 Top-Down-Parsing, LL-Parsing Wir wollen zunächst anhand eines Beispiels überlegen, dass Wörter zu kontextfreien Grammatiken mit Kellerautomaten verarbeitet werden können. Dazu betrachten wir die Grammatik G = (V, Σ, S, P ) mit V = {S}, Σ = {(, )} und P = {S → (S)S | ε}, die 180 nach Proposition 4.2.8 die korrekten Klammerausdrücke erzeugt. Der Kellerautomat hat Bandalphabet Σ, Kelleralphabet Γ = {S, (, )} und Anfangs-Kellerzeichen Z0 = S. Erlaubt sind folgende Aktionen: 1) Ist (“ oberstes Kellerzeichen und nächstes Eingabezeichen, streiche (“ aus dem ” ” Keller und rücke den Lesekopf auf dem Eingabeband um ein Feld nach rechts ( Le” sen“: L). 2) Wie 1), mit (“ durch )“ ersetzt ( Lesen“ : L). ” ” ” 3) Ist S oberstes Kellerzeichen, ersetze dies durch nichts (ε) oder durch die 4 Zeichen (S)S“ ( Expandieren“: E). ” ” Die Eingabe ()(()()) kann dann folgendermaßen verarbeitet werden: Aktionstyp gelesene Bandbuchstaben Keller Start S E (S)S L ( S)S E ( )S L () S E () (S)S L ()( S)S E ()( (S)S)S L ()(( S)S)S E ()(( )S)S L ()(() S)S E ()(() (S)S)S L ()(()( S)S)S E ()(()( )S)S L ()(()() S)S E ()(()() )S L ()(()()) S E ()(()()) Schluss Beobachte: Konkateniert man in jeder Zeile die gelesenen Buchstaben und den Kellerinhalt, ergibt sich, von oben nach unten gelesen, eine Linksableitung für das Eingabewort ()(()()). Leseschritte bringen dabei die Ableitung nicht voran, sie verschieben nur ein Zeichen aus dem Keller in das schon gelesene Anfangsstück. Expansionsschritte entsprechen Ableitungsschritten. Das Lesen eines Wortes w aus L(G) unter Herstellung einer Ableitung (insbesonodere eines Ableitungsbaums für w) nennen wir Parsing . In unserem Beispiel wird das Wort von links nach rechts gelesen; dabei wird eine Linksableitung erzeugt ( LL-Parsing“). ” 181 Wenn man die in dieser Linksableitung durchgeführten Expansionsschritte in der in Lemma 4.2.3 ( ⇒“) beschriebenen Weise in einen Ableitungsbaum umsetzt, dann entsteht ” dieser von der Wurzel (oben) her auf die Blätter (unten) zu wachsend. Wir sprechen daher beim LL-Parsing auch von Top-Down-Syntaxanalyse“. ” 5.2.1 Beispiel Wir formalisieren den oben skizzierten NPDA zur Grammatik mit den Produktionen S → (S)S | ε wie folgt: • Q = {0}; q0 = 0 (der Zustand ist irrelevant); • Σ = {(,)}; • Γ = {S, (, )}, Z0 = S; • δ(0,(,() = {(0, ε)} (Leseschritt) , δ(0,),)) = {(0, ε)} (Leseschritt) , δ(0, ε, S) = {(0, ε), (0, (S)S)} (Expansionsschritt). Das eben an einem Beispiel beschriebene Vorgehen lässt sich für jede kontextfreie Grammatik anwenden. 5.2.2 Satz Zu jeder kontextfreien Grammatik G gibt es einen NPDA M mit L(G) = LM . Der Kellerautomat M hat nur einen Zustand. Beweis: Es sei G = (V, Σ, S, P ) eine kontextfreie Grammatik. Wir konstruieren M = (Q, Σ, Γ, q0 , Z0 , δ) in Verallgemeinerung von Beispiel 5.2.1 wie folgt. Wenn das oberste Kellersymbol eine Variable A ist, kann diese in einem Expansionsschritt“ durch irgend” eine rechte Seite α einer Produktion A → α ersetzt werden. Der Nichtdeterminismus liegt darin, dass zu einer Variablen mehrere rechte Seiten gehören können. Wenn das oberste Kellerzeichen ein Terminalzeichen a ist, kann nur ein Leseschritt“ erfolgen: es wird ge” prüft, ob das nächste Eingabezeichen ebenfalls a ist; in diesem Fall wird dieses a gelesen und aus dem Keller gelöscht. Formal: • Q = {0}, • Γ = V ∪ Σ, • Z0 = S, • δ(0, a, a) = {(0, ε)} (Leseschritt) δ(0, ε, A) = {(0, γ) | A → γ ist in P }, für A ∈ V (Expansionsschritt). 182 Es folgt nun der formale Beweis dafür, dass tatsächlich L(G) = LM ist. Dabei ist die Idee des Beweises ganz einfach. Aus einer akzeptierenden Berechnung von M auf w erhalten wir durch Betrachten der Expansionsschritte eine Linksableitung für w in G; umgekehrt kann man aus einer Linksableitung eine akzeptierende Berechnung erhalten, indem man passende Leseschritte dazwischenschiebt. Die Details des Beweises sind nicht prüfungsrelevant. Jedoch muss man in der Lage sein, zu einer gegebenen Grammatik G den NPDA M zu definieren sowie aus einer akzeptierenden Berechnung von M die entsprechende Linksableitung abzulesen und aus einer Linksableitung eine akzeptierende Berechnung des NPDA zu konstruieren. L(G) ⊆ LM “: Es sei ein Wort w ∈ L(G) mit einer Linksableitung ” S = α0 ⇒G α1 ⇒G · · · ⇒G αt = w, (mit t ≥ 1) gegeben. Die Idee ist, zu zeigen, dass es eine akzeptierende Berechnung von M auf w gibt, die genau dieser Linksableitung folgt. Technisch zeigen wir, dass für j = 0, 1, . . . , t die folgende Aussage (Aj ) gilt: Es sei w′ das längste Präfix von αj , das nur aus Terminalzeichen besteht. Schreibe αj = w′ β und w = w′ w′′ . (D. h.: Für j < t ist β = Aγ mit einer Variablen A; für j = t ist β = ε.) Dann gilt für M : (0, w, S) ⊢∗M (0, w′′ , β). Wir beweisen (Aj ) durch Induktion über j. I.A.: j = 0. In diesem Fall ist w′ = ε, also β = S, und w′′ = w; damit gilt (0, w, S) ⊢∗M (0, w′′ , β), weil beide Konfigurationen gleich sind. Nun sei j ≥ 1. I.V.: Die Behauptung (Aj−1 ) gilt. Das heißt: Es sei u′ das längste Präfix von αj−1 ohne Variable, w = u′ u′′ , und und αj−1 = u′ Aγ. Es gibt eine Berechnung (0, w, S) ⊢∗M (0, u′′ , Aγ). I.S.: In der Konfiguration (0, u′′ , Aγ) wenden wir einen Expansionsschritt an, und zwar mit der Produktion A → α, die von αj−1 = u′ Aγ zu αj = u′ αγ führt. Dies liefert: (5.1) (0, u′′ , Aγ) ⊢M (0, u′′ , αγ). In Kombination mit der I.V. ergibt sich daraus: (5.2) (0, w, S) ⊢∗M (0, u′′ , αγ). Wenn nun αγ mit einer Variablen beginnt oder gleich ε ist, sind wir fertig, da dann u′ auch das längste Präfix von αj aus Terminalzeichen ist. Sonst sei v ′ das längste Präfix von 183 αγ, das nur aus Terminalzeichen besteht. Schreibe αγ = v ′ ζ. Da u′ αγ = u′ v ′ ζ ⇒∗G u′ u′′ im Rahmen einer Linksableitung, ist v ′ auch Präfix von u′′ , und wir können u′′ = v ′ v ′′ schreiben. In der Konfiguration (0, u′′ , αγ) wenden wir |v ′ | Leseschritte an und erhalten (5.3) (0, u′′ , αγ) = (0, v ′ v ′′ , v ′ ζ) ⊢∗M (0, v ′′ , ζ), wobei entweder ζ = ε ist oder mit einer Variablen beginnt. Wenn wir nun (5.2) und (5.3) zusammensetzen, ergibt sich: (5.4) (0, w, S) ⊢∗M (0, v ′′ , ζ), und das ist die Induktionsbehauptung. Damit haben wir die Aussage (Aj ) für alle j bewiesen. Insbesondere gilt (At ). Weil aber αt = w ist, heißt (At ) einfach, dass es eine Berechnung (0, w, S) ⊢∗M (0, ε, ε) gibt, was zu zeigen war. L ⊆ L(G)“: Sei w ∈ LM . Dann haben wir eine akzeptierende Berechnung ” M initM (w) = (0, w, S) = k0 ⊢M k1 ⊢M · · · ⊢M kt = (0, ε, ε). Wir zeigen (wie im Beispiel am Anfang dieses Abschnitts schon beobachtet), dass aus dieser Berechnung eine Linksableitung abgelesen werden kann. Technisch gehen wir wie folgt vor. Eine Konfiguration kj in dieser Berechnung hat folgende Form: kj = (0, wj′′ , βj ), wo wj′′ der noch nicht gelesene Teil von w ist und βj ∈ (V ∪ Σ)∗ der Kellerinhalt. Wir können also w = wj′ wj′′ schreiben, für ein Wort wj′ (der schon gelesene Teil, der in der Konfiguation kj nicht mehr erwähnt wird). Behauptung: (Bj ) S ⇒∗G wj′ βj , für j = 0, . . . , t. (Wenn (Bj ) für alle j bewiesen ist, wenden wir (Bt ) an und erhalten S ⇒∗G wt′ βt = w, also w ∈ L(G), wie gewünscht.) Die Aussage (Bj ) beweisen wir durch Induktion über j. I.A.: j = 0: Es ist w0′ = ε (noch nichts gelesen) und β0 = S. Daher gilt S ⇒∗G w0′ β0 . Nun sei 1 ≤ j ≤ t. ′ I.V.: (Bj−1 ) gilt, d. h. S ⇒∗G wj−1 βj−1 . I.S.: 1. Fall : Der Schritt von kj−1 zu kj ist ein Expansionsschritt. Dann kann man βj−1 = Aγ schreiben, für eine Variable A und γ ∈ (V ∪ Σ)∗ , und βj = αγ, ′′ ′ wobei A → α eine Produktion ist. Weiter gilt wj′′ = wj−1 und daher wj′ = wj−1 , weil kein Zeichen gelesen wird. Daraus folgt: ′ ′ ′ wj−1 βj−1 = wj−1 Aγ ⇒G wj−1 αγ = wj′ βj . 184 Wenn wir dies mit der I.V. kombinieren, ergibt sich S ⇒∗G wj′ βj , also die Induktionsbehauptung (Bj ). 2. Fall : Der Schritt von kj−1 zu kj ist ein Leseschritt. Dann gibt es ein a ∈ Σ so dass ′′ βj−1 = aβj und wj−1 = awj′′ ′ gilt. Daraus folgt sofort wj′ = wj−1 a. Wir erhalten: ′ ′ wj−1 βj−1 = wj−1 aβj = wj′ βj , und daher nach der Induktionsvoraussetzung auch S ⇒∗G wj′ βj , also die Induktionsbehauptung (Bj ). Dieser Beweis kann als Rezept interpretiert werden, wie aus einer akzeptierenden Berechnung von M eine Linksableitung in G zu erhalten ist und umgekehrt. Die Leseschritte tauchen in der Ableitung nicht auf; die Schritte der Linksableitung entsprechen genau den Expansionsschritten der Berechnung des NPDAs. Man prüfe dies noch einmal anhand des Beispiels am Anfang dieses Abschnitts (5.2) nach. Ausblick: LL(1)-Grammatiken und ihre deterministischen Parser Die Benutzung des Nichtdeterminismus zum Finden der richtigen Ableitungsschritte ist natürlich recht störend. Wenn die Grammatik G eindeutig ist (siehe Def. 4.2.6(a)), dann hat jedes Wort w ∈ L(G) genau eine Linksableitung; nach der Konstruktion aus dem eben geführten Beweis gibt es also genau eine akzeptierende Berechnung des NPDA M . Das heißt, dass es in jeder Situation genau eine korrekte Entscheidung gibt, die am Ende zur akzeptierenden Situation führt. Wenn man einen wirklichen, benutzbaren Parser erstellen will, der nach dem Top-DownPrinzip (und ohne Zurücksetzen) arbeitet, muss man einen Mechanismus bereitstellen, der es erlaubt, in jeder Situation diesen einen korrekten Zug zu finden. Eine Möglichkeit hierfür sind die sogenannten LL(1)-Parser, die diese Entscheidung aufgrund des obersten Kellersymbols und des nächsten anstehenden Zeichen in der Eingabe treffen. In Verallgemeinerung der LL(1)-Grammatiken betrachtet man auch LL(k)-Grammatiken für beliebige k ≥ 1, bei denen der Parser die jeweils nächsten k Zeichen der Eingabe inspizieren darf ( lookahead“), um die Entscheidung über den nächsten vorzunehmenden ” Zug zu treffen. Details zu LL(k)-Grammatiken und zur Konstruktion von LL-Parsern erfährt man in der Vorlesung Übersetzerbau“ oder aus den entsprechenden Lehrbüchern ” wie [Aho, Sethi, Ullman, Compilerbau, Oldenbourg 1999] oder [Wilhelm, Maurer, Übersetzerbau, Springer 1997]. Wir skizzieren das Vorgehen bei LL(1)-Grammatiken. Um die Diskussion zu vereinfachen, vereinbaren wir folgendes. Zu einer Grammatik G = (V, Σ, S, P ) wird ein neues 185 Terminalzeichen $, eine neue Variable S ′ und eine neue Produktion S ′ → S$ hinzugefügt. Die Variable S ′ wird die Startvariable. Die neue (erweiterte) Grammatik soll dann G′ = (V ′ , Σ′ , S ′ , P ′ ) heißen, und wir betrachten nur Grammatiken, die diese Struktur haben. Damit endet jedes Wort in L(G′ ) auf $, und dieses Zeichen kommt nirgendwo anders vor. (In tatsächlich verwendeten Sprachen gibt es Abwandlungen dieser Vereinbarung. Zum Beispiel signalisiert in der Programmiersprache Pascal die Zeichenfolge end. das Ende des Programms. In anderen Programmiersprachen spielt das nicht-druckbare Zeichen eof, das das Dateiende markiert, die Rolle des Schlusszeichens.) Die betrachteten LL-Kellerautomaten beginnen ihre Berechnung damit, die Zeichen $ und S in den Keller zu schreiben. Eingabewörter, die das Zeichen $ nicht oder nicht nur am Schluss enthalten, führen immer zu einem Fehler. Damit ist klar, dass akzeptierende Berechnungen mit einem Leseschritt enden müssen, bei dem das Schlusszeichen $ der Eingabe gelesen und das Schlusszeichen $ im Keller gelöscht wird. 5.2.3 Definition Eine kontextfreie Grammatik G′ = (V ′ , Σ′ , S ′ , P ′ ) (mit Endezeichen $) heißt vom Typ LL(1), wenn für jede Variable A und jedes Paar verschiedener Produktionen A → α und A → β gilt: ∗ ∗ ∗ ∗ (a) Wenn α ⇒ au, β ⇒ bv, a, b ∈ Σ′ , u, v ∈ (Σ′ )∗ , dann ist a 6= b. (Aus zwei verschiedenen rechten Seiten in Produktionen von A kann nie derselbe erste Terminalbuchstabe entstehen.) ∗ (b) Wenn α ⇒ au, β ⇒ ε, S ′ ⇒ xAbv, u, x, v ∈ (Σ′ )∗ , a, b ∈ Σ′ , dann ist a 6= b. (Es kann nicht vorkommen, dass aus einer Produktion von A ein Terminalbuchstabe als erstes Zeichen entsteht, der auch in einer Ableitung an dieser Stelle stehen kann, die aus A das leere Wort erzeugt.) Der Effekt dieser Definition ist folgender: Wenn man beim bislang fehlerlosen LL-Parsing eines Wortes w ∈ L(G′ ) in einer Situation angekommen ist, wo w = w′ aw′′ , w′ das schon gelesene Teilwort, und aw′′ das noch zu lesende Restwort ist, und wenn der Kellerinhalt Aγ ist, mit A ∈ V ′ , γ ∈ (V ′ ∪ Σ′ )∗ , dann gibt es nur eine Produktion A → α, die jetzt anwendbar ist. Diese Produktion ist durch A und a eindeutig bestimmt. 5.2.4 Fakt Es gibt einen Algorithmus, der Grammatiken auf die LL(1)-Eigenschaft testet und der zu jeder Kombination (A, a), A ∈ V ′ , a ∈ Σ′ , den richtigen Zug (d. h. die jetzt anzuwendende Produktion) ermittelt. 5.2.5 Beispiel Wir demonstrieren die Struktur eines LL(1)-Parsers an einem ausführlichen Beispiel. Unsere erste Grammatik in Beispiel 3.1.1 diente zur Erzeugung der Menge der arithmetischen Ausdrücke mit Klammern und Prioritäten. Wir wiederholen die Grammatik hier, mit abgekürzten Variablen: 186 G = ({T, E, F }, {+, -, *, /, (, ), n}, E, P ), wobei P die folgenden Regeln enthält: E → E+T |E-T |T T → T *F |T /F |F F → (E)|n Diese Grammatik enthält eine Erscheinung, die man Linksrekursion“ nennt: es gibt Pro∗ ” duktionen der Form A → Aα (allgemeiner: A ⇒ Aα). Solche Grammatiken können niemals LL(1)-Grammatiken sein. (Wieso?) Man baut (mit einem einfachen Algorithmus, den wir hier nicht besprechen) die Grammatik zu einer äquivalenten Grammatik um, die die Erscheinung Linksrekursion“ nicht hat, und fügt gleich das Abschlusszeichen $ hinzu. ” Dies liefert die folgende Grammatik: G′ = ({T, T ′ , E, E ′ , F, S ′ }, {+, -, *, /, (, ), n, $}, E ′ , P ′ ), wobei P ′ die folgenden Regeln enthält: S′ E E′ T T′ F → → → → → → E$ T E′ + T E′ | - T E′ | ε F T′ * F T′ | / F T′ | ε (E)|n 187 S’ $ E E’ T F T’ n ε + T E’ ε T’ F ( E T F n * ) ( E’ T’ F / T’ ε F T’ F T’ n ε n ε ε ) E T E’ − T E’ F T’ − n ε T E’ F T’ n ε ε Abbildung 5.7: Der Ableitungsbaum in G′ für das Wort n+(n*n)/(n-n-n)$ Als Anschauungsmaterial für das Funktionieren dieser Grammatik geben wir den Ableitungsbaum (Abb. 5.7) und eine Linksableitung (Abb. 5.8) für das Wort n+(n*n)/(n-n-n)$ an. Um diese etwas abzukürzen, notieren wir die Teilableitung T ⇒ F T ′ ⇒ nT ′ ⇒ n, die ∗ stillschweigend (mit ⇒) benutzt wird. 188 S′ ⇒ ⇒ ∗ ⇒ ⇒ ⇒ ⇒ ⇒ ⇒ ⇒ ⇒ ⇒ ⇒ ⇒ ⇒ ⇒ ⇒ ∗ ⇒ ⇒ ∗ ⇒ ⇒ ∗ ⇒ ⇒ ⇒ ⇒ E$ T E ′$ nE ′ $ n+T E ′ $ n+F T ′ E ′ $ n+(E)T ′ E ′ $ n+(T E ′ )T ′ E ′ $ n+(F T ′ E ′ )T ′ E ′ $ n+(nT ′ E ′ )T ′ E ′ $ n+(n*F T ′ E ′ )T ′ E ′ $ n+(n*nT ′ E ′ )T ′ E ′ $ n+(n*nE ′ )T ′ E ′ $ n+(n*n)T ′ E ′ $ n+(n*n)/F T ′ E ′ $ n+(n*n)/(E)T ′ E ′ $ n+(n*n)/(T E ′ )T ′ E ′ $ n+(n*n)/(nE ′ )T ′ E ′ $ n+(n*n)/(n-T E ′ )T ′ E ′ $ n+(n*n)/(n-nE ′ )T ′ E ′ $ n+(n*n)/(n-n-T E ′ )T ′ E ′ $ n+(n*n)/(n-n-nE ′ )T ′ E ′ $ n+(n*n)/(n-n-n)T ′ E ′ $ n+(n*n)/(n-n-n)E ′ $ n+(n*n)/(n-n-n)$ Abbildung 5.8: Die Linksableitung in G′ für n+(n*n)/(n-n-n)$ Um die Wirkungsweise der Grammatik intuitiv zu verstehen, kann man sich vorstellen, dass E“ für einen Ausdruck mit + und -“ steht, E ′“ für Erweiterung eines ” ” ” ” +/-Ausdrucks“, und dass ähnlich T“ für einen Ausdruck mit * und /“ steht, T ′“ für ” ” ” Erweiterung eines *//-Ausdrucks“. Schließlich steht F“ für einen Faktor“ innerhalb ” ” ” eines *//-Ausdrucks. Eine Entscheidungstabelle für die Expansionsschritte für diese Grammatik sieht folgendermaßen aus. Die Spalte Var.“ gibt die Variable an, die oben im Keller steht. Wenn das ” oberste Kellerzeichen ein Terminalzeichen ist, kommt nur ein Leseschritt in Frage. 189 nächstes Eingabezeichen Var. n + - * / ( ) $ S′ S ′ → E$ – – – – S ′ → E$ – – – – – – – – E ′ → +T E ′ E ′ → -T E ′ E → T E′ – – – E′ → ε – – – – – – – T′ → ε T′ → ε T ′ → *F T ′ T ′ → /F T ′ T → FT′ E′ → ε – T′ → ε T′ → ε F →n – – – – F → (E) – E E′ T T′ F E → T E′ – T → FT′ Erste Schritte des deterministischen LL(1)-Parsers auf der Eingabe n+(n*n)/(n-n-n): gelesen ε ε ε ε ε n n n n+ n+ n+ n+( n+( n+( n+( n+(n n+(n n+(n* n+(n* n+(n*n n+(n*n n+(n*n n+(n*n) .. . nächstes Zeichen n n n n n + + + ( ( ( n n n n * * n n ) ) ) / .. . Keller S′ E$ T E ′$ F T ′E ′$ nT ′ E ′ $ T ′E ′$ E ′$ +T E ′ $ T E ′$ F T ′E ′$ (E)T ′ E ′ $ E)T ′ E ′ $ T E ′ )T ′ E ′ $ F T ′ E ′ )T ′ E ′ $ nT ′ E ′ )T ′ E ′ $ T ′ E ′ )T ′ E ′ $ *F T ′ E ′ )T ′ E ′ $ F T ′ E ′ )T ′ E ′ $ nT ′ E ′ )T ′ E ′ $ T ′ E ′ )T ′ E ′ $ E ′ )T ′ E ′ $ )T ′ E ′ $ T ′E ′$ .. . Es ist eine gute Übung, die Tabelle zu vervollständigen. 190 Zug S′ → E E → T E′ T → FT′ F →n Lesen T′ → ε E ′ → +T E ′ Lesen T → FT′ F → (E) Lesen E → T E′ T → FT′ F →n Lesen T ′ → *F T ′ Lesen F →n Lesen T′ → ε E′ → ε Lesen ... .. . 5.3 Bottom-Up-Parsing, LR-Parsing In Abschnitt 5.2 haben wir mit dem Top-Down-Parsing oder LL-Parsing eine Methode kennengelernt, wie man (im Prinzip) zu einem gegebenen Wort w ∈ L(G) mit einem Kellerautomaten eine Ableitung und einen Ableitungsbaum entwickeln kann. In diesem Abschnitt besprechen wir einen anderen Ansatz, der denselben Effekt hat. Die Eingabewörter werden wieder von links nach rechts gelesen; im Gegensatz zum LL-Parsing wird aber eine Rechts-Ableitung erzeugt; der Ableitungsbaum entsteht von den Blättern her auf die Wurzel zu wachsend. Daher spricht man von LR-Parsing oder von BottomUp-Parsing . Der Ausgangspunkt ist derselbe wie vorher. Gegeben ist eine kontextfreie Grammatik G = (V, Σ, S, P ) und ein w ∈ Σ∗ . Wir wollen eine Ableitung und damit implizit einen Syntaxbaum konstruieren, falls w ∈ L(G) ist. Hierzu nehmen wir hier, in diesem theoretischen Rahmen, wieder den Nichtdeterminismus zu Hilfe. Wir diskutieren zum Schluss noch kurz, wie deterministische Parser aussehen, die nach dem Bottom-Up-Prinzip arbeiten. Die Grundidee ist, bei w zu beginnen und Schritt für Schritt rückwärts eine Ableitung von w zu konstruieren. Ein elementarer Schritt in diesem Vorgang ist die Reduktion“, ” das ist das Überführen eines Wortes α β γ ∈ (V ∪ Σ)∗ in α A γ, wobei A → β eine Produktion ist. In Erweiterung unserer Standardnotation könnte man αβ γ ⇐ αAγ für einen solchen Schritt schreiben. Wenn man bei w beginnt und nach Anwenden einer Reihe solcher Reduktionsschritte bei S ankommt, dann hat man gezeigt, dass w ∈ L(G) ist, und eine Ableitungsfolge rückwärts durchlaufen. Diesen Vorgang wollen wir auf einem Kellerautomaten durchführen, der w von links nach rechts liest, und zwar so, dass die Reduktionsschritte immer am oberen Kellerende stattfinden. Schematisch kann man sich das so vorstellen. Wir zeichnen einen Kellerautomaten, wobei einstweilen der Zustand keine Rolle spielen soll, so dass der Keller links steht, horizontal angeordnet, mit dem oberen Kellerende rechts. Die Eingabe wird rechts davon ebenfalls horizontal angeordnet. Anfangssituation: Eingabe a1 a2 Keller unten oben Steuereinheit 191 ......... an Zwischensituation: Eingabe ai Z r . . . . Z1 Keller ......... an gelesen Steuereinheit oben unten In einer gegebenen Situation sind zwei Arten von Aktion möglich: 1) shift“: Falls noch ungelesene Eingabebuchstaben vorhanden sind, kann das nächste ” Eingabesymbol gelesen und oben auf den Keller gelegt werden. Eingabe a Zr . . . .Z 1 a i Keller i+1 . . . . an gelesen Steuereinheit 2) reduce“: Falls die s obersten Kellersymbole Z1 , . . . , Zs , s ≥ 0, zusammen eine rechte ” Seite β = Zs . . . Z1 , s ≥ 0, einer Produktion A → β bilden, dann kann Z1 , . . . , Zs durch A ersetzt werden. Dabei wird kein Eingabezeichen gelesen. Das Wort β ∈ (V ∪ Σ)∗ am oberen Kellerende nennt man handle“ (oder Griff“) für die Reduktion. ” ” Eingabe ai Z r . . . . Z s +1 A Keller Ende: ......... an gelesen Steuereinheit Die gesamte Kellerinschrift ist ⊥S. Dann kann diese gelöscht werden. Beispiel : Folgende Produktionen, mit Startsymbol S, gehören zu einer eindeutigen kontextfreien Grammatik für die Sprache der korrekten Klammerausdrücke ohne ε: S → (S)S | () | (S) | ()S. Wir arbeiten die Eingabe nach den formulierten Regeln ab. Die Stelle in der Eingabe, an der der Lesekopf steht, ist durch einen senkrechten Strich (|) markiert. Mitunter sind ein einer Konfiguration mehrere Züge möglich. Immer wenn eine Reduktion anwendbar ist und die Eingabe noch nicht vollständig gelesen ist, könnte man auch einen Leseschritt anwenden ( shift-reduce-Konflikt“). Es kann aber auch sein, dass nicht eindeutig bestimmt ist, ” welcher Reduktionsschritt, d. h. welche Produktion, auf die Zeichen am oberen Kellerende 192 anzuwenden ist. Dies kann vorkommen, wenn es verschiedene Produktionen A → β und B → γ gibt, wo β ein Präfix von γ oder gar gleich γ ist ( reduce-reduce-Konflikt“; in der ” hier betrachteten Grammatik nicht vorliegend). Wir benutzen hier Nichtdeterminismus, um denjenigen Zug zu wählen, der zum Ziel führt. Keller Eingabe ⊥ | (())((()())()) shift: ⊥( ( | ())((()())()) shift: ⊥(( (( | ))((()())()) shift: ⊥(() (() | )((()())()) reduce: ⊥(S (() | )((()())()) shift: ⊥(S) (()) | ((()())()) shift: Griff“:() ” Griff“:(S) ” Shift-Reduce-Konflikt“ : für shift entscheiden: ” ⊥(S)( (())( | (()())()) shift: ⊥(S)(( (())(( | ()())()) shift: ⊥(S)((( (())((( | )())()) shift: ⊥(S)((() (())((() | ())()) shift: ⊥(S)((()( (())((()( | ))()) shift: ⊥(S)((()() (())((()() | )()) reduce: ⊥(S)((()S (())((()() | )()) reduce: ⊥(S)((S (())((()() | )()) shift: ⊥(S)((S) (())((()()) | ()) shift: ⊥(S)((S)( (())((()())( | )) shift: ⊥(S)((S)() (())((()())() | ) reduce: ⊥(S)((S)S (())((()())() | ) reduce: ⊥(S)(S (())((()())() | ) 193 Konflikt! → shift Konflikt! → shift shift: ⊥(S)(S) (())((()())()) | reduce: ⊥(S)S (())((()())()) | reduce: ⊥S (())((()())()) | Schlussschritt: leere den Keller (())((()())()) | ε Wenn wir parallel zu dieser Berechnung die den Reduktionsschritten entsprechenden Teile des Syntaxbaumes aufschreiben, so entsteht dieser von den Blättern beginnend nach oben auf die Wurzel zu. Wir sprechen daher von Bottom-Up-Parsing“. ” Beobachtung: Von unten nach oben gelesen, bilden die Konkatenationen Kellerinhalt Resteingabe eine Rechtsableitung für das Eingabewort w. Das liegt daran, dass shift“-Schritte die ” Konkatenation nicht ändern und dass in reduce“-Schritten ein Reduktionsschritt ange” wendet wird, der die Umkehrung eines Ableitungsschrittes ist. Wegen der Endebedingung (Kellerinhalt ⊥S) und der Anfangsbedingung (Kellerinhalt ⊥, Restwort w) handelt es sich um eine vollständige Ableitung für w. Schließlich ist in jedem Reduktionsschritt die in der jeweiligen Satzform am weitesten rechts stehende Variable betroffen, da in der Resteingabe“ natürlich nur Terminalzeichen stehen. ” Bevor wir tatsächlich sagen können, dass diese Art von Reduktion von einem NPDA durchgeführt werden kann, müssen wir noch ein technisches Problem diskutieren. Nach unserer Definition können NPDA’s nur das oberste Kellerzeichen lesen; in unserer Strategie haben wir aber so getan, als könnten wir die obersten l = max |α| A → α Produktion Kellerzeichen sehen. Dies kann man aber leicht durch die Benutzung von Zuständen der Steuereinheit simulieren. In der Steuereinheit sind (Cache-artig) stets die obersten l Kellersymbole gespeichert; nur die noch tiefer liegenden Kellereinträge stehen wirklich“ im ” Keller. Eine Kopie des ⊥-Zeichens verbleibt immer im Keller. 194 r >l Eingabe Zr Z l +1 Zl Z1 gelesen r<l Eingabe Zr Z1 gelesen Als Zustandsmenge benutzen wir [ Q= Γr , wobei Γ = {⊥} ∪ V ∪ Σ. 0≤r≤l Die Bedingung, dass der Zustand die bis zu l obersten Kellerzeichen darstellt, ist leicht aufrechtzuerhalten. Wenn in einem shift“-Schritt die Kellerhöhe wächst, muss das l-te ” Zeichen aus dem Zustand in den echten“ Keller verschoben werden. Wenn in einem ” reduce“-Schritt die Kellerhöhe sinkt, muss man mit ε-Schritten Zeichen aus dem Keller ” nachziehen“, bis dieser leer ist oder die Steuereinheit wieder l Zeichen kennt. (Die formale ” Definition von δ ist nicht schwer, nur etwas mühsam.) vorher Zr Eingabe . . . Z l +1 Zl ...Z 1 gelesen nachher Zr ... Eingabe Z l+s Z l+s +1 . . . Z s +1A gelesen Im Beispiel sind schon shift-reduce-Konflikte“ aufgetreten. Die zweite oben erwähnte Art ” von Konflikten, die eintreten, wenn in einer Konfiguration mehrere verschiedene Reduktionsschritte anwendbar sind ( reduce-reduce-Konflikt“) gibt es in der Grammatik des ” Beispiels nicht, da es keine rechten Seiten von Produktionen gibt, die gleich oder Präfix voneinander sind. Allerdings sind solche Grammatiken nicht selten. Bevor man den Shift-Reduce-Parsing-Vorgang algorithmisch einsetzt, müssen also noch Wege gefunden werden, diese Konflikte jeweils deterministisch zu entscheiden. Hierfür 195 geht man bei der Konstruktion von Parsern für Programmiersprachen folgenden Weg. Um zwischen dem ε-Zug reduce“ und einem Leseschritt ( shift“) zu entscheiden, darf der ” ” Parser die nächsten k ≥ 1 Eingabesymbole ansehen. (Man nennt dies lookahead“. Falls ” er sich für reduce“ entscheidet, wird keines dieser Zeichen verbraucht; im Fall von shift“ ” ” nur eines. Man beachte, dass technisch gesehen unser NPDA-Modell im Fall eines ε-Zuges das nächste Eingabesymbol überhaupt nicht ansieht.) Es gibt nun gewisse eindeutige2 Grammatiken (die man dann LR(k)-Grammatiken“ nennt), bei denen es möglich ist, ” mit dieser Zusatzinformation sämtliche Konflikte eindeutig aufzulösen, wobei immer die eine richtige Möglichkeit gewählt wird, die zum Ableitungsbaum bzw. zur Rechtsableitung für das Eingabewort w führt – falls w zu der Sprache, gehört, die von der Grammatik erzeugt wird. Der Algorithmus, der entscheidet, ob eine vorgelegte Grammatik eine LR(k)Grammatik ist und eventuell einen entsprechenden NPDA baut, der die beschriebene Eindeutigkeitseigenschaft hat, ist etwas komplexer. Mit dieser Problemstellung beschäftigt sich die Vorlesung Übersetzerbau“. Es gibt aber auch schon seit langem Werkzeuge, ” sogenannte Parser-Generatoren, die diese Arbeit durchführen. Es ist also in der Praxis kein Problem, eine Grammatik auf die LR(1)-Eigenschaft (oder die LR(k)-Eigenschaft) zu testen und automatisch einen entsprechenden Kellerautomaten erzeugen zu lassen. Dies leistet zum Beispiel der Parser-Generator yacc, der zu den Standardapplikationen gehört, die in jedem Unix-System enthalten sind. 5.4 Akzeptierungsmodi Die bislang betrachteten NPDA’s akzeptieren mit leerem Keller“. Alternativ (und näher ” am NFA-Modell) kann man auch den Modus Akzeptieren durch akzeptierenden Zustand“ ” betrachten. Diese Variante von NPDA’s hat eine weitere Komponente F ⊆ Q. Die Definition von Konfiguration und der Relation ⊢∗M bleibt gleich, jedoch wird w ∈ Σ∗ akzeptiert, ist also in LM , wenn (q0 , w, Z0 ) ⊢∗M (q, ε, γ) für ein q ∈ F und ein beliebiges γ ∈ Γ∗ . Das heißt, man fragt, ob von der Startkonfiguration aus das ganze Wort gelesen werden kann und dann ein akzeptierender Zustand erreicht werden kann. Die beiden Modelle sind äquivalent. Zur Übung beschreiben wir die Transformation genau. 5.4.1 Behauptung Es sei L ⊆ Σ∗ . Dann gilt: L = LM für einen NPDA M , der mit leerem Keller akzeptiert, genau dann wenn L = LM ′ für einen NPDA M ′ , der mit akzeptierendem Zustand akzeptiert. Beweis ⇒“ : Betrachte M = (Q, Σ, Γ, q0 , Z0 , δ). Wir bauen einen äquivalenten NPDA ” M ′ = (Q′ , Σ, Γ′ , q0′ , Z0′ , δ ′ ), der mit akzeptierenden Zuständen arbeitet. Die Idee ist einfach: M ′ hat ein neues Keller-Anfangssymbol Z0′ und einen neuen Startzustand q0′ . Als erste Aktion jeder Berechnung schreibt M ′ zusätzlich das Keller-Anfangs-Zeichen Z0 von M in 2 also Grammatiken, bei denen jedes ableitbare Wort genau einen Ableitungsbaum besitzt, siehe Def. 4.2.6 196 seinen Keller und geht in den Zustand q0 über. Von hier an verhält sich M ′ genau wie M . Nur wenn der Keller von M leer wäre, kann M ′ dies dadurch feststellen, dass das Keller-Zeichen Z0′ im Keller sichtbar ist. Wann immer das passiert, kann M ′ mit einem optionalen ε-Zug in einen neuen akzeptierenden Zustand qacc wechseln, von dem aus nicht weitergerechnet werden kann. Wenn M ′ dies durchführt, nachdem das Eingabewort w vollständig gelesen worden ist, wird w von M ′ akzeptiert. Formal wird diese Idee durch die folgenden Definitionen umgesetzt: Q′ = Q ∪ {q0′ , qacc }, Γ′ = Γ ∪ {Z0′ }, F = {qacc }. (i) δ(q0′ , ε, Z0′ ) = {(q0 , Z0 Z0′ )}. (ii) δ ′ stimmt auf Q × (Σ ∪ {ε}) × Γ mit δ überein. (iii) δ ′ (q, ε, Z0′ ) = {(qacc , ε)} für q ∈ Q. Es ist nicht schwer zu sehen, dass tatsächlich LM = LM ′ gilt. ⇐“ : Wir gehen von einem NPDA M ′ = (Q′ , Σ, Γ′ , q0′ , Z0′ , δ ′ , F ′ ) aus, der L mit akzep” ” tierenden Zuständen“ akzeptiert. Wir suchen einen NPDA M , der dieselbe Sprache mit leerem Keller akzeptiert. Hierfür müssen wir M ′ simulieren, und immer, wenn M ′ in einem akzeptierenden Zustand ist, die Möglichkeit eröffnen, nichtdeterministisch in einen Modus (Zustand qevac ) zu wechseln, in dem nur noch der Keller geleert wird. Hierfür definieren wir M = (Q, Σ, Γ, q0 , Z0 , δ) folgendermaßen. Die Zustandsmenge Q = Q′ ∪ {q0 , qevac } enthält einen neuen Startzustand q0 und einen Leere-den-Keller“-Zustand qevac . Das Kelleral” phabet Γ = Γ′ ∪ {Z0 } enthält einen neuen Keller-Anfangs-Zustand Z0 . Dieses besondere Zeichen dient dazu, zu verhindern, dass der Keller von M leer wird, obgleich M ′ keinen akzeptierenden Zustand erreicht hat. Die Übergangsfunktion δ wird wie folgt definiert. (i) δ(q0 , ε, Z0 ) = {(q0′ , Z0′ Z0 )}. (ii) δ stimmt auf Q′ × (Σ ∪ {ε}) × Γ′ mit δ ′ überein. (iii) zusätzlich ist(qevac , ε) ∈ δ(q, ε, Z) für q ∈ F ′ ∪ {qevac }, Z ∈ Γ′ ∪ {Z0 }. Man sieht, dass M dieselben Rechnungen wie M ′ durchführt, nur mit dem zusätzlichen Kellersysmbol Z0 . Wenn (aus Sicht von M ′ ) ein akzeptierender Zustand erreicht wurde, kann begonnen werden, den Keller, einschließlich Z0 , zu leeren, und damit M zu einer akzeptierenden Konfiguration zu führen – falls das Eingabewort fertig gelesen ist. Man beachte, dass das zusätzliche Kellersymbol Z0 verhindert, dass die Situation, wo M ′ das Eingabewort fertig liest und gleichzeitig den Keller leert, jedoch nicht in einem akzeptierenden Zustand ist, versehentlich“ zum Akzeptieren durch M führt. ” 197 5.5 Kellerautomaten und Grammatiken Wir wenden uns nun dem bereits angekündigten Äquivalenzsatz zu, der besagt, dass kontextfreie Grammatiken und NPDA’s dieselbe Sprachklasse beschreiben. Der Satz ist sehr wichtig. Von großer praktischer Bedeutung ist die Konstruktion von Parsern aus kontextfreien Grammatiken, wie in den Abschnitten 5.2 und 5.3 in Grundzügen dargestellt. Der Übergang von Kellerautomaten zu Grammatiken ist von prinzipieller und theoretischer Bedeutung. Daher werden wir (für die Neugierigen und Unerschrockenen) auch einen vollständigen Beweis angeben. (In der Vorlesung werden die Details nicht ausgeführt, und diese sind auch nicht prüfungsrelevant.) 5.5.1 Satz Sei L ⊆ Σ∗ Sprache. Dann sind äquivalent: (a) L = L(G) für eine kontextfreie Grammatik G. (b) L = LM für einen NPDA M . (a) ⇒ (b)“: Diese Richtung wurde mit Satz 5.2.2 schon gezeigt. ” (b) ⇒ (a)“: ” Es sei ein NPDA M = (Q, Σ, Γ, q0 , Z0 , δ) gegeben. Wir geben eine kontextfreie Grammatik G = (V, Σ, S, P ) an, die LM = L(G) erfüllt. Wegen der besonderen Form der Variablen von G heißt diese Konstruktion auch die Tripelkonstruktion“. Wir definieren ” Beweis V := {S} ∪ {hq, A, pi | p, q ∈ Q, A ∈ Γ}. (S ist das Startsymbol von G.) Unsere Absicht ist es, die Produktionen von G so anzulegen, dass für q, p ∈ Q, A ∈ Γ und w ∈ Σ∗ gilt: (5.5) hq, A, pi ⇒∗G w (q, w, A) ⊢∗M (p, ε, ε). ⇔ In Worten: Es gibt einen G-Ableitungsbaum mit Wurzelbeschriftung hq, A, pi und Ergebnis (Blattinschrift) w ⇔ M kann von der Konfiguration (q, w, A) (Zustand q, Restwort w zu lesen, genau das Symbol A im Keller) aus die Konfiguration (p, ε, ε) (Zustand p, w vollständig gelesen, Keller leer) erreichen. 5.5.2 Bemerkung Es ist günstig, sich gleich hier klarzumachen, dass (q, w, A) ⊢∗M (p, ε, ε) auch bedeutet, dass dieselbe Rechnung als Teilrechnung oben auf einem irgendwie gefüllten Keller und mit einem nachfolgenden Restwort möglich ist, dass also (q, wu, Aγ) ⊢∗M (p, u, γ) gilt, für beliebige u ∈ Σ∗ und γ ∈ Γ∗ . 198 Um den in (5.5) angegebenen Effekt zu erzielen, legen wir fest, dass P folgende Produktionen enthält: (i) S → hq0 , Z0 , pi, für jedes p ∈ Q. (ii) hq, A, qm+1 i → ahq1 , A1 , q2 ihq2 , A2 , q3 i · · · hqm , Am , qm+1 i, für (q, a, A) ∈ Q × (Σ ∪ {ε}) × Γ , q1 , . . . , qm+1 ∈ Q , m ≥ 0, wenn (q1 , A1 · · · Am ) ∈ δ(q, a, A). Man beachte zwei Spezialfälle: m = 0, was zur Produktion hq, A, q1 i → a führt, und a = ε, was zu einer Produktion hq, A, qm+1 i → hq1 , A1 , q2 i · · · hqm , Am , qm+1 i führt. Damit ist die Konstruktion beendet. Der Umbau von NPDA in eine Grammatik ist also überhaupt nicht schwierig (nur etwas mühsam). Etwas komplizierter (und nicht prüfungsrelevant) ist der Beweis dafür, dass die neue Grammatik die von M definierte Sprache erzeugt. Behauptung: Aussage (5.5) gilt. Bevor wir dies beweisen, folgern wir, dass L(G) = LM ist: w ∈ LM ⇔ (5.5) ⇔ ⇔ ⇔ ∃p ∈ Q : (q0 , w, Z0 ) ⊢∗M (p, ε, ε) ∃p ∈ Q : hq0 , Z0 , pi ⇒∗G w S ⇒∗G w w ∈ L(G). Die vorletzte Äquivalenz gilt dabei, weil aus S im ersten Schritt nur Variable hq0 , Z0 , pi, p ∈ Q, ableitbar sind. Es bleibt die Behauptung zu beweisen. ⇒“: Wir beweisen die Aussage ” hq, A, pi ⇒∗G w impliziert (q, w, A) ⊢∗M (p, ε, ε) durch verallgemeinerte Induktion über die Tiefe k ≥ 1 eines hq, A, pi-Ableitungsbaumes mit Blattwort w. Ist k = 1, so sieht der Ableitungsbaum für w ∈ Σ∗ so aus: <q,A,p> w 199 Damit muss hq, A, pi → w eine Regel in P sein. Nach der Definition von P kann dies nur dann passieren, wenn w = ε oder w ∈ Σ ist; weiter gilt (p, ε) ∈ δ(q, w, A). Daraus folgt aber (q, w, A) ⊢M (p, ε, ε). Sei nun k > 1. Der Ableitungsbaum für die Ableitung hq, A, pi ⇒∗G w hat folgendes Format: <q,A,p> a <q , A , q 2 > 1 ... <q , A , q > 1 m m m+1 Tiefe < k w1 wm Dabei ist m ≥ 0, q1 , . . . , qm ∈ Q, qm+1 = p, a ∈ Σ ∪ {ε} (wenn a = ε, fällt das erste Blatt weg), und w1 , . . . , wm ∈ Σ∗ sind die Einträge an den Blättern der m Teilbäume, also w = aw1 · · · wm , und hqi , Ai , qi+1 i ⇒∗G wi mittels Ableitungsbäumen der Tiefe < k. Also gilt nach Induktionsvoraussetzung (qi , wi , Ai ) ⊢∗M (qi+1 , ε, ε), für 1 ≤ i ≤ m. Also gilt mit der Regel (q1 , A1 . . . Am ) ∈ δ(q, a, A): (q, aw1 · · · wm , A) ⊢M (q1 , w1 · · · wm , A1 · · · Am ) ⊢∗M (q2 , w2 · · · wm , A2 · · · Am ) .. . ⊢∗M (qm+1 , ε, ε) = (p, ε, ε), wie gewünscht. (Man benutzt Bemerkung 5.5.2, um zu sehen, dass es legal ist, diese Teilrechnungen aneinanderzuhängen.) ⇐“: Wir beweisen die Aussage ” (q, w, A) ⊢∗M (p, ε, ε) impliziert hq, A, pi ⇒∗G w durch Induktion über die Zahl k ≥ 1 der Schritte, die M macht, um (q, w, A) in (p, ε, ε) zu überführen. Ist k = 1, so muss w ∈ Σ ∪ {ε} und (p, ε) ∈ δ(q, w, A) sein. Also ist, nach Definition von P , hq, A, pi → w eine Produktion, also gilt hq, A, pi ⇒G w. Sei nun k > 1. Wir 200 betrachten eine Rechnung, die M in k Schritten von (q, w, A) nach (p, ε, ε) führt. Wir zerlegen w = aw′ , wo a ∈ Σ oder a = ε ist, je nachdem, ob M im ersten Schritt einen Buchstaben von w liest oder nicht. Es sei (q1 , A1 · · · Am ) ∈ δ(q, a, A) das Paar in der Übergangsfunktion δ von M , das im ersten Schritt verwendet wird. Die letzten k − 1 Schritte der betrachteten Berechnung von M führen also (q1 , w′ , A1 · · · Am ) in (p, ε, ε) über. Wir teilen diese Berechnung in m Phasen (t0 , t1 ], . . . , (tm−1 , tm ] ein, wobei 0 = t0 < t1 < · · · < tm die Schritte der Rechnung von M sind, die durch folgende Ereignisse gekennzeichnet sind: ti ist der Schritt von M , nach dem erstmals Ai+1 · · · Am die Kellerinschrift ist, 1 ≤ i ≤ m. Offensichtlich dauert jede dieser Phasen < k Schritte, Mit wi , 1 ≤ i ≤ n, bezeichnen wir das Teilwort von w, das während Phase (ti−1 , ti ] von M gelesen wird. Offenbar gilt dann w′ = w1 · · · wm . Während Phase i spielt sich also folgender Konfigurationsübergang ab, für gewisse qi ∈ Q, i = 2, . . . , m: (qi , wi · · · wm , Ai · · · Am ) ⊢M · · · ⊢M (qi+1 , wi+1 · · · wm , Ai+1 · · · Am ). Da während dieser Rechnung der Teil Ai+1 · · · Am des Kellers nicht berührt, auch nicht gelesen wird, ist auch folgendes eine legale (Teil-)Rechnung des NPDA M , mit < k Schritten: (qi , wi , Ai ) ⊢M · · · ⊢M (qi+1 , ε, ε). Nach Induktionsvoraussetzung folgt hqi , Ai , qi+1 i ⇒∗G wi , für 1 ≤ i ≤ m. Da nach Definition von G auch A ⇒G ahq1 , A1 , q2 i · · · hqm , Am , qm+1 i gilt, haben wir (durch Betrachten des Ableitungsbaums): A ⇒∗G aw1 · · · wm = w. Damit ist der Beweis der Behauptung, und auch der von Satz 5.5.1, beendet. 5.6 Abschlusseigenschaften II Wir ergänzen noch eine interessante (und wichtige) Abschlusseigenschaft von L2 . 5.6.1 Satz Ist L1 kontextfrei und L2 regulär, so ist L1 ∩ L2 kontextfrei. 201 Beweis(idee): Weil L1 kontextfrei ist, gibt es nach Satz 5.5.1 und Behauptung 5.4.1 einen NPDA M , der L1 mit akzeptierenden Zuständen akzeptiert. Außerdem existiert ein DFA M ′ = (Q′ , Σ, q0′ , F ′ , δ ′ ) für L2 . Um einen NPDA M∩ für L1 ∩ L2 zu erhalten, erweitert man die Steuereinheit von M in der folgenden Weise: Es wird ein zusätzliches Register (mathematisch: eine Komponente) angelegt, die einen Zustand von M ′ speichern kann. Dieses wird anfangs mit q0′ besetzt. Bei Zügen von M , bei denen ein Buchstabe a gelesen wird, wird dieses Register gemäß δ ′ weitergeschaltet. Bei ε-Zügen bleibt der Registerinhalt unverändert. Der neue DPDA M∩ ist in einem akzeptierenden Zustand, wenn M in einem akzeptierenden Zustand ist und das Register einen Zustand q ′ ∈ F ′ enthält. Es ist nicht schwierig, den NPDA M∩ durch eine leichte Verallgemeinerung der Kreuzproduktkonstruktion (siehe Satz 2.1.10(c)) präzise zu definieren und zu zeigen, dass LM∩ = L1 ∩ L2 ist. Wir bemerken, dass es nicht möglich ist, zwei NPDA’s mit einer an die Kreuzproduktkonstruktion angelehnten Verfahren zu kombinieren. Grund ist, dass jeder NPDA seinen eigenen Keller mitbringt und es nicht möglich ist, diese beiden Keller zu einem einzigen zu vermischen“. Hier handelt es sich um eine mathematisch präzise Aussage! Wäre es im” mer möglich, auf eine solche Weise aus zwei NPDA’s einen NPDA für den Durchschnitt der zwei Sprachen zu konstruieren, dann wären die kontextfreien Sprachen unter der Durchschnittsoperation abgeschlossen, was nach Satz 4.6.4 nicht der Fall ist. Tatsächlich werden wir in der Vorlesung Berechenbarkeit und Komplexitätstheorie“ sehen, dass zwei ” unabhängige Keller zu Rechenmodellen führen, die viel stärker sind als die NPDA’s. 5.7 Deterministische Kellerautomaten und ihre Sprachen Wir betrachten hier eine Teilklasse der NPDA’s, nämlich deterministische Kellerautomaten (DPDA’s). Diese zeichnen sich dadurch aus, dass in jeder Konfiguration höchstens ein nächster Zug möglich ist. Weil dazu auch keine Wahlmöglichkeit zwischen ε-Zug und Lesen eines Symbols vom Eingabeband bestehen darf, verlangt man: (5.6) |δ(q, a, A)| + |δ(q, ε, A)| ≤ 1 für jedes q ∈ Q, a ∈ Σ, A ∈ Γ. Der Berechnungsbaum (vgl. Abb. 5.5) degeneriert zu einem Weg ohne Verzweigung. Weiterhin muss man (aus technischen Gründen) festlegen, dass über akzeptierende Zustände akzeptiert wird, wie in der in Abschnitt 5.4 besprochenen Variante. Beispiel : Wir wollen die Klammersprache mit einem deterministischen Kellerautomaten bearbeiten. Würde dieser mit leerem Keller“ akzeptieren, dann müsste zum Beispiel nach ” dem Lesen des Wortes (()) der Keller leer sein; damit ist aber das Weiterrechnen und 202 Akzeptieren auf der Eingabe (())() nicht möglich. (Allgemein können deterministische Verfahren mit Akzeptierungsmodus leerer Keller“ nicht funktionieren, wenn die zu ak” zeptierende Sprache L nicht präfixfrei ist, d. h. wenn es Wörter w1 , w2 ∈ L gibt, derart dass w1 ein echtes Präfix von w2 ist.) Ein DPDA hat also eine Menge F ⊆ Q von akzeptierenden Zuständen, und M akzeptiert w ∈ Σ∗ , wenn w vollständig gelesen wird und nach dem vollständigen Lesen von w ein akzeptierender Zustand erreicht wird. Die formalen Definitionen lauten folgendermaßen. 5.7.1 Definition Ein deterministischer Kellerautomat (DPDA) besteht aus 7 Komponenten: Q, Σ, Γ, q0 , Z0 sind wie in Definition 5.1.2, F ist Teilmenge von Q, und δ : Q × (Σ ∪ {ε} × Γ) → P<∞ (Q × Γ∗ ), wobei |δ(q, a, A)| + |δ(q, ε, A)| ≤ 1, für alle a ∈ Σ, q ∈ Q, A ∈ Γ. 5.7.2 Definition Sei M = (Q, Σ, Γ, q0 , Z0 , F, δ) ein DPDA, der (5.6) erfüllt. (a) Konfigurationen und die Relationen ⊢M und ⊢∗M sind wie in Abschnitt 5.1.5 definiert. (Man beachte, dass für jede Konfiguration k höchstens eine direkte Nachfolgekonfiguration existiert.) (b) M akzeptiert w ∈ Σ∗ , falls (q0 , w, Z0 ) ⊢∗M (q, ε, γ) für ein q ∈ F, γ ∈ Γ∗ . (c) LM = {w ∈ Σ∗ | M akzeptiert w}. Beachte: (i) Es ist erlaubt, dass M die Eingabe vollständig liest und dann noch einen oder mehrere ε-Züge durchführt, die den Keller (lesen und) verändern können und auch durch mehrere Zustände führt. Akzeptiert wird, wenn schließlich ein akzeptierender Zustand erreicht wird. (ii) Bei nicht akzeptierten Wörtern ist über das Verhalten zunächst nichts gesagt. Die Rechnung kann (ohne Nachfolgekonfiguration) in der Mitte des Wortes anhalten oder (mit ε-Zügen) in eine Endlosschleife geraten, in der sich nur noch Kellerinhalt und Zustände ändern. Dabei kann sogar der Keller immer weiter wachsen. (Wir kommen auf diese Problematik zurück.) 203 5.7.3 Beispiel Wir konstruieren einen deterministischen Kellerautomaten für die Sprache L ⊆ {(, )}∗ der korrekten Klammerausdrücke. Die grundlegende Idee ist einfach: Der Keller realisiert einen (unären) Zähler. Wenn ein (“ gelesen wird, erhöht sich der Zähler; wenn ein )“ gelesen ” ” wird, erniedrigt er sich. Dadurch wird erreicht, dass der Zählerstand den Vorsprung“ der ” gelesenen öffnenden Klammern vor den schließenden Klammern ausdrückt, der natürlich immer nichtnegativ ist. Man kann akzeptieren, wenn der Zählerstand 0 ist. Technisch arbeitet man mit dem Kelleralphabet Γ = {1, ⊥}. Dabei wird das Kelleranfangszeichen ⊥ nie gelöscht und markiert immer das Ende des Kellers. Wenn dieses Zeichen im Keller sichtbar ist, wechseln wir mit einem ε-Zug in einen akzeptierenden Zustand. Der Keller wird dadurch nicht verändert, so dass auch Weiterrechnen möglich ist. Formal legen wir den DPDA M wie folgt fest: • Q = {A, V }, • q0 = V , • Σ = {(, )}, • Γ = {1, ⊥}, • Z0 = ⊥, • F = {A}, • δ ist als Graph und als Tabelle beschrieben. (, 1 11 ε, A V Start (, 1 ), 1 ε Abbildung 5.9: Ein DPDA für die Klammersprache δ ⊥ (V, ε) (A, ⊥) (V, () − (V, )) − − (A, ε) (A, () (V, 1⊥) (A, )) − 204 1 − (V, 11) (V, ε) − − − Auf der Eingabe ()(())((()())) arbeitet dieser DPDA wie folgt: schon gelesen Keller − ⊥ − ⊥ ( 1⊥ () ⊥ () ⊥ ()( 1⊥ ()(( 11⊥ ()(() 1⊥ ()(()) ⊥ ()(()) ⊥ ()(())( 1⊥ ()(())(( 11⊥ ()(())((() 11⊥ ()(())((()( 111⊥ ()(())((()() 11⊥ ()(())((()()) 1⊥ ()(())((()())) ⊥ ()(())((()())) ⊥ Zustand V A V V A V V V V A V V V V V V V A Man beachte, wie der Keller tatsächlich immer die Anzahl der momentan geöffneten Klammern widerspiegelt, und wie der ε-Zug im Zustand V genutzt wird, um die Beobachtung, dass das Kellersymbol ⊥ sichtbar ist, in einen Zustandswechsel umzusetzen. 5.7.4 Beispiel Wir konstruieren einen Kellerautomaten für die Sprache L = {ai bj | i, j ≥ 0, i 6= j}. Hierbei ist die erste Idee, die Bedingung, dass erst a’s und dann b’s kommen sollen, im Zustand der Steuereinheit zu kontrollieren. Weiterhin zählen wir die gelesenen a’s im Keller, um dann für jedes gelesene b den Zählerstand um 1 zu erniedrigen. Solange der Zählerstand nicht 0 ist, erklären wir den Zustand für akzeptierend. Wichtig ist hier, beim Herunterzählen zunächst in einen verwerfenden Zustand zu gehen und erst dann mit einem ε-Zug in einen akzeptierenden zu wechseln, wenn sich der Keller nicht als leer erweist. Wenn der Zählerstand exakt 0 ist, muss verworfen werden; wenn dann weitere b’s folgen, können wir wieder akzeptieren. Das Kellerendezeichen ⊥ wird nie gelöscht. Formal sieht der DPDA für L folgendermaßen aus. • Q = {S, A, B, C, D}, • q0 = S, • Σ = {a, b}, 205 • Γ = {1, ⊥} • Z0 = ⊥, • F = {A, C, D}, • δ ist als Graph beschrieben. a,1 11 a, Start 1 S b, b ,1 ε A b, B D b, 1 ε ε ,1 1 C b, Abbildung 5.10: Ein DPDA für die Sprache {ai bj | i, j ≥ 0, i 6= j} Man prüfe nach, dass in diesem DPDA es nie zwei miteinander konkurrierende Züge gibt. Die Zustände S und A dienen zum Lesen von a’s, die Zustände B, C und D zum Lesen von b’s. Die Kombination der Zustände B und C realisiert das vorsichtige Lesen der b’s: erst wird gelesen und der Zähler erniedrigt (Zustand B), dann wird mit einem ε-Zug geprüft, dass der Keller nicht leer ist. Eine Beispielberechnung dieses DPDA’s sieht wie folgt aus: Eingabe: aaabbbbbbb schon gelesen Keller Zustand − − a aa aaa aaab aaab aaabb aaabb aaabbb aaabbbb aaabbbbb ... ⊥ ⊥ 1⊥ 11⊥ 111⊥ 11⊥ 11⊥ 1⊥ 1⊥ ⊥ ⊥ ⊥ ... S S A A A B C B C B D D ... 206 5.7.5 Definition Eine Sprache L heißt deterministisch kontextfrei , wenn L = LM für einen DPDA M gilt. Wir merken an, dass die Klasse der deterministisch kontextfreien Sprachen über ein Maschinenmodell definiert ist, obwohl die kontextfreien Sprachen über eine Eigenschaft der zugehörigen Grammatiken definiert ist. Gibt es auch einen Grammatiktyp, der zu den deterministisch kontextfreien Grammatiken gehört? Dies ist tatsächlich der Fall; es handelt sich um die LR(k)-Grammatiken“, für k ≥ 1. Die Definition der Klasse der LR(k)” Grammatiken ist nicht einfach syntaktisch wie bei den Typ-i-Grammatiken, i = 0, 1, 2, 3, sondern bezieht sich auf eine unendliche Menge von Situationen, die in Ableitungen auftreten können. Die Eigenschaft läuft darauf hinaus, dass ein bestimmtes deterministisches Bottom-Up-Parsing-Verfahren (siehe Abschnitt 5.3), das für das Auflösen von Shift-Reduce- und Reduce-Reduce-Konflikten die nächsten k Zeichen des Eingabewortes ansehen darf, erfolgreich arbeiten kann. Man kann aber Grammatiken algorithmisch auf diese Eigenschaft testen. LR(k)-Grammatiken mit den zugehörigen Parsern sind die mächtigsten bekannten Syntaxbeschreibungsverfahren mit Syntaxanalyse in Linearzeit“. ” Man kann zeigen (dies wäre ein Thema einer fortgeschrittenen Vorlesung über formale Sprachen), dass jede deterministisch kontextfreie Sprache sogar eine LR(1)-Grammatik hat, so dass die Grammatikklassen LR(k), k ≥ 1, alle gleichmächtig sind. Insbesondere LR(1)-Grammatiken werden bei der Konstruktion von Übersetzern für Programmiersprachen bevorzugt eingesetzt. Näheres zu diesen Grammatiken und zur Konstruktion der zugehörigen Parser erfährt man in der Vorlesung Übersetzerbau“. ” Wir notieren, dass die Klasse der deterministisch kontextfreien Sprachen unter Komplementbildung abgeschlossen ist. Sonst ist diese Klasse unter ziemlich wenigen Operationen abgeschlossen, insbesondere nicht unter Vereinigung oder Durchschnitt, Konkatenation und Kleene-Abschluss. Die Grundidee für die Konstruktion eines DPDA M ′ für LM ist einfach: Man lasse M auf Eingabe w laufen; wenn M akzeptiert, verwirft man, sonst akzeptiert man. Mit dieser Idee treten verschiedene Probleme auf. Das wichtigste davon ist, dass M auf Eingaben w∈ / LM nicht zu einem vernünftigen Abschluss der Berechnung finden muss. 5.7.6 Lemma Wenn M ein DPDA ist, dann kann man aus M einen DPDA M1 für dieselbe Sprache konstruieren, der folgende Eigenschaften hat : • M1 liest jede Eingabe w bis zum letzten Buchstaben (es gibt kein vorzeitiges Akzeptieren oder Verwerfen); • nach dem Lesen des letzten Buchstabens führt M1 nur eine begrenzte Zahl von εZügen aus (es kann nicht unendlich viele ε-Züge geben, die keinen Buchstaben der Eingabe lesen). Für einen Beweis (der etwas technisch ist) wird auf die Literatur verwiesen (z. B. [Floyd, Beigel, Die Sprache der Maschinen, Thomson 1996, S. 373ff.]). 207 5.7.7 Lemma Wenn L deterministisch kontextfrei ist, dann auch L̄. Beweis: Nach Lemma 5.7.6 gibt es einen DPDA M = (Q, Σ, Γ, q0 , Z0 , F, δ) mit L = LM , der alle Eingabewörter bis zum Ende liest und nach dem Lesen eines Eingabebuchstabens nur endlich viele Schritte macht, bevor der nächste Buchstabe gelesen wird. Die naheliegende Idee ist, in M einfach F und Q − F zu vertauschen. (Das funktioniert bei DFA’s, siehe Satz 2.1.10(e).) Es gibt aber noch ein kleines technisches Problem: M könnte nach dem Lesen von w ∈ Σ∗ noch einige ε-Schritte machen und dabei Zustände in F und Zustände in Q − F erreichen. Würde man F und Q − F einfach vertauschen, würde auch der neue DPDA w akzeptieren – fälschlicherweise. Dieses Problem ist aber leicht zu lösen. Der neue DPDA M ′ registriert (in der Steuereinheit), welche Art von Zuständen M in den ε-Zügen nach dem Lesen eines Buchstabens durchläuft. Irgendwann erreicht M eine Situation, in der kein weiterer ε-Zug möglich ist. Nun gibt es zwei Möglichkeiten: (1) Alle Zustände nach dem Lesen des letzten Buchstabens waren nicht in F . Dann wechselt M ′ mit einem ε-Zug in einen (neuen) akzeptierenden Zustand, und rechnet dann mit dem Lesen des nächsten Buchstabens weiter. (2) Nach dem Lesen des letzten Buchstabens wurde mindestens ein Zustand aus F durchlaufen. Dann rechnet M ′ einfach weiter, ohne in den akzeptierenden Zustand zu wechseln. Außer gegen Komplementbildung sind deterministisch kontextfreie Sprachen gegen keine weitere der Standard-Operationen abgeschlossen. 5.7.8 Behauptung sind. Es gibt kontextfreie Sprachen, die nicht deterministisch kontextfrei Beweis: L = {ai bj ck | i 6= j ∨ j 6= k} ist kontextfrei. (Das haben wir im Beweis von Satz 4.6.4 gesehen, Behauptung 1 über L3 .) Wäre L deterministisch kontextfrei, wäre nach 5.7.7 auch L̄ deterministisch kontextfrei, also insbesondere kontextfrei. Die Sprache L̄ ist aber nicht kontextfrei, sonst wäre nach Satz 5.6.1 L̄ ∩ {a}∗ {b}∗ {c}∗ = {an bn cn | n ≥ 0} ebenfalls kontextfrei, was nicht der Fall ist. Ein sehr naheliegendes Beispiel einer kontextfreien, aber nicht deterministisch kontextfreien Sprache ist {w | w ∈ {0, 1}∗ , w = wR }. Intuitiv gesprochen kann ein deterministischer Kellerautomat die Stelle in einem Eingabewort w nicht identifizieren, an der umzukehren“ und der Kellerinhalt mit dem bisher ” Gelesenen zu vergleichen ist. Der Beweis für diese einleuchtende Tatsache ist allerdings technisch aufwendig. 5.7.9 Behauptung ∩ abgeschlossen. Die deterministisch kontextfreien Sprachen sind nicht gegen ∪ und 208 L1 = {ai bj ck | i 6= j} und L2 = {ai bj ck | j 6= k} sind deterministisch kontextfrei (Beweis von Satz 4.6.4); aber L1 ∪ L2 ist nicht deterministisch kontextfrei (Beweis von Behauptung 5.7.8). Beweis: L3 = {ai bj ck | i = j} und L4 = {ai bj ck | j = k} sind deterministisch kontextfrei; aber L3 ∩ L4 ist nicht kontextfrei. (Vgl. Beweis von Satz 4.6.4.) 5.7.10 Behauptung Die deterministisch kontextfreien Sprachen sind nicht gegen Konkatenation und Kleene-Abschluss abgeschlossen. (Ohne Beweis.) 5.7.11 Satz Die deterministisch kontextfreien Sprachen sind gegen Durchschnitt mit regulären Sprachen abgeschlossen. (D. h.: L1 deterministisch kontextfrei, L2 regulär ⇒ L1 ∩ L2 deterministisch kontextfrei.) Dies beweist man genauso wie Satz 5.6.1. 5.8 Entscheidungsfragen für kontextfreie Sprachen Ebenso wie bei regulären Sprachen kann man sich fragen, welche Eigenschaften der Sprache L(G) man anhand der Grammatik G effizient – oder zumindest effektiv, also algorithmisch – testen kann. Dabei stellt sich heraus, dass viele Probleme bezüglich kontextfreier Grammatiken unentscheidbar werden. Das bedeutet, dass es prinzipiell keinen Algorithmus geben kann, der dieses Problem für alle Grammatiken lösen kann. Den technischen Hintergrund für Unentscheidbarkeitsaussagen werden wir jedoch erst in der Vorlesung Berechenbarkeit und Komplexitätstheorie“ kennenlernen. Daher werden hier alle Unent” scheidbarkeitsaussagen (einstweilen) ohne Beweis bleiben. 5.8.1 Satz lösbar : Die folgenden Aufgaben bezüglich kontextfreier Sprachen sind algorithmisch (a) (Leerheitsproblem) Gegeben eine kontextfreie Grammatik G = (V, Σ, S, P ), entscheide ob L(G) = ∅ ist. (b) (Wortproblem) Gegeben eine kontextfreie Grammatik G = (V, Σ, S, P ) und ein w ∈ Σ∗ , entscheide ob w ∈ L(G), und finde im positiven Fall einen Ableitungsbaum. (c) (Unendlichkeitsproblem) Gegeben eine kontextfreie Grammatik G, entscheide ob |L(G)| = ∞ ist. 209 Beweis: (a) Nach Proposition 4.3.14(c) genügt es, mit dem dort angegebenen Markierungsalgorithmus die Menge der produktiven Variablen in V zu bestimmen. Die Sprache L(G) ist nicht leer genau dann wenn S produktiv ist. (b) Man wandelt G in eine äquivalente Grammatik G′ in Chomsky-Normalform um (s. Abschnitt 4.3). Dann wendet man auf G′ und w den CYK-Algorithmus an, der in Abschnitt 4.5 besprochen wurde. (c) Mit dem Algorithmus aus Abschnitt 4.3 wandeln wir G in eine äquivalente Grammatik G′ = (V ′ , Σ, S ′ , P ′ ) in Chomsky-Normalform um. Mit dem Algorithmus zu Proposition 4.3.14 ermitteln wir die Menge der produktiven Variablen in V ′ . Wenn S ′ nicht produktiv ist, ist L(G) = ∅, und wir sind fertig. Sonst lassen wir aus V ′ die nicht produktiven (die nutzlosen“) Variablen weg, und erhalten eine zu G äquivalente Grammatik ” G′′ = (V ′′ , Σ, S ′ , P ′′ ) in Chomsky-Normalform, die keine nutzlosen Variablen hat. Mit einem weiteren Markierungsalgorithmus ermitteln wir nun die Menge V ′′′ aller Variablen A ∈ V ′′ , die in einer Satzform α von G′′ vorkommen, also mit einer Ableitungsfolge S ⇒G′′ α1 ⇒G′′ α2 ⇒G′′ · · · ⇒G′′ αt = α erreichbar sind. (Die Details möge man sich als Übung überlegen.) Wenn wir aus G′′ die nicht erreichbaren Variablen weglassen und alle Produktionen streichen, in denen solche Variablen vorkommen, erhalten wir eine zu G äquivalente Grammatik G′′′ = (V ′′′ , Σ, S ′ , P ′′′ ), in der jede Variable erreichbar und produktiv ist. Zur Vereinfachung der Notation nehmen wir ab hier einfach an, dass L(G) 6= ∅ ist und dass V keine nutzlosen und keine unerreichbaren Variablen enthält. Nun definieren wir einen gerichteten Graphen H = (V, E) mit Knotenmenge V und Kantenmenge E := {(A, B) ∈ V × V | ∃C ∈ V : A → BC oder A → CB ist Produktion}. Mit einem geeigneten Graphalgorithmus oder auch einem simplen Markierungsalgorithmus können wir überprüfen, ob es r ≥ 1 und eine Folge A0 , A1 , . . . , Ar in V gibt mit A0 = Ar und (A0 , A1 ), . . . , (Ar−1 , Ar ) ∈ E. (Diese Kantenfolge bildet also einen gerichteten Kreis der Länge r im Graphen H.) Dieser Test liefert die gewünschte Antwort, wie die folgende Behauptung feststellt. Behauptung: |L(G)| = ∞ ⇔ H besitzt einen gerichteten Kreis. Beweis der Behauptung: “⇒“: Wenn H keinen Kreis besitzt, dann besitzt jeder Weg in einem Ableitungsbaum von G höchstens |V | viele innere Knoten. Es gibt aber nur endlich viele Binärbäume der Tiefe ≤ |V | mit Knotenmarkierungen aus V , also lässt G nur endlich viele Ableitungsbäume zu. Also ist L(G) endlich. “⇐“: Angenommen, H besitzt einen Kreis A0 , A1 , . . . , Ar = A0 . Nun bauen wir einen Ableitungsbaum in G wie folgt: 210 1. Bilde einen Ableitungsbaum T mit Wurzelbeschriftung S für eine Satzform α(T ), in der A0 vorkommt. (Dies geht, weil jede Variable, also auch A0 , erreichbar ist.) Das heißt, dass T einen Blattknoten k1 hat, der mit A0 beschriftet ist. 2. Bilde einen A0 -Ableitungsbaum T1′ mit Wurzelbeschriftung A0 , der nicht nur aus der Wurzel besteht und ein Wort α(T1 ) als Ergebnis hat, in dem A0 vorkommt. (Dies geht mit den Produktionen, die den Kreis A0 , A1 , . . . , Ar = A0 in H erzeugen.) 3. Füge T1′ in T ein, indem die Wurzel von T1′ mit k1 identifiziert wird. Das Resultat ist der Baum T ′ . Der Blattknoten in T1′ , der mit A0 beschriftet ist, heiße k2 . 4. Wenn k ein Blatt von T ′ ist, das mit einer Variablen A beschriftet ist, so ergänze unter k einen A-Ableitungsbaum, dessen Blätter mit Terminalzeichen beschriftet sind. (Dies geht, weil A produktiv ist.) 5. Der resultierende Ableitungsbaum heiße T0 . Der Unterbaum mit Wurzel k1 heißt T1 ; der Unterbaum von T1 mit Wurzel k2 heißt T2 . Nun haben wir eine Situation erreicht, die der im Beweis des Pumping-Lemmas (Satz 4.4.1) entspricht. Wenn wir w = α(T2 ) setzen und v und x so wählen, dass α(T1 ) = vwx, und schließlich u und y so, dass uvwxy = α(T0 ) ist, so können wir genau wie im Beweis des Pumping-Lemmas schließen, dass |vx| ≥ 1 ist und alle Wörter uv i wxi y ∈ L(G) sind. Diese Wörter sind alle verschieden; also ist L(G) unendlich. 5.8.2 Satz Die folgenden Aufgaben bezüglich NPDA’s sind algorithmisch lösbar: (a) (Leerheitsproblem) Gegeben ein NPDA M , entscheide ob LM = ∅ ist. (b) (Wortproblem) Gegeben ein NPDA M und ein w ∈ Σ∗ , entscheide ob w ∈ LM , und finde im positiven Fall eine akzeptierende Berechnung von M auf x. (c) (Unendlichkeitsproblem) Gegeben ein NPDA M , entscheide ob |LM | = ∞ ist. Beweis: Aus Satz 5.5.1 wissen wir, dass man aus M eine kontextfreie Grammatik G (in Chomsky-Normalform) mit L(G) = LM konstruieren kann. Auf diese Grammatik wenden wir die Algorithmen aus Satz 5.8.1(a), (b) und (c) an. Wenn wir in Aufgabe (b) herausfinden, dass w ∈ LM ist, dann probieren wir systematisch alle Berechnungen von M auf Eingabe w durch, die t Schritte machen, für t = |w|, |w| + 1, |w| + 2, . . ., bis wir eine akzeptierende Berechnung finden. Bemerkung: Man beachte das vosichtige Vorgehen in (b). Es genügt nicht, den NPDA einfach alle möglichen Berechnungen durchprobieren zu lassen, da es für ein Wort w ∈ /L möglicherweise unendlich viele Berechnungen gibt und man nie feststellt, dass es keine akzeptierende Berechnung gibt. 211 Natürlich sind dieselben Fragen für DPDA’s im Prinzip mit denselben Algorithmen lösbar, da DPDA’s nur ein Spezialfall von NPDA’s sind. Im Fall des Wortproblems gibt es für DPDA’s einen einfacheren Algorithmus. Gegeben einen DPDA M und ein Eingabewort w, bauen wir M nach den in Lemmas 5.7.6 und 5.7.7 erwähnten Methoden in einen zu M äquivalenten DPDA M ′ um, der seine Eingabe w vollständig liest und dann mittels seines Zustandes mitteilt, ob w ∈ LM oder nicht. Damit lässt sich das Wortproblem dann direkt lösen, ohne den DPDA in eine Grammatik umzuformen. Weiter kann man für einen DPDA M algorithmisch testen, ob LM = Σ∗ ist. (Man baut mit der Methode der eben erwähnten Lemmata einen DPDA M ′ für LM und testet, ob LM ′ = ∅.) Zum Abschluss wollen wir noch einige algorithmisch unentscheidbare“ Eigenschaften von ” kontextfreien Sprachen diskutieren. Eine Eigenschaft“ ist dabei einfach eine Aussage, ” die auf kontextfreie Grammatiken zutreffen kann oder nicht, beispielsweise die Aussagen L(G) ist endlich“ oder G ist mehrdeutig“. ” ” Zunächst erklären wir: 5.8.3 Erklärung Eine Eigenschaft E von kontextfreien Grammatiken heißt unentscheidbar , wenn es keinen Algorithmus A gibt, der zu jeder vorgelegten kontextfreien Grammatik G als Eingabe die Antwort ja“ liefert, wenn G die Eigenschaft E hat, und ” nein“ sonst. ” Die Erklärung des Begriffs unentscheidbar“ muss momentan noch etwas vage und ma” thematisch ungenau bleiben, weil wir den Begriff Algorithmus“ nicht präzise definiert ” haben (und dies auch gar nicht können). In der Vorlesung Berechenbarkeit und Komple” xitätstheorie“ wird gezeigt, wie man den intuitiven Algorithmusbegriff durch eine formale Definition ersetzen kann, so dass die Behauptung es gibt keinen Algorithmus“ mathema” tischer Argumentation zugänglich wird. Natürlich kann man genauso über Eigenschaften anderer Dinge, wir NPDA’s oder DPDA’s sagen, sie seien unentscheidbar. Manchmal bezeichnet man auch eine Eigenschaft von kontextfreien Sprachen als unentscheidbar (z. B. sagt man, die Eigenschaft L = Σ∗“ oder ” L ist regulär“ sei für kontextfreie Sprachen unentscheidbar“). Dann ist aber implizit ” ” immer gemeint, dass die Sprachen durch eine endliche Beschreibung wie eine Grammatik oder einen Kellerautomaten gegeben sein müssen. Wenn eine Eigenschaft von Grammatiken unentscheidbar ist, dann bedeutet dies insbesondere, dass es prinzipiell kein Debugging-Tool“ geben kann, das das entsprechen” de Entscheidungsproblem allgemein und für jede Grammatik löst. Beispielsweise ist die Eigenschaft G ist mehrdeutig“ unentscheidbar. Das bedeutet, dass jeder menschliche ” Grammatik-Designer, aber auch automatische Grammatik-Konstruktions-Verfahren auf andere Weise sicherstellen müssen, dass eine neu konstruierte Grammatik nicht versehentlich mehrdeutig wird. Wir geben nun einige unentscheidbare Fragen im Zusammenhang mit kontextfreien Sprachen an. Für die Beweise (Auswahl) verweisen wir auf die Vorlesung Berechenbarkeit ” 212 und Komplexitätstheorie“. 5.8.4 Satz (Unentscheidbare Fragen für zwei kontextfreie Grammatiken) Folgende Probleme sind unentscheidbar : Gegeben seien zwei kontextfreie Grammatiken G1 und G2 . (a) Ist L(G1 ) ∩ L(G2 ) = ∅? (b) Ist L(G1 ) = L(G2 )? 5.8.5 Satz (Unentscheidbare Fragen für eine kontextfreie Grammatik) Folgende Probleme sind unentscheidbar : Gegeben sei eine kontextfreie Grammatik G. (a) Ist G mehrdeutig? (b) Ist L(G) inhärent mehrdeutig? (c) Ist L(G) kontextfrei ? (d) Ist L(G) deterministisch kontextfrei? (e) Ist L(G) regulär ? Wir bemerken, dass die Unentscheidbarkeit sich auf NPDA’s überträgt, da man nach Satz 5.5.1 Grammatiken und NPDA’s algorithmisch ineinander umformen kann. Wir benennen noch den Entscheidbarkeitsstatus dreier Fragen zu DPDA’s. Der Status des Äquivalenzproblems bildete jahrzehntelang ein (berühmtes) offenes Problem, bis er 1997 geklärt wurde. 5.8.6 Satz (Entscheidungsfragen für DPDA’s) (a) (Schnittproblem) Es ist unentscheidbar, ob für gegebene DPDA’s M1 und M2 gilt, dass LM1 ∩ LM2 = ∅. (b) (Äquivalenzproblem) Es gibt einen Algorithmus, der zu gegebenen DPDA’s M1 und M2 entscheidet, ob LM1 = LM2 gilt. (G. Sénizergues, 1997.) (c) (Regularitätsproblem) Es gibt einen Algorithmus, der zu einem gegebenen DPDA M entscheidet, ob L(M ) regulär ist. 213