Eine Bekannte hat mich kürzlich gefragt, ob ich so Bücher kenne wie "Compilers: Principles, Techniques, and Tools" (das so genannte Drachenbuch). Meine Meinung: Man kann nur hoffen, dass Compilerbauer dieses Buch höchstens als Schrankfußersatz verwenden.
Was hab ich damit für Probleme:
a) Es wird mit Kanonen auf Spatzen geschossen. (LEX)
b) Die Theorie der formalen Sprachen, die da immer zugrunde gelegt wird, ist für Compilerbau ungeeignet. Wozu brauche ich eine Fabrik die Autos herstellen kann, die für Fahrer mit einer variablen Anzahl von Gliedmaßen bestimmt sind?
c) Ich brauche nicht etwas, was mir zu einem Text sagt "Gehört zur Sprache L" oder "Gehört nicht zur Sprache L". Was bringt das? Was ich brauche, ist erstmal ein Syntaxbaum und dann etwas, mit dem ich denselben durchwandere, um den Code zu "stricken".
Klar geht das mit den o. g. Tools, aber es ist reingefummelt, viel zu kompliziert und viel zu eingeschränkt.
Deshalb geht Reni anders vor: Reni hat einen Prioritätsparser, der den Syntaxbaum erstellt und einen kontextabhängigen Visitor, der durch den Baum marschiert und dabei den Code erzeugt.
Der kontextabhängige Visitor wird später vorgestellt. Hier geht es zunächst um den Prioritätsparser.
Jeder kennt die Regel "Punktrechnung geht vor Strichrechnung". Nichts anderes ist das Prinzip des Prioritätsparsers (Eine entscheidende Kleinigkeit kommt noch dazu, doch davon gleich.).
Der Ausdruck 2 + 3 * 4 ergibt 14, weil erst 3*4 gerechnet werden muss und dann das Ergebnis zu 2 addiert wird. Das Beispiel ist sehr einfach, hier die Darstellung als Syntaxbaum:
P(Zahl) > P("*", "/") > P("+", "-")
Was ist aber jetzt mit einem Ausdruck wie 2 + 3 + 4? Sieht simpel und unproblematisch aus. Aber das gilt nur für einen menschlichen Betrachter. Der arme Compiler hat nämlich jetzt keine Ahnung, ob er erst 2 + 3 rechnen muss
Was wäre, wenn man die Priorität nicht als Ordnungsrelation ansetzt, sondern einfach nur als Relation - mit einer schnöden Tabelle? Hier mal ein Beispiel für eine solche Tabelle (Erklärt wird sie im nächsten Eintrag):
(bot) | ( | (any) | * | / | + | - | ) | |
---|---|---|---|---|---|---|---|---|
( | <- | <- | <- | <- | <- | <- | <- | ^^ |
(any) | <- | <- | ^^ | <- | <- | <- | <- | ^^ |
* | <- | <- | ^^ | ^^ | ^^ | <- | <- | ^^ |
/ | <- | <- | ^^ | ^^ | ^^ | <- | <- | ^^ |
+ | <- | <- | ^^ | ^^ | ^^ | ^^ | ^^ | ^^ |
- | <- | <- | ^^ | ^^ | ^^ | ^^ | ^^ | ^^ |
) | <- | = | ^^ | ^^ | ^^ | ^^ | ^^ | ^^ |
(eot) | = | ^^ | ^^ | ^^ | ^^ | ^^ | ^^ | ^^ |