Ich habe eine einfache Grammatik:
%Vor%Nun möchte ich einige Rewrite-Regeln hinzufügen, um einen AST zu generieren. Von dem, was ich online gelesen habe und in dem Language Patterns-Buch, sollte ich in der Lage sein, die Grammatik wie folgt zu ändern:
%Vor%Aber es funktioniert nicht. Obwohl es kompiliert, wenn ich den Parser ausführen, erhalte ich einen RewriteEmptyStreamException Fehler. Hier werden die Dinge komisch.
Wenn ich die Pseudo-Token ADD und MULT definiere und sie anstelle der Tree-Node-Literale verwende, funktioniert es ohne Fehler.
%Vor%Alternativ, wenn ich die Knotensuffixnotation verwende, scheint es auch zu funktionieren:
%Vor%Ist diese Diskrepanz im Verhalten ein Fehler?
Nein, kein Fehler, AFAIK. Nehmen Sie Ihre expr
Regel zum Beispiel:
Da die *
möglicherweise nicht vorhanden ist, sollte sie auch nicht in Ihrer AST-Rewrite-Regel enthalten sein. Also, das obige ist falsch und ANTLR beschweren sich darüber ist korrekt.
Wenn Sie jetzt stattdessen ein imaginäres Token wie MULT
einfügen:
alles ist in Ordnung, da Ihre Regel immer ein oder mehrere factor
s erzeugt.
Was Sie wahrscheinlich tun wollten, ist so etwas:
%Vor%Siehe auch Kapitel 7: Baumkonstruktion von The Definitive ANTLR Reference . Insbesondere die Absätze Regeln in Unterregeln umschreiben (Seite 173) und Referenzregeln für AST in früheren Regeln in Regeln zum Umschreiben (Seite 174/175).
Wenn Sie einen N-ären Baum für den '*' Operator mit allen Kindern auf der gleichen Ebene generieren möchten, können Sie dies tun:
%Vor%Hier sind einige Beispiele dafür, was dies zurückgibt:
%Vor%Barts drittes Beispiel oben erzeugt einen verschachtelten Baum, da das Ergebnis von $ expr für jede nachfolgende Iteration ein Knoten mit zwei Kindern ist, wie folgt:
%Vor%was Sie wahrscheinlich nicht brauchen, da die Multiplikation kommutativ ist.