I.5. Kontextfreie Sprachen
Zieht man in Betracht, dass BNF-Syteme gerade so beschaffen sind, dass auf der
linken Seite immer genau ein Nichtterminal steht, so sind das also gerade die
Ableitungsregeln einer kontextfreien Grammatik. Kontextfreie Grammatiken sind also
für die Struktur von Programmiersprachen von prinzipieller Bedeutung. (Ein mittels
BNF-Regeln abgeleitetes Terminalwort ist ein Programm in der jeweiligen
Programmiersprache - mit gewissen Einschränkungen (siehe später).
Ableitungsbäume
Ableitungen in kontextfreien Sprachen werden häufig Ableitungsbäume zugeordnet:
Sei G = (N, T, S, P) eine kontextfreie Grammatik. Jeder Ableitung
S ⇒ w1 ⇒ w2 ⇒ ... ⇒ wn
wird ein Ableitungsbaum mit der Wurzel S wie folgt zugeordnet:
(induktive Definition über n)
Für n = 0 besteht der Baum nur aus dem Knoten S
Ist Bn-1 der Ableitungsbaum von S ⇒ w1 ⇒ w2 ⇒ ... ⇒ wn-1 und entsteht wn
aus wn-1 durch Anwendung der Regel A → w = x1 ... xl, xi ∈ N ∪ T, d.h. wn-1 =
w’ A w’’, wn = w’ w w“,
so erhält man den Ableitungsbaum Bn von S ⇒ w1 ⇒ ... ⇒ wn aus Bn-1, indem
man den Knoten A in Bn-1 ersetzt durch den Baum
A
x1
x2
x3
…
xl
Beispiel:
Sei G = ({S}, {a}, S, {S → a, S → SS})
Der Ableitungsbaum für die Ableitung S ⇒ SS ⇒ aS ⇒ aa ist
S
S
S
a
a
Offenbar können verschiedene Ableitungen den gleichen Ableitungsbaum besitzen;
z.B. hat die Ableitung S ⇒ SS ⇒ Sa ⇒ aa den gleichen Ableitungsbaum.
Die Zuordnung von Ableitungen zu den Ableitungsbäumen wird eineindeutig, wenn
man nur Linksableitungen zulässt:
Definition: Die Ableitung S ⇒ w1 ⇒ w2 ⇒ ... ⇒ wn heißt Linksableitung, wenn bei
jedem Ableitungsschritt das am weitesten links stehende Nichtterminal
vermöge einer Regel aus P ersetzt wird.
Es ist aber möglich, dass es für ein Wort w ∈ L(G) verschiedene Linksableitungen
gibt:
Definition: Die (kontextfreie) Grammatik G heißt mehrdeutig, wenn ∃ w ∈ L(G), so
dass w 2 verschiedene Linksableitungen besitzt.
Anderenfalls heißt G eindeutig.
Die kontextfreie Sprache L heißt eindeutig, wenn es eine eindeutige
kontextfreie Grammatik G mit L = L(G) gibt.
Anderenfalls heißt L mehrdeutig.
Beispiel:
Die Grammatik G = ({S}, {a}, S, {S a, S SS}) ist mehrdeutig, denn es gibt für
aaa die Linksableitungen
S ⇒ SS ⇒ aS ⇒ aSS ⇒ aaS ⇒ aaa
S ⇒ SS ⇒ SSS ⇒ aSS ⇒ aaS ⇒ aaa
mit den Ableitungsbäumen
S
S
S
a
S
S
S
S
S
S
S
a
a
a
a
a
Es ist L(G) = {ai: i ≥ 1}. L(G) ist (natürlich) regulär und wird z.B. von der Grammatik
G1 = ({S}, {a}, S, {S→ a, S→ aS}) erzeugt. G1 ist eindeutig, also auch L(G) = L(G1).
Beispiel:
für eine mehrdeutige kontextfreie Sprache:
L = {ai bj ck : i = j oder j = k}
(o.B.)
Dagegen gilt:
Satz 5.1.:
Jede reguläre Sprache ist eindeutig.
Beweis:
Sei L regulär. Dann wird (nach Hauptsatz für die regulären Sprachen) L von einem
DA akzeptiert. Im Beweisteil (i) ⇒ (ii) wird dann gerade eine eindeutige Grammatik G
mit L = L(G) konstruiert.
Normalformen
Es gibt für eine kontextfreie Sprache L viele verschiedene Grammatiken, die L
erzeugen. Für Einsichten in die Struktur solcher Sprachen sind gewisse
„Normierungen“ für erzeugende Grammatiken relevant. Hier sei nur eine erwähnt:
Definition: Eine kontextfreie Grammatik G = (N, T, S, P} ist in ChomskyNormalform, wenn alle Regeln von der Form X YZ oder X a mit
X, Y; Z ∈ N, a ∈T sind.
Satz 5.2.:
Zu jeder kontextfreien Grammatik G = (N, T, S, P) mit ε ∉ L(G) gibt es
eine äquivalente kontextfreie Grammatik G’ in Chomsky-Normalform.
(o.B.)
Zum Pumping-Lemma für reguläre Sprachen gibt es ein Analogon:
Satz 5.3.: (Pumping-Lemma für kontextfreie Sprachen)
Sei L kontextfrei. Dann gibt es eine natürliche Zahl n, so dass für jedes Wort w ∈ L
mit w ≥ n gilt: Es gibt w1, w2, w3, w4, w5, mit w = w1w2w3w4w5, w2w3w4≤ n,
w2w4 ≠ ε,
und w1 w2i w3 w4i w5 ∈ L ∀i ≥ 0 .
Das P.-Lemma erlaubt häufig den Nachweis, dass eine Sprache nicht kontextfrei ist.
L={v v : v ∈ {0,1}*}
Beispiel:
Angenommen L wäre kontextfrei. Dann existierte eine Zahl n mit den Eigenschaften
des Pumping-Lemmas. Sei w = 1 ...1 0 ...0 1 ... 1 0 ...0 ∈ L
Dann ist also w = w1w2w3w4w5
n
n
n
n
mit w2w3w4≤ n.
Wenn w2w3w4 in der 1.Hälfte von w liegt, so endet im für i = 0 erzeugten Wort die
1. Hälfte mit 1, die 2. mit 0 (falls überhaupt: ein Wort gerader Länge entsteht).
Wenn w2w3w4 in der 2.Hälfte von w liegt, so beginnt im für i = 0 erzeugten Wort die
1. Hälfte mit 1, die 2. Hälfte mit 0.
Wenn w2w3w4 die Mitte überlappt, so beginnt im für i = 0 erzeugten Wort die 1. Hälfte
mit n Einsen, die 2. nicht.
Bemerkung:
Dieses Beispiel dokumentiert die mangelnde Kopierfähigkeit kontextfreier
Grammatiken. Eine Konsequenz ist, dass die meisten Programmiersprachen nicht
kontextfrei sind.
Z.B. gibt es in Pascal die Bedingung, dass Anzahl und Typen der formalen
Parameter und der aktuellen Parameter übereinstimmen müssen. Diese Bedingung
lässt sich - unserem obigen Beispiel entsprechend - nicht durch BNF-Regeln
formulieren!
Bei Programmiersprachen erzeugt man durch kontextfreie Grammatiken (BNFRegeln) eine echte Obermenge der zulässigen Programme, aus denen die
Programme durch verbale Einschränkungen ausgesondert werden.
Abschlusseigenschaften
Satz 5.4.:
Kontextfreie Sprachen sind abgeschlossen gegenüber den regulären
Operationen Vereinigung, Verkettung und Iteration.
Beweis:
Seien L1 = L(G1) und L2 = L(G2) erzeugt von den kontextfreien Grammatiken
G1= (N1, T1, S1, P1) , G2= (N2, T2, S2, P2) und o.B.d.A. sei N1∩N2 = ∅.
Seien S3, S4, S5 neue Nichtterminale.
G3 := (N1 ∪ N2 ∪ {S3}, T1 ∪ T2, S3, P3) mit P3 = P1 ∪ P2 ∪ {S3 → S1, S3 → S2}.
Offenbar ist L(G3) = L1 ∪ L2.
G4 := (N1 ∪ N2 ∪ {S4}, T1 ∪ T2, S4, P4) mit P4 = P1 ∪ P2 ∪ {S4 → S1S2}.
Offenbar ist L(G4) = L1L2.
G5 := (N1 ∪ {S5}, T1, S5, P5) mit P5 = P1 ∪ {S5 → ε, S5 → S1S5}.
Offenbar ist L(G5) = L1*.
Satz 5.5.:
Die kontextfreien Sprachen sind nicht abgeschlossen gegenüber
Durchschnitten.
Beweis:
L2 := {ai bi cj : i ≥ 1, j ≥1}
L3 := {ai bj cj : i ≥ 1, j ≥1}
L2 wird erzeugt von Grammatik mit den Produktionen
S AB, A aAbab, B cBc
(Übung!!)
L3 wird erzeugt von Grammatik mit den Produktionen
S CD, C aCa, D bDcbc
Aber L2 ∩ L3 = { ai bi ci : i ≥ 1} ist nicht kontextfrei
(Übung!!)
(Übung!)