ANTLR - 合成和继承的属性

时间:2014-03-30 13:06:29

标签: antlr grammar

我有一个简单的语法,我必须为算术表达式实现评估器,并注意到特定的ANTLR。

语法:

        start ::= expr
        expr    ::= term exprp
        exprp ::= + term exprp
                  | - term exprp
                  | e
        term    ::= fact termp
        termp ::= * fact termp
                  | / fact termp
                  | e
        fact    ::= ( expr ) | ID | NUM

带有属性的语法:

        start ::= expr
        expr    ::= term {exprp.i = term.val} exprp {expr.val = exprp.val}
        exprp ::= + term {exprp1.i = exprp.i + term.val} exprp1 {exprp.val = exprp1.val}
                  | - term {exprp1.i = exprp.i - term.val} exprp1 {exprp.val = exprp1.val}
                  | e {exprp.val = exprp.i}
        term    ::= fact {termp.i = fact.val} termp {term.val = termp.val}
        termp ::= * fact {termp1.i = termp.i * fact.val} termp1 {termp.val = termp1.val}
                  | / fact {termp1.i = termp.i/fact.val} termp1 {termp.val = termp1.val}
                  | e {termp.val = termp.i}
        fact    ::= ( expr ) {fact.val = expr.val}
                  | NUM {fact.val = Integer.parseInt(NUM.text)}

我写了这个:

grammar Expr;

start
    : expr EOF              { System.out.println($expr.val); }
    ;

expr returns [int val]
    : term exprP[$exprP.i = $term.val]      { $val = $exprP.val; }
    ;

exprP[int i] returns [int val]
    :                                           { $val = $i; }
    | '+' term e = exprP[$i + $term.val]        { $val = $e.val; }
    | '-' term e = exprP[$i - $term.val]        { $val = $e.val; }
    ;

term returns [int val]
    : fact termP[$termP.i = $fact.val]      { $val = $termpP.val; }
    ;

termP[int i] returns [int val]
    :                                           { $val = $i; }
    | '*' fact e = termP[$i * $fact.val]        { $val = $e.val; }
    | '/' fact e = termP[$i / $fact.val]        { $val = $e.val; }
    ;

fact returns [int val]
    : '(' expr ')'                  { $val = $expr.val; }
    | NUM                                       { $val = Integer.parseInt($NUM.text); }
    ;

ID : ('a'.. 'z'|'A'.. 'Z') ('a'.. 'z'|'A'.. 'Z'|'0'.. '9'|'_')* ;

NUM : '0'.. '9'+ ;

WS : (' ' | '\t' | '\r' | '\n')+        { skip (); } ;  

但是当我用命令:

调用ANTLR工具时
java -cp antlr-3.5-complete.jar org.antlr.Tool Expr.g

存在以下错误:

error(115): II.2/Expr.g:0:: cannot access rule exprP's parameter: i
error(115): II.2/Expr.g:0:: cannot access rule termP's parameter: i

我明白错误在哪里,但我不知道如何解决它们。有人向我解释了什么是错的,我该如何解决?非常感谢你

1 个答案:

答案 0 :(得分:3)

问题出在您的exprterm规则中。

  1. expr中,您尝试分配$exprP.i而不是仅传递参数。它应该如下所示。

    expr returns [int val]
        : term exprP[$term.val]     { $val = $exprP.val; }
        ;
    
  2. expr中,您尝试分配$termP.i而不是仅传递参数。它应该如下所示。

    term returns [int val]
        : fact termP[$fact.val]     { $val = $termpP.val; }
        ;
    
  3. 我认为较新版本的ANTLR 3(3.5.2是最新版本)在为这些错误提供行号和列号方面做得更好,但这可能是ANTLR 4的新功能。