Parsing Bison-移位/减少冲突标识符
我在19号州有1个班次/减少冲突。我认为“标识符”的不同出现可能有问题,但我正在努力理解野牛报告并解决冲突。下面是我的语法,后面是野牛报告和州信息:Parsing Bison-移位/减少冲突标识符,parsing,compiler-construction,bison,shift-reduce-conflict,Parsing,Compiler Construction,Bison,Shift Reduce Conflict,我在19号州有1个班次/减少冲突。我认为“标识符”的不同出现可能有问题,但我正在努力理解野牛报告并解决冲突。下面是我的语法,后面是野牛报告和州信息: %{ #include <cstdio> #include <iostream> using namespace std; extern "C" int yylex(); extern "C" int yyparse(); void yyerror(const char *s
%{
#include <cstdio>
#include <iostream>
using namespace std;
extern "C" int yylex();
extern "C" int yyparse();
void yyerror(const char *s);
%}
%union{
int int_val;
double d_val;
char *strng;
}
%token TLINEC TBLOCKC TPRINT
%token TASSIGN TCPA TOB TCB TCOMMA TSEMIC
%token TIF TELSE TFOR
%token TINT TFLOAT TD TCHAR
%token TPLUS TMINUS TDIV TMULT
%token TLT TGT TAND TOR TEQUAL TNE
%token<int_val> TINTEGER
%token<d_val> TDOUBLE
%token<strng> TID
%token TOPA
%start program
%%
program : command_list
command_list : declaration
| command_list declaration
declaration : function_dec
| variable_dec
| expression
variable_dec : type identifier TSEMIC
| type assignment TSEMIC
assignment : identifier TASSIGN expression
var_list : expression
| var_list TCOMMA expression
|
function_dec : type identifier TOPA p_list TCPA scope
p_list : variable_dec
| p_list TCOMMA variable_dec
type : TINT
| TD
| TFLOAT
| TCHAR
/* inside function scope */
scope : TOB command_list TCB
| TOB TCB
function_call : identifier TOPA var_list TCPA TSEMIC
/* expression rules */
expression : assignment
| function_call
| TOPA expression TCPA
| constant arithmetic_op expression
| constant logical_op expression
| constant
constant : identifier
| num
identifier : TID
num : TINTEGER
| TDOUBLE
arithmetic_op : TPLUS | TMINUS | TDIV | TMULT
logical_op : TLT | TGT | TAND | TOR | TEQUAL | TNE
%%
int main(int, char**){
int y=0;
do{
y=yyparse();
}while(y);
}
void yyerror(const char *s){
cout << "parse error! Message: " << s << endl;
exit(-1);
}
根据bison的输出,从状态19开始,可以提前减少
expression
。这怎么可能?换句话说,在什么情况下expression
后面可以加一个括号
在语法中搜索只会发现TOPA
的三种用法。其中两种用法(函数声明和函数调用)跟在identifier
后面,而identifier
无法派生表达式,因此它必须是第三种用法:
expression: TOPA expression TCPA;
但是,expression
的减少可以在(的)实例之前立即发生的唯一方法是两个expression
可以连续发生。通常,在类C语言中,通过要求a;分隔语句来消除这种可能性(可能是以表达式开始,也可能以表达式结束),我想这就是你的意图
然而,我们看到:
command_list: declaration
| command_list declaration
declaration: expression
它允许两个连续的表达式而不插入分号
一如既往,我鼓励在野牛语法中使用更具可读性的标记。(“
比TOPA
更容易理解,老实说,我不知道COB
可能是什么。但这是一个风格问题
command_list: declaration
| command_list declaration
declaration: expression