所以我的规则是
/* 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而不是char。
有谁知道我如何测试AddOp的值?
在ANTLR4 Actions and Attributes的示例中,它应该有效:
stat: ID '=' INT ';'
{
if ( !$block::symbols.contains($ID.text) ) {
System.err.println("undefined variable: "+$ID.text);
}
}
| block
;
答案 0 :(得分:1)
您确定$op.text
始终是null
吗?您的比较似乎是检查$op.text=="+"
而不是检查null
。
我总是提出这些答案时建议您在使用ANTLR 4时将所有操作代码迁移到侦听器和/或访问者。它将清理您的语法并大大简化代码的长期维护。
这可能是此处的主要问题:比较Java中的String
对象应使用equals
:"+".equals($op.text)
执行。请注意,即使NullPointerException
为$op.text
,我也使用此排序来保证您永远不会获得null
。
我建议删除op=
标签并改为引用$AddOp
。
当您切换到使用侦听器和访问者时,删除显式标签会略微减小解析树的大小。
(仅与高级用户相关)在涉及语法错误的某些边缘情况下,如果对象仍存在于解析树中,则可能无法分配标签。特别是,当标签分配给规则引用(您的op
标签已分配给令牌引用)时,可能会发生这种情况,并且标记的规则中会出现错误。如果您通过侦听器/访问者中自动生成的方法引用上下文对象,即使未分配标签,实例也将可用,从而提高报告某些错误详细信息的能力。