As others have noted, the problem is that you need more than one token of lookahead to differentiate between a function definition and a function call. The problem with the grammar as written is that it needs to decide between reducing the rule trailed: NAME
and shifting to match the rule statement: NAME arglist COLON expression SEMICOLON
after seeing a NAME
when the lookahead is OPAREN
. But it can't decide until after it sees the arglist to see if there's a COLON
after it or not (which is what distinguishes the two cases).
To fix this, you need to refactor the grammar so that there's no need to reduce anything only present on one alternative until you get to the COLON
. With this grammar, you can do this by refactoring the trailed
rule to always require at least one arglist, and making a NAME
with no arglist
a separate expression
rule:
trailed:
NAME arglist
| trailed arglist;
expression:
NAME
| trailed
| expression PLUS NAME
| expression PLUS trailed;
Now when your get an input NAME OPAREN ...
there's no need to reduce anything yet -- you just shift into the rule matching an arglist
and after matching the arglist
, you can see the next token and decide whether this is a function call or a function definition.