tengo una gramática sencilla:reglas antlr AST fallar con 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;} ;
Ahora quiero añadir algunas reglas de reescritura para generar un AST. Por lo que he leído en línea y en el libro de patrones de lenguaje, yo debería ser capaz de modificar la gramática de esta manera:
assignment
: IDENT ':=' expr ';' -> ^(':=' IDENT expr)
;
expr
: factor ('*' factor)* -> ^('*' factor+)
;
factor
: primary ('+' primary)* -> ^('+' primary+)
;
primary
: NUM
| '(' expr ')' -> ^(expr)
;
Pero no funciona. Aunque compila bien, cuando ejecuto el analizador obtengo un error RewriteEmptyStreamException. Aquí es donde las cosas se ponen raras.
Si defino los pseudocódigos ADD y MULT y los uso en lugar de los literales del nodo de árbol, funciona sin error.
tokens { ADD; MULT; }
expr
: factor ('*' factor)* -> ^(MULT factor+)
;
factor
: primary ('+' primary)* -> ^(ADD primary+)
;
Alternativamente, si utilizo la notación nodo sufijo, sino que también parece funcionar bien:
expr
: factor ('*'^ factor)*
;
factor
: primary ('+'^ primary)*
;
¿Es esta discrepancia en el comportamiento de un error?
Gracias a ton @JoelPM. Esto es exactamente lo que estaba buscando. Tuvimos un problema con los desbordamientos de pila y árboles anidados mientras evaluamos.Esto nos da la oportunidad de generar un árbol N-ary y reduce drásticamente la profundidad del árbol –