我收到以下错误:
Warning : *** Shift/Reduce conflict found in state #116
between Statement ::= Matched (*)
and Unmatched ::= IF LPAREN Condition RPAREN Matched (*) ELSE Unmatched
and Matched ::= IF LPAREN Condition RPAREN Matched (*) ELSE Matched
under symbol ELSE
Resolved in favor of shifting.
现在,我知道悬挂的其他问题,我试图明确地使用语法:
Statement ::= Matched | Unmatched ;
Matched ::= IF LPAREN Condition RPAREN Matched ELSE Matched
|
Others
;
Unmatched ::= IF LPAREN Condition RPAREN Statement
|
IF LPAREN Condition RPAREN Matched ELSE Unmatched
;
有没有办法在没有优先级运算符的情况下解决这个问题,或者语法还有其他问题?
答案 0 :(得分:6)
问题中提出的语法没有任何问题,所以我的猜测是转移/减少冲突是与另一个生产交互的结果。
将陈述分为Matched
和Unmatched
:
Statement ::= Matched | Unmatched ;
正是为了确保 else 与最近的不匹配 if 正确匹配。无法使用else子句扩展Matched
语句;可能是Unmatched
陈述。因此我们要求语法中的 else 标记不能遵循Unmatched
语句,从而避免过早地减少可能已使用else
子句扩展的语句。
因此,在If
语句中, else 只能跟随Matched
语句。如果语句没有Unmatched
子句,或者else
子句本身是else
,则语句本身为Unmatched
。因此,我们有三个作品:
Unmatched_If ::= IF LPAREN Condition RPAREN Statement
| IF LPAREN Condition RPAREN Matched ELSE Unmatched ;
Matched_If ::= IF LPAREN Condition RPAREN Matched ELSE Matched ;
但这不是整个故事,因为还有其他可能的复合陈述。例如,考虑while
语句。如果语言有这样的结构,语法可能包含这样的内容:
While ::= WHILE LPAREN Condition RPAREN Statement ; /* Wrong! */
这不会起作用,因为while
语句也可以是Unmatched
,与if...else
语句完全相同:如果内部{{1}是Statement
。
例如,考虑
Unmatched
如果上面的while (x) if (y) do_x_and_y;
制作不正确,则会减少如下:
While
但这违反了 else 无法跟随 WHILE LPAREN Condition RPAREN Unmatched_If
-> WHILE LPAREN Condition RPAREN Statement
-> Matched
的要求。 Unmatched
后面可以跟 else ,但在这种情况下,Matched
以Matched
结尾。因此,我们有一个转变/减少冲突:
Unmatched_If
这可以解析为
if (w)
while (x) if (y) do_this;
else do_that;
但这实际上不是预期的解析。 (缩进可能会让我们认为这是程序员的意图,但这不是语言设计者的意图。) else 应匹配第二个 if ,而不是第一个,导致:
IF ( Condition:[w] ) Matched:[while(x)if(y)do_this;] ELSE Statement:[do_that;]
因此,我们需要区分匹配和不匹配的if (w)
while (x)
if (y) do_this; else do_that;
语句,而不仅仅是匹配和不匹配的While
语句:
If
有了它,Unmatched_While ::= WHILE LPAREN Condition RPAREN Unmatched ;
Matched_While ::= WHILE LPAREN Condition RPAREN Matched ;
将被解析为while (x) if (y) do_x_and_y;
,因此它不再是开始Unmatched_While
的作品的一部分
当然,其他复合语句也需要做同样的事情,例如IF LPAREN Condition RPAREN Matched ELSE...
语句。
所以最终的结果将是:
for