Java 扩展令牌选择操作符
我在ANTLR3中有一个表达式Java 扩展令牌选择操作符,java,antlr,antlr3,lexer,Java,Antlr,Antlr3,Lexer,我在ANTLR3中有一个表达式 num_addition : num_multi ((plus^|minus^) num_multi)* ; 我想把标记“加”和“减”改成一个不同的标记,所以我试着制定这个重写规则 num_addition : num_multi (plus num_multi)* -> ^(num_multi ^(plus_special num_multi)*) | num_multi (minus num_multi)* ->
num_addition
: num_multi ((plus^|minus^) num_multi)*
;
我想把标记“加”和“减”改成一个不同的标记,所以我试着制定这个重写规则
num_addition
: num_multi (plus num_multi)* -> ^(num_multi ^(plus_special num_multi)*)
| num_multi (minus num_multi)* -> ^(num_multi ^(minus_special num_multi)*)
;
如果我这样做,ANTLRWORKS中的生成似乎需要更长的时间,但它生成了正确的语法和标记。如果我将此样式应用于其他规则,例如“multi”和“divide”以及“equalequal”等,那么当我按下Generate时,AntlWorks最终将无法执行任何操作
根据ANTLRWORKS,没有错误,但当I pres生成时,什么也没有发生
我是否错误地改写了我想要实现的目标 您不能将任何产品或终端注入到您的AST中,这些产品或终端在您为其创建AST的解析器规则中不匹配。在本例中,您可以插入
plus
或minus
,因为它们由解析器规则匹配,但不能插入plus_special
或minus_special
,因为它们不由解析器规则num_addition
匹配
不过,您可以注入虚构的令牌
试着这样做:
grammar T;
tokens {
// Some imaginary tokens:
PLUS_SPECIAL;
MINUS_SPECIAL;
}
// ...
num_addition
: (a=num_multi -> $a) ( PLUS b=num_multi -> ^(PLUS_SPECIAL $num_addition $b)
| MINUS b=num_multi -> ^(MINUS_SPECIAL $num_addition $b)
)*
;
// ...
PLUS : '+';
MINUS : '-';
我希望您也可以插入普通令牌(加上而不是加上特殊)。但您对任意产品的看法是正确的。@MikeLischke,是的,您可以插入普通标记(或产品中的AST),只要它们在产品中匹配:您不能在要创建AST的产品中插入不匹配的普通标记。我将重新表述我的答案。很好的答案。正是我要找的!Grammar生成代码,但它看起来确实较慢。我在所有数学和逻辑运算符中都使用了这段代码,使用ANTLRWorks开始代码生成甚至需要4分钟。那只是大约20秒之前。这似乎出乎意料。@meriley你有
backtrack=true代码>定义,有可能吗?如果是这样,您可以尝试启用memoize=true代码>以及加快速度。给ANTLR更多的堆空间也值得一试。同时也要检查它是否会把事情搞砸:还要从shell中进行测试。