archetype | title | linkTitle | author | readings | outcomes | attachments | |||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
lecture-bc |
Syntaxanalyse: LR-Parser (LR(0), LALR) |
LR-Parser |
BC George (HSBI) |
|
|
|
-
Baumaufbau von oben nach unten
-
eine Möglichkeit: recursive-descent parser
-
alternativ: tabellengesteuerter Parser
-
First- und Follow-Mengen bestimmen Wahl der Ableitungen
-
nicht mehr rekursiv, sondern mit PDA
Die Menge der LL-Sprachen ist eine echte Teilmenge der deterministisch kontextfreien Sprachen.
Bei
Bei der Bottom-Up-Analyse wird der Parse Tree wird von unten nach oben aufgebaut, von links nach rechts. Dabei entsteht eine Rechtsableitung.
Def.: Bei einer kontextfreien Grammatik
Mit Hilfe der Produktionen und der Vorschautoken werden die Ableitungen "rückwärts" angewandt und "Reduktionen" genannt.
:::notes Hier entsteht ein Tafelbild. :::
:::notes Hier entsteht ein Tafelbild. :::
:::notes Hier entsteht ein Tafelbild. :::
Im Stack stehen nur Zustandsnummern, am Anfang die Nummer des Startzustandes (+ Bottomzeichen, oft auch $$$).
-
Lesen des obersten Stackelements ergibt Zustand
$q$ -
Lesen des nächsten Eingabezeichens ergibt Zeichen
$a$ -
Nachschlagen der Reaktion auf
$(q, a)$ in der Parse Table -
Durchführung der Reaktion
-
Shift: Schiebe logisch das nächste Eingabesymbol auf den Stack (in Wirklichkeit Zustandsnummern)
-
Reduce: (Identifiziere ein Handle oben auf dem Stack und ersetze es durch das Nichtterminal der dazugehörigen Produktion.) Das ist gleichbedeutend mit: Entferne so viele Zustände vom Stack wie die rechte Seite der zu reduzierenden Regel Elemente hat, und schreibe den Zustand, der im Goto-Teil für
$(q, a)$ steht, auf den Stack. -
Accept: Beende das Parsen erfolgreich
-
Reagiere auf einen Syntaxfehler
Def.: Ein (dotted) Item einer Grammatik
Bsp.:
Zu der Produktion
Das zu
-
füge
$I$ zu$CLOSURE_0 (I)$ hinzu -
gibt es ein Item
$[A \rightarrow \alpha \cdot B\beta]$ aus$CLOSURE_0 (I)$ und eine Produktion$(B \rightarrow \gamma)$ , füge$[B \rightarrow \cdot \gamma]$ zu$CLOSURE_0 (I)$ hinzu
für eine Itemmenge
-
Bilde die Hülle von
$S' \rightarrow S$ und mache sie zum ersten Zustand. -
Für jedes noch nicht betrachtete
$\cdot X, X \in (N \cup T)$ in einem Zustand$q$ des Automaten berechne$GOTO_0(q, X)$ und mache$GOTO_0(q, X)$ zu einem neuen Zustand$r$ . Verbinde$q$ mit einem Pfeil mit$r$ und schreibe$X$ an den Pfeil. Ist ein zu$r$ identischer Zustand schon vorhanden, wird$p$ mit diesem verbunden und kein neuer erzeugt.
-
Erstelle eine leere Tabelle mit den Zuständen als Zeilenüberschriften. Für den Aktionstabellenteil überschreibe die Spalten mit den Terminalen, für den Sprungtabellenteil mit den Nonterminals.
-
Shift: Für jeden mit einem Terminal beschrifteten Pfeil aus einem Zustand erstelle in der Aktionstabelle die Aktion shift mit der Nummer des Zustands, auf den der Pfeil zeigt. Für Pfeile mit Nonterminals schreibe in die Sprungtabelle nur die Nummer des Folgezustands.
-
Schreibe beim Zustand
$[S' \rightarrow S \cdot]$ ein$accept$ bei dem Symbol$\bot$ . -
Für jedes Item mit
$[A \rightarrow \beta \cdot]$ aus allen Zuständen schreibe für alle Terminals$reduce$ und die Nummer der entsprechenden Grammatikregel in die Tabelle.
(0)
(1)
(2)
(3)
(4)
Zunächst: Zu jeder LR(k)-Sprache gibt es eine LR(1)-Grammatik.
Ist eine Grammatik nicht LR(0), müssen nichtdeterminsistische Tabelleneinträge verhindert werden:
-
SLR(1)-Parsing (
$A \rightarrow \beta$ wird nur reduziert, wenn das Vorschautoken in der$FOLLOW$ -Menge von$A$ ist.) -
(kanonisches) LR(1)-Parsing (wie LR(0) mit einem Vorschautoken)
-
LALR(1)-Parsing (Zusammenfassung aller LR(1)-Zustände, die sich nur in den LOOKAHEAD-Mengen unterscheiden)
Mehrdeutige Grammatiken sind oft leichter zu lesen und kleiner als die Grammatiken, die man erhält, wenn man die Mehrdeutigkeit auflöst, sofern möglich.
Folgendes kann bei Mehrdeutigkeiten helfen:
-
Angabe von Vorrangregeln
-
Angabe von Assoziativität
-
Voreinstellung des Parsergenearators: z. B. Shiften bei Shift-Reduce-Konflikten
-
Voreinstellung des Parsergenearators: z. B. Reduzieren nach der Regel, die in der Grammatik zuerst kommt bei Reduce-Reduce-Konflikten
-
LR-Analyse baut den Ableitungbaum von unten nach oben auf
-
es wird ein DFA benutzt zusammen mit einem Stack, der Zustände speichert
-
eine Parse-Tabelle steuert über Aktions- und Sprungbefehle das Verhalten des Parsers
-
die Tabelle wird mit (dotted) Items und Closures konstruiert
-
mit Bottom-Up-Parsing LR(1) kann man alle deterministisch kontextfreien Sprachen parsen
-
LR(0)-, SLR- und LALR- Parsing sind vereinfachte Verfahren für Teilmengen der LR-Sprachen
::: slides
Unless otherwise noted, this work is licensed under CC BY-SA 4.0. :::