Some time ago I discovered that RACC has one trouble. When a rule has a code block executed before entering the rule, usual numbering for ''val'' array becomes broken.
For example, if we have a rule:
foo: moo booThe result of the rule is computed by calculation of a sum of right part nonterminal's return values.
{ result = val[0] + val[1] }
;
But if we use the rule like this:
foo:then we suddenly break ''val'' numbering scheme. Instead of ''val[0]'' and ''val[1]'' we should reference nonterminal's return values using ''val[1]'' and ''val[2]''. Apparently the code block before nonterminals breaks. Not a grave bug... but costed me several minutes to get an idea of what is happening.
{ result = "I break " }
moo boo
{ result = val[1] + val[2] }
;
But today I glanced over racc output file and was stunned! RACC effectively considers:
foo: {} moo boo ;asfoo: _nonterminal_ moo boo;and adds extra rule that breaks not only val[] numbering ;)
Example 1:
a: {} a B
| A
|
;
Example 2:
a: a B
| A
|
;
I implemented two examples (first is broken and second is ok) and studied them. I found that the source of the problem was that for {} a special nonterminal @1 will be created and artificial rule like
@1 -> εwill be added. But given input token A the parser allows both reducing the rule above and shifting A. Thus we have shift/reduce conflict that RACC hapily reports.
Another issue is endless loop: if the input is B then the parser reduces using the artificial rule and keeps reducing it forever. That happens because it always observes the empty symbol(together with B) and has the rule to reduce it. Ironically, another competing rule to reduce (say hello to reduce/reduce conflict!!!)
a -> εstays after the first one and is not selected for reduce.
To summarize, we have two shift/reduce conflicts and one reduce/reduce conflicts just because of the block. RACC is either was not designed to have before-rule blocks or the developers had something else in their mind. Alas, I haven't found any references to this issue yet.

1 comment:
Um, isn't that the same thing that Yacc does?
Post a Comment