ML-Yacc Tiger Parser Уменьшить / уменьшить ошибку

Я выполняю упражнение по программированию Ch3 по созданию Tiger Parser в книге Аппеля "Современная реализация компилятора в ML". Мой файл tiger.grm находится здесь. Ошибка, которую я пытаюсь диагностировать, - это конфликт типа "уменьшить-уменьшить", возникающий из правил для унарного и двоичного оператора минус. Вот ошибка yacc:

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 с более высоким приоритетом, чем MINUS, и установил его явно в моем правиле, используя %prec, Конечно, когда я удаляю одно из правил, конфликт исчезает, но грамматика неправильно анализирует знак МИНУС.

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

2 ответа

Решение

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

Как продолжение принятого ответа (он / она был прав) - в постановке была допущена ошибка, которая позволила 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*)
Другие вопросы по тегам