我是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
知道我哪里出错了?
答案 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
为空或不空,必须后跟NL
或Record
。它不能直接跟随另一个{{1}}。