Зубр: Если / Остальное уменьшить / уменьшить конфликт - PullRequest
0 голосов
/ 29 ноября 2018

Я новичок в зубрах.Я получаю ошибку уменьшения / уменьшения конфликта, но не понимаю, где она происходит. Сообщение об ошибке «конфликтов: 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.Исключая эту часть, мой код работает просто отлично.Я также хотел бы знать, есть ли способ определить, где происходит этот конфликт, с помощью команды.

1 Ответ

0 голосов
/ 29 ноября 2018
  1. Проблема действительно вызвана вашей 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&rArr; <b>CODE STATEMENTS NL</b> NL     (CODE: CODE STATEMENTS NL)
           &rArr; <b>STMNT</b> STATEMENTS NL NL    (CODE: STMNT)
           &rArr; <b>MIF NL</b> STATEMENTS NL NL   (STMNT: MIF NL)
           &rArr; <b>MIF</b> NL STATEMENTS NL NL   (MIF: CODE STATEMENTS NL)
           &rArr; <b>CODE STATEMENTS NL</b> NL STATEMENTS NL NL
    

    Это, безусловно, конфликт уменьшения-уменьшения.Когда синтаксический анализатор обнаружил CODE STATEMENTS NL и видит NL в качестве предварительного просмотра, он может использовать сокращение CODE: CODE STATEMENTS NL или MIF: CODE STATEMENTS NL.

  2. Если вы используете Википедия, висящая остальная страница в качестве руководства (или даже если вы не были), внимательно посмотрите на производство closed_statement: non_if_statement.(closed_statement является эквивалентом вашего MIF).

  3. Хотя волшебной команды where_is_my_error нет, довольно легко увидеть эту проблему, используя файл отчета, который будет обрабатывать бизон.производить по запросу (с опциями -v или --report).См. Полностью проработанный пример в главе по ручной отладке бизонов *1037*.Также супер-полезна утилита трассировки бизонов , которая избавит вас от необходимости разбрасывать printf операторов по всему парсеру (а затем удалять их).

  4. Вашграмматика была бы намного более удобочитаемой (для других, чем вы), если бы вы соответствовали обычным правилам стиля:

    1. Используйте UPPER_CASE для токенов и lower_case или camelCase для нетерминалов.
    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 ')'
      
...