2017-02-16 29 views
1

Я прохожу через упражнение программирования Ch3, создавая Parser Tiger в книге «Современный сборщик компиляторов в ML». Мой файл tiger.grm - here. Ошибка, которую я пытаюсь диагностировать, - это конфликт с уменьшением сокращения, возникающий из правил для унарного и двоичного оператора-минуса. Здесь ошибка Yacc:ML-Yacc Tiger Parser Уменьшить/уменьшить ошибку

error: state 128: reduce/reduce conflict between rule 48 and rule 46 on OR 
error: state 128: reduce/reduce conflict between rule 48 and rule 46 on AND 
error: state 128: reduce/reduce conflict between rule 48 and rule 46 on GE 
error: state 128: reduce/reduce conflict between rule 48 and rule 46 on GT 
error: state 128: reduce/reduce conflict between rule 48 and rule 46 on LE 
error: state 128: reduce/reduce conflict between rule 48 and rule 46 on LT 
error: state 128: reduce/reduce conflict between rule 48 and rule 46 on NEQ 
error: state 128: reduce/reduce conflict between rule 48 and rule 46 on EQ 
error: state 128: reduce/reduce conflict between rule 48 and rule 46 on DIVIDE 
error: state 128: reduce/reduce conflict between rule 48 and rule 46 on TIMES 
error: state 128: reduce/reduce conflict between rule 48 and rule 46 on MINUS 
error: state 128: reduce/reduce conflict between rule 48 and rule 46 on PLUS 
error: state 128: reduce/reduce conflict between rule 48 and rule 46 on RPAREN 

state 128: 

    boolean : exp . AND exp 
    boolean : exp . OR exp 
    arithmetic : MINUS exp . (reduce by rule 46) 
    arithmetic : exp . PLUS exp 
    arithmetic : exp . MINUS exp 
    arithmetic : exp MINUS exp . (reduce by rule 48) 
    arithmetic : exp . DIVIDE exp 
    arithmetic : exp . TIMES exp 
    comparison : exp . EQ exp 
    comparison : exp . NEQ exp 
    comparison : exp . GT exp 
    comparison : exp . LT exp 
    comparison : exp . LE exp 
    comparison : exp . GE exp 

Я определил UNARY с более высоким приоритетом, чем МИНУС, и установить его в явном виде в моем правиле, используя %prec. Конечно, когда я удаляю любое правило, конфликт исчезает, но грамматика неправильно анализирует знак MINUS.

Я не могу диагностировать эту ошибку - любые идеи?

ответ

3

Дикая догадка: возможно ли, что одно из ваших правил допускает, чтобы exp был пустым? Если это так, то это создаст двусмысленность в любом месте, где exp не является обязательным - например, до - exp.

2

В соответствии с принятым ответом (он был прав) - произошла ошибка в производстве для последовательностей, которые позволили exp перейти на epsilon.

Вот обижая бит кода (см последнюю строку):

sequence : LPAREN exp_sequence RPAREN() 
exp_sequence : (*epsilon*)() 
     | exp seq () 

seq : (*epsilon*)    () (*an exp sequence can be empty*) 
    | SEMICOLON exp exp_sequence() (*exps separated by semicolon*) 

Вот исправленный код:

sequence : LPAREN exp_sequence RPAREN() 
exp_sequence : (*epsilon*)() 
      | exp seq () 

seq : (*epsilon*)    () (*an exp sequence can be empty*) 
    | SEMICOLON exp seq() (*exps separated by semicolon*) 

 Смежные вопросы

  • Нет связанных вопросов^_^