Parsing 解决表达式语法中的移位/减少冲突
我是新来的野牛,我正在尝试做一个语法分析表达式。 我现在面临着一个转换/减少冲突,我无法解决 语法如下:Parsing 解决表达式语法中的移位/减少冲突,parsing,bison,shift-reduce-conflict,Parsing,Bison,Shift Reduce Conflict,我是新来的野牛,我正在尝试做一个语法分析表达式。 我现在面临着一个转换/减少冲突,我无法解决 语法如下: %left "[" "(" %left "+" %% expression_list : expression_list "," expression | expression | /*empty*/ ; expression : "(" expression ")"
%left "[" "("
%left "+"
%%
expression_list : expression_list "," expression
| expression
| /*empty*/
;
expression : "(" expression ")"
| STRING_LITERAL
| INTEGER_LITERAL
| DOUBLE_LITERAL
| expression "(" expression_list ")" /*function call*/
| expression "[" expression "]" /*index access*/
| expression "+" expression
;
这是我的语法,但我面临着与这两个规则的移位/减少冲突“(“表达式”)”
和表达式”(“表达式列表”)”
。
我如何解决这一冲突
编辑:我知道我可以使用优先级爬升来解决这个问题,但我不想这样做,因为这只是表达式语法的一小部分,而表达式语法的大小将使用优先级爬升来爆炸。语法中没有shift-reduce冲突,所以我想这只是完整语法的摘录。特别是,如果真正的语法包括:
%start program
%%
program: %empty
| program expression
在这种情况下,您将遇到歧义,因为给定例如,a(b)
,解析器无法判断它是单个调用表达式还是两个连续表达式,第一个是单个变量,第二个是带括号的表达式。为了避免这个问题,您需要一些分隔表达式(语句)的标记
还有一些其他问题:
expression_list : expression_list "," expression
| expression
| /*empty*/
;
这允许表达式列表为,foo
(如f(,foo)
),这可能是不可取的。最好是
arguments: %empty
| expr_list
expr_list: expr
| expr_list ',' expr
而先例可能是倒退的。通常,人们希望像call和index这样的后缀操作符比算术操作符绑定得更紧密,所以它们应该在末尾。否则
a+b(7)
就是(a+b)(7)
,这是非常规的。如果这是你的全部语法,它就没有移位-减少冲突。然而,我怀疑这是你的全部语法。哇,我现在觉得真的很愚蠢。。。我在另一条规则中发现了一个拼写错误,这影响了这条规则。这就是为什么我们要求a,这与“我的代码的几行”非常不同。如果你制作了,它通常会帮助你澄清问题,从而为你解决问题。