问题中显示的语法没有错,所以我的猜测是,移位/减少冲突是与另一种产品相互作用的结果。
将语句拆分为
Matched和的想法
Unmatched:
Statement ::= Matched | Unmatched ;
正是为了确保
else正确匹配最接近的unmatched
if。一个
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 ;
那是行不通的,因为
while语句也可以
Unmatched与
if...else语句可以完全相同:如果内部
Statement为
Unmatched。
例如,考虑
while (x) if (y) do_x_and_y;
由于
While上面的生产不正确,可以将其减少如下:
WHILE LPAREN Condition RPAREN Unmatched_If-> WHILE LPAREN Condition RPAREN Statement-> Matched
但这违反了
Unmatched不能遵循的要求
else。
Matched可以紧随其后
else,但在这种情况下以
Matched结束
Unmatched_If。因此,我们有一个转移/减少冲突:
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 (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,因此它不再是开始的制作的一部分
IFLPAREN Condition RPAREN Matched ELSE...
当然,对于其他复合语句,例如语句,也需要执行相同的操作
for。
因此,最终结果将类似于:
Matched ::= Matched_If | Matched_While | Matched_For | ... | Simple_Statement ;Unmatched ::= Unmatched_If | Unmatched_While | Unmatched_For | ... ;



