Ive been working on a project and have come across:
Below is the list of if declarations, I have everything here except for the types in typeSpec, but we don't have to worry about those for right now. I am fairly sure that I understand what shift/reduce and reduce/reduce errors are but (lucky for me) the compiler doesn't tell me where the conflicts are. Can someone point me in the right direction on where the conflicts are, or give me some tips on how to find where the conflicts are would be really appreciated. Also if I am missing something from the post, anything and everything is greatly appreciated aswell!
%%
program
: declList { syntaxTree = $1; }
;
declList
: declList decl { $$ = AddSibling($1, $2); }
| decl { $$ = $1; }
;
decl
: varDecl { $$ = $1; }
| funDecl { $$ = $1; }
;
varDecl
: typeSpec varDeclList SEMICOLON { $$ = $2; SetType($2, $1, false); }
;
scopedVarDecl
: STATIC typeSpec varDeclList SEMICOLON { $$ = $3; SetType($3, $2, true); }
| typeSpec varDeclList SEMICOLON { $$ = $2; SetType($2, $1, false); }
;
varDeclList
: varDeclList COMMA varDeclInit { $$ = AddSibling($1, $3); }
| varDeclInit { $$ = $1; }
;
varDeclInit
: varDeclId { $$ = $1; }
| varDeclId COLON simpleExp { $$ = $1; AddChild($$, $3); }
;
varDeclId
: ID { $$ = NewDeclNode(VarK, UndefinedType, $1); $$->tmp = $1->idIndex; }
| ID LBRACKET NUMCONST RBRACKET{ $$ = NewDeclNode(VarK, UndefinedType, $1); $$->isArray = true; $$->aSize = $3->nvalue; $$->tmp = $1->idIndex;}
;
typeSpec
: {}
;
funDecl
: typeSpec ID LPAREN parms RPAREN compoundStmt { $$ = NewDeclNode(FuncK, $1, $2, $4, $6);$$->tmp = $2->idIndex; SetType($$, $1, true);}
| ID LPAREN parms RPAREN compoundStmt{ $$ = NewDeclNode(FuncK, Void, $1, $3, $5); $$->tmp = $1->idIndex; }
;
parms
: parmList { $$ = $1; }
| { $$ = NULL; }
;
parmList
: parmList SEMICOLON parmTypeList { $$ = AddSibling($1, $3); }
| parmTypeList { $$ = $1; }
;
parmTypeList
: typeSpec parmIdList { $$ = $2; SetType($2, $1, false); }
;
parmIdList
: parmIdList COMMA parmId { $$ = AddSibling($1, $3); }
| parmId { $$ = $1; }
;
parmId
: ID { $$ = NewDeclNode(ParamK, Void, $1); $$->tmp = $1->svalue; }
| ID LBRACKET RBRACKET { $$ = NewDeclNode(ParamK, Void, $1); $$->isArray = true; $$->tmp = $1->svalue; }
;
stmt
: matched { $$ = $1; }
| unmatched { $$ = $1; }
;
matched
: expStmt { $$ = $1; }
| compoundStmt { $$ = $1; }
| returnStmt { $$ = $1; } //
| breakStmt { $$ = $1; } //
| matchedSelectStmt { $$ = $1; }
| matchedIterStmt { $$ = $1; }
;
unmatched
: unmatchedSelectStmt{ $$ = $1; }
| unmatchedIterStmt { $$ = $1; }
;
expStmt
: exp SEMICOLON { $$ = $1; }
| SEMICOLON { $$ = NULL; }
;
compoundStmt
: BEG localDecls stmtList END { $$ = NewStmtNode(CompoundK, $1, $2, $3); }
;
localDecls
: localDecls scopedVarDecl { $$ = AddSibling($1, $2); }
| { $$ = NULL; }
;
stmtList
: stmtList stmt { $$ = AddSibling($1, $2); }
| { $$ = NULL; }
;
matchedSelectStmt : IF simpleExp THEN matched ELSE matched
{ $$ = NewStmtNode(IfK, $1, $2, $4, $6); }
;
unmatchedSelectStmt
: IF simpleExp THEN stmt { $$ = NewStmtNode(IfK, $1, $2, $4); }
| IF simpleExp THEN matched ELSE unmatched { $$ = NewStmtNode(IfK, $1, $2, $4, $6); }
;
matchedIterStmt
: WHILE simpleExp DO matched { $$ = NewStmtNode(WhileK, $1, $2, $4); }
| FOR ID ASGN iterRange DO matched { $$ = NewStmtNode(ForK, $1, NewDeclNode(VarK, Integer, $2), $4, $6); $$->tmp = $2->idIndex; }
;
unmatchedIterStmt
: WHILE simpleExp DO unmatched { $$ = NewStmtNode(WhileK, $1, $2, $4); }
| FOR ID ASGN iterRange DO unmatched { $$ = NewStmtNode(ForK, $1, NewDeclNode(VarK, Integer, $2), $4, $6); $$->tmp = $2->idIndex; }
;
iterRange
: simpleExp TO simpleExp { $$ = NewStmtNode(RangeK, $2, $1, $3);}
| simpleExp TO simpleExp BY simpleExp { $$ = NewStmtNode(RangeK, $2, $1, $3, $5); $$->tmp = $2->idIndex; }
;
returnStmt
: RETURN SEMICOLON { $$ = NewStmtNode(ReturnK, $1); }
| RETURN exp SEMICOLON { $$ = NewStmtNode(ReturnK, $1, $2); }
;
breakStmt
: BREAK SEMICOLON { $$ = NewStmtNode(BreakK, $1); }
;
exp
: mutable ASGN exp { $$ = NewExpNode(AssignK, $2, $1, $3); }
| mutable ADDASGN exp { $$ = NewExpNode(AssignK, $2, $1, $3); }
| mutable SUBASGN exp { $$ = NewExpNode(AssignK, $2, $1, $3); }
| mutable MULASGN exp { $$ = NewExpNode(AssignK, $2, $1, $3); }
| mutable DIVASGN exp { $$ = NewExpNode(AssignK, $2, $1, $3); }
| mutable INC { $$ = NewExpNode(AssignK, $2, $1); }
| mutable DEC { $$ = NewExpNode(AssignK, $2, $1); }
| simpleExp {$$ = $1; }
;
simpleExp
: simpleExp OR andExp { $$ = NewExpNode(OpK, $2, $1, $3); }
| andExp { $$ = $1; }
;
andExp
: andExp AND unaryRelExp { $$ = NewExpNode(OpK, $2, $1, $3); }
| unaryExp { $$ = $1; }
;
unaryRelExp
: NOT unaryRelExp { $$ = NewExpNode(OpK, $1, $2); }
| relExp { $$ = $1; }
;
relExp
: sumExp relop sumExp { $$ = $2; AddChild($$, $1); AddChild($$, $3); }
| sumExp { $$ = $1; }
;
relop
: GT { $$ = NewExpNode(OpK, $1); }
| GEQ { $$ = NewExpNode(OpK, $1); }
| LT { $$ = NewExpNode(OpK, $1); }
| LEQ { $$ = NewExpNode(OpK, $1); }
| EQ { $$ = NewExpNode(OpK, $1); }
| NEQ { $$ = NewExpNode(OpK, $1); }
;
sumExp
: sumExp sumop mulExp { $$ = $2; AddChild($$,$1); AddChild($$,$3); }
| mulExp { $$ = $1; }
;
sumop
: ADD { $$ = NewExpNode(OpK, $1); }
| MINUS { $$ = NewExpNode(OpK, $1); }
;
mulExp
: mulExp mulop unaryExp { $$ = $2; AddChild($$, $1); AddChild($$, $3); }
| unaryExp { $$ = $1; }
;
mulop
: STAR { $$ = NewExpNode(OpK, $1); }
| DIV { $$ = NewExpNode(OpK, $1); }
| PERCENT { $$ = NewExpNode(OpK, $1); }
;
unaryExp
: unaryop unaryExp { $$ = $1; AddChild($$, $2); }
| factor { $$ = $1; }
;
unaryop
: MINUS { $$ = NewExpNode(OpK, $1); }
| STAR { $$ = NewExpNode(OpK, $1); }
| QMARK { $$ = NewExpNode(OpK, $1); }
;
factor
: mutable { $$ = $1; }
| immutable { $$ = $1; }
mutable
: ID { $$ = NewExpNode(IdK, $1); $$->name = $1->idIndex; }
| ID LBRACKET exp RBRACKET { $$ = NewExpNode(OpK, $2, NewExpNode(IdK, $1), $3); $$->child[0]->name = $1->idIndex; }
;
immutable
: LPAREN exp RPAREN { $$ = $2; }
| call { $$ = $1; }
| constant { $$ = $1; }
;
call
: ID LPAREN args RPAREN { $$ = NewExpNode(CallK, $1, $3); $$->name = $1->idIndex; }
;
args
: argList { $$ = $1; }
| { $$ = NULL; }
;
argList
: argList COMMA exp { $$ = AddSibling($1, $3); $$->name = $2->svalue; }
| exp { $$ = $1; }
;
constant
: NUMCONST { $$ = NewExpNode(ConstantK, $1); $$->expType = Integer; $$->value = $1->nvalue; }
| CHARCONST { $$ = NewExpNode(ConstantK, $1); $$->expType = Char; $$->cvalue = $1->cvalue; }
| STRINGCONST { $$ = NewExpNode(ConstantK, $1); $$->expType = String; $$->string = $1->svalue; }
| BOOLCONST { $$ = NewExpNode(ConstantK, $1); $$->expType = Boolean; $$->value = $1->nvalue;}
;
%%

-voption to bison to get a dump of the state machine inparser.output. If you have a fairly recent bison, you can use-Wcounterexamples(or-Wcex) and it will find you concrete examples of each conflict. (Although it's pretty easy to see that the fact thattypeSpecderives the empty string is problematic. For example, how do you expect the parser to decide between the two productions for funDecl?typeSpec : BOOL { $$ = Boolean; } | CHAR { $$ = Char; } | INT { $$ = Integer; } ;but was getting errors, but I got them fixed, so I think that did it honestly