help-bison
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Misunderstanding %prec?


From: Tom Lieber
Subject: Re: Misunderstanding %prec?
Date: Sun, 25 Jan 2009 13:21:35 -0500

2009/1/25 Luca <address@hidden>:
> Using your grammar :
>
> %token NEG FUNCALL SEMICOLON ID MINUS LPAREN RPAREN
>
> %left NEG
> %left FUNCALL
>
> %%
>
> input:
> | input exp SEMICOLON
> ;
>
> exp:
>  ID
> | MINUS exp %prec NEG
> | exp LPAREN exp RPAREN %prec FUNCALL
> ;
>
> %%
>
> bison (2.4.1) complains
>
> exp:
>   4    | MINUS exp
> ...
>
> state 6
>
>   4 exp: MINUS exp .
>   5    | exp . LPAREN exp RPAREN
>
>   LPAREN  shift, and go to state 8
>
>   LPAREN    [reduce using rule 4 (exp)]
>   $default  reduce using rule 4 (exp)
>
> state 8
>
>   5 exp: exp LPAREN . exp RPAREN
>
>   ID     shift, and go to state 3
>   MINUS  shift, and go to state 4
>
>   exp  go to state 9
>
> because when, in state 6, it sees a MINUS, followed by an expression and
>  the lookahed symbol is LPAREN, the parser can shift the symbol LPAREN
> (expecting a function) or reduce MINUS exp to an exp (expecting a exp). The
> latter is the default, so -f(); will be never recognized as an function
> call.
>
> You can rewrite the grammar in the following way, this is dirty but right:
>
> %token NEG FUNCALL SEMICOLON ID MINUS LPAREN RPAREN
>
> %left NEG
> %left ID
>
> %%
>
> input:
> | input exp SEMICOLON
> ;
>
> exp:
>  ID
> | MINUS exp %prec NEG
> | ID LPAREN exp RPAREN
> ;
>
> %%
>
> If you don't like it, you have to introduce a precedence using the rules
> rather than Context-Dependent Precedence (% prec % left % right ans so on)
> breaking the "expression rule" in many rules.
> A useful example is the C grammar:
> http://www.lysator.liu.se/c/ANSI-C-grammar-y.html
> where postifix expression has an higher precedence than "numeric expression"
> but no Context-Dependent Precedence is used. The grammar has only one
> conflict, due to the "dangling else", but the default action of bison fixes
> it.
>
> %token NEG FUNCALL SEMICOLON ID MINUS LPAREN RPAREN
> %left NEG
>
> %%
>
> input:
> | input postfix_expression SEMICOLON
> ;
>
> postfix_expression:
>  ID LPAREN exp RPAREN
>  ;
>
> exp:
>  ID
> | MINUS exp %prec NEG
>
> ;
>
> %%
>
> A hint: you can use directly the token '(' rather than LPAREN in .y file; of
> course lex has to return the char and not the token.

Thank you for two good solutions! My question resulted from trying to
move away from a more restrictive grammar with ID LPAREN exp RPAREN,
but I would not have been too upset about splitting up the rule as in
the ANSI C grammar.

I found on another mailing list that a third fix is to set a
precedence for LPAREN, which has side-effects in other part of the
grammar I'm sure, but seems to solve the -a(b) and -a[b] problems
gracefully at least. I'm going to do this one for now (path of least
resistance...) and if problems turn up, I'll turn to splitting up the
rules.

-- 
Tom Lieber
http://AllTom.com/




reply via email to

[Prev in Thread] Current Thread [Next in Thread]