Java 扩展令牌选择操作符

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)* ->

我在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_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中进行测试。