野牛:如果/其他减少/减少冲突

时间:2018-11-29 10:52:25

标签: bison flex-lexer

我是野牛新手。我得到的是减少/减少冲突错误,但没有得到它发生的地方。错误消息是“冲突:1减少/减少”。这是我的语法规则。

%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($3);printf("V\n");}              
    | V_NM                          {AddNewVar($1);printf("Vn %s\n",$1);}               
    | /* empty */                   {printf("E\n");}
    ;
STATEMENTS :                        { $$ = 0; }
    | EXP EQU X                     {AsgnVal($3,$1);}
    | PRINT EXP                     {printf("Output: %d\n",$2);}
    | EXP                           { $$ = $1 ;}                                                                
    ;
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 > $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 zero\n");}   
                                    }
    | FACTOR                        { $$ = $1; }
    | X                             { $$=VarVal($1); }
    ;
FACTOR : NUMBER                     { $$ = $1; }
    | LP EXP RP                     { $$ = $2; }
    ; 

当我为IF / ELSE插入语法时,开始出现冲突错误。 除去那部分,我的代码就可以了。我也想知道是否有任何方法可以使用command检测此冲突在哪里发生。

1 个答案:

答案 0 :(得分:2)

  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 NL NL     (CODE: CODE STATEMENTS NL)
           ⇒ STMNT STATEMENTS NL NL    (CODE: STMNT)
           ⇒ MIF NL STATEMENTS NL NL   (STMNT: MIF NL)
           ⇒ MIF NL STATEMENTS NL NL   (MIF: CODE STATEMENTS NL)
           ⇒ CODE STATEMENTS NL 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中的完整示例。野牛的trace facility也是非常有用的,它将使您不必在整个解析器中分散printf语句(然后将其删除)。

  4. 如果您遵循通常的样式准则,那么您的语法(对您以外的其他人)将更具可读性:

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

      %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 ')'