[antlr-interest] Precedence problem

Todd O'Bryan toddobryan at gmail.com
Thu Oct 30 16:30:57 PDT 2008


That makes perfect sense! I was too busy thinking that spaces were
insignificant to realize that they're significant. Thanks!

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