1
votes

The error message:

bison -vdy tjc.y
conflicts: 2 shift/reduce
tjc.y:72.26-29: warning: rule useless in parser due to conflicts: return_type: type

EDIT 2: Further reduced the grammar to only the following rules. Same error due to same conflict. If I remove field_decl in the rules then the conflict goes away.

member_decl:      field_decl |  method_decl;

field_decl: STATIC type IDENT EQ SEMI;

method_decl:      STATIC return_type IDENT LPAR RPAR;

type:             INT | FLOAT;

return_type:      type | VOID;

Here's the section with the shift/reduce conflict in y.output:

state 18

7 field_decl: STATIC type . IDENT EQ SEMI
14 return_type: type .

IDENT  shift, and go to state 23

IDENT  [reduce using rule 14 (return_type)]

Please help me see what's going wrong here.

2
Is it possible that you're not mentioning that a type can be an ident as well? Is this really your (unedited) grammar?Perry
I added a rule for type->IDENT and it produced more conflicts. And yes it is a part of the unedited grammar. This is a very simplified parser.Leif
Could you manage to reduce this to the smallest grammar that displays the same error message?Perry
Yes, please see the edit. Same error.Leif
Try reducing it further. Does the error remain if you remove the last three forms of method_decl? can you remove the field_decl rule and its referents etc? We're trying to get to the smallest grammar that exhibits the error.Perry

2 Answers

3
votes

I think Perry's analysis of why you have problems is correct.

I was able to get similar warnings with this complete grammar (identical to yours, but with %token rules in place so I can compile it):

%token STATIC IDENT FLOAT INT VOID LPAR RPAR EQ SEMI

%%
member_decl:    field_decl |  method_decl;
field_decl:     STATIC type IDENT EQ SEMI;
method_decl:    STATIC return_type IDENT LPAR RPAR;
type:           INT | FLOAT;
return_type:    type | VOID;
%%

Given the analysis, the way I would probably fix it is this:

%token STATIC IDENT FLOAT INT VOID LPAR RPAR EQ SEMI

%%
member_decl:    field_decl |  method_decl;
field_decl:     STATIC type IDENT EQ SEMI;
method_decl:    STATIC type IDENT LPAR RPAR;
type:           INT | FLOAT | VOID;
%%

This compiles without any error in Bison. You just need to add a semantic check in the processing for field_decl that ensures that the relevant type ($2) is not VOID.

2
votes

Okay, so the problem would appear to be this: you're generating an LALR(1) parser. With a lookahead of one, you can't distinguish the field_decl and method_decl rules. Why? Because both look identical since at first glance the parser can't distinguish a return_type from a type (both might contain INT or FLOAT). I'm not 100% sure as my memory of the distinctions between LR, LALR, etc. are all fuzzy right now, but it would appear that this is the problem -- that is especially indicated by the fact that when you tried removing field_decl the error vanished.