如何删除移降低野牛冲突对于给定的语法?
selection-stmt -> if ( expression ) statement |
if ( expression ) statement else statement
的溶液给予修饰的语法将高度赞赏。
如何删除移降低野牛冲突对于给定的语法?
selection-stmt -> if ( expression ) statement |
if ( expression ) statement else statement
的溶液给予修饰的语法将高度赞赏。
还有一个更简单的解决方案。 如果你知道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.
就足够了。
你必须认识到一个事实,即中间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;
不要。
如果作出比正常的语句,像其他更高层次:
statements:
statements lineEnd statement
| statements lineEnd IfStat
| statements lineEnd IfElseStat
| IfStat
| IfElseStat
;
IfStat:
if ( statement )
;
IfElse:
IfStat else statement
;