I've got the following (heavily stripped down) Happy grammar
%token
'{' { Langle }
'}' { Rangle }
'..' { DotDot }
'::' { ColonColon }
'@' { At }
mut { Mut }
ident { Ident }
%%
pattern
: binding_mode ident at_pat { error "identifier pattern" }
| expr_path { error "constant expression" }
| expr_path '{' '..' '}' { error "struct pattern" }
binding_mode
: mut { }
| { }
at_pat
: '@' pat { }
| { }
expr_path
: expr_path '::' ident { }
| ident { }
Which has shift/reduce conflicts around identifiers in patterns. By default, Happy chooses to shift, but in this case that isn't what I want: it tries to shoe-horn everything into constant expression
even when it could be an identifier pattern
.
I've read that precedence/associativity is the way to solve this sort of problem, but nothing I've added has been able to budge the grammar in the right direction (to be fair, I've been taking mostly shots in the dark).
Using some obvious tokenization, I would like to have:
x
to yieldidentifier pattern
mut x
to yieldidentifier pattern
std::pi
to yieldconstant expression
point{..}
to yieldstruct pattern
std::point{..}
to yieldstruct pattern
Basically, unless there is a {
or ::
token waiting to be consumed, an identifier should go to the identifier pattern
case.
I apologize if my question is unclear - part of the problem is that I'm having a tough time pinpointing what the problem even is. :(