14

我是新手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

知道我哪里出错了吗?

4

1 回答 1

28

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

但在这种情况下,问题很简单。剥离到它的基本要素,你有:

List  : Record

Record: Something
      | /* Nothing */

忽略的定义Something是什么,问题是 aList可以由任意数量的 组成Records,一个接一个,并且 aRecord可以是空的。这意味着没有任何东西可以被解析为任意数量的 empty Records,这完全是模棱两可的。输入中任何两个连续Somethings的都可以用 0、1、2、42 或 273 empty 分隔Records。由于解析器不知道是开始解析新的Something(移位)还是发出空的Record(减少),它抱怨存在移位/减少冲突。

解决方案也很简单。我们可以看到非空必须以;Something结尾。NL大概的意图是File由任意数量的 组成Records,每个都在自己的行上。所以我们可以重写:

List  : Record
      | List NL Record

Record: Name Surname Year
      | %empty

现在 a Record,无论是否为空,后面必须跟 aNL或任何可以跟随的内容List(在这种情况下是输入结束指示符,尽管您通常不需要显式添加这样的规则)。它不能直接跟在另一个后面Record

于 2013-07-11T15:49:13.690 回答