0

我在 yacc 中使用了 -v 选项来生成一个 y.output 文件。在文件的顶部它说

状态 98 冲突:1 班次/减少

文件的下方是以下内容:

state 98

   30 selection_stmt: IF '(' expression ')' statement .
   31               | IF '(' expression ')' statement . ELSE statement

    ELSE  shift, and go to state 101

    ELSE      [reduce using rule 30 (selection_stmt)]
    $default  reduce using rule 30 (selection_stmt)

冲突是什么,如何解决?

4

3 回答 3

1

几乎每一个shift/reduceif/then/else语句的错误都是臭名昭著的悬空 else问题。

使用此代码段:

if (f1):
    if (f2):
        c1
    else:
        c2

(和 Python,因为它奇怪的缩进规则)知道属于哪个ifelse但是解析器并不那么聪明。

它无法判断 是else属于 first 还是 second if

此链接显示如何将 LR(n) 转换为 LR(1) 等效项,这应该可以解决问题。

另一种选择是更改您的基本语言定义(如果可能),以便消除歧义:

: IF '(' cond ')' THEN statement ENDIF
| IF '(' cond ')' THEN statement ELSE statement ENDIF
于 2009-11-18T07:49:59.877 回答
0

尝试这样的事情:

election_stmt: IF '(' expression ')' statement . selection_stmt_else_part;
selection_stmt_else_part: ELSE statement 
                        | 
                        ;
于 2009-11-18T07:49:12.827 回答
0

咳咳,这个问题的正确答案通常是:什么都不做

模棱两可的语法预计会发生移位/减少冲突。它们不是错误,它们是冲突

冲突将通过优先使用 shift 而不是 reduce 来解决,这恰好解决了规范的悬空 else 问题。

bison 甚至还有一个 %expect n语句,这样当恰好有n 个冲突时,您就不会收到 S/R 冲突警告。

于 2013-01-11T23:12:33.660 回答