为什么我会遇到冲突:1 班次/减少
我是野牛新手,我收到“冲突:1 移位/减少”错误。有人能解释一下吗?
这是 y 文件。
test.y:
%{
#include <stdio.h>
#include <string.h>
#define YYERROR_VERBOSE
#define YYDEBUG 1
void yyerror(const char *str);
int yywrap();
%}
%union
{
int integer;
char *string;
}
%token <string> VAR_LOCAL
%token <integer> LIT_NUMBER
%token <string> LIT_STRING
%token WS_LINEBRK
//%token SYMB_EQL
%token SYMB_PLUS
%token SYMB_MINUS
%token SYMB_MUL
%token SYMB_DIV
%%
/*
// Sample input
num = 10
str = "this is a string"
*/
inputs: /* empty token */
| literal
| variable
| inputs stmt WS_LINEBRK
;
stmt: variable "=" exps
;
exps: variable op literal
| variable op variable
| literal op literal
| literal op variable
;
op: SYMB_PLUS | SYMB_MINUS | SYMB_MUL | SYMB_DIV ;
variable: VAR_LOCAL
{
printf("variable: %s\n", $1);
}
;
literal:
number | string
;
string: LIT_STRING
{
printf("word: %s\n", $1);
}
;
number: LIT_NUMBER
{
printf("number: %d\n", $1);
}
;
%%
void yyerror(const char *str)
{
fprintf(stderr,"error: %s\n",str);
}
int yywrap()
{
return 1;
}
main()
{
yyparse();
}
这是 lex 文件 测试.l:
%{
#include <stdio.h>
#include <stdlib.h>
#include "y.tab.h"
int line_no = 0;
%}
%%
[a-z][a-zA-Z0-9]* {
// local variable
yylval.string=strdup(yytext);
return VAR_LOCAL;
}
[0-9]+ {
//number literal
yylval.integer=atoi(yytext);
return LIT_NUMBER;
}
= return SYMB_EQL;
\+ return SYMB_PLUS;
\- return SYMB_MINUS;
\* return SYMB_MUL;
\/ return SYMB_DIV;
\"[-+\!\.a-zA-Z0-9' ]+\" {
// word literal
yylval.string=strdup(yytext);
return LIT_STRING;
}
\n {
// line break
printf("\n");
return WS_LINEBRK;
}
[ \t]+ /* ignore whitespace */;
%%
I'm new to bison and I'm getting a "conflicts: 1 shift/reduce" error. Can anyone shed some light on this?
Here's the y file.
test.y:
%{
#include <stdio.h>
#include <string.h>
#define YYERROR_VERBOSE
#define YYDEBUG 1
void yyerror(const char *str);
int yywrap();
%}
%union
{
int integer;
char *string;
}
%token <string> VAR_LOCAL
%token <integer> LIT_NUMBER
%token <string> LIT_STRING
%token WS_LINEBRK
//%token SYMB_EQL
%token SYMB_PLUS
%token SYMB_MINUS
%token SYMB_MUL
%token SYMB_DIV
%%
/*
// Sample input
num = 10
str = "this is a string"
*/
inputs: /* empty token */
| literal
| variable
| inputs stmt WS_LINEBRK
;
stmt: variable "=" exps
;
exps: variable op literal
| variable op variable
| literal op literal
| literal op variable
;
op: SYMB_PLUS | SYMB_MINUS | SYMB_MUL | SYMB_DIV ;
variable: VAR_LOCAL
{
printf("variable: %s\n", $1);
}
;
literal:
number | string
;
string: LIT_STRING
{
printf("word: %s\n", $1);
}
;
number: LIT_NUMBER
{
printf("number: %d\n", $1);
}
;
%%
void yyerror(const char *str)
{
fprintf(stderr,"error: %s\n",str);
}
int yywrap()
{
return 1;
}
main()
{
yyparse();
}
Here's the lex file
test.l:
%{
#include <stdio.h>
#include <stdlib.h>
#include "y.tab.h"
int line_no = 0;
%}
%%
[a-z][a-zA-Z0-9]* {
// local variable
yylval.string=strdup(yytext);
return VAR_LOCAL;
}
[0-9]+ {
//number literal
yylval.integer=atoi(yytext);
return LIT_NUMBER;
}
= return SYMB_EQL;
\+ return SYMB_PLUS;
\- return SYMB_MINUS;
\* return SYMB_MUL;
\/ return SYMB_DIV;
\"[-+\!\.a-zA-Z0-9' ]+\" {
// word literal
yylval.string=strdup(yytext);
return LIT_STRING;
}
\n {
// line break
printf("\n");
return WS_LINEBRK;
}
[ \t]+ /* ignore whitespace */;
%%
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
bison -r test.y
将编写一个文件test.output
,其中包含生成的状态机的详细描述,使您可以查看正在发生的情况 - 例如状态发生移位/归约冲突。就您而言,问题出在启动状态(对应于您的启动非终端,
inputs
)。假设第一个标记是 VAR_LOCAL。您的解析器可以做两件事:变量
大小写。inputs stmt WS_LINEBRK
情况:inputs
匹配空字符串(第一行),stmt
匹配variable "= “exps
。对于野牛解析器使用的前瞻这一单一标记,我们无法判断。你需要改变你的语法来摆脱这种情况。
bison -r test.y
will write a filetest.output
with a detailed description of the generated state machine that allows you to see what's going on - such as the state where the shift/reduce conflict occurs.In your case, the problem is in the start state (corresponding to your start nonterminal,
inputs
). Say the first token is VAR_LOCAL. There's two things your parser could do:variable
case.inputs stmt WS_LINEBRK
case:inputs
matches the empty string (first line), andstmt
matchesvariable "=" exps
.With the one token of lookahead that bison parsers use, there's no way to tell. You need to change your grammar to get rid of this case.
要修复语法,正如 Fabian 建议的那样,将变量和文字从输入移动到exps的末尾
这允许使用
x= y
,x="aliteral"
语法。要允许空输入行,请将
/* 空标记 */
规则更改为WS_LINEBREAK
:另一方面,由于扫描器仍会查找 SYMB em>_ 等于 ;但解析器不再定义它(它被注释掉),需要做一些事情才能编译。一种选择是取消注释
%token
定义并使用 SYMB_ EQUAL 而不是解析器 .y 文件中的文字“=”。To fix the grammar, as Fabian has suggested, move the variable and literal to the end of exps from inputs
That allows
x= y
,x="aliteral"
syntax.To allow for empty input lines, change the
/* empty token */
rule toWS_LINEBREAK
:On another note, since the scanner still looks for the SYMB_ EQUAL ; but the parser no longer defines it (its commented out), something needs to be done in order to compile. One option is to uncomment the
%token
definition and use SYMB_ EQUAL instead of the literal "=" in the parser .y file.