[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