Bison:如果/否则减少/减少冲突



我是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 completen");}
|   CODE DECLARATION NL         {printf("Declaration completen");} 
|   STMNT 
;
DECLARATION :  TYPE V               {printf("Dn");}
;
TYPE : INT                          {printf("In");}
| FLOAT                         {printf("Fn");}
| CHAR
;
V : V CM V_NM                       {AddNewVar($3);printf("Vn");}              
| V_NM                          {AddNewVar($1);printf("Vn %sn",$1);}               
| /* empty */                   {printf("En");}
;
STATEMENTS :                        { $$ = 0; }
| EXP EQU X                     {AsgnVal($3,$1);}
| PRINT EXP                     {printf("Output: %dn",$2);}
| EXP                           { $$ = $1 ;}                                                                
;
STMNT : MIF NL
| UIF NL
;
MIF : IF CON THN HH MIF HH ELSE HH MIF HH   {printf("MIF1n");}
| CODE STATEMENTS NL
;
UIF : IF CON THN HH STMNT HH                {printf("UIF1n");}
| IF CON THN HH MIF HH ELSE HH UIF HH   {printf("UIF2n");}
;
CON : EXP GT EXP                    { $$ =  $1 > $3? 1: 0 ; }
| EXP LT EXP                    { $$ =  $1 < $3? 1: 0 ; }
| EXP EQU EXP                   { $$ = $1 == $3? 1: 0 ; }
;
X : V_NM                            { $$=$1;CheckIfFound($1);}
;
EXP : TERM 
| EXP ADD TERM                  { $$ = $1 + $3; }
| EXP SUB TERM                  { $$ = $1 - $3; }
;
TERM : TERM MUL FACTOR              { $$ = $1 * $3; }
| TERM DIV FACTOR               { if($3){$$ = $1 / $3;}
else {printf("Division by zeron");}   
}
| FACTOR                        { $$ = $1; }
| X                             { $$=VarVal($1); }
;
FACTOR : NUMBER                     { $$ = $1; }
| LP EXP RP                     { $$ = $2; }
; 

当我插入IF/ELSE的语法时,冲突错误开始了。排除这一部分,我的代码工作得很好。我还想知道是否有任何方法可以使用命令来检测冲突发生在哪里。

  1. 问题确实是由if产品引发的。它是这样的(忽略了其他无关的制作(:

    MIF  : CODE STATEMENTS NL
    CODE : STMNT
    | CODE STATEMENTS NL
    STATEMENTS: %empty
    STMNT: MIF NL
    

    注意,NL始终是CODE的可能前瞻,因为CODE: CODE STATEMENTS NLSTATEMENTS: %empty,这意味着CODE可以导出CODE NL。(

    CODE NL⇒CODE STATEMENTS NLNL     (CODE: CODE STATEMENTS NL)
    ⇒STMNTSTATEMENTS NL NL    (CODE: STMNT)
    ⇒MIF NLSTATEMENTS NL NL   (STMNT: MIF NL)
    ⇒MIFNL STATEMENTS NL NL   (MIF: CODE STATEMENTS NL)
    ⇒CODE STATEMENTS NLNL STATEMENTS NL NL
    

    这当然是减少冲突。当解析器找到CODE STATEMENTS NL并将NL视为前瞻时,它可以使用缩减CODE: CODE STATEMENTS NLMIF: CODE STATEMENTS NL

  2. 如果你正在使用维基百科的其他页面作为指南(或者即使你没有(,请仔细查看产品closed_statement: non_if_statement。(closed_statement相当于您的MIF(。

  3. 虽然没有神奇的命令where_is_my_error,但使用bison将在请求时生成的报告文件(使用-v--report选项(很容易看到这个问题。请参阅bison手动调试一章中的完整示例。bison的跟踪功能也非常有用,它将使您不必在整个解析器中散布printf语句(稍后再将其删除(。

  4. 如果你遵循通常的风格准则:,你的语法(对你以外的人(会可读得多

    1. 对令牌使用UPPER_CASE,对非终端使用lower_casecamelCase
    2. 写出完整的单词。Rmvng vwls frm dntfrs mks yr cd nrdbl
    3. 使用bison的别名功能将关键字写为关键字本身(用引号括起来(:

      %token T_THEN "then" T_IF "if" T_ELSE "else"
      %%
      matchedIf: "if" condition "then" HH matchedIf HH "else" HH matchedIf HH
      

      参见野牛手册中关于符号的章节

    4. 您还可以使用单引号字符标记来简化语法。这些甚至不需要声明:

      term: term '*' factor
      factor: '(' expression ')'
      

相关内容

最新更新