Background
I'm working on a compiler for a latex-like language. I've already written the lex file and that's working the way it ought to, so far. However, I've been running into problems now that I'm working on the grammar in the .y file.
Problem
I've reproduced the part of the grammar that I believe is responsible for stymieing me:
%start document
%%
document: BEGINDOCUMENT documentbody ENDDOCUMENT;
documentbody: contentseq | ws MAKETITLE contentseq | MAKETITLE contentseq;
contentseq: | contentseq content;
content: STRING | ws;
ws: WHITESPACE;
Whitespace, in this context, is basically any mix of spaces, tabs, and newlines.
As I understand it from looking at the y.output file, the shift/reduce error is raised because of the rule
documentbody: ... | ws MAKETITLE contentseq | ...
Given the WHITESPACE token, Bison doesn't know whether this is part of the terminal "content" or if it will instead be followed by a MAKETITLE token. Both are perfectly valid input, and I'm unsure of how to fix this issue.
For clarity, a paraphrase of the original EBNF specification:
document: BEGINDOCUMENT [ws] [MAKETITLE] contentseq ENDDOCUMENT
In other words, both the ws terminal and MAKETITLE are optional.
Example input
BEGINDOCUMENT WHITESPACE MAKETITLE STRING ENDDOCUMENT
BEGINDOCUMENT WHITESPACE STRING ENDDOCUMENT
BEGINDOCUMENT MAKETITLE STRING ENDDOCUMENT
BEGINDOCUMENT STRING ENDDOCUMENT
All of the above should be accepted by the grammar.
What I've tried
I know many conflicts can be smoothed over by using precedence, but nothing I've tried in that vein has worked. I've tried assigning the MAKETITLE and WHITESPACE tokens every kind of precedence, but that hasn't solved the problem.
I've seen suggestions on other shift/reduce-related problems to rewrite the grammar to be less ambigous, but I'm not sure how to go about doing that - at least without changing what input the grammar accepts and does not accept.
One solution I have thought of, but not attempted, is messing with the lex file, but that seems a rather icky solution and I would rather find some way of doing it in yacc.