警告:2 shift/reduce 冲突 [-Wconflicts-sr] 错误

Warning: 2 shift/reduce conflicts [-Wconflicts-sr] err

%{
#include<stdio.h>
#include<stdlib.h>
int regs[30];
%}
%token NUMBER LETTER
%left  PLUS MINUS 
%left MULT DIV 
%%

prog: prog st | ; //when I remove this line the error goes
st : E {printf("ans %d", );}| LETTER '=' E {regs[] = ; printf("variable contains %d",regs[]);}; 
E :  E PLUS E{$$ =  + ;} //addition
| E MINUS E{$$ =  -  ;} //subtraction
| MINUS E{$$ = -;} 
| E MULT E{$$ =  *  ;} 
| E DIV E { if()$$=  / ; else yyerror("Divide by 0");} 
/*|LBRACE E RBRACE{$$= ;} 
| RBRACE E LBRACE{yyerror("Wrong expression");} */
| NUMBER {$$ = ;}
| LETTER {$$ = regs[];}
;
%%

int main(void)
{
printf("Enter Expression: ");
yyparse();
return 0;
}

int yyerror(char *msg)
{
printf("%s", msg);// printing error
exit(0);
}

我无法解决冲突。当我 运行 进行一些编辑时,我也遇到了分段错误。我正在使用 yacc 和 lex。

这两个 shift-reduce 冲突是由于您不需要在语句之间使用任何显式分隔符这一事实造成的。因此,a = b - 3 可以解释为一个语句或两个语句(a = b- 3)。第二种解释对你来说可能不是很自然,但它很容易从语法中推导出来。

此外,您使用一元减号会导致 -2/3 错误解析为 -(2/3) 而不是 (-2)/3。 (您可能会或可能不会觉得这很严重,因为它对这些特定运算符几乎没有语义影响。)bison manual 和许多其他互联网资源中讨论了这个特定问题和正确的解决方案。

如果您使用 bison 的 -v 命令行选项来生成解析器的描述,那么这两种解释都会变得更加明显。请参阅 Understanding your parser(同样在 bison 手册中)。