Как убрать сдвиг-уменьшить конфликт в грамматике yacc?

У меня есть следующая грамматика:

Expression
    : SimpleExpression {$$ = $1;};
    | SimpleExpression LTnum SimpleExpression
        { MkLeftC($1, $2); $$ = MkRightC($3, $2); }
    | SimpleExpression LEnum SimpleExpression
        { MkLeftC($1, $2); $$ = MkRightC($3, $2); }
    | SimpleExpression EQnum SimpleExpression
        { MkLeftC($1, $2); $$ = MkRightC($3, $2); }
    | SimpleExpression NEnum SimpleExpression
        { MkLeftC($1, $2); $$ = MkRightC($3, $2); }
    | SimpleExpression GEnum SimpleExpression
        { MkLeftC($1, $2); $$ = MkRightC($3, $2); }
    | SimpleExpression GTnum SimpleExpression
        { MkLeftC($1, $2); $$ = MkRightC($3, $2); }
    ;

SimpleExpression
    : PLUSnum Term op_terms
        { $$ = MakeTree(AddOp,$3,$2); }
    | MINUSnum Term op_terms
        { $$ = MakeTree(SubOp,$3,$2); }
    ;

op_terms
    : PLUSnum Term
        { $$ = MakeTree(AddOp,NullExp(),$2); }
    | PLUSnum Term op_terms
        { $$ = MakeTree(AddOp,$3,$2); }
    | MINUSnum Term
        { $$ = MakeTree(SubOp,NullExp(),$2); }
    | MINUSnum Term op_terms
        { $$ = MakeTree(SubOp,$3,$2); }
    | ORnum Term
        { $$ = MakeTree(OrOp,NullExp(),$2); }
    | ORnum Term op_terms
        { $$ = MakeTree(OrOp,$3,$2); }
    ;

Я получаю следующие конфликты сдвига-уменьшения в файле y.output:

51: shift/reduce conflict (shift 74, reduce 57) on GTnum
51: shift/reduce conflict (shift 75, reduce 57) on NEnum
51: shift/reduce conflict (shift 76, reduce 57) on EQnum
51: shift/reduce conflict (shift 77, reduce 57) on GEnum
51: shift/reduce conflict (shift 78, reduce 57) on LEnum
51: shift/reduce conflict (shift 79, reduce 57) on LTnum
state 51
    Expression : SimpleExpression .  (57)
    Expression : SimpleExpression . LTnum SimpleExpression  (58)
    Expression : SimpleExpression . LEnum SimpleExpression  (59)
    Expression : SimpleExpression . EQnum SimpleExpression  (60)
    Expression : SimpleExpression . NEnum SimpleExpression  (61)
    Expression : SimpleExpression . GEnum SimpleExpression  (62)
    Expression : SimpleExpression . GTnum SimpleExpression  (63)

Мне нужна помощь в устранении этих конфликтов. Что я здесь не так делаю? Я пытался установить правила приоритета, но они почему-то здесь не работают. Есть идеи?

1 ответ

Решение

Странная грамматика. Это должно быть в такой форме:

Expression
    : SimpleExpression {$$ = $1;};
    | Expression LTnum SimpleExpression
    | Expression LEnum SimpleExpression
    | Expression EQnum SimpleExpression
    | Expression NEnum SimpleExpression
    | Expression GEnum SimpleExpression
    | Expression GTnum SimpleExpression
    ;

то есть используя левую рекурсию.

Странное дерево тоже. Он должен иметь общую форму:

$$ = MkBinaryNode($1,$2,$3);
Другие вопросы по тегам