views:

26

answers:

2

I have the following lemon grammar (simplified from the real grammar):

%right ASSIGN .
%nonassoc FN_CALL .

program ::= expression .
expression ::= expression ASSIGN expression .
expression ::= function_call . [FN_CALL]
expression ::= IDENTIFIER .


function_call ::= expression LPAREN RPAREN . [FN_CALL]

I'm not able to fix the shift-reduce conflict in the following state:

State 3:
      expression ::= expression * ASSIGN expression
  (1) expression ::= expression ASSIGN expression *
      function_call ::= expression * LPAREN RPAREN
                    ASSIGN shift  1
                    LPAREN shift  4
                    LPAREN reduce 1   ** Parsing conflict **
                 {default} reduce 1

My thought is that the problem was the ambiguity between a=(b(c)) and (a=b)(c), but I would have thought that giving the function call a higher precedence than assignment would fix it. Any ideas what could be the case?

A: 

First and biggest point: a shift-reduce conflict is rarely a real problem. As such, this may well be something you don't need (or even care) to fix.

Second point: unfortunately, it looks to me like you may have over-simplified your grammar. Just for example, the grammar (as you've posted it) looks like both a=(b(c)) and (a=b)(c) should be rejected outright (the only place you've specified an LPAREN, it has to be followed immediately by an RPAREN). What you've posted doesn't give us enough to guess about what's likely to be wrong with the real grammar.

Jerry Coffin
I only parenthesized to show the ambiguity; the two possible parse trees I was trying to show are the ones where the top level expression is a function call whose expression is "a=b" and the tree where the top level expression is an assignment whose first expression is an identifier and whose second is a function call.The problem shows up even in this tiny grammar though; there's a conflict if you compile this as is.
Topoli
A: 

Does this do what you want?

program ::= assignment .

assignment ::= expression ASSIGN assignment .
assignment ::= expression .

expression ::= expression LPAREN RPAREN .
expression ::= IDENTIFIER .

It lets you assign to function calls (which is unusual), but so did your original grammar. I realize this is just a part of a larger grammar.

xscott
That would do it though but yeah the fact that I'd have to rewrite the entire grammar to encode precedence rules sort of makes me a little bit worried there.
Topoli
You won't have to rewrite all of it. You could probably separate it into just binary, prefix, and suffix ops easily enough, and use the %right %left declarations on the binary parts.
xscott