【发布时间】:2010-04-26 00:26:48
【问题描述】:
我有一个简单的语法:
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;} ;
现在我想添加一些重写规则来生成 AST。根据我在网上和语言模式书中阅读的内容,我应该能够像这样修改语法:
assignment
: IDENT ':=' expr ';' -> ^(':=' IDENT expr)
;
expr
: factor ('*' factor)* -> ^('*' factor+)
;
factor
: primary ('+' primary)* -> ^('+' primary+)
;
primary
: NUM
| '(' expr ')' -> ^(expr)
;
但它不起作用。虽然它编译得很好,但是当我运行解析器时,我得到了 RewriteEmptyStreamException 错误。这就是事情变得奇怪的地方。
如果我定义伪标记 ADD 和 MULT 并使用它们而不是树节点文字,它可以正常工作。
tokens { ADD; MULT; }
expr
: factor ('*' factor)* -> ^(MULT factor+)
;
factor
: primary ('+' primary)* -> ^(ADD primary+)
;
或者,如果我使用节点后缀表示法,它似乎也可以正常工作:
expr
: factor ('*'^ factor)*
;
factor
: primary ('+'^ primary)*
;
这种行为差异是错误吗?
【问题讨论】: