警告:shift/reduce 冲突
warning: shift/reduce conflict
我正在尝试编写一个 yacc 程序来查明算术表达式是否有效。
我的程序似乎 运行 正常,但我在控制台收到警告。
warning: 2 shift/reduce conflicts [-Wconflicts-sr]
lex 代码
%{
#include "y.tab.h"
%}
%%
[0-9]+ { return NUMBER; }
[_a-zA-Z][_a-zA-Z0-9]* { return ID; }
[-+*/] { return OPERATOR; }
.|\n { return *yytext; }
%%
int yywrap(){
return 1;
}
yacc代码
%{
#include<stdio.h>
int yylex();
void yyerror(const char*);
%}
%token NUMBER ID OPERATOR
%%
E : E '\n' { return 0; }
| E OPERATOR E
| '(' E ')'
| NUMBER
| ID
;
%%
void yyerror(const char* s){
printf("%s\n", s);
}
int main(){
if(yyparse() == 0)
printf("Valid Arithmetic Expression\n");
else
printf("Invalid Arithmetic Expression\n");
}
我怎样才能摆脱这个?
你的语法有歧义; E OPERATOR E
可以以两种方式应用于 a + b * c
(具有两种不同的含义),具体取决于第一个 E
是否用于派生 a
或 a + b
。
不明确的语法总是有冲突,因为在解析中总是有一个点,解析器可以使用多个冲突的动作。 (反之则不然:有冲突的文法不一定有歧义。我想这会在你的课程后面出现。)
所以如果你想消除冲突,你需要选择上面两种可能的推导中哪一个是正确的(以及所有类似的歧义,但由于它们都有相同的原因,所以相对简单的修复是可能的)。
我正在尝试编写一个 yacc 程序来查明算术表达式是否有效。 我的程序似乎 运行 正常,但我在控制台收到警告。
warning: 2 shift/reduce conflicts [-Wconflicts-sr]
lex 代码
%{
#include "y.tab.h"
%}
%%
[0-9]+ { return NUMBER; }
[_a-zA-Z][_a-zA-Z0-9]* { return ID; }
[-+*/] { return OPERATOR; }
.|\n { return *yytext; }
%%
int yywrap(){
return 1;
}
yacc代码
%{
#include<stdio.h>
int yylex();
void yyerror(const char*);
%}
%token NUMBER ID OPERATOR
%%
E : E '\n' { return 0; }
| E OPERATOR E
| '(' E ')'
| NUMBER
| ID
;
%%
void yyerror(const char* s){
printf("%s\n", s);
}
int main(){
if(yyparse() == 0)
printf("Valid Arithmetic Expression\n");
else
printf("Invalid Arithmetic Expression\n");
}
我怎样才能摆脱这个?
你的语法有歧义; E OPERATOR E
可以以两种方式应用于 a + b * c
(具有两种不同的含义),具体取决于第一个 E
是否用于派生 a
或 a + b
。
不明确的语法总是有冲突,因为在解析中总是有一个点,解析器可以使用多个冲突的动作。 (反之则不然:有冲突的文法不一定有歧义。我想这会在你的课程后面出现。)
所以如果你想消除冲突,你需要选择上面两种可能的推导中哪一个是正确的(以及所有类似的歧义,但由于它们都有相同的原因,所以相对简单的修复是可能的)。