Search code examples
parsingsyntax-errorbisonoperator-precedence

Problematic Bison grammar not accepting a call of a call or anything after a call other than ;


I have some grammar here in Bison: https://pastebin.com/raw/dA2bypFR. It's fairly long but not very complex.

The problem is that after a call, it won't accept anything other than ; e.g a(b)(c) and is invalid, a(b).c is invalid, which both only accept a semicolon after the closing parenthesis. a(b)+c is fine though.

I tried separating call_or_getattr into 2 where . has higer precedence than ( but this meant that a().b was invalid grammar.

I also tried putting call and getattr into the definition for basic_operand but this resulted in a 536 shift/reduce errors.


Solution

  • Your last production reads as follows (without the actions, which are an irrelevant distraction):

    call_or_getattr:
        basic_operand
    |   basic_operand '(' csv ')'
    |   basic_operand '.' T_ID
    

    So those are postfix operators whose argument must be a basic_operand. In a(b)(c), the (c) argument list is not being applied to a basic_operand, so the grammar isn't going to match it.

    What you were looking for, I suppose, is:

    call_or_getattr:
        basic_operand
    |   call_or_getattr '(' csv ')'
    |   call_or_getattr '.' T_ID
    

    This is, by the way, very similar to the way you write productions for a binary operator. (Of course, the binary operator has a right-hand operand.)