1

I'm having trouble fixing shift/reduce conflicts in my grammar. This is the grammar:

body: variable_decl function_list
    | variable_decl
    ;

variable_decl: variable variable_decl
             | /* no variables declaration */

variable: KW_STATIC basictypes varhelp2 SEMICOLON
        | basictypes varhelp2 SEMICOLON 
        ;

varhelp2: varhelp2 COMA id varhelp1
        | id varhelp1
        ;

varhelp1: dimarray
        | ASSIGN constants
        ;

dimarray: /* no array */ 
        | LBRACKET id RBRACKET dimarray
        ;

constants: pint
         | real
         | bool
         ;

basictypes: KW_INTEGER 
          | KW_BOOLEAN 
          | KW_CHARACTER 
          | KW_REAL 
          | KW_STRING
          ;

function_list: function_list function
             | function
             ;

function: KW_VOID id LEFT_PARENTHESIS function_help1 RIGHT_PARENTHESIS
        | basictypes id LEFT_PARENTHESIS function_help1 RIGHT_PARENTHESIS
        ;

function_help1: /* empty */ 
              | function_help2
              ;

function_help2: function_help2 COMA basictypes id
              | basictypes id 
              ;

I think the problem is caused by function_list and variable_decl. Both functions and variables can start with basictypes and id. How should I make function_list in order to resolve this problem?

I 've tried a lot of things, I've changed my grammar several times but the shift/reduce conflicts remain. I 've just started with bison and I lack of experience, so any help would be greatly appreciated.

Here is the bison debug output:

State 0

    0 $accept: . program $end
    1 program: . body
    7 body: . variable_decl function_list
    8     | . variable_decl
    9 variable_decl: . variable variable_decl
   10              | . %empty  [$end, KW_BOOLEAN, KW_INTEGER, KW_CHARACTER, KW_REAL, KW_STRING, KW_VOID]
   11 variable: . KW_STATIC basictypes varhelp2 SEMICOLON
   12         | . basictypes varhelp2 SEMICOLON
   27 basictypes: . KW_INTEGER
   28           | . KW_BOOLEAN
   29           | . KW_CHARACTER
   30           | . KW_REAL
   31           | . KW_STRING

    KW_STATIC     shift, and go to state 1
    KW_BOOLEAN    shift, and go to state 2
    KW_INTEGER    shift, and go to state 3
    KW_CHARACTER  shift, and go to state 4
    KW_REAL       shift, and go to state 5
    KW_STRING     shift, and go to state 6

    KW_BOOLEAN    [reduce using rule 10 (variable_decl)]
    KW_INTEGER    [reduce using rule 10 (variable_decl)]
    KW_CHARACTER  [reduce using rule 10 (variable_decl)]
    KW_REAL       [reduce using rule 10 (variable_decl)]
    KW_STRING     [reduce using rule 10 (variable_decl)]
    $default      reduce using rule 10 (variable_decl)

    program        go to state 7
    body           go to state 8
    variable_decl  go to state 9
    variable       go to state 10
    basictypes     go to state 11




State 10

    9 variable_decl: . variable variable_decl
    9              | variable . variable_decl
   10              | . %empty  [$end, KW_BOOLEAN, KW_INTEGER, KW_CHARACTER, KW_REAL, KW_STRING, KW_VOID]
   11 variable: . KW_STATIC basictypes varhelp2 SEMICOLON
   12         | . basictypes varhelp2 SEMICOLON
   27 basictypes: . KW_INTEGER
   28           | . KW_BOOLEAN
   29           | . KW_CHARACTER
   30           | . KW_REAL
   31           | . KW_STRING

    KW_STATIC     shift, and go to state 1
    KW_BOOLEAN    shift, and go to state 2
    KW_INTEGER    shift, and go to state 3
    KW_CHARACTER  shift, and go to state 4
    KW_REAL       shift, and go to state 5
    KW_STRING     shift, and go to state 6

    KW_BOOLEAN    [reduce using rule 10 (variable_decl)]
    KW_INTEGER    [reduce using rule 10 (variable_decl)]
    KW_CHARACTER  [reduce using rule 10 (variable_decl)]
    KW_REAL       [reduce using rule 10 (variable_decl)]
    KW_STRING     [reduce using rule 10 (variable_decl)]
    $default      reduce using rule 10 (variable_decl)

    variable_decl  go to state 18
    variable       go to state 10
    basictypes     go to state 11
Mike7
  • 11
  • 3
  • This is essentially the same problem as http://stackoverflow.com/questions/43579367/shift-reduce-conflict (possibly a classmate of yours :-) ) and if I were to answer, I would produce basically the same answer. So read it and see if it helps. – rici Apr 29 '17 at 18:59
  • By the way, do try to use meaningful names. Avoid plurals if the non-terminal produces only one token (`basic_type` and `constant`, not `basictypes` and `constants`); do use a plural or the word "list" (consistently!) for non-terminals which produce a list (`variable_decl_list`, not `variable_decl`, and generally try to be descriptive (`optional_parameters` and `parameter_list`, not `function_help1` and `function_help2`); use underscores consistently or not at all; and use lower-case for non-terminals and upper case for terminals (not `pint`, `real` and `bool`)... – rici Apr 29 '17 at 19:02
  • Similarly, use single-character tokens if possible, and if not be consistent with your names. Eg., ideal is `'('`, `')'`, `'['`, `']'`, but if you feel the absolute need to name (why?) then use `LBRACKET` and `LPARENTHESIS` or `LEFT_BRACKET` and `LEFT_PARENTHESIS`. Mixing `LBRACKET` and `LEFT_PARENTHESIS` gives the impression that you are copying and pasting from different sources rather than writing your own code. – rici Apr 29 '17 at 19:05

0 Answers0