以下是我的语法:
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
。
我已将+
的优先级设置为-
,将?
设置为左关联,并将{{1}}设置为更高级别(我设置为右关联)。
我做错了什么?
答案 0 :(得分:3)
如果我理解正确,您会执行以下操作:
%left '+' '-'
%right '?'
%%
arithmetic_expression : expression + expression
| expression - expression
;
ternary : expression ? expression : expression
;
那是行不通的,因为你没有告诉野牛ternary
制作的优先顺序是什么。
为了解决shift-reduce冲突,bison将可能减少的生产优先级与可能被移位的终端的优先级进行比较。您已声明终端'+',' - '和'?'的优先级,以及arithmetic_expression
中两个产品的优先级,但不是ternary
中产品的优先级。
引用野牛手册,重点补充:
每个规则都优先于组件中提到的 last 终端符号。
这非常微妙,你不会是第一个没有注意到的人。
解决方案:要么声明终端:
的优先级,要么将%prec '?'
添加到ternary
中的作品中。
答案 1 :(得分:1)
Exaclty - 您没有指定关联性。
在C语言中,语法说:
conditional_expression = logical_or_expression [ '?' expression ':' conditional_expression ];
所以我相信你想要像
这样的东西conditional_expression = arithmetic_expression [ '?' expression ':' conditional_expression ];
如果你想要一个类似C的行为(以及正确的关联性,以及其他属性)。