野牛:If/Else reduce/reduce 冲突
Bison: If/Else reduce/reduce conflict
我是 Bison 的新手。我收到 reduce/reduce 冲突错误,但不知道发生了什么。错误消息是 "conflicts: 1 reduce/reduce"。这是我的语法规则。
%token INT FLOAT CHAR EXIT V_MAIN BS BE NL EQU CM ADD SUB MUL DIV LT GT LP RP PRINT IF ELSE THN HH
%token <VarNm> V_NM
%token <num> NUMBER
%token <flt> R_NUM
%type <num> EXP TERM FACTOR CON STATEMENTS
%type <VarNm> X
%nonassoc THN
%nonassoc ELSE
%start STRT
%left LT GT
%left PLUS MINUS
%left MULT DIV
%%
STRT : V_MAIN BS CODE BE {printf("Compilation complete. :)\n");}
| EXIT {exit(EXIT_SUCCESS);}
;
CODE : /* empty */
| CODE STATEMENTS NL {printf("Statements complete\n");}
| CODE DECLARATION NL {printf("Declaration complete\n");}
| STMNT
;
DECLARATION : TYPE V {printf("D\n");}
;
TYPE : INT {printf("I\n");}
| FLOAT {printf("F\n");}
| CHAR
;
V : V CM V_NM {AddNewVar();printf("V\n");}
| V_NM {AddNewVar();printf("Vn %s\n",);}
| /* empty */ {printf("E\n");}
;
STATEMENTS : { $$ = 0; }
| EXP EQU X {AsgnVal(,);}
| PRINT EXP {printf("Output: %d\n",);}
| EXP { $$ = ;}
;
STMNT : MIF NL
| UIF NL
;
MIF : IF CON THN HH MIF HH ELSE HH MIF HH {printf("MIF1\n");}
| CODE STATEMENTS NL
;
UIF : IF CON THN HH STMNT HH {printf("UIF1\n");}
| IF CON THN HH MIF HH ELSE HH UIF HH {printf("UIF2\n");}
;
CON : EXP GT EXP { $$ = > ? 1: 0 ; }
| EXP LT EXP { $$ = < ? 1: 0 ; }
| EXP EQU EXP { $$ = == ? 1: 0 ; }
;
X : V_NM { $$=;CheckIfFound();}
;
EXP : TERM
| EXP ADD TERM { $$ = + ; }
| EXP SUB TERM { $$ = - ; }
;
TERM : TERM MUL FACTOR { $$ = * ; }
| TERM DIV FACTOR { if(){$$ = / ;}
else {printf("Division by zero\n");}
}
| FACTOR { $$ = ; }
| X { $$=VarVal(); }
;
FACTOR : NUMBER { $$ = ; }
| LP EXP RP { $$ = ; }
;
当我为 IF/ELSE 插入语法时开始出现冲突错误。
排除那部分我的代码工作得很好。我还想知道是否有任何方法可以使用 command 检测此冲突发生在何处。
确实是你的if
作品引起的。它是这样的(省略其他不相关的作品):
MIF : CODE STATEMENTS NL
CODE : STMNT
| CODE STATEMENTS NL
STATEMENTS: %empty
STMNT: MIF NL
请注意,NL
始终是 CODE
的可能先行,因为 CODE: CODE STATEMENTS NL
和 STATEMENTS: %empty
,这意味着 CODE
可以导出 CODE NL
.)
CODE NL⇒ <b>CODE STATEMENTS NL</b> NL (CODE: CODE STATEMENTS NL)
⇒ <b>STMNT</b> STATEMENTS NL NL (CODE: STMNT)
⇒ <b>MIF NL</b> STATEMENTS NL NL (STMNT: MIF NL)
⇒ <b>MIF</b> NL STATEMENTS NL NL (MIF: CODE STATEMENTS NL)
⇒ <b>CODE STATEMENTS NL</b> NL STATEMENTS NL NL
这肯定是减少-减少冲突。当解析器找到 CODE STATEMENTS NL
并将 NL
视为超前时,它可以使用缩减 CODE: CODE STATEMENTS NL
或 MIF: CODE STATEMENTS NL
.
如果您使用 Wikipedia dangling-else page 作为指导(或者即使您不是),请仔细查看作品 closed_statement: non_if_statement
。 (closed_statement
相当于您的 MIF
)。
虽然没有神奇的命令where_is_my_error
,但使用 bison 在需要时生成的报告文件(使用 -v
或 --report
选项)。请参阅 bison manual debugging chapter. Also super-useful is bison's trace facility 中的完整示例,这将使您不必在整个解析器中散布 printf
语句(然后删除它们)。
如果您遵循通常的风格指南,您的语法将更具可读性(对您以外的人而言):
- 对令牌使用
UPPER_CASE
,对非终端使用 lower_case
或 camelCase
。
- 把单词写完整。 Rmvng vwls frm dntfrs mks yr cd nrdbl.
使用bison的别名功能将关键字写成关键字本身(引号):
%token T_THEN "then" T_IF "if" T_ELSE "else"
%%
matchedIf: "if" condition "then" HH matchedIf HH "else" HH matchedIf HH
您还可以使用单引号字符标记来简化语法。这些甚至不需要声明:
term: term '*' factor
factor: '(' expression ')'
我是 Bison 的新手。我收到 reduce/reduce 冲突错误,但不知道发生了什么。错误消息是 "conflicts: 1 reduce/reduce"。这是我的语法规则。
%token INT FLOAT CHAR EXIT V_MAIN BS BE NL EQU CM ADD SUB MUL DIV LT GT LP RP PRINT IF ELSE THN HH
%token <VarNm> V_NM
%token <num> NUMBER
%token <flt> R_NUM
%type <num> EXP TERM FACTOR CON STATEMENTS
%type <VarNm> X
%nonassoc THN
%nonassoc ELSE
%start STRT
%left LT GT
%left PLUS MINUS
%left MULT DIV
%%
STRT : V_MAIN BS CODE BE {printf("Compilation complete. :)\n");}
| EXIT {exit(EXIT_SUCCESS);}
;
CODE : /* empty */
| CODE STATEMENTS NL {printf("Statements complete\n");}
| CODE DECLARATION NL {printf("Declaration complete\n");}
| STMNT
;
DECLARATION : TYPE V {printf("D\n");}
;
TYPE : INT {printf("I\n");}
| FLOAT {printf("F\n");}
| CHAR
;
V : V CM V_NM {AddNewVar();printf("V\n");}
| V_NM {AddNewVar();printf("Vn %s\n",);}
| /* empty */ {printf("E\n");}
;
STATEMENTS : { $$ = 0; }
| EXP EQU X {AsgnVal(,);}
| PRINT EXP {printf("Output: %d\n",);}
| EXP { $$ = ;}
;
STMNT : MIF NL
| UIF NL
;
MIF : IF CON THN HH MIF HH ELSE HH MIF HH {printf("MIF1\n");}
| CODE STATEMENTS NL
;
UIF : IF CON THN HH STMNT HH {printf("UIF1\n");}
| IF CON THN HH MIF HH ELSE HH UIF HH {printf("UIF2\n");}
;
CON : EXP GT EXP { $$ = > ? 1: 0 ; }
| EXP LT EXP { $$ = < ? 1: 0 ; }
| EXP EQU EXP { $$ = == ? 1: 0 ; }
;
X : V_NM { $$=;CheckIfFound();}
;
EXP : TERM
| EXP ADD TERM { $$ = + ; }
| EXP SUB TERM { $$ = - ; }
;
TERM : TERM MUL FACTOR { $$ = * ; }
| TERM DIV FACTOR { if(){$$ = / ;}
else {printf("Division by zero\n");}
}
| FACTOR { $$ = ; }
| X { $$=VarVal(); }
;
FACTOR : NUMBER { $$ = ; }
| LP EXP RP { $$ = ; }
;
当我为 IF/ELSE 插入语法时开始出现冲突错误。 排除那部分我的代码工作得很好。我还想知道是否有任何方法可以使用 command 检测此冲突发生在何处。
确实是你的
if
作品引起的。它是这样的(省略其他不相关的作品):MIF : CODE STATEMENTS NL CODE : STMNT | CODE STATEMENTS NL STATEMENTS: %empty STMNT: MIF NL
请注意,
NL
始终是CODE
的可能先行,因为CODE: CODE STATEMENTS NL
和STATEMENTS: %empty
,这意味着CODE
可以导出CODE NL
.)CODE NL⇒ <b>CODE STATEMENTS NL</b> NL (CODE: CODE STATEMENTS NL) ⇒ <b>STMNT</b> STATEMENTS NL NL (CODE: STMNT) ⇒ <b>MIF NL</b> STATEMENTS NL NL (STMNT: MIF NL) ⇒ <b>MIF</b> NL STATEMENTS NL NL (MIF: CODE STATEMENTS NL) ⇒ <b>CODE STATEMENTS NL</b> NL STATEMENTS NL NL
这肯定是减少-减少冲突。当解析器找到
CODE STATEMENTS NL
并将NL
视为超前时,它可以使用缩减CODE: CODE STATEMENTS NL
或MIF: CODE STATEMENTS NL
.如果您使用 Wikipedia dangling-else page 作为指导(或者即使您不是),请仔细查看作品
closed_statement: non_if_statement
。 (closed_statement
相当于您的MIF
)。虽然没有神奇的命令
where_is_my_error
,但使用 bison 在需要时生成的报告文件(使用-v
或--report
选项)。请参阅 bison manual debugging chapter. Also super-useful is bison's trace facility 中的完整示例,这将使您不必在整个解析器中散布printf
语句(然后删除它们)。如果您遵循通常的风格指南,您的语法将更具可读性(对您以外的人而言):
- 对令牌使用
UPPER_CASE
,对非终端使用lower_case
或camelCase
。 - 把单词写完整。 Rmvng vwls frm dntfrs mks yr cd nrdbl.
使用bison的别名功能将关键字写成关键字本身(引号):
%token T_THEN "then" T_IF "if" T_ELSE "else" %% matchedIf: "if" condition "then" HH matchedIf HH "else" HH matchedIf HH
您还可以使用单引号字符标记来简化语法。这些甚至不需要声明:
term: term '*' factor factor: '(' expression ')'
- 对令牌使用