| author | BC George (HSBI) |
|---|---|
| slide_numbering | fraction |
| title | LL-Parser |
::: attachments
- Warum reichen uns DFAs nicht zum Matchen von Eingabezeichen?
- Wie könnnen wir sie minimal erweitern?
- Sind PDAs deterministisch?
- Wie sind kontextfreie Grammatiken definiert?
- Sind kontextfreie Grammatiken eindeutig?
- einen Grammatiktypen, aus dem sich manuell oder automatisiert ein Programm zur deterministischen Syntaxanalyse (=Parser) erstellen lässt
- einen Algorithmus zum Parsen von Programmen mit Hilfe einer solchen Grammatik
- Automatische Generierung von Top-Down-Parsern aus LL-Grammatiken
Wir verstehen unter Syntax eine Menge von Regeln, die die Struktur von Daten (z. B. Programmen) bestimmen.
Syntaxanalyse ist die Bestimmung, ob Eingabedaten einer vorgegebenen Syntax entsprechen.
Diese vorgegebene Syntax wird im Compilerbau mit einer kontextfreien Grammatik beschrieben und mit einem sogenannten Parser analysiert.
Wir beshäftigen uns heute mit LL-Parsing, mit dem man eine Teilmenge der eindeutigen kontextfreien Grammatiken syntaktich analysieren kann.
Der Ableitungsbaumwird von oben nach unten aufgebaut.
- aussagekräftige Fehlermeldungen, wenn ein Eingabeprogramm syntaktisch nicht korrekt ist
- evtl. Fehlerkorrektur
- Bestimmung der syntaktischen Struktur eines Programms
- Erstellung des AST (abstrakter Syntaxbaum): Der Parse Tree ohne Symbole, die nach der Syntaxanalyse inhaltlich irrelevant sind (z. B. Semikolons, manche Schlüsselwörter)
- die Symboltablelle(n) mit Informationen bzgl. Bezeichner (Variable, Funktionen und Methoden, Klassen, benutzerdefinierte Typen, Parameter, ...), aber auch die Gültigkeitsbereiche.
Welche Produktion nehmen?
Wir brauchen die "terminalen k-Anfänge" von Ableitungen von Nichtterminalen, um
eindeutig die nächste zu benutzende Produktion festzulegen.
Def.: Wir definieren
$a \in T^\ast, |a| \leq k: {First}_k (a) = \lbrace a\rbrace$ $a \in T^\ast, |a| > k: {First}_k (a) = \lbrace v \in T^\ast \mid a = vw, |v| = k\rbrace$ $\alpha \in (N \cup T)^\ast \backslash T^\ast: {First}_k (\alpha) = \lbrace v \in T^\ast \mid \alpha \overset{\ast}{\Rightarrow} w,\text{mit}\ w \in T^\ast, First_k(w) = \lbrace v \rbrace \rbrace$
Def.: Bei einer kontextfreien Grammatik
Man schreibt
Def.: Eine kontextfreie Grammatik G = (N, T, P, S) ist genau dann eine LL(k)-Grammatik, wenn für alle Linksableitungen der Form:
und
mit
::: notes Hier entsteht ein Tafelbild. :::
Die von LL(k)-Grammatiken erzeugten Sprachen sind eine echte Teilmenge der deterministisch parsbaren Sprachen.
Die von LL(k)-Grammatiken erzeugten Sprachen sind eine echte Teilmenge der von LL(k+1)-Grammatiken erzeugten Sprachen.
Für eine kontextfreie Grammatik G ist nicht entscheidbar, ob es eine LL(1) -
Grammatik G' gibt mit
In der Praxis reichen
Algorithmus: Konstruktion einer LL-Parsertabelle {#algorithmus-konstruktion-einer-ll-parsertabelle .fragile}
Eingabe: Eine Grammatik G = (N, T, P, S)
Ausgabe: Eine Parsertabelle P
Hier ist
::: notes Hier entsteht ein Tafelbild. :::
Rekursive Programmierung bedeutet, dass das Laufzeitsystem einen Stack benutzt. Diesen Stack kann man auch "selbst programmieren", d. h. einen PDA implementieren. Dabei wird ebenfalls die oben genannte Tabelle zur Bestimmung der nächsten anzuwendenden Produktion benutzt. Der Stack enthält die zu erwartenden Eingabezeichen, wenn immer eine Linksableitung gebildet wird. Diese Zeichen im Stack werden mit dem Input gematcht.
Algorithmus: Tabellengesteuertes LL-Parsen mit einem PDA {#algorithmus-tabellengesteuertes-ll-parsen-mit-einem-pda .fragile}
Eingabe: Eine Grammatik G = (N, T, P, S), eine Parsertabelle P mit "$w\perp$" als initialem Kellerinhalt
Ausgabe: Wenn
- eventuelle Syntaxfehler mit Angabe der Fehlerart und des -Ortes
- Fehlerkorrektur
- Format für die Weiterverarbeitung:
- Ableitungsbaum oder Syntaxbaum oder Parse Tree
- abstrakter Syntaxbaum (AST): Der Parse Tree ohne Symbole, die nach der
Syntaxanalyse inhaltlich irrelevant sind (z. B. ;, Klammern, manche
Schlüsselwörter,
$\ldots$ )
- Symboltabelle
- Syntaxanalyse wird mit deterministisch kontextfreien Grammatiken durchgeführt.
- Eine Teilmenge der dazu gehörigen Sprachen lässt sich top-down parsen.
- Ein effizienter LL(k)-Parser realisiert einen DPDA und kann automatisch aus einer LL(k)-Grammatik generiert werden.
- Der Parser liefert in der Regel einen abstrakten Syntaxbaum.
::: readings
- @Aho2023
- @hopcroft2003 :::
::: outcomes
- k1: Ich kenne die Top-Down-Analyse
- k1: Ich kenne LL-Parser
- k2: Ich kann den algorithmischen Ablauf von LL-Parsern an einem Beispiel erklären :::

