0

I am new in Bison. I've made my .y file but in the compilation I get this error:

warning: 42 shift/reduce conflicts [-Wconflicts-sr]

I've opened the .output file that is produced and I've seen the following but can't understand it and can't figure out where is the problem.

Here is a part of my .output file:

    State 63

   56 expr_decl: KW_NOT expr_decl .  [KW_END, KW_OR, OP_OR, KW_AND, OP_AND, '>', OP_LESSOREQUAL, OP_GREATEROREQUAL, '=', OP_NOTEQUAL, '<', '*', '/', KW_DIV, KW_MOD, ';', ')', '+', '-']
   59          | expr_decl . '*' expr_decl
   60          | expr_decl . '/' expr_decl
   61          | expr_decl . KW_DIV expr_decl
   62          | expr_decl . KW_MOD expr_decl
   63          | expr_decl . '+' expr_decl
   64          | expr_decl . '-' expr_decl
   65          | expr_decl . '=' expr_decl
   66          | expr_decl . '<' expr_decl
   67          | expr_decl . '>' expr_decl
   68          | expr_decl . OP_NOTEQUAL expr_decl
   69          | expr_decl . OP_LESSOREQUAL expr_decl
   70          | expr_decl . OP_GREATEROREQUAL expr_decl
   71          | expr_decl . OP_AND expr_decl
   72          | expr_decl . KW_AND expr_decl
   73          | expr_decl . KW_OR expr_decl
   74          | expr_decl . OP_OR expr_decl

    '+'  shift, and go to state 87
    '-'  shift, and go to state 88

    '+'       [reduce using rule 56 (expr_decl)]
    '-'       [reduce using rule 56 (expr_decl)]
    $default  reduce using rule 56 (expr_decl)

    Conflict between rule 56 and token KW_OR resolved as reduce (KW_OR < KW_NOT).
    Conflict between rule 56 and token OP_OR resolved as reduce (OP_OR < KW_NOT).
    Conflict between rule 56 and token KW_AND resolved as reduce (KW_AND < KW_NOT).
    Conflict between rule 56 and token OP_AND resolved as reduce (OP_AND < KW_NOT).
    Conflict between rule 56 and token '>' resolved as reduce ('>' < KW_NOT).
    Conflict between rule 56 and token OP_LESSOREQUAL resolved as reduce (OP_LESSOREQUAL < KW_NOT).
    Conflict between rule 56 and token OP_GREATEROREQUAL resolved as reduce (OP_GREATEROREQUAL < KW_NOT).
    Conflict between rule 56 and token '=' resolved as reduce ('=' < KW_NOT).
    Conflict between rule 56 and token OP_NOTEQUAL resolved as reduce (OP_NOTEQUAL < KW_NOT).
    Conflict between rule 56 and token '<' resolved as reduce ('<' < KW_NOT).
    Conflict between rule 56 and token '*' resolved as reduce ('*' < KW_NOT).
    Conflict between rule 56 and token '/' resolved as reduce ('/' < KW_NOT).
    Conflict between rule 56 and token KW_DIV resolved as reduce (KW_DIV < KW_NOT).
    Conflict between rule 56 and token KW_MOD resolved as reduce (KW_MOD < KW_NOT).

Any help please? I've been searching for hours and still nothing ..

Here is my declaration part:

%left KW_OR OP_OR
%left KW_AND OP_AND
%left '>' OP_LESSOREQUAL OP_GREATEROREQUAL
%left '=' OP_NOTEQUAL '<'
%left OP_PLUS OP_MINUS
%left '*' '/' KW_DIV KW_MOD
%left cast
%right POSITIVE NEGATIVE
%right KW_NOT '!'

Here is my rule in bison:

expr_decl : 
        | REAL
        | POSINT
        | '!' expr_decl { $$ = template("!(%s)", $2); }
        | KW_NOT expr_decl { $$ = template("not(%s)", $2); }
        | '+' expr_decl %prec POSITIVE { $$ = template("+(%s)", $2); }
        | '-' expr_decl %prec NEGATIVE { $$ = template("-(%s)", $2); }
        | expr_decl '*' expr_decl { $$ = template("%s * %s", $1, $3); }
        | expr_decl '/' expr_decl { $$ = template("%s / %s", $1, $3); }
        | expr_decl KW_DIV expr_decl { $$ = template("%s div %s", $1, $3); }
        | expr_decl KW_MOD expr_decl { $$ = template("%s mod %s", $1, $3); }
        | expr_decl '+' expr_decl %prec OP_PLUS{ $$ = template("%s + %s", $1, $3); }
        | expr_decl '-' expr_decl %prec OP_MINUS{ $$ = template("%s + %s", $1, $3); }
        | expr_decl '=' expr_decl { $$ = template("%s = %s", $1, $3); }
        | expr_decl '<' expr_decl { $$ = template("%s < %s", $1, $3); }
        | expr_decl '>' expr_decl { $$ = template("%s > %s", $1, $3); }
        | expr_decl OP_NOTEQUAL expr_decl { $$ = template("%s <> %s", $1, $3); }
        | expr_decl OP_LESSOREQUAL expr_decl { $$ = template("%s <= %s", $1, $3); }
        | expr_decl OP_GREATEROREQUAL expr_decl { $$ = template("%s >= %s", $1, $3); }
        | expr_decl OP_AND expr_decl { $$ = template("%s && %s", $1, $3); }
        | expr_decl KW_AND expr_decl { $$ = template("%s and %s", $1, $3); }
            | expr_decl KW_OR expr_decl { $$ = template("%s || %s", $1, $3); }
            | expr_decl OP_OR expr_decl { $$ = template("%s or %s", $1, $3); }
                | '(' expr_decl ')' { $$ = template("(%s)", $2); }
;
  • What does your grammar file look like? Did you set a precedence and associativity for all the operators in question? – sepp2k May 01 '18 at 12:18
  • @sepp2k I've set a precedence only for +, - symbol so as to separate the plus and minus operation from the positive and negative sign.. –  May 01 '18 at 12:31
  • Without knowing the precedence of all operators involved, it is impossible to know whether e.g. `a+b*c` is `(a+b)*c` or `a+(b*c)`. This kind of ambiguity causes conflicts. – sepp2k May 01 '18 at 12:36
  • @sepp2k I've used prec for every operator used but still the same.. –  May 01 '18 at 12:53
  • All that `%prec` does is to associate a rule with a terminal symbol, so that those symbol's associativity and precedence are applied to that rule. You don't need that (except for unary + and -, as you said before). What you need is for your terminal symbols to have an associativity and precedence associated with them (or to encode them manually in the grammar if you prefer). You do that with `%left` and `%right` (or `%nonassoc` for operators that have no associativity) declarations in ascending order of precedence. See https://www.gnu.org/software/bison/manual/html_node/Precedence.html – sepp2k May 01 '18 at 13:02
  • It's evident that you do not list `+` and `-` in your precedence declarations (`%left` and `%right`, as @sepp2k notes). The parser state you quote is after the parse sees a `KW_NOT` and the conflict shown is because you have not provided any order for `+` and `-`. You might also want to check the order of your declarations; as shown in that listing, `KW_NOT` comes between `KW_AND` and `KW_OR`, which seems a bit strange to me. – rici May 01 '18 at 15:25
  • @rici okay I've modified my code .. %left KW_OR OP_OR %left KW_AND OP_AND %left '>' OP_LESSOREQUAL OP_GREATEROREQUAL %left '=' OP_NOTEQUAL '<' %left OP_PLUS OP_MINUS %left '*' '/' KW_DIV KW_MOD %left cast %right POSITIVE NEGATIVE %right KW_NOT '!' here is the declaration part .. Still the same problem though .. I can not understand.. I've edited my post and add the declaration part .. –  May 01 '18 at 15:32
  • `OP_PLUS` is not the same token as `'+'`. That confusion is probably the source of your original error. – rici May 01 '18 at 15:36
  • @rici yes , op_plus is for addition and '+' is for positive sign. In my code it has this form: expr_decl : '+' expr_decl %prec POSITIVE | expr_decl '+' expr_decl %prec OP_PLUS –  May 01 '18 at 15:42
  • 2
    That is confusing and unnecessary. I suggest you read about precedence, starting with the link @sepp2k provided. (Hint: you should only need one pseudotoken for unary operators, unless you have two prefix operators with different precedences.) Anyway, it is impossible to diagnose your problem further without actually seeing some code. And please make sure your debugging output actually corresponds to the version if your code which you include. – rici May 01 '18 at 15:49
  • @rici I've added my grammar rule .. Still trying to understand what's going on.. I've tried everything.. –  May 02 '18 at 17:30

1 Answers1

2

This part of the output file:

'+'  shift, and go to state 87
'-'  shift, and go to state 88

'+'       [reduce using rule 56 (expr_decl)]
'-'       [reduce using rule 56 (expr_decl)]

is telling you that you have two shift/reduce conflicts in this state, on the lookahead symbols '+' and '-'. The [..] around the reduce action indicates that that action has been removed (resolving the conflict in favor of the shift).

The messages:

Conflict between rule 56 and token KW_OR resolved as reduce (KW_OR < KW_NOT).
Conflict between rule 56 and token OP_OR resolved as reduce (OP_OR < KW_NOT).
Conflict between rule 56 and token KW_AND resolved as reduce (KW_AND < KW_NOT).
       :

tell you about shift/reduce conflicts that were resolved by precedence rules in your grammar (so are not included in 42 shift/reduce conflicts in the warning).

The precedence rules do not resolve the conflict for '+' and '-' as you have no precedence set for those tokens.

Chris Dodd
  • 119,907
  • 13
  • 134
  • 226