Use yacc's (or bison's) -v
option to get a full listing of the generated parser and the grammar conflicts in the y.output
file. When you do this with your grammar, you get something like (from bison):
State 16 conflicts: 1 shift/reduce
:
state 16
6 Conceito: word SEP Atributos .
8 Atributos: Atributos . SEP Atributo
SEP shift, and go to state 20
SEP [reduce using rule 6 (Conceito)]
$default reduce using rule 6 (Conceito)
This tells you exactly where the conflict is -- after reducing an Attributos
and looking at a SEP
lookahead, the parser doesn't know if it should shift the SEP
to parse another Atributo
after it, or to reduce the Conceito
, which would only be valid if there's another SEP
after the SEP
(two token lookahead needed).
One way to avoid this would be to have your lexer return multiple SEP
s (blank lines) as a single token:
\n return SEP;
\n\n return SEP_SEP;
You might want to allow whitespace on the blank line or more than a single blank line instead:
\n([ \t]*\n)+ return SEP_SEP;