Earley-Algorithmus
aus Wikipedia, der freien Enzyklopädie
Der Earley-Algorithmus ist in der Informatik ein Algorithmus, der entscheidet, ob ein Wort von einer kontextfreien Grammatik erzeugt werden kann. Er wurde 1970 von Jay Earley entwickelt. Er ähnelt dem Cocke-Younger-Kasami-Algorithmus und löst wie dieser das Wortproblem der kontextfreien Sprachen. Er verwendet dynamische Programmierung.
Inhaltsverzeichnis |
[Bearbeiten] Verwendung
Eine Aufgabe eines Compilers ist es, zu überprüfen, ob der eingegebene Quelltext der Syntax der Programmiersprache entspricht. Dies entspricht dem Lösen des Wortproblems. Da die meisten Programmiersprachen kontextsensitiv sind, werden dabei bestimmte Bedingungen zunächst ignoriert. Dadurch kann man erreichen, dass nur das wesentlich einfachere (nicht NP-vollständige) Wortproblem der kontextfreien Sprachen gelöst werden muss. Die kontextsensitiven Nebenbedingungen, wie etwa die Vollständigkeit der Variablendeklarationen müssen dann mit einem anderen Algorithmus geprüft werden. So wird der erste Schritt der Syntaxprüfung auf das Wortproblem der kontextfreien Sprachen zurück geführt. Diese wird vom Earley-Algorithmus und auch vom CYK-Algorithmus erreicht. Beide sind optimal, um das Problem für eine allgemeine Sprache zu lösen. Der Earley Algorithmus hat jedoch den Vorteil, dass keine Umwandlung der Grammatik in Chomsky-Normalform nötig ist.
In der Praxis versucht man meist, den relativ hohen Rechenaufwand der beiden Algorithmen zu vermeiden oder zu reduzieren. Man optimiert dabei den Compiler speziell an die verwendete Programmiersprache und kann so oft einen geringeren Berechnungsaufwand erreichen. Besonders große Verbesserungen können dabei erreicht werden, wenn man die Syntax der Programmiersprache so weit einschränkt, dass sie LR1- oder sogar LL1-Eigenschaften hat.
[Bearbeiten] Algorithmus
Der Algorithmus benötigt als Eingabe eine kontextfreie Grammatik und ein Wort über dem selben Alphabet. Er entscheidet dann, ob die Grammatik das Wort erzeugen kann. Dabei geht er nicht wie der CYK-Algorithmus 'rückwärts' wieder zum Startsymbol der Grammatik, sondern versucht das Wort zeichenweise zu erzeugen. In jedem Berechnungsschritt versucht er also, ein Zeichen des Wortes weiter zu kommen, bis das ganze Wort erzeugt ist. In einem solchen Fall ist das Wort von der Grammatik erzeugbar. Falls das Wort nicht erzeugbar (also nicht in der Sprache enthalten) ist, bricht der Algorithmus ab, da er an einem Zeichen ankommt, das er nicht vorhersagen kann. Bei der Eingabe eines Wortes verwendet der Algorithmus die Zustandsmengen
. Ein Zustand des Algorithmus ist dabei eine Produktion, deren rechte Seite durch einen Punkt
zerlegt ist. Alle Zeichen vor diesem Punkt gelten als schon überprüft. Eine solche Produktion
ist in einer Zustandsmenge Qj enthalten und durch einen zusätzlichen Zähler i gekennzeichnet. Dieser bestimmt, aus welcher Menge die Produktion ursprünglich stammt, damit der Algorithmus mit Rekonstruktionschritten schnell einen Ableitungsbaum erzeugen kann.
Am Anfang wird gesetzt. Dabei ist S das Startsymbol der Grammatik. Der Algorithmus läuft nun Zeichen für Zeichen und wendet im i ten Schritt immer die drei folgenden Regeln an:
- Voraussage: falls
in Qi enthalten ist, wird für jede Produktion
aus der Grammatik
zu Qi hinzugefügt.
- Eingabeüberprüfung: falls
und c = ai, wird
zu Qi hinzugefügt.
- Rekonstruktion: falls
existiert werden alle
für die ein
existiert zu Qi hinzugefügt.
Genau dann wenn am Ende in der Zustandsmenge Qn enthalten ist, kann die Grammatik das Wort erzeugen.
[Bearbeiten] Beispiel
Die Dyck-Sprache D1 der korrekt geklammerten Ausdrücke mit nur einer Art Klammern wird von dieser kontextfreien Grammatik erzeugt:
Bei Eingabe des Wortes ()(()) läuft der Algorithmus folgendermaßen ab:
- In Q0:
-
- Die Voraussagen für S:
(V)
(V)
(V)
(V)
- In Q1:
- Zuerst alle Eingabeüberprüfungen
(E)
(E)
(E)
(E)
- Jetzt ist es möglich A vorauszusagen. Dieses A ist kann dann ab dem zweiten Zeichen eingesetzt werden. Es 'kommt' also sozusagen aus Q1, daher wird der Zähler auf 1 gesetzt.
(V)
(V)
(V)
- Wegen der Epsilonproduktion ist das Nichtterminal A hier fertig produziert. Es ist also schon ein Rekonstruktionsschritt möglich:
(R)
(R)
Weitere Schritte sind nicht möglich,
- Also geht es weiter in Q2:
- wieder zuerst die Vorhersagen, das aktuelle Zeichen ist ')':
(E)
(E)
(E)
(E)
- alle anderen Regeln lassen sich hier nicht anwenden.
- In Q3:
- Nur bei einer Produktion lässt sich das richtige Zeichen einlesen:
(E)
- Jetzt können neue Vorhersagen für A gemacht werden:
(V)
(V)
(V)
(R)
- In Q4:
(E)
(E)
- A wird wieder vorhergesagt:
(V)
(V)
(V)
(R)
(R)
- In Q5:
(E)
(E)
- Da das obere A fertig eingelesen ist, dann jetzt aus Q3 rekonstruiert werden
(R)
- In Q6:
(E)
- Das Startsymbol wurde also komplett gelesen.
kann also rekonstruiert werden.
(R)
Damit ist das Wort in der Dycksprache enthalten.
[Bearbeiten] Literatur
[Bearbeiten] Weblink
Vorlesungsskript mit Beispielen und Korrektheitsbeweis (pdf)