[antlr-interest] Precedence problem

Tim Halloran hallorant at gmail.com
Thu Oct 30 10:45:34 PDT 2008


Upps, delete the WHITESPACE from cosExpr and lnExpr (harmless but bad)

On Thu, Oct 30, 2008 at 1:44 PM, Tim Halloran <hallorant at gmail.com> wrote:
> 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