转移/减少java杯中的冲突 - 悬空其他问题

时间:2015-12-13 17:34:27

标签: java parsing compiler-construction cup

我收到以下错误:

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
              ;

有没有办法在没有优先级运算符的情况下解决这个问题,或者语法还有其他问题?

1 个答案:

答案 0 :(得分:6)

问题中提出的语法没有任何问题,所以我的猜测是转移/减少冲突是与另一个生产交互的结果。

将陈述分为MatchedUnmatched

的想法
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 ,但在这种情况下,MatchedMatched结尾。因此,我们有一个转变/减少冲突:

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