Zum Inhalt springen
Zurück zur Themenübersicht

Theoretische Informatik

Formale Sprachen: Syntax, Semantik und Grammatiken

Wie man mit endlich vielen Regeln unendlich viele richtige Sätze beschreibt, und warum ein Übersetzer genau das braucht.

Benötigte Grundlagen

Dieses Vorwissen brauchst du für das Kapitel. Schau kurz nach, wenn dir etwas davon nicht mehr präsent ist, sonst leg direkt los.

Einführung

„Der Hund bellt den Regenbogen an." Der Satz ist grammatisch einwandfrei und inhaltlich sinnlos. „Bellt Hund der den an Regenbogen" ist beides nicht.

Diesen Unterschied kennst du aus Klasse 9 als und Semantik. In der Qualifikationsphase geht es einen entscheidenden Schritt weiter: Wie schreibt man die Syntax einer Sprache so auf, dass eine Maschine sie prüfen kann?

Die Antwort ist bemerkenswert: mit endlich vielen Regeln, aus denen sich unendlich viele richtige Sätze ableiten lassen. Genau das leistet eine Grammatik, und genau darauf beruht jeder Übersetzer, jede Programmiersprache und jede Eingabeprüfung.

Das kannst du nach diesem Kapitel

  • natürliche und formale Sprachen vergleichen und die Unterschiede benennen.

  • die Begriffe Alphabet, Wort und Sprache im formalen Sinn verwenden.

  • eine Grammatik lesen und mit ihr Wörter ableiten.

  • einfache Grammatiken in EBNF darstellen.

  • begründen, warum endlich viele Regeln unendlich viele Wörter beschreiben können.

Kurz aufgefrischt

Vorausgesetzt wird die Unterscheidung von (Form) und Semantik (Bedeutung) aus Variablen, Datentypen und Wertzuweisung. Neu ist hier, wie man Syntax aufschreibt, statt sie nur zu beschreiben.

Natürliche und formale Sprachen

natürliche Spracheformale Sprache
entstandenhistorisch gewachsenfestgelegt
Regelnmit Ausnahmen und Grauzonenvollständig und eindeutig
Bedeutungvom Zusammenhang abhängiggenau festgelegt
Mehrdeutigkeiterwünscht (Ironie, Poesie)ausgeschlossen
geprüft vonMenschenMaschinen

Der wichtigste Unterschied ist die letzte Zeile, und er erklärt die anderen. Eine Maschine kann nicht nachfragen, was gemeint war. Deshalb muss bei einer formalen Sprache jede Zeichenfolge eindeutig entweder dazugehören oder nicht, und diese Entscheidung muss sich rein aus der Form treffen lassen.

Zwei Arten von Sprache

NatürlicheSpracheFormale SpracheWie entsteht sie?gewachsen,niemand hat siefestgelegtdurch Regelndefiniert,Zeichen fürZeichenWas ist mit Mehrdeutigkeit?Mehrdeutigkeitist normal undoft gewolltjedes Wortgehört dazu odernicht,dazwischennichtsWer entscheidet, was gilt?der Menschversteht aus demZusammenhangeine Maschineentscheidet ohneZusammenhangNur weil die Zugehörigkeitentscheidbar ist, kann einÜbersetzer ein Programm überhauptprüfen.

Die mittlere Zeile ist der eigentliche Unterschied. In der natürlichen Sprache ist Mehrdeutigkeit ein Merkmal: „Ich sah den Mann mit dem Fernglas“ hat zwei Lesarten, und Menschen wählen die passende aus dem Zusammenhang. In einer formalen Sprache wäre genau das eine Katastrophe: Ein Übersetzer könnte nicht entscheiden, was gemeint ist, und dasselbe Programm liefe auf zwei Rechnern verschieden. Deshalb ist die Zugehörigkeit scharf definiert: Ein Wort gehört zur Sprache oder nicht, ein Drittes gibt es nicht. Erst das macht Syntaxprüfung überhaupt möglich.

Die drei Grundbegriffe

Ein Alphabet Σ\Sigma ist eine endliche Menge von Zeichen.

Σ={a,b}Σ={0,1}Σ={A,…,Z,0,…,9}\Sigma = \{a, b\} \qquad \Sigma = \{0, 1\} \qquad \Sigma = \{\texttt{A}, \ldots, \texttt{Z}, 0, \ldots, 9\}

Ein Wort über Σ\Sigma ist eine endliche Folge von Zeichen aus Σ\Sigma. Auch das leere Wort gehört dazu; es wird ε\varepsilon geschrieben.

Eine Sprache LL über Σ\Sigma ist eine Menge von Wörtern.

L1={ab,aabb,aaabbb,…}L2={alle gu¨ltigen E-Mail-Adressen}L_1 = \{ab, aabb, aaabbb, \ldots\} \qquad L_2 = \{\text{alle gültigen E-Mail-Adressen}\}

🔴 Beachte, dass eine Sprache hier nichts mit Bedeutung zu tun hat. Sie ist schlicht die Menge derjenigen Zeichenfolgen, die als „dazugehörig" gelten. Ob sie etwas aussagen, ist eine ganz andere Frage; das ist genau die Trennung von und Semantik.

Eine Sprache ist eine Auswahl

ΩLalle WörterabbaL ⊆ Σ*

So hängen die drei Begriffe zusammen. Das Alphabet Σ={a,b}\Sigma = \{a, b\} liefert die Zeichen; Wörter sind alle endlichen Folgen daraus, und davon gibt es unendlich viele. Das ist der große Kreis. Eine Sprache LL ist nichts weiter als eine Auswahl daraus, hier L={anbn}L = \{a^n b^n\}. Im inneren Kreis steht abab. Dort gehören auch aabbaabb und aaabbbaaabbb hin; außerhalb steht baba, und dorthin gehören ebenso aabaab und bbbb. Halte das fest, weil es die ganze Theorie trägt: Eine Sprache zu beschreiben heißt, für jedes der unendlich vielen Wörter zu klären, ob es dazugehört, und genau deshalb reicht eine Liste nicht.

Das Problem: unendlich viele Wörter

L1L_1 oben enthält unendlich viele Wörter. Man kann sie nicht aufzählen, und ein Programm kann keine unendliche Liste durchsuchen.

Also braucht man eine endliche Beschreibung einer möglicherweise unendlichen Menge. Genau das leistet eine Grammatik.

Grammatiken

Eine Grammatik besteht aus Regeln, mit denen sich Wörter erzeugen lassen. Man beginnt bei einem Startsymbol und ersetzt so lange, bis nur noch Zeichen des Alphabets übrig sind.

Beispiel für L1={anbn∣n≥1}L_1 = \{a^n b^n \mid n \ge 1\}, also gleich viele aa wie bb, alle aa zuerst:

S → a S b
S → a b

Gelesen: „SS darf durch aSbaSb ersetzt werden, oder durch abab."

Eine Ableitung wendet die Regeln nacheinander an:

S⇒aSb⇒a aSb b⇒a a ab b b=aaabbbS \Rightarrow aSb \Rightarrow a\,aSb\,b \Rightarrow a\,a\,ab\,b\,b = aaabbb

Die Zeichen, die ersetzt werden dürfen (SS), heißen Nichtterminale und stehen üblicherweise groß. Die Zeichen des Alphabets (aa, bb) heißen Terminale und werden nicht weiter ersetzt. Eine Ableitung ist fertig, wenn kein Nichtterminal mehr übrig ist.

Eine Ableitung, Schritt für Schritt

Sdas Startsymbol, noch keineinziges Zeichen des AlphabetsRegel S → a S ba S bein a und ein b entstanden, Sist noch dadieselbe Regel: sie darfbeliebig ofta a S b bdieselbe Regel noch einmalRegel S → a b bricht aba a a b b bkein Nichtterminal mehr, dieAbleitung ist fertig

Verfolge das S von oben nach unten: Es wandert durch die ganze Ableitung und wird immer weiter nach innen geschoben, bis die Abbruchregel es beseitigt. Genau daran erkennst du, wann eine Ableitung fertig ist, wenn kein Nichtterminal mehr übrig ist. Beachte außerdem, dass in jedem Schritt gleich viele aa und bb hinzukommen, immer eines links und eines rechts. Das ist kein Zufall, sondern die Bauart der Regel S→aSbS \to aSb, und deshalb erzeugt sie ausschließlich Wörter der Form anbna^n b^n, nie eines mit ungleich vielen.

Warum endlich viele Regeln unendlich viele Wörter erzeugen

Das ist der Kern des ganzen Kapitels, und die Antwort steckt in einer einzigen Eigenschaft: .

Die Regel S→aSbS \to aSb enthält auf der rechten Seite wieder SS. Man kann sie deshalb beliebig oft anwenden, bevor man mit S→abS \to ab abbricht. Jede Anwendung erzeugt ein weiteres Paar aa und bb.

Zwei Bestandteile braucht jede solche Grammatik:

Eine rekursive Regel, die das Wort verlängert. Eine Abbruchregel ohne Nichtterminal auf der rechten Seite.

Fehlt die Abbruchregel, endet keine Ableitung, und die Sprache ist leer. Fehlt die Rekursion, ist die Sprache endlich. Das ist dieselbe Struktur wie bei einer : Rumpf und Abbruchbedingung.

Rekursion und Abbruch, beides nötig

S → a S bS → a bWas tut die Regel?verlängert dasWort um ein aund ein bbeendet dieAbleitungWoran erkennt man das?rechts stehtwieder ein S.Sie darf sichselbst aufrufenrechts stehtkeinNichtterminalmehrWas wäre, wenn sie fehlte?die Sprache wäreendlich: nurnoch abkeine Ableitungkäme je zumEnde, dieSprache wäreleerDieselbe Struktur wie bei einerSchleife: ein Rumpf, derwiederholt, und eine Bedingung,die abbricht.

Zwei Regeln, und jede wird gebraucht. Lies die letzte Zeile in beiden Spalten: Ohne die Regel bliebe genau ein einziges Wort übrig, ohne die Abbruchregel käme keine Ableitung je zum Ende und die Sprache wäre leer. Erst zusammen erzeugen sie unendlich viele Wörter aus zwei Zeilen Text, und das ist die Antwort auf die Frage des Abschnitts. Wenn dir das bekannt vorkommt: Es ist genau die Struktur einer , und ein rekursiver Aufruf ohne Abbruchbedingung ist derselbe Fehler wie eine Endlosschleife.

EBNF

Für Programmiersprachen benutzt man eine besser lesbare Schreibweise, die erweiterte Backus-Naur-Form. Sie kennt drei zusätzliche Zeichen:

ZeichenBedeutung
∣\midAlternative („oder")
[  ][\;]optional (null- oder einmal)
{  }\{\;\}Wiederholung (nullmal oder öfter)

Damit lässt sich vieles ohne ausdrücken. Eine ganze Zahl mit optionalem Vorzeichen:

Ziffer     = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ;
Zahl       = [ "-" ] Ziffer { Ziffer } ;

Gelesen: „Eine Zahl besteht aus einem optionalen Minuszeichen, danach einer Ziffer, danach beliebig vielen weiteren Ziffern."

Die geschweiften Klammern übernehmen hier die Rolle der Rekursion, und deshalb sind auch mit EBNF unendlich viele Wörter beschreibbar. Beachte außerdem: Die Regel verlangt mindestens eine Ziffer, denn eine steht vor der Wiederholung. Ohne diese eine Ziffer wäre auch das leere Wort eine Zahl.

Ein etwas größeres Beispiel, ein Bezeichner in einer Programmiersprache:

Buchstabe  = "a" | "b" | … | "z" | "A" | … | "Z" ;
Bezeichner = Buchstabe { Buchstabe | Ziffer | "_" } ;

Daraus liest man unmittelbar zwei bekannte Regeln ab: Ein Bezeichner beginnt mit einem Buchstaben, und danach sind Buchstaben, Ziffern und Unterstriche in beliebiger Folge erlaubt. Genau das prüft ein Übersetzer, wenn er einen Variablennamen liest.

Wozu das gut ist

Jede Programmiersprache ist über eine Grammatik definiert. Der Übersetzer benutzt sie für zwei Aufgaben:

Prüfen, ob der Quelltext zur Sprache gehört. Tut er es nicht, entsteht ein , und zwar genau an der Stelle, an der keine Regel mehr passt. Das erklärt die Beobachtung aus Klasse 9, dass die gemeldete Zeile nicht immer die Ursache ist: Gemeldet wird, wo der Übersetzer stolpert.

Zerlegen in eine Struktur. Aus 2+3⋅42 + 3 \cdot 4 entsteht ein Baum, in dem die Multiplikation tiefer steht als die Addition. Erst diese Struktur legt fest, dass zuerst multipliziert wird. Punkt vor Strich ist also keine Zusatzregel des Rechners, sondern steckt bereits in der Grammatik.

Und die Semantik?

Eine Grammatik beschreibt ausschließlich die Form. Der Satz aus der Einführung ist grammatisch korrekt und sinnlos; in einer Programmiersprache ist flaeche := laenge + breite\texttt{flaeche := laenge + breite} ebenso korrekt und falsch gemeint.

Die legt fest, was ein syntaktisch richtiges Konstrukt bedeutet, also welche Wirkung es bei der Ausführung hat. Sie lässt sich nicht mit einer Grammatik beschreiben, und deshalb kann kein Übersetzer prüfen, ob dein Programm das Richtige tut. Er prüft die Form; für die Bedeutung bist du zuständig.

Mit einer Grammatik ableiten

Gegeben ist die Grammatik S→aSbS \to aSb, S→abS \to ab. Leite aaabbbaaabbb ab und prüfe, ob aabbbaabbb zur Sprache gehört.

  1. 1

    Ableitung von aaabbbaaabbb: Man beginnt beim Startsymbol und wendet die Regel an, solange noch aa und bb fehlen.

  2. 2

    S⇒aSbS \Rightarrow aSb (Regel 1) ⇒aaSbb\Rightarrow aaSbb (Regel 1) ⇒aaabbb\Rightarrow aaabbb (Regel 2).

  3. 3

    Drei Schritte, und kein Nichtterminal ist übrig. Also gehört aaabbbaaabbb zur Sprache.

  4. 4

    Prüfung von aabbbaabbb: Beide Regeln erzeugen bei jeder Anwendung genau ein aa und genau ein bb. Nach nn Schritten stehen also immer nn Zeichen aa und nn Zeichen bb da.

  5. 5

    In aabbbaabbb sind es zwei aa und drei bb. Eine solche Ungleichheit kann durch keine Ableitung entstehen. Also gehört aabbbaabbb nicht zur Sprache.

  6. 6

    Beachte die Beweisführung: Man zeigt nicht, dass man keine Ableitung gefunden hat, sondern dass es keine geben kann. Das ist der Unterschied zwischen Ratlosigkeit und Begründung.

S⇒aSb⇒aaSbb⇒aaabbbS \Rightarrow aSb \Rightarrow aaSbb \Rightarrow aaabbb. Für aabbbaabbb gibt es keine Ableitung, weil jede Regel aa und bb paarweise erzeugt.

Eine EBNF-Regel lesen und anwenden

Gegeben: Zahl=[  "-"  ]  Ziffer  {  Ziffer  }\texttt{Zahl} = [\;\texttt{"-"}\;]\;\texttt{Ziffer}\;\{\;\texttt{Ziffer}\;\}. Welche der Zeichenfolgen gehören dazu: 42\texttt{42}, -7\texttt{-7}, --3\texttt{--3}, \texttt{} (leer), 3.5\texttt{3.5}?

  1. 1

    Regel zerlegen: optionales Minus, dann genau eine Ziffer, dann beliebig viele weitere Ziffern.

  2. 2

    42\texttt{42}: kein Minus (erlaubt, weil optional), Ziffer 4, dann eine weitere Ziffer 2. Gehört dazu.

  3. 3

    -7\texttt{-7}: Minus, Ziffer 7, keine weiteren. Gehört dazu.

  4. 4

    --3\texttt{--3}: Das Minus ist mit [  ][\;] höchstens einmal erlaubt. Nach dem ersten Minus müsste eine Ziffer folgen, es kommt aber ein zweites Minus. Gehört nicht dazu.

  5. 5

    Leeres Wort: Die Regel verlangt mindestens eine Ziffer, denn eine steht vor der geschweiften Klammer. Gehört nicht dazu.

  6. 6

    3.5\texttt{3.5}: Der Punkt ist kein Terminal dieser Regel. Gehört nicht dazu. Für Kommazahlen bräuchte man eine erweiterte Regel, etwa Zahl  [  "."  Ziffer  {  Ziffer  }  ]\texttt{Zahl}\;[\;\texttt{"."}\;\texttt{Ziffer}\;\{\;\texttt{Ziffer}\;\}\;].

Dazu gehören 42\texttt{42} und -7\texttt{-7}; nicht dazu gehören --3\texttt{--3}, das leere Wort und 3.5\texttt{3.5}.

Typischer Fehler

„Eine Grammatik mit endlich vielen Regeln kann nur endlich viele Wörter beschreiben."

Der Schluss wirkt zwingend und ist falsch, weil er eine Möglichkeit übersieht: Eine Regel darf sich selbst enthalten.

Sieh dir S→aSbS \to aSb an. Diese eine Regel lässt sich beliebig oft anwenden, weil nach jeder Anwendung wieder ein SS dasteht. Mit der zweiten Regel S→abS \to ab bricht man ab, wann man will. Zwei Regeln erzeugen so unendlich viele Wörter.

Der Vergleich, der es festigt: Eine im Programm besteht auch nur aus wenigen Zeilen und läuft beliebig oft. Der Grund ist derselbe, nämlich dass etwas auf sich selbst zurückgreift.

Umgekehrt gilt: Ohne ist die Sprache endlich. Eine Grammatik, in der kein Nichtterminal je wieder auftaucht, kann jede Ableitung nur eine feste Zahl von Schritten führen.

In EBNF ist die Rekursion in den geschweiften Klammern versteckt: {  Ziffer  }\{\;\texttt{Ziffer}\;\} heißt „beliebig oft" und leistet dasselbe wie eine rekursive Regel. Wer nur EBNF kennt, übersieht das leicht, weil dort kein Symbol sichtbar auf sich selbst verweist.

Übung 1

leicht

Gegeben: S→0S1S \to 0S1, S→εS \to \varepsilon über Σ={0,1}\Sigma = \{0, 1\}.

a) Leite 00110011 ab. b) Gehört ε\varepsilon zur Sprache? c) Gehört 01010101 dazu? Begründe.

Tipp anzeigen

Zu c): Welche Reihenfolge erzwingen die Regeln?

Lösung anzeigen

a) S⇒0S1⇒00S11⇒0011S \Rightarrow 0S1 \Rightarrow 00S11 \Rightarrow 0011 (die letzte Regel ersetzt SS durch das leere Wort).

b) Ja. Die Regel S→εS \to \varepsilon ist direkt anwendbar, also ist das leere Wort ableitbar.

c) Nein. Jede Anwendung der ersten Regel setzt eine 00 links und eine 11 rechts an. Alle Nullen stehen deshalb zwangsläufig vor allen Einsen. In 01010101 steht eine 00 hinter einer 11; das kann durch keine Ableitung entstehen.

Detaillierte Schritterklärung anzeigen

Hier wird jeder Schritt einzeln erklärt, vor allem, warum er gemacht wird.

Erklärungstiefe

✦ Empfohlen: Standard – Die normale Erklärungstiefe passt zum Einstieg.

  1. 1

    a) Ableiten heißt: Regeln anwenden, bis nichts Ersetzbares übrig ist

    Man beginnt beim Startsymbol und ersetzt in jedem Schritt ein Nichtterminal durch eine rechte Seite: S⇒0S1⇒00S11⇒0011S \Rightarrow 0S1 \Rightarrow 00S11 \Rightarrow 0011. Der letzte Schritt benutzt S→εS \to \varepsilon und ersetzt SS durch das leere Wort.

    S⇒0S1⇒00S11⇒0011S \Rightarrow 0S1 \Rightarrow 00S11 \Rightarrow 0011

  2. 2

    b) Das leere Wort gehört dazu, weil es eine Regel dafür gibt

    Ja. Die Regel S→εS \to \varepsilon ist direkt auf das Startsymbol anwendbar, also ist das leere Wort in einem einzigen Schritt ableitbar und gehört zur Sprache.

  3. 3

    c) Warum 0101 nicht ableitbar ist: die Regel erzwingt die Reihenfolge

    Nein. Jede Anwendung der ersten Regel setzt eine 00 links und eine 11 rechts an das bisherige Zwischenergebnis. Alle Nullen stehen deshalb zwangsläufig vor allen Einsen. In 01010101 steht eine 00 hinter einer 11. Das kann durch keine Ableitung entstehen.

Übung 2

mittel

a) Schreibe eine EBNF-Regel für eine Uhrzeit im Format Stunde:Minute, wobei beide Teile zweistellig sind. b) Welche Zeichenfolgen erzeugt deine Regel fälschlich mit, die keine gültige Uhrzeit sind? c) Erkläre, warum sich das mit EBNF allein nur schwer beheben lässt. d) Schreibe eine Grammatik für die Sprache aller Wörter aus aa und bb, die mit aa beginnen und mit bb enden.

Tipp anzeigen

Zu b): Welche Zahlen lässt eine reine Ziffernregel zu?

Lösung anzeigen

a) EBNF:

Ziffer  = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ;
Uhrzeit = Ziffer Ziffer ":" Ziffer Ziffer ;

b) Sie erzeugt zum Beispiel 99:99\texttt{99:99}, 45:70\texttt{45:70} und 00:99\texttt{00:99}. Die Regel prüft nur die Form, nämlich zwei Ziffern, Doppelpunkt, zwei Ziffern, nicht den Wertebereich.

c) Man könnte den Wertebereich zwar erzwingen, aber nur durch eine deutlich umständlichere Regel, die die erlaubten Ziffernkombinationen einzeln aufzählt:

Stunde = ( "0" | "1" ) Ziffer | "2" ( "0" | "1" | "2" | "3" ) ;
Minute = ( "0" | "1" | "2" | "3" | "4" | "5" ) Ziffer ;

Das geht hier noch, wird aber schnell unhandlich. Der eigentliche Grund liegt tiefer: Eine Grammatik beschreibt Form, keine Bedeutung. Bedingungen wie „der 31. Februar existiert nicht" oder „das Enddatum liegt nach dem Startdatum" lassen sich damit gar nicht mehr ausdrücken; sie gehören zur und werden im Programm geprüft.

d) Grammatik:

S → a M b
M → a M
M → b M
M → ε

MM erzeugt eine beliebige Folge aus aa und bb, einschließlich der leeren. Das kürzeste Wort ist abab.

Detaillierte Schritterklärung anzeigen

Hier wird jeder Schritt einzeln erklärt, vor allem, warum er gemacht wird.

Erklärungstiefe

✦ Empfohlen: Standard – Die normale Erklärungstiefe passt zum Einstieg.

  1. 1

    Teil a): Die Form in Bausteine zerlegen

    Man liest die Beschreibung wörtlich und schreibt jeden Bestandteil einzeln auf: zwei Ziffern, ein Doppelpunkt, zwei Ziffern. Der Doppelpunkt ist ein Terminal und steht deshalb in Anführungszeichen.

    Zwischenergebnis

    Ziffer Ziffer ":" Ziffer Ziffer

    Weil die Stellenzahl fest ist, braucht man hier keine geschweiften Klammern. Sie stünden für „beliebig oft" und würden auch 123:4\texttt{123:4} zulassen.

  2. 2

    Teil b): Die eigene Regel gegen sich selbst prüfen

    Man erzeugt bewusst Wörter, die die Regel erlaubt, und fragt bei jedem, ob es fachlich zulässig wäre. Das ist dieselbe Randfallprüfung wie beim Algorithmenentwurf.

    Zwischenergebnis

    99:99\texttt{99:99} passt zur Form und ist keine Uhrzeit.

  3. 3

    Teil c): Warum die Grenze grundsätzlich ist

    Der Wertebereich lässt sich mit Mühe noch in Regeln fassen, indem man die erlaubten Ziffernpaare aufzählt. Der eigentliche Punkt ist aber, dass eine Grammatik nur Form beschreibt.

    Zwischenergebnis

    Form ist erzwingbar, Bedeutung nicht.

  4. 4

    Teil d): Anfang und Ende festnageln, Mitte freilassen

    Die Bedingung betrifft nur das erste und das letzte Zeichen. Also schreibt man diese beiden als Terminale in die Startregel und lässt für die Mitte ein Nichtterminal, das alles erzeugen darf.

    S \to a,M,b

    Zwischenergebnis

    MM muss beliebige Folgen aus aa und bb erzeugen können, auch die leere.

    Die Regel M→εM \to \varepsilon ist die Abbruchregel. Ohne sie gäbe es kein Wort, denn jede Ableitung liefe endlos weiter.

Übung 3

schwer

a) Entwirf eine Grammatik für arithmetische Ausdrücke aus Ziffern, ++ und ⋅\cdot, in der Punkt vor Strich bereits in der Struktur steckt. b) Leite 2+3⋅42 + 3 \cdot 4 ab und zeige, dass die Multiplikation dabei tiefer liegt. c) Erkläre, warum eine Grammatik nicht prüfen kann, ob ein Programm das Richtige tut. d) Ein Mitschüler schreibt eine Grammatik ohne Abbruchregel. Was folgt daraus für die beschriebene Sprache?

Tipp anzeigen

Zu a): Baue drei Ebenen, eine für Summen, eine für Produkte, eine für einzelne Zahlen.

Lösung anzeigen

a) Drei Ebenen erzwingen die Vorrangregel:

Ausdruck → Ausdruck "+" Produkt | Produkt
Produkt  → Produkt "*" Faktor  | Faktor
Faktor   → Ziffer
Ziffer   → "0" | "1" | … | "9"

Der Trick ist die Schachtelung: Eine Summe besteht aus Produkten, ein Produkt aus Faktoren. Eine Addition kann deshalb nie innerhalb eines Produkts stehen, ohne geklammert zu sein.

b) Ableitung:

Ausdruck ⇒ Ausdruck + Produkt
         ⇒ Produkt  + Produkt
         ⇒ Faktor   + Produkt
         ⇒ 2        + Produkt
         ⇒ 2        + Produkt * Faktor
         ⇒ 2        + Faktor  * Faktor
         ⇒ 2 + 3 * 4

Die Addition entsteht in der obersten Ebene, die Multiplikation erst darunter. Im Ableitungsbaum liegt 3⋅43 \cdot 4 damit tiefer als die Addition, und wer den Baum von unten nach oben auswertet, rechnet zwangsläufig zuerst 3⋅43 \cdot 4. Punkt vor Strich ist damit keine zusätzliche Regel des Rechners, sondern eine Folge der Grammatik.

c) Weil eine Grammatik ausschließlich die Form beschreibt, also welche Zeichenfolgen zur Sprache gehören. Ob ein formal richtiges Konstrukt das Gemeinte bewirkt, ist eine Frage der und der Absicht des Programmierers. flaeche := laenge + breite\texttt{flaeche := laenge + breite} ist grammatisch einwandfrei; dass hier addiert statt multipliziert wird, kann keine Regel über Zeichenfolgen erkennen, weil dem Übersetzer die Absicht unbekannt ist.

d) Ohne Abbruchregel enthält jede rechte Seite mindestens ein Nichtterminal. Eine Ableitung kann deshalb nie enden, denn es bleibt immer etwas zu ersetzen. Damit lässt sich kein einziges Wort vollständig ableiten, und die beschriebene Sprache ist leer. Das ist bemerkenswert: Die Grammatik ist nicht fehlerhaft aufgeschrieben, sie beschreibt nur nichts.

Detaillierte Schritterklärung anzeigen

Hier wird jeder Schritt einzeln erklärt, vor allem, warum er gemacht wird.

Erklärungstiefe

✦ Empfohlen: Standard – Die normale Erklärungstiefe passt zum Einstieg.

  1. 1

    a) Drei Ebenen bauen, die Schachtelung erzeugt den Vorrang

    Man baut drei Ebenen: Ausdruck (Summen), Produkt (Produkte), Faktor (einzelne Zahlen). Ein Ausdruck besteht aus Produkten, ein Produkt aus Faktoren. Eine Addition kann deshalb nie innerhalb eines Produkts stehen, ohne geklammert zu sein, und genau das ist Punkt vor Strich.

    Ausdruck → Ausdruck "+" Produkt | Produkt; Produkt → Produkt "*" Faktor | Faktor; Faktor → Ziffer

  2. 2

    b) Die Ableitung zeigt: die Multiplikation liegt tiefer

    Die Addition entsteht in der obersten Ebene (Ausdruck⇒Ausdruck+Produkt\text{Ausdruck} \Rightarrow \text{Ausdruck} + \text{Produkt}), die Multiplikation erst darunter (Produkt⇒Produkt∗Faktor\text{Produkt} \Rightarrow \text{Produkt} * \text{Faktor}). Im Ableitungsbaum liegt 3⋅43 \cdot 4 damit tiefer als die Addition.

    Ausdruck⇒Ausdruck+Produkt⇒…⇒2+3∗4\text{Ausdruck} \Rightarrow \text{Ausdruck} + \text{Produkt} \Rightarrow \ldots \Rightarrow 2 + 3 * 4

  3. 3

    c) Warum eine Grammatik nicht prüfen kann, ob ein Programm das Richtige tut

    Weil eine Grammatik ausschließlich die Form beschreibt, also welche Zeichenfolgen zur Sprache gehören. Ob ein formal richtiges Konstrukt das Gemeinte bewirkt, ist eine Frage der Semantik und der Absicht des Programmierers.

  4. 4

    d) Eine Grammatik ohne Abbruchregel beschreibt die leere Sprache

    Ohne Abbruchregel enthält jede rechte Seite mindestens ein Nichtterminal. Eine Ableitung kann deshalb nie enden. Es bleibt immer etwas zu ersetzen. Damit lässt sich kein einziges Wort vollständig ableiten, und die beschriebene Sprache ist leer.

Zusammenfassung

Formale Sprachen unterscheiden sich von natürlichen dadurch, dass ihre Regeln vollständig, eindeutig und maschinell prüfbar sind. Ein Alphabet ist ein endlicher Zeichenvorrat, ein Wort eine Zeichenfolge daraus, eine Sprache eine Menge von Wörtern; mit Bedeutung hat das zunächst nichts zu tun. Weil eine Sprache unendlich viele Wörter enthalten kann, beschreibt man sie durch eine Grammatik aus endlich vielen Regeln, die Nichtterminale zu Terminalen ableiten. Möglich wird das durch : eine Regel, die sich selbst enthält, zusammen mit einer Abbruchregel; fehlt die Rekursion, ist die Sprache endlich, fehlt die Abbruchregel, ist sie leer. Die EBNF schreibt dasselbe lesbarer mit Alternative, Option und Wiederholung. Übersetzer nutzen die Grammatik zum Prüfen und zum Zerlegen in eine Struktur, aus der sich sogar die Vorrangregel Punkt vor Strich ergibt. Was eine Grammatik grundsätzlich nicht leisten kann, ist die : ob ein formal richtiges Programm auch das Gemeinte tut.