所以我的规则是
/* Addition and subtraction have the lowest precedence. */
additionExp returns [double value]
: m1=multiplyExp {$value = $m1.value;}
( op=AddOp m2=multiplyExp )* {
if($op != null){ // test if matched
if($op.text == "+" ){
$value += $m2.value;
}else{
$value -= $m2.value;
}
}
}
;
AddOp : '+' | '-' ;
我的测试是3 + 4
,但op.text总是返回NULL,从不返回字符。
有人知道我如何测试AddOp的价值吗?
在ANTLR4 Actions and Attributes的例子中,它应该起作用:
stat: ID '=' INT ';'
{
if ( !$block::symbols.contains($ID.text) ) {
System.err.println("undefined variable: "+$ID.text);
}
}
| block
;
您确定$op.text
总是null
吗?您的比较显示为检查$op.text=="+"
,而不是检查null
。
-
在回答这些问题时,我总是建议您在使用ANTLR 4时将所有操作代码迁移到侦听器和/或访问者。它将清理您的语法,并大大简化代码的长期维护。
-
这可能是这里的主要问题:在Java中比较
String
对象应该使用equals
:"+".equals($op.text)
执行。请注意,我使用此排序来保证您永远不会得到NullPointerException
,即使$op.text
是null
。 -
我建议删除
op=
标签,改为引用$AddOp
。-
当您切换到使用侦听器和访问者时,删除显式标签将略微减少解析树的大小。
-
(仅与高级用户相关)在某些涉及语法错误的边缘情况下,当对象仍然存在于解析树中时,可能不会分配标签。特别是,当标签被分配给规则引用(
op
标签被分配到令牌引用),并且在标记的规则中出现错误时,可能会发生这种情况。如果您通过侦听器/访问者中自动生成的方法引用上下文对象,则即使没有分配标签,实例也将可用,从而提高了报告某些错误详细信息的能力。
-