野牛:减少/减少非令牌冲突

时间:2019-05-28 00:32:10

标签: c parsing compiler-construction bison

所以我正在为C创建编译器-并且我目前正在创建文字,变量和函数表。

这条规则使我减少/减少冲突:

lval: ID { check_var(); }
| ID { check_var(); } LBRACK NUM RBRACK
| ID { check_var(); } LBRACK ID { check_var(); } RBRACK;

错误如下:

parser.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
parser.y:104.6-21: warning: rule useless in parser due to conflicts [-Wother]
 | ID { check_var(); } LBRACK ID { check_var(); } RBRACK;
      ^^^^^^^^^^^^^^^^

我有优先规则来避免减少令牌上的错误,但是现在它指向的是非令牌,所以不确定我该怎么做?

如果有任何帮助,这些是我的优先规则:

%token INPUT OUTPUT WRITE
%token  RETURN VOID IF ELSE WHILE ASSIGN SEMI COMMA
%token LPAREN RPAREN LBRACE RBRACE LBRACK RBRACK
%token NUM ID STRING INT
%left EQ NEQ GE LE GT LT
%left PLUS MINUS
%left TIMES OVER

1 个答案:

答案 0 :(得分:5)

Bison不会检查语法中的两个自定义代码块是否相同。因此,它基本上将您的语法视为:

lval: ID action_1
    | ID action_2 LBRACK NUM RBRACK
    | ID action_3 LBRACK ID action_4 RBRACK
; 

并且Bison(默认情况下)充当LALR(1) parser,这意味着在做出决策之前,Bison只向前看一个标记。因此,当它看到堆栈的顶部是一个ID令牌,而预见令牌是一个LBRACK令牌时,它无法决定应执行action_2还是{{ 1}},没有意识到这实际上并不重要。

通过使用子规则来解决action_3后跟ID(以及在其他情况下)时应该发生的常见情况,以解决此问题:

LBRACK