转移/减少野牛的冲突

Zri*_*nka 10 grammar parsing bison shift-reduce-conflict

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

struct  _data
{
  char name[50]; 
  char surname[50]; 
  int year;
} data[1000];
Run Code Online (Sandbox Code Playgroud)

这是我的野牛代码的一部分:

%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); }
       ;

%%            
Run Code Online (Sandbox Code Playgroud)

我收到此错误:

conflicts: 5 shift/reduce
Run Code Online (Sandbox Code Playgroud)

知道我哪里错了吗?

ric*_*ici 21

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

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

List: Record
    | List Record
    ;

Record: Something
      | /* Nothing */
      ;
Run Code Online (Sandbox Code Playgroud)

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

在这种情况下,解决方案非常简单.我们可以看到非空Something必须以a结尾NL; 大概是意图是File由任意数量的Records,每个都在其自己的行上组成.所以我们可以改写:

File:    List EOF
    ;

List:    Record
    |    List NL Record
    ;

Record:  Name Surname Year
      |  /* Empty */
      ;
Run Code Online (Sandbox Code Playgroud)

现在a Record,空或不,必须后跟EOFa或a NL.它不能被另一个直接跟随Record.