警告: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 是否用于派生 aa + b

不明确的语法总是有冲突,因为在解析中总是有一个点,解析器可以使用多个冲突的动作。 (反之则不然:有冲突的文法不一定有歧义。我想这会在你的课程后面出现。)

所以如果你想消除冲突,你需要选择上面两种可能的推导中哪一个是正确的(以及所有类似的歧义,但由于它们都有相同的原因,所以相对简单的修复是可能的)。