Removing shift/reduce conflict on optional else block

时光总嘲笑我的痴心妄想 提交于 2020-02-08 07:22:16

问题


I'm in the process of defining a grammar with Bison and I stumbled upon a shift/reduce conflict I'd like to eliminate. The conflict is caused by a rule that aims to match if/else statements:

state 17

   13 Stmt: IfBlock . OptionalElseBlock

    ELSE  shift, and go to state 42

    ELSE      [reduce using rule 16 (OptionalElseBlock)]
    $default  reduce using rule 16 (OptionalElseBlock)

    OptionalElseBlock  go to state 43

The OptionalElseBlock was defined as follows:

   16 OptionalElseBlock: /* empty */
   17                  | ELSE Stmt

States 42 and 43 look like this with the shift and reduce info omitted:

state 42
   17 OptionalElseBlock: ELSE . Stmt

state 43
   13 Stmt: IfBlock OptionalElseBlock .

I've used optional tokens before, but I'm guessing that since the parser's lookahead buffer only contains 1 terminal OptionalElseBlock causes a conflict. Is there an easy way to resolve this conflict?


回答1:


This is the classic shift/reduce conflict. The problem is the following:

if (c1) if (c2) stmt1; else stmt2;

The question is which if the else belongs to. If it were not optional, there would be no problem, or if the if statement had to be terminated (say with fi or end, to choose two popular alternatives), but the C syntax seems to have won, and hence we have shift/reduce conflicts.

It is possible but non-trivial to write a grammar which does not exhibit this problem. You can hide the conflict, either by playing games with precedence rules or by simply "expecting" the shift/reduce conflict. (I prefer the latter but there are many who would say that the precedence hack is better, although it amounts to the same thing imho.)

The rewritten grammar is an exercise in the dragon book, and probably other parsing texts, so it might be worth doing for learning purposes, but it's a real pain in terms of grammar maintenance and it makes the grammar much harder to read, if that's at all a concern.


The classic paper on how to use precedence and shift-preference to simplify parsing is "Deterministic parsing of ambiguous grammars" by Aho, Johnson and Ullman, published in 1975 or so. Google will probably find you a copy you can read online if you don't have access to a good library.




回答2:


You might want to have a look at my answer to the same question. This is an FAQ.

Reforming the grammar to remove shift reduce conflict in if-then-else

I would recommend not using %expect n for anything but 0.



来源:https://stackoverflow.com/questions/13550936/removing-shift-reduce-conflict-on-optional-else-block

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!