2

以下是我的语法:

arithmetic_expression : expression + expression
                      | expression - expression

expression            : constant
                      | ID
                      | arithmetic_expression
                      | ternary

ternary               : expression ? expression : expression

在这种状态下,我收到一个 shift-reduce 错误:

state 126

    (19) ternary -> expression QUESTION_MARK expression COLON expression .
    (27) arithmetic_exp -> expression . PLUS expression
    (28) arithmetic_exp -> expression . MINUS expression
    (19) ternary -> expression . QUESTION_MARK expression COLON expression

  ! shift/reduce conflict for PLUS resolved as shift
  ! shift/reduce conflict for MINUS resolved as shift
  ! shift/reduce conflict for QUESTION_MARK resolved as shift

    PLUS            shift and go to state 86
    MINUS           shift and go to state 88
    QUESTION_MARK   shift and go to state 85

  ! PLUS            [ reduce using rule 19 (ternary -> expression QUESTION_MARK expression COLON expression .) ]
  ! MINUS           [ reduce using rule 19 (ternary -> expression QUESTION_MARK expression COLON expression .) ]
  ! QUESTION_MARK   [ reduce using rule 19 (ternary -> expression QUESTION_MARK expression COLON expression .) ]

我相信冲突在于

true ? 1 : false ? 3 : 2

可以解释为true ? 1 : (false ? 3 : 2)(true ? 1 : false) ? 3 : 2

我已将 和 的优先级设置+-左关联和比?(我设置为右关联)更高的级别。

我究竟做错了什么?

4

2 回答 2

4

如果我理解正确,您执行了以下操作:

%left '+' '-'
%right '?'

%%

arithmetic_expression : expression + expression
                      | expression - expression
                      ;
ternary               : expression ? expression : expression
                      ;

那是行不通的,因为你还没有告诉野牛ternary生产的优先级是什么。

为了解决班次减少冲突,bison 将可能减少的生产的优先级与可能转移的终端的优先级进行比较。您已经声明了终端“+”、“-”和“?”的优先级,以及 中的两个产生式的优先arithmetic_expression级,但没有声明 中的产生式的优先级ternary

引用野牛手册,重点补充说:

每个规则从组件中提到的最后一个终端符号获取其优先级。

这是非常微妙的,你不会是第一个没有注意到的人。

解决方案:要么声明终端的优先级,:要么%prec '?'ternary.

于 2013-07-28T04:55:16.310 回答
1

Exaclty - 您没有指定关联性。

在 C 中,语法说:

conditional_expression = logical_or_expression [ '?' expression ':' conditional_expression ];

所以我相信你想要类似的东西

conditional_expression = arithmetic_expression [ '?' expression ':' conditional_expression ];

如果您想要类似 C 的行为(因此需要正确的关联性以及其他属性)。

于 2013-07-28T03:36:38.110 回答