转移/减少野牛的冲突

时间:2013-07-11 09:46:32

标签: parsing grammar bison shift-reduce-conflict

我是Bison的新手,我在转换/减少冲突时遇到问题......我正在尝试从文件加载到array data[]

struct  _data
{
  char name[50]; 
  char surname[50]; 
  int year;
} data[1000];

以下是我的野牛代码的一部分:

%token ID NUM NL EOF 

%%

File   : List EOF
       ;
List   : Record
       | List Record
       ;
Record : Name Surname Year NL  { count++; }
       | NL                    { count++; }
       | /*empty*/
       ;
Name   : ID                    { strcpy(data[count].name, yytext); }
       ;
Surname: ID                    { strcpy(data[count].surname, yytext); }
       ;
Year   : NUM                   { data[count].year= atoi(yytext); }
       ;

%%            

我收到此错误:

conflicts: 5 shift/reduce

知道我哪里出错了?

1 个答案:

答案 0 :(得分:19)

您可以使用-v选项让bison生成一个.output文件,其中包含更多可帮助您诊断轮班/减少冲突的信息。特别是,它将向您显示每个解析器状态,包括项目列表,并指出哪些状态存在冲突。

但在这种情况下,问题非常简单。剥夺了它的基本要素:

List: Record
    | List Record
    ;

Record: Something
      | /* Nothing */
      ;

忽略Something的定义,问题是List可以包含任意数量的Records,一个接一个,Record可以空。这意味着没有任何东西可以被解析为任何数量的空Records,这是完全不明确的。输入中的任何两个连续Somethings可以用0,1,2,42或273空Records分隔。由于解析器无法知道是开始解析新的Something(移位)还是发出空Record(减少),因此它会抱怨存在移位/减少冲突。

在这种情况下,解决方案非常简单。我们可以看到非空Something必须以NL结尾;据推测,意图是File由任意数量的Records组成,每个File: List EOF ; List: Record | List NL Record ; Record: Name Surname Year | /* Empty */ ; 都在其自己的行上。所以我们可以改写:

Record

现在,EOF为空或不空,必须后跟NLRecord。它不能直接跟随另一个{{1}}。