Reputation: 2553
I have a very big YACC file to debug but the part I am currently focusing on looks like this :
....
%token TOKEN_HASH 123 "#"
...
RULE1 : TOKEN_XYZ TOKEN_HASH '(' ')'
{
//DO something here
//some C code
}
I want to write RULE1 as follows :
RULE1 : TOKEN_XYZ '#' '(' ')'
{
//DO something here
//some C code
}
Is this not allowed in yacc? Because I get the following error with second code :
parser.y: conflicts: 1 shift/reduce
parser.y: expected 0 shift/reduce conflicts
Any kind of help/comment is highly appreciated.
Thanks!
Upvotes: 1
Views: 272
Reputation: 241931
bison
does not let you both use a single-quoted terminal ('#'
) and define a named terminal (like TOKEN_HASH
) whose numeric code is the equivalent of the quoted character (in this case, 35). It won't complain if you use '#'
and you specify
%token TOKEN_HASH 123 "#"
because 123
is not the same as '#'
; rather, it is the value of '{'
. However, such a declaration is highly misleading: it tells the reader that a TOKEN_HASH
is a hash character, but it is actually an open brace. (Of course, your lexer might return an open brace when it encounters a hash, but that would be even more confusing.)
The double-quoted string in the %token
declaration (or the grammar) is only useful for documentation purposes. As such, you should try to make sure that the documentation is accurate. Neither bison nor flex will enforce or even take any notice of what is inside the double quotes, so you will receive no error or warning for a misleading label.
On the whole, you should not mix and match named single-character tokens and quoted single-character tokens, and you should never specify an integer code for a named token, even though bison allows you to. All you are doing in such cases is confusing people who read your code (and quite possibly yourself) and creating maintenance problems.
Now, the shift/reduce conflict will have to do with some other production in the grammar which includes the terminal '#'
. Since TOKEN_HASH
is a different terminal than '#'
,, the other production cannot conflict with RULE1 : TOKEN_XYZ TOKEN_HASH '(' ')'
. But it certainly can conflict with RULE1 : TOKEN_XYZ '#' '(' ')'
.
If you give bison
the -v
flag, it will produce a file with the extension .output
which will provide useful information for tracking down the conflict.
Upvotes: 2
Reputation: 311050
You should economize on %token
directives and use the actual character literals wherever you can in the grammar. That way you also economize on flex
directives: you don't need one per special character, you only need this:
. return yytext[0];
as your last rule.
Upvotes: 0