[antlr-interest] Precedence problem
Tim Halloran
hallorant at gmail.com
Thu Oct 30 10:44:35 PDT 2008
Well, one fix is to separate, taking "sin" as an example, sin SPACE from sin(
I just made the SPACE significant -- It seems to work on all your
examples. Good luck
grammar Expression;
options {
output = AST;
ASTLabelType=CommonTree;
}
expr
: addExpr EOF!
;
addExpr
: multExpr (('+'^|'-'^) multExpr)*
;
multExpr
: unaryExpr (('*'^|'/'^) unaryExpr)*
;
unaryExpr
: '~'^ expExpr
| sinExpr
| cosExpr
| lnExpr
| expExpr
;
sinExpr
: 'sin ' expExpr
;
cosExpr
: 'cos ' WHITESPACE expExpr
;
lnExpr
: 'ln ' WHITESPACE expExpr
;
expExpr
: atom ('^'^ atom)*
;
atom
: parenExpr
| NUMBER
| VAR
;
parenExpr
: 'sin(' addExpr ')'
| 'cos(' addExpr ')'
| 'ln(' addExpr ')'
| '('! addExpr ')'!
;
NUMBER : '-'? '0'..'9'+ ('.' '0'..'9'*)? ;
VAR : 'x' ;
WHITESPACE : (' '|'\t'|'\n'|'\r')+ { skip(); } ;
On Thu, Oct 30, 2008 at 1:05 PM, Todd O'Bryan <toddobryan at gmail.com> wrote:
> 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(); } ;
>
> List: http://www.antlr.org/mailman/listinfo/antlr-interest
> Unsubscribe: http://www.antlr.org/mailman/options/antlr-interest/your-email-address
>
>
More information about the antlr-interest
mailing list