6.7 LR-Grammatiken
Motivation und Intuition
Die LL-Parser, die wir in Kapitel 5.4 gesehen haben,
versuchen, eine Linksableitung Schritt für
Schritt zu konstruieren. Eine Hauptschwäche ist, dass Sie von
einer Wortform
die nächste Ableitungsregel bestimmen müssen,
ohne das "Endergebnis" von überhaupt vollständig gelesen zu haben.
Sie müssen also erkennen, dass der rote / mit "?" markierte Pfeil in der Ableitung
die richtige Entscheidung ist, obwohl sie von dem aus abgeleiteten
Wort nur die ersten Buchstaben sehen.
Dem entgegen haben wir in den letzten zwei Teilkapiteln LR-Parser gesehen.
Diese versuchen, von ausgehend eine Rechtsableitung zu finden,
allerdings in zeitlich umgekehrter Reihenfolge, also
Notation
Da aus der Sicht unseres neuen Parsers die Rückwärtsanwendung einer Produktion
, also der Schritt
einen Fortschritt
darstellt und zeitlich auch
nach vorne geht, verwende ich ab jetzt ein neues Pfeilsymbol, das
von links nach rechts geht und daher dem in Europa üblichen Gefühlt,
dass die Zeit von links nach rechts verläuft, mehr entgegen kommt:
.
Definition 6.7.1
(Reduktion und Linksreduktion)
Seien
Wortformen und
eine Produktion. Dann schreiben wir
und sagen
reduziert zu .
Man nennt einen solchen Schritt auch einen
Reduktionsschritt.
Wir nennen den Schritt einen Linksreduktionsschritt, wenn
rechts von nur Terminale stehen. Wenn also
und somit
Eine Folge von Linksreduktionsschritten nennen wir eine
Linksreduktion.
Links, weil wir uns
von links nach rechts in den terminalen Teil hineinarbeiten.
Wir werden im folgenden nur Linksreduktionsschritte betrachten und
sagen daher manchmal auch einfach nur Reduktionsschritt.
Beobachtung: Wenn wir
einen Linksreduktionsschritt
betrachten, also
so sehen wir, dass das am weitesten rechts stehende Nichtterminal
ersetzt worden ist; Linksreduktionen
entsprechen also einer Rechtsableitung.
In den vorherigen Kapiteln, insbesondere beim Implementieren eines Parsers, haben wir gesehen,
dass nicht jeder Linksreduktionsschritt automatisch auch korrekt ist.
Ein einfaches Beispiel war die "Zahlengrammatik"
So ist folgende Linksreduktion korrekt:
weil sie einer gültigen Rechtsableitung entspricht ( ist das Startsymbol).
Folgende Reduktionen sind
allerdings inkorrekt:
da zwar , allerdings es keine Rechtsableitung gibt.
Auch
ist inkorrekt. In unserer Java-Implementierung haben wir dieses Problem händisch gelöst, indem
wir der Regel den Vorzug vor gegebene haben. Im allgemeinen
müssen wir definieren, was ein korrekter Linksreduktionsschritt ist. Und dann
überlegen, wie wir herausfinden, ob ein Linksreduktionsschritt korrekt ist. Diese Fragen
werden uns für den Rest dieses und des nächsten Teilkapitels beschäftigen.
Definition 6.7.2
(Gültige Wortform, korrekter Reduktionsschritt)
Eine Wortform heißt
gültig,
wenn es eine Rechtsableitung
gibt. Ein Linksreduktionsschritt
heißt
korrekt, wenn gültig ist.
In diesem Fall ist natürlich selbst gültig.
Den Präfix nennen wir eine
Front der gültigen Wortform .
Wenn die Grammatik eindeutig ist, dann hat
jede gültige Wortform genau eine Front, die wir
mit bezeichnen.
Wenn wir uns erinnern, wie wir in den letzten zwei Teilkapiteln informell LR-Parser
entworfen und implementiert haben, dann sehen wir, dass in einem
Linksreduktionsschritt die
Front
der Stackinhalt ist und der bis jetzt ungelesene Teil des Eingabewortes.
Wir wünschen wir uns folgendes:
Wunsch.
Ob gültig ist oder nicht,
wollen wir allein auf Grund der Front entscheiden können, das heißt,
ohne betrachten zu müssen.
Wir haben allerdings bereits gesehen, dass das nicht immer möglich ist. Bei der Implementierung
von
ArithmeticGrammar.java
zum Beispiel
haben wir manchmal das erste Zeichen von betrachten müssen. Allerdings behalten wir erst
einmal obigen Wunsch als Idealziel.
Um ihn zu formalisieren, fragen wir uns, wann es denn nicht möglich ist,
ohne Betrachten von zu eintscheiden, ob
gültig ist.
Schlechter Fall 1:
Es gibt für eine Wortform zwei
korrekte Linksreduktionsschritte:
und
.
In diesem Falle gäbe es zwei verschiedene
Rechtsableitungen
(wir nehmen an, dass man aus jedem Nichtterminal
mindestens ein Wort ableiten kann; andernfalls
kann man solche nutzlosen Nichtterminale eliminieren).
Das Wort hat also zwei verschiedene Ableitungsbäume.
Die Grammatik ist somit mehrdeutig.
Mit uneindeutigen Grammatiken beschäftigen wir uns zunächst gar nicht;
sie sind von einem praktischen Standpunkt aus auch
unattraktiv: wenn z.B. eine Programmiersprache eine mehrdeutige Grammatik
hätte, dann wäre ja für gewisse Programme nicht eindeutig
festzustellen, was damit gemeint ist.
Wir nehmen also an, dass die Grammatik eindeutig ist und somit
dieser Fall nicht eintreten kann.
Schlechter Fall 2:
Der Linksreduktionsschritt
ist korrekt, aber für ein anderes ist
nicht korrekt, obwohl eine
gültige Wortform ist.
Dieser Fall ist schlecht, weil der Parser nur
gelesen hat und somit nicht
weiß, ob es sich bei der gesamten Wortform
um oder um
handelt. Da beide gültig sind, können ja auch
beide in einer Linksreduktion auftreten.
Korrektheit hängt also davon ab, was weiter rechtskommt.
Beispiel 6.7.3
Erinnern Sie sich: unsere obige Grammatik
ist eindeutig (das ist leicht zu sehen), allerdings tritt
Schlechte Fall 2 ein: der Reduktionsschritt
ist korrekt (hier also , aber leider ist
nicht korrekt (hier , da gültig ist,
aber nicht. Die Entscheidung für eine Reduktionsregel
kann also nicht ohne Wissen über das, was dahinter kommt,
getroffen werden.
Wir definieren nun eine Klasse von Grammatiken, bei denen diese schlechten Fälle nicht
auftreten.
Definition 6.7.4
(-Grammatiken)
Eine kontextfreie Grammatik heißt -Grammatik,
wenn keiner der obigen schlechten Fälle eintritt.
Formal, wenn (1) die Grammatik eindeutig ist und (2) wenn ein
korrekter Linksreduktionsschritt
bedeutet, dass auch alle anderen Linksreduktionsschritte
korrekt sind, sofern ist und selbst eine gültige
Wortform ist.
In Worten/Graustufen: wenn wir
guten Gewissens anwenden dürfen, ohne auch nur ein Zeichen von
gelesen zu haben, sofern wir sicher sind, dass es irgendein gibt, das
zu einer gültigen Wortform macht.
Lemma 6.7.5
(LR(0), äquivalente Formulierung).
Eine Grammatik ist LR(0) genau dann, wenn für
alle korrekten Linksreduktionsschritte
und
gilt:
- Falls dann
auch und ; in Worten:
wenn die Fronten identisch sind, dann auch die
Reduktionsschritte.
-
Wenn und
, dann
; in Worten: wenn
ein echter Präfix von
ist, dann muss in dem überstehenden Teil von
mindestens ein
Nichtterminal vorkommen.
Beweis.
Der Beweis ist leider etwas mechanisch und
repetitiv. Aber vielleicht ist es eine
gute Übung, ihn genau durchzugehen, um die
Definitionenen Linksreduktion, gültige Wortform etc.
zu verinnerlichen. Ich bin auch immer noch auf der Suche nach
einem knapperen, klareren Beweis, der nicht so viele
Fallunterscheidungen enthält.
Wenn-Dann-Richtung.
Wenn eine LR(0)-Grammatik ist, dann gelten
die Schlussfolgerungen des Lemmas.
Beweis. Um Punkt 1 zu zeigen,
nehmen wir an, dass gilt.
Da korrekt
ist, eine gültige Wortform ist und
eine LR(0)-Grammatik ist, so ist auch
ein korrekter Linksreduktionsschritt. Also sind
und
beides
korrekte Linksreduktionsschritte. Da eindeutig ist,
kann es nur eine Rechtsableitung geben, d.h.
, was und
somit impliziert.
Um Punkt 2 zu zeigen, nehmen wir an, dass
gilt.
Falls - entgegen der Schlussfolgerung - nun
gälte, wäre
ein korrekter Linksreduktionsschritt; nach Voraussetzung
ist auch
korrekt. Es gäbe also zwei korrekte Linksreduktionsschritte
und wäre nicht eindeutig. Wir folgern,
dass . Beachten Sie,
dass es, wenn Nichtterminale enthält, keinen
Widerspruch gibt: dann ist nämlich
gar kein Linksreduktionsschritt, geschweige denn ein
korrekter.
Nur-dann-Richtung.
Wenn die Grammatik die
Schlussfolgerungen des Lemmas erfüllt und
müssen zeigen, dass sie auch LG(0).
Beweis.
Als erstes zeigen wir, dass eindeutig ist; dass es
also für jede gültige Wortform genau einen korrekten
Linksreduktionsschritt gibt.
Dafür nehmen wir dann, dass es von aus
die Linksreduktionsschritte
gibt und müssen zeigen, dass es sich in der Tat um denselben
Schritt handelt. Ohne Beschränkung der Allgemeinheit
ist und
wir schreiben .
Da ein Präfix von ist und ,
so gilt auch .
Nach Punkt 2 der Schlussfolgerung muss also
gelten. Es ist also . Nach Punkt 1
der Schlussfolgerung gelten nun also auch ,
und und somit auch . Es handelt
sich um ein und den selben Linksreduktionsschritt. Die
Gramatik ist eindeutig.
Um den zweiten Punkt der LR(0)-Eigenschaft zu zeigen,
nehmen wir an, dass
ein korrekter Linksreduktionsschritt ist und
eine gültige Wortform ist mit .
Wir müssen zeigen,
dass auch gültig ist. Da eindeutig ist,
gibt es einen eindeutigen korrekten Linksreduktionsschritt
Da und beides
Präfixe von sind, gibt es drei Fälle:
(1) ;
(2)
mit ;
(3)
mit .
(1) Wenn nun gilt, dann
sind nach Punkt 1 der Schlussfolgerung
und und
; also ist
und auch und somit .
Somit ist und letztere ist
eine gültige Wortform.
(2) Wir haben zwei korrekte Linksreduktionsschritte
und
. Nach Punkt 2
der Schlussfolgerung des Lemmas
mindestens ein Nichtterminal enthalten. Das
kann aber nicht sein, da ein Präfix von
ist. (3) kann aus dem gleichen Grund nicht gelten.
Wir haben nun beide Richtungen gezeigt und somit
das Lemma bewiesen.
Übungsaufgabe 6.7.1
Zeigen Sie, dass die folgende Grammatik ist:
Als ersten Schritt sollten Sie sich überlegen, wie gültige
Wortformen überhaupt aussehen können.
Übungsaufgabe 6.7.2
Wir ändern die Grammatik etwas ab:
Die erzeugte Sprache ist .
Zeigen Sie, dass die Grammatik nicht ist.
Übungsaufgabe 6.7.3
Zeigen Sie, dass die folgende Grammatik ist:
Als ersten Schritt sollten Sie sich überlegen, wie gültige
Wortformen überhaupt aussehen können.
Algorithmische Fragen
Es stellen sich unmittelbar zwei zentrale Fragen:
- Wie können wir verifizieren, ob eine gegebene Grammatik
die -Bedingung erfüllt?
-
Falls sie es tut, wie können wir für eine gegebene gültige Wortform
den korrekten Reduktionsschritt
finden? Insbesondere die Zerlegung in
?
Beide Aufgaben können mit Hilfe eines endlichen Automaten,
des DK-Automaten erledigt werden (DK steht als Abkürzung für Donald Knuth,
der als erstes diese Idee hatte).
Hinweis. Was nun folgt, ist mathematisch
recht herausfordernd. Lesen Sie daher gerne auch
das Kapitel 2.4 (Deterministic context free languages) im Lehrbuch
Introduction to the Theory of Computing von Michael Sipser.
Meine Darstellung des doch recht schwierigen Materials fußt auf diesem
Kapitel, weicht aber doch stark genug von Sipser ab, so dass es
womöglich hilfreich ist, beides zu lesen: dieses Vorlesungsskript und
das Kapitel in Sipers Buch.