野牛: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 检测此冲突发生在何处。

  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⇒ <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 NLMIF: CODE STATEMENTS NL.

  2. 如果您使用 Wikipedia dangling-else page 作为指导(或者即使您不是),请仔细查看作品 closed_statement: non_if_statement。 (closed_statement 相当于您的 MIF)。

  3. 虽然没有神奇的命令where_is_my_error,但使用 bison 在需要时生成的报告文件(使用 -v--report 选项)。请参阅 bison manual debugging chapter. Also super-useful is bison's trace facility 中的完整示例,这将使您不必在整个解析器中散布 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
      

      bison manual chapter on Symbols

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

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