2009/1/25 Luca <yel...@tin.it>: > 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/ _______________________________________________ help-bison@gnu.org http://lists.gnu.org/mailman/listinfo/help-bison