Compiler construction 在不使用混合运算符解析表达式时减少/减少冲突
我的编译器课程作业中的语言不允许在没有括号的表达式中使用混合运算符,这可能不会让我们处理实现优先级问题。这意味着以下是有效的表达式:Compiler construction 在不使用混合运算符解析表达式时减少/减少冲突,compiler-construction,bison,yacc,Compiler Construction,Bison,Yacc,我的编译器课程作业中的语言不允许在没有括号的表达式中使用混合运算符,这可能不会让我们处理实现优先级问题。这意味着以下是有效的表达式: # Valid 1 + 2 + 3 1 + (2 * 3) 1 但这不是: # Invalid 1 + 2 * 3 这也不是空洞的表达。从我的实际语法中摘录,表达式解析如下: %token TNumber %start expr %% expr : mulexpr | addexpr ; mulexpr : mulexpr '*' t
# Valid
1 + 2 + 3
1 + (2 * 3)
1
但这不是:
# Invalid
1 + 2 * 3
这也不是空洞的表达。从我的实际语法中摘录,表达式解析如下:
%token TNumber
%start expr
%%
expr : mulexpr
| addexpr
;
mulexpr : mulexpr '*' term
| term
;
addexpr : addexpr '+' term
| term
;
term : '(' expr ')'
| TNumber
;
但是,这会导致reduce/reduce冲突。我猜这是因为像123
这样的单个术语表达式可以简化为TNumber->term->mulexpr->expr
,或者TNumber->term->addexpr->expr
,但我不是很确定。我更喜欢语法清晰,而不是希望歧义是我认为的那样。然而,我想不出一个办法来解决这个模棱两可的问题
我的想法是,我应该添加一个规则expr:term
,然后以某种方式使addexpr
和mulexpr
需要两个或更多的术语,但我不知道如何表达这一点
更新:当我找到一个有效的解决方案时,如果有一个“代码”重复较少的解决方案,它将得到接受。使
mulexpr
和addexpr
的递归停止条件成为一个两项表达式:
expr : mulexpr
| addexpr
| term
;
mulexpr : mulexpr '*' term
| term '*' term
;
addexpr : addexpr '+' term
| term '+' term
;
(发帖五秒钟后,我就想出来了。这是一个很好的橡皮鸭。
我猜我的大脑只是痴迷地试图避免这种重复。)