改革语法删除移位减少的if-then-else的冲突(Reforming the grammar t

2019-06-18 10:53发布

如何删除移降低野牛冲突对于给定的语法?

 selection-stmt -> if ( expression ) statement |
                      if ( expression ) statement else statement

的溶液给予修饰的语法将高度赞赏。

Answer 1:

还有一个更简单的解决方案。 如果你知道LR分析器是如何工作的,那么你知道,冲突发生在这里:

if ( expression ) statement * else statement

其中,星痕光标的当前位置。 解析器必须回答的问题是“我应该转移,或者我应该减少”。 通常情况下,你要绑定的else到最近的if ,这意味着你要移位else记号了。 现在减少将意味着你希望else等待被绑定到一个“旧的” if

现在,你想“告诉”你的解析器生成器,“当有移进/减少标记之间的冲突"else"和治‘STM - >如果(EXP)STM’,则标志必须赢”。 要做到这一点,你的规则(例如,优先级“给一个名为” "then" ),并指定"then"比少优先"else" 。 就像是:

// Precedences go increasing, so "then" < "else".
%nonassoc "then"
%nonassoc "else"
%%
stm: "if" "(" exp ")" stm            %prec "then"
   | "if" "(" exp ")" stm "else" stm

使用野牛语法。

其实,我最喜欢的答案是,即使给"then""else"相同的优先级。 当优先级相等,打破这种希望被转移的令牌,并希望减少规则之间的联系,野牛/ Yacc的会看的关联性。 在这里,你要推广右键关联可以这么说(更确切地说,你要推广“移动”),那么:

%right "then" "else" // Same precedence, but "shift" wins.

就足够了。



Answer 2:

你必须认识到一个事实,即中间statement中的if-else情况下不能(或终止)一个晃来晃去,如果(一个,如果没有别的。)这样做最简单的方法是分裂stmt两个规则:

stmt -> stmt-ending-with-dangling-if | stmt-not-ending-with-dangling-if
stmt-not-ending-with-dangling-if ->
    if ( expression ) stmt-not-ending-with-dangling-if else stmt-not-ending-with-dangling-if |
    ...other statements not ending with dangling if...
stmt-ending-with-dangling-if ->
    if ( expression ) stmt |
    if ( expression ) stmt-not-ending-with-dangling-if else stmt-ending-with-dangling-if |
    ...other statements ending with dangling if...

任何其他stmt -> whatever规则,其中whatever不以结束stmt去的stmt-not-ending-with-if规则,而任何stmt ,它最终在规则stmt有两个版本GET分; 一个not-ending-with-if版本在not-ending-with-if规则和dangling-if版本在dangling-if规则。

编辑

更完整的语法与其他作品:

stmt : stmt-ending-with-dangling-if | stmt-not-ending-with-dangling-if
stmt-not-ending-with-dangling-if :
    IF '(' expr ')' stmt-not-ending-with-dangling-if ELSE stmt-not-ending-with-dangling-if |
    WHILE '(' expr ')' stmt-not-ending-with-dangling-if |
    DO stmt WHILE '(' expr ')' ';' |
    expr ';' |
    '{' stmt-list '}'
stmt-ending-with-dangling-if:
    IF '(' expr ')' stmt |
    IF '(' expr ')' stmt-not-ending-with-dangling-if ELSE stmt-ending-with-dangling-if |
    WHILE '(' expr ')' stmt-ending-with-dangling-if

规则像WHILE (expr) stmt在二送分(因为他们与结束stmt ),而像规则expr; 不要。



Answer 3:

如果作出比正常的语句,像其他更高层次:

statements:
  statements lineEnd statement
| statements lineEnd IfStat
| statements lineEnd IfElseStat
| IfStat
| IfElseStat
;
IfStat:
  if ( statement )
;
IfElse:
  IfStat else statement
;


文章来源: Reforming the grammar to remove shift reduce conflict in if-then-else