I have a grammar that, depending on the order of productions, happy reports 3 reduce/reduce conflicts or none. The minimal example I can find is:
%tokentype {Token}
%token
int { Int }
'-' { Neg }
both { Both }
%nonassoc both
%left '-'
%nonassoc NEG
%%
E : int {IntE}
| both E E {BothE $2 $3}
| '-' E %prec NEG {NegE $2}
| E '-' E {SubE $1 $3}
{
data Token = Int | Neg | Both deriving Show
data Expr = BothE Expr Expr | IntE | SubE Expr Expr | NegE Expr deriving Show
}
This has 3 reduce-reduce conflicts, based around the inability to distinguish "both 7 -3
" and "both 7-3 2
". Fair enough!
However, if you swap the last two productions for E ('-' E %prec NEG
and E '-' E
), the reduce/reduce conflicts disappear. More puzzling, if you then remove the %prec NEG
directive, they return. I am quite confused as to what is happening here: why would the order matter?