转移/减少java cup中的冲突-悬而未决的其他问题
我得到以下错误:转移/减少java cup中的冲突-悬而未决的其他问题,java,parsing,compiler-construction,cup,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
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.
现在,我意识到了悬而未决的else问题,我已经尝试将语法弄清楚:
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
;
有没有办法在没有优先运算符的情况下解决此问题,或者语法有其他问题?问题中的语法没有问题,因此我猜测移位/减少冲突是与另一个产品交互的结果 将语句分为
匹配的和不匹配的:
Statement ::= Matched | Unmatched ;
正是为了确保else与最近的未匹配if正确匹配。匹配的
语句不能用else子句扩展;可能出现了不匹配的语句。因此,我们要求语法中的else标记不能跟在Unmatched
语句后面,从而避免过早地减少可能已使用else
子句扩展的语句
因此在If
语句中,else只能跟随匹配的语句。如果语句本身没有else
子句,或者else
子句本身是Unmatched
,则语句本身是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 LPAREN Condition RPAREN Statement ; /* Wrong! */
这是行不通的,因为while
语句也可以是不匹配的
,就像if…else
语句可以是:if内部语句
是不匹配的
例如,考虑
while (x) if (y) do_x_and_y;
如果上面的生产不正确,则将按如下方式减少:
WHILE LPAREN Condition RPAREN Unmatched_If
-> WHILE LPAREN Condition RPAREN Statement
-> Matched
但这违反了不匹配
后面不能跟其他人的要求Matched
后面可以跟else,但在这种情况下,Matched
以Unmatched\u结尾(如果
)。因此,我们需要改变/减少冲突:
if (w)
while (x) if (y) do_this;
else do_that;
这可以被解析为
IF ( Condition:[w] ) Matched:[while(x)if(y)do_this;] ELSE Statement:[do_that;]
但这实际上并不是预期的解析。(缩进可能会让我们认为这是程序员的意图,但不是语言设计者的意图。)else应该匹配第二个if,而不是第一个if,从而导致:
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_和_y当
时,code>将被解析为一个不匹配的
,因此如果LPAREN条件RPAREN匹配,它将不再是启动的产品的一部分…
当然,对于其他复合语句也需要这样做,例如for
语句
因此,最终结果将类似于:
Matched ::= Matched_If
| Matched_While
| Matched_For
| ...
| Simple_Statement
;
Unmatched ::= Unmatched_If
| Unmatched_While
| Unmatched_For
| ...
;