I have created an extremely simple byacc grammar (ok, it's not really that simple but I simplified purposefully to be a minimal complete verifiable example):
%token NEWLINE SPECIFIER %token EQUALS STRING VAR %start st %% st: toplevel; toplevel: | toplevel VAR EQUALS STRING NEWLINE | toplevel list NEWLINE ; list: maybe_specifier VAR | list maybe_specifier VAR ; maybe_specifier: | SPECIFIER ;
However, it is warning about a shift-reduce conflict. If I remove
maybe_specifier from the grammar entirely (so that variables cannot be prefixed by a specifier in a list), the conflict disappears. Similarly, if I remove the variable assignment from the grammar entirely, the conflict disappears too.
My questions are:
- Where does this shift-reduce conflict come from? Is it an artifact of LALR? Or would it be there even with an LR(1) parser generator?
- Does this shift-reduce conflict matter? Or is it always doing the right thing anyway by using shift instead of reduce?
- Is there any way to modify the grammar to accept the same language without having the shift-reduce conflict, other than by prefixing
VARin assignment line by
maybe_specifierand then checking whether the
SPECIFIERwas there in a semantic action, and failing if the
My current approach is to modify the assignment rule to initially accept a
SPECIFIER in the form of
maybe_specifier but then terminate with a parse error if the
SPECIFIER was there. I'm wondering if there's a cleaner approach that would allow me to do the same without adding a semantic action.