5. Kontextfreie Sprachen
5.1 Ableitungen und Ableitungsbäume
Betrachten wir im Folgenden ein weiteres Beispiel einer Ableitung, in diesem Falle eine Rechtsableitung, in der in jedem Schritt das am weitesten rechts stehende Nichtterminal expandiert wird:
\begin{align*} E & \stackrel{2}{\Longrightarrow} T \stackrel{3}{\Longrightarrow} T * F \stackrel{5}{\Longrightarrow} T * (E) \stackrel{1}{\Longrightarrow} T * (E+T) \stackrel{4}{\Longrightarrow} T * (E+F) & \\ & \stackrel{6}{\Longrightarrow} T * (E+a) \stackrel{2}{\Longrightarrow} T * (T + a) \stackrel{4}{\Longrightarrow} T * (F + a) & \\ & \stackrel{6}{\Longrightarrow} T * (a + a) \stackrel{4}{\Longrightarrow} F * (a + a) \stackrel{6}{\Longrightarrow} a * (a + a) & \end{align*} Rechtsableitungen können auch kompakt als Zahlenfolge repräsentiert werden. Allerdings geben wir Rechtsableitungen immer in umgekehrter Reihenfolge an, also von hinten nach vorne, in diesem Falle also nicht 2351... sondern 64642641532.Beachten Sie, dass wir es hier mit einer eindeutigen Grammatik zu tun haben, es also nur einen Syntaxbaum gibt:
Rechtsableitung und Linksableitung sowie deren Codierung als Zahlenfolge spiegeln also nur zwei verschiedene Weisen wieder, den Baum auszugeben.
def treeToLeftDerivation (tree):
print tree.ruleAtRoot (bzw. drucke nur die Nummer der Regel)
for child in tree.children (from left ro right):
treeToLeftDerivation(child)
def treeToRightDerivation (tree):
for child in tree.children (from left ro right):
treeToLeftDerivation(child)
print tree.ruleAtRoot (bzw. drucke nur die Nummer der Regel)
Beachten Sie, dass wir in beiden Fällen die Liste Kinder von links nach rechts durchgehen.