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

Bison 野牛:如果/否则减少/减少冲突,bison,flex-lexer,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 <nu

我是野牛队的新手。我收到“减少/减少冲突”错误,但没有得到它发生的位置。错误消息是“冲突: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; }
    ; 
%token INT FLOAT CHAR EXIT V_MAIN BS BE NL eq CM ADD SUB MUL DIV LT GT LP RP PRINT IF ELSE THN HH
%令牌V_NM
%令牌号
%令牌R_NUM
%类型EXP术语因子CON语句
%X型
%非饱和THN
%非ASSOC ELSE
%启动STRT
%左LT GT
%左加减
%左多功能分区
%%
STRT:V_主BS代码为{printf(“编译完成:\n”);}
|退出{EXIT(EXIT_SUCCESS);}
;
代码:/*空*/
|代码语句NL{printf(“语句完成\n”);}
|代码声明NL{printf(“声明完成\n”);}
|STMNT
;
声明:类型V{printf(“D\n”);}
;
类型:INT{printf(“I\n”);}
|浮点{printf(“F\n”);}
|煤焦
;
V:vcm V_NM{AddNewVar($3);printf(“V\n”);}
|V_NM{AddNewVar($1);printf(“Vn%s\n”,$1);}
|/*空*/{printf(“E\n”);}
;
语句:{$$=0;}
|EXP eq X{AsgnVal($3,$1);}
|PRINT EXP{printf(“输出:%d\n”,$2);}
|EXP{$$=$1;}
;
STMNT:MIF-NL
|UIF NL
;
MIF:IF CON THN HH MIF HH ELSE HH MIF HH{printf(“MIF1\n”);}
|代码语句NL
;
UIF:IF CON THN HH STMNT HH{printf(“UIF1\n”);}
|如果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 eq EXP{$$=$1==$3?1:0;}
;
X:V_NM{$$=1;checkifound($1);}
;
出口:期限
|EXP ADD TERM{$$=$1+$3;}
|EXP子项{$$=$1-$3;}
;
术语:术语多因子{$$=$1*$3;}
|术语DIV因子{if($3){$$=$1/$3;}
else{printf(“被零除”);}
}
|因子{$$=$1;}
|X{$$=VarVal($1);}
;
系数:数字{$$=$1;}
|LP EXP RP{$$=$2;}
; 
当我插入IF/ELSE的语法时,冲突错误开始了。 排除这一部分,我的代码工作得很好。我还想知道是否有任何方法可以使用命令来检测冲突发生在哪里

  • 问题确实是由您的
    if
    产品引发的。它是这样的(不考虑其他无关的产品):

    请注意,
    NL
    始终是
    code
    的一种可能的前瞻,因为
    code:code语句NL
    语句:%empty
    ,这意味着
    code
    可以派生
    code-NL

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

    term: term '*' factor
    factor: '(' expression ')'
    
  • 问题确实是由您的
    if
    产品引发的。它是这样的(不考虑其他无关的产品):

    请注意,
    NL
    始终是
    code
    的一种可能的前瞻,因为
    code:code语句NL
    语句:%empty
    ,这意味着
    code
    可以派生
    code-NL

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

    term: term '*' factor
    factor: '(' expression ')'
    
  • %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 ')'