2014-01-09 28 views
1

所以我的原则是令牌空当匹配语法规则,虽然符合

/* 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 : '+' | '-' ; 

我的测试IST 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 
    ; 
+0

有相当多的事情不正确,据我所知。 ANTLR工具是否接受你的语法?我认为它应该会产生'additionExp'工具的错误,因为actions/embedded-code必须放在替代的末尾。另外,'$ op!= null'也会触发一个错误,不是?最后,你使用'=='比较字符串('$ op.text ==“+”'),这是不正确的(参见:http://stackoverflow.com/questions/767372/java-string-equals-与)。 –

+0

@BartKiers它可以正常工作,你可以从发布的例子中看到。但是你在字符串比较上是正确的。我需要'.equals'而不是'=='。 – RedX

+0

你会惊讶有多少人发布一些不反映他们实际代码的代码片段。 B.t.w.,我只是注意到你把嵌入式代码放在'(...)*'之外。这应该在里面。 –

回答

1

确定$op.text总是null?您的比较似乎检查$op.text=="+"而不是检查null

  1. 我总是从这些答案与您在使用ANTLR 4时,它会清理你的语法,并大大简化代码的长期维护你所有的行动代码迁移到听众和/或观众的建议。

  2. 这可能是这里的主要问题:在Java中比较String对象应使用equals进行:"+".equals($op.text)。请注意,我使用此顺序来保证你永远不会得到NullPointerException,即使$op.textnull

  3. 我建议删除op=标签并引用$AddOp

    1. 当您切换到使用侦听器和访问者时,删除显式标签将稍微减小分析树的大小。

    2. (仅与高级用户相关)在某些涉及语法错误的边界情况下,标记可能不会被分配,而对象仍然存在于分析树中。特别是,当标签分配给规则引用(您的op标签分配给标记引用)时会发生这种情况,并且标记的规则中会显示错误。如果通过侦听器/访问者中自动生成的方法引用上下文对象,即使未分配标签,实例也可用,从而提高了报告某些错误详细信息的能力。