0

Firstly, I have already referred to many similar questions here, but unable to resolve the conflicts.

I have this piece in my .y file

.
.
.
obj
    : INT { $$ = objNew($1, INT_T); }
    | FLOAT { $$ = objNew($1, FLOAT_T); }
    | STR { $$ = objNew($1, STR_T); }
    ;

var
    : IDEN { $$ = varLookup($1); }
    ;

atom
    : '(' expression ')' { $$ = $2; }
    ;

index
    : '[' obj ']' { $$ = $2; }
    ;

primary_expr
    : obj { $$ = objExpr($1); }
    | var { $$ = varExpr($1); }
    | atom { $$ = atmExpr($1); }
    | expression index { $$ = idxExpr($1, $2); }
    ;

unary_expr
    : primary_expr { $$ = $1; }
    | '+' unary_expr { $$ = unExpr(UPLUS, $2); }
    | '-' unary_expr { $$ = unExpr(UMINUS, $2); }
    ;

power_expr
    : unary_expr { $$ = $1; }
    | power_expr '^' unary_expr { $$ = biExpr('^', $1, $3); }
    ;

multiplicative_expr
    : power_expr { $$ = $1; }
    | multiplicative_expr '*' power_expr { $$ = biExpr('*', $1, $3); }
    | multiplicative_expr '/' power_expr { $$ = biExpr('/', $1, $3); }
    ;

additive_expr
    : multiplicative_expr { $$ = $1; }
    | additive_expr '+' multiplicative_expr { $$ = biExpr('+', $1, $3); }
    | additive_expr '-' multiplicative_expr { $$ = biExpr('-', $1, $3); }
    ;

relational_expr
    : additive_expr { $$ = $1; }
    | relational_expr '>' additive_expr { $$ = biExpr('>', $1, $3); }
    | relational_expr '<' additive_expr { $$ = biExpr('<', $1, $3); }
    | relational_expr '=' additive_expr { $$ = biExpr('=', $1, $3); }
    ;

referential_expr
    : relational_expr { $$ = $1; }
    | referential_expr IS relational_expr { $$ = biExpr(IS, $1, $3); }
    ;

conjunction_expr
    : referential_expr { $$ = $1; }
    | conjunction_expr AND referential_expr { $$ = biExpr(AND, $1, $3); }
    ;

disjunction_expr
    : conjunction_expr { $$ = $1; }
    | disjunction_expr OR conjunction_expr { $$ = biExpr(OR, $1, $3); }
    ;

conditional_expr
    : disjunction_expr { $$ = $1; }
    | disjunction_expr '?' disjunction_expr ':' conditional_expr { $$ = trExpr('?', $1, $3, $5); }
    ;

sequence
    : conditional_expr { $$ = seqChain(NULL, $1); }
    | sequence ',' conditional_expr { $$ = seqChain($1, $3); }
    ;

assignment_expr
    : sequence { $$ = seqAssign($1, NULL); }
    | sequence ASS assignment_expr { $$ = seqAssign($1, $3); }
    ;

expression
    : assignment_expr { $$ = $1; }
    ;

statement
    : ';' { $$ = NULL; }
    | expression ';' { $$ = exprStmt($1); }
    ;

routine
    : routine statement { $$ = rtnChain($1, $2); }
    | { $$ = NULL; }
    ;

program
    : routine { compile($1); exit(0); }
    ;

.
.
.

This grammer is producing lots of reduce\reduce conflicts. Eg:

State 81

   18 power_expr: unary_expr .
   19           | power_expr '^' unary_expr .

    '+'       reduce using rule 18 (power_expr)
    '+'       [reduce using rule 19 (power_expr)]

I have lots of conflicts exactly similar to this. But I'm failing to understand this.
According to my knowledge, it is saying that, when the production is unary_expr or when it is power_expr '^' unary_expr and then it looks a '+', it is facing a reduce\reduce conflict. But why there is a reduce\reduce conflict? When it has power_expr '^' part, it can use rule 19 (and should use since otherwise production will be power_expr '^' power_expr which is not defined in grammer.) and when does not have power_expr '^' part, it has to use rule 18. Where does the ambiguity arises here, and how to resolve it.

Sourav Kannantha B
  • 2,860
  • 1
  • 11
  • 35
  • Show your entire grammar please (or show a complete reduced grammar which exhibits the same problem). The problem undoubtedly resides in the unseen part of the grammar. I could guess the cause but I'd rather know what I'm talking about. – rici Jan 31 '21 at 15:41
  • @rici I have added entire grammer. Check it now. – Sourav Kannantha B Jan 31 '21 at 15:49
  • I'm glad I didn't try to second-guess, because I would have guessed wrong. – rici Jan 31 '21 at 16:33
  • Have you tried running [`bison -Wcounterexamples`](https://www.gnu.org/software/bison/manual/html_node/Counterexamples.html)? – akim Feb 14 '21 at 05:36
  • @akim I think it won't work in windows. I am getting `bison: invalid argument 'counterexamples' for '--warning'` error. – Sourav Kannantha B Feb 14 '21 at 09:57
  • @SouravKannanthaB Unrelated to the OS, but to the version of Bison: it was introduced in Bison 3.7. – akim Feb 15 '21 at 07:04

1 Answers1

2

The problem stems from the rule

primary_expr: expression index 

That rule cannot be correct, since it implies that a+b[3] could be parsed by applying the [3] to the expression a+b. But it could also be parsed as though written a+(b[3]). This ambiguity produces the reduce-reduce conflicts.

We know that only the second interpretation is correct, which strongly suggests that the rule should be

primary_expr: primary_expr index 

I believe that change will resolve your conflicts.

rici
  • 234,347
  • 28
  • 237
  • 341
  • Thank you very much. Instantly it resolved all reduce\reduce conflicts. But how did you find that? Is it your experience? or can I would have also found it just based on .output of bison? (This is first time I'm using yacc/bison) – Sourav Kannantha B Jan 31 '21 at 16:44
  • 1
    @SouravKannanthaB: i found it by looking for uses of `expression` in your grammar. That was a hunch based on experience. In general, when you see an unexpected reduction in a state table, you need to work backwards to answer the question "how could the parser get to this reduction?"; a text editor which lets you easily search for text ("to state 81", for example) can make it easier to navigate backwards through bison's state table output – rici Jan 31 '21 at 16:55
  • 1
    @SouravKannanthaB: The other thing is that you were focussing on the productions for the `^`, both in the text of your question and in your initial selection of productions to show. But that's not where the problem lies. The key to the problem is the lookahead token which triggers it (or, more likely, the large set of lookahead tokens), because there might be a large chain of reductions involved. (That's just a heuristic, but at least it can lead to looking in the right place.) – rici Jan 31 '21 at 17:22