Ich habe eine einfache Grammatik:ANTLR AST Regeln scheitern mit RewriteEmptyStreamException
grammar sample;
options { output = AST; }
assignment
: IDENT ':=' expr ';'
;
expr
: factor ('*' factor)*
;
factor
: primary ('+' primary)*
;
primary
: NUM
| '(' expr ')'
;
IDENT : ('a'..'z')+ ;
NUM : ('0'..'9')+ ;
WS : (' '|'\n'|'\t'|'\r')+ {$channel=HIDDEN;} ;
Jetzt möchte ich einige Rewrite-Regeln fügen Sie ein AST zu erzeugen. Von dem, was ich habe online und in der Sprache Patterns Buch lesen, soll ich in der Lage sein, die Grammatik wie folgt zu ändern:
assignment
: IDENT ':=' expr ';' -> ^(':=' IDENT expr)
;
expr
: factor ('*' factor)* -> ^('*' factor+)
;
factor
: primary ('+' primary)* -> ^('+' primary+)
;
primary
: NUM
| '(' expr ')' -> ^(expr)
;
Aber es funktioniert nicht. Obwohl es kompiliert, wenn ich den Parser ausführen, erhalte ich einen RewriteEmptyStreamException Fehler. Hier wird es komisch.
Wenn ich die Pseudo-Token ADD und MULT definiere und sie anstelle der Tree-Node-Literale verwende, funktioniert es ohne Fehler.
tokens { ADD; MULT; }
expr
: factor ('*' factor)* -> ^(MULT factor+)
;
factor
: primary ('+' primary)* -> ^(ADD primary+)
;
Alternativ kann, wenn ich den Knoten Suffix-Notation, wie es scheint auch zu funktionieren:
expr
: factor ('*'^ factor)*
;
factor
: primary ('+'^ primary)*
;
Ist diese Diskrepanz im Verhalten ein Fehler?
Danke eine Tonne @JoelPM. Genau das habe ich gesucht. Wir hatten ein Problem mit tief verschachtelten Baum- und Stapelüberläufen während der Auswertung.Dies gibt uns die Möglichkeit, einen N-ary-Baum zu erzeugen und die Baumtiefe drastisch zu reduzieren –