[antlr-interest] Precedence problem
Todd O'Bryan
toddobryan at gmail.com
Thu Oct 30 10:05:44 PDT 2008
I've assigned my high school programming students a symbolic algebra
project and provided them an ANTLR parser so they could translate
Strings to values easily. I used an AST, so the translation is pretty
easy. The basic idea is a mapping like this:
"sin(x ^ 2)" --> new Sin(new Exp(new Var(), new Number(2.0))
Everything was working great, until... I wanted exponentiation to have
higher precedence than unary operators, so
"~x^3" ---> new Neg(new Exp(new Var(), new Number(2.0)))
"sin x ^ 2" ---> new Sin(new Exp(new Var(), new Number(2.0)))
But a student tried this:
"sin(x) ^ 2"
Clearly this SHOULD be new Exp(new Sin(new Var()), new Number(2.0)),
but since ^ has higher precedence than sin, it doesn't work.
I can't figure out how to fix it, however, because sin(...) should
have the same precedence as a parenthesized expression (higher than
^), but sin ... should have lower precedence. I tried a syntactic
predicate, but since the sin rule is in two rules, I can't get rid of
the ambiguity. Here's my grammar that doesn't work. Can anybody help?
grammar Expression;
options {
output = AST;
ASTLabelType=CommonTree;
}
expr : addExpr EOF!
;
addExpr : multExpr (('+'^|'-'^) multExpr)*
;
multExpr : unaryExpr (('*'^|'/'^) unaryExpr)*
;
unaryExpr : ('sin'^|'cos'^|'ln'^|'~'^) expExpr
| expExpr
;
expExpr : atom ('^'^ atom)*
;
parenExpr : ('sin'^|'cos'^|'ln'^|'~'^)? '('! addExpr ')'!
;
atom : parenExpr
| NUMBER
| VAR
;
NUMBER : '-'? '0'..'9'+ ('.' '0'..'9'*)? ;
VAR : 'x' ;
WHITESPACE : (' '|'\t'|'\n'|'\r')+ { skip(); } ;
More information about the antlr-interest
mailing list