Lässt es sich mit cremefarbenem Papier, einer Tönung, mehr Kontrast oder größerer Schrift besser lesen? Wählen Sie Ihre Farben und Ihre Schrift, einmalig für alle Seiten.

Kostenlose Lektion

Kontextfreie Grammatiken verstehen

Nach dieser Lektion: Ich kann mit einer Grammatik entscheiden, ob ein Wort gültig ist.

Lektion, 60 Min.7 BefehleLab für Compilerbau und Rechnerarchitektur: gcc, flex, bison und RISC-V in einer VM

Warum der Rechner die Klammer vermisst

Eine Grammatik ist ein Satz von Regeln, der beschreibt, welche Wörter zu einer Sprache gehören. Mit ihr entscheiden Sie zum Beispiel, ob in einer Formel jede Klammer, die aufgeht, auch wieder zugeht.

Ein Tabellenprogramm meldet bei =(2+3*4 sofort einen Fehler. Dahinter steckt eine Grammatik, die verschachtelte Klammern kennt. Das schafft kein endlicher Automat und kein regulärer Ausdruck.

Am Ende dieser Lektion

Notiz

Ich kann mit einer Grammatik entscheiden, ob ein Wort gültig ist.

Schlüsselwörter

BegriffWas er bedeutetBeispiel
Grammatikein Satz von Regeln für die Wörter einer Sprache
Regeleine Zeile, die ein Zeichen durch andere ersetztK → ( K ) K
Terminalein Zeichen, das im fertigen Wort steht(
Nichtterminalein Platzhalter, den eine Regel ersetztK
Ableitungdie Schritte vom Startzeichen zum fertigen Wort
Verschachtelungein Teil, der innen in einem gleichartigen Teil steht

Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.

Eine Grammatik ersetzt Zeichen nach Regeln

Eine Grammatik hat Terminale, das sind die Zeichen im fertigen Wort, und Nichtterminale, das sind Platzhalter. Eine Regel sagt, wodurch ein Platzhalter ersetzt werden darf.

Für Klammern genügt eine Regel mit zwei Seiten: K darf zu ( K ) K werden, oder zu nichts. Ein Wort ist gültig, wenn es sich vom Startzeichen K aus so ableiten lässt.

Die Grammatik für Klammern

RegelGelesen alsBeispiel
K → ( K ) KEine Klammer auf, ein K, eine Klammer zu, danach wieder ein K(()) entsteht daraus
K → leerK darf auch verschwindenbeendet jede Ableitung

Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.

Die Ableitung von (()) Schritt für Schritt

Code: python
# Grammatik fuer Klammern:  K -> ( K ) K  oder leer.
# Jeder Schritt ersetzt das linkeste K durch eine Regel.
schritte = [
    "K",
    "( K ) K",
    "( ( K ) K ) K",
    "( ( ) K ) K",
    "( ( ) ) K",
    "( ( ) )",
]
for nummer in range(len(schritte)):
    print(nummer, schritte[nummer])
# Aendern Sie die Schritte so, dass "( ) ( )" entsteht.

Eine Grammatik kann verschachteln

In der Regel K → ( K ) K kommt K auf der rechten Seite wieder vor. So darf innen in einer Klammer wieder eine Klammer stehen, beliebig tief.

Ein Automat kann das nicht, denn er müsste die Tiefe zählen und hat nur endlich viele Zustände. Grammatiken wie diese heißen kontextfrei: Eine Regel ersetzt K, ganz gleich, was daneben steht.

Ein häufiger Fehler

Warnung

Viele denken, man prüfe Klammern, indem man „(“ und „)“ zählt. Gleich viele reichen aber nicht: )( hat von beiden eine. Es zählt die Reihenfolge. Eine Klammer zu braucht eine offene davor, und ([)] ist ungültig, obwohl die Zahlen stimmen.

bison liest eine Grammatik und baut den Parser

Die Grammatik eines echten Rechners steht in der Datei calc.y. bison macht aus ihr einen Parser, der prüft, ob eine Eingabe gültig ist.

Dort steht dieselbe Idee wie bei den Klammern: expr darf zu ( expr ) werden. Die Befehle zeigen die Regeln und füttern den Rechner mit Rechnungen, gültigen und ungültigen.

In den Ordner compiler wechseln

Befehl
cd ~/compiler

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Den Rechner bauen, falls nötig

Befehl
make

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Die Regeln mit einem Rechenzeichen

Befehl
grep -oE "expr '[-+*/]' expr" calc.y

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Wie viele Vorrangzeilen hat die Grammatik?

Befehl
grep -c "%left" calc.y

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Punkt vor Strich

Befehl
echo "2 + 3 * 4" | ./calc

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Die Klammer ändert die Reihenfolge

Befehl
echo "(2 + 3) * 4" | ./calc

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Eine Klammer bleibt offen

Befehl
echo "((2 + 3) * 4" | ./calc

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Über dieses Lab und seinen Quellcode: Lab für Compilerbau und Rechnerarchitektur: gcc, flex, bison und RISC-V in einer VM

Sie unterrichten eine Gruppe? Weisen Sie dieses Modul Ihren Studierenden zu, mit Handbuch für Lehrende, automatisch geprüften Aufgaben und einem Lab für jede Person.