[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