Question

I have a simple grammar and I have to implement the evaluator for arithmetic expressions appropriately noting the specific ANTLR.

Grammar:

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

Grammar with attributes:

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

I wrote this:

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 (); } ;  

But when I invoke the tool ANTLR with the command:

java -cp antlr-3.5-complete.jar org.antlr.Tool Expr.g

There are the following errors:

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

I understand where the errors but I do not know how to solve them. Someone explained to me what is wrong and how can I fix it? Thank you very much

Was it helpful?

Solution

The problems are in your expr and term rules.

  1. In expr, you try to assign $exprP.i instead of just passing an argument. It should look like the following.

    expr returns [int val]
        : term exprP[$term.val]     { $val = $exprP.val; }
        ;
    
  2. In expr, you try to assign $termP.i instead of just passing an argument. It should look like the following.

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

I thought newer versions of ANTLR 3 (3.5.2 is the most recent) did a better job providing line and column numbers for these errors, but that may be a feature that's new to ANTLR 4.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top