解决表达式语法中的转换/减少冲突

时间:2017-03-09 23:49:46

标签: parsing bison shift-reduce-conflict

我是Bison的新手,我正在尝试使用语法解析表达式。 我现在正面临转移/减少混乱,我无法解决。

语法如下:

%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         
           ;

这是我的语法,但我面临着与这两个规则"(" expression ")"expression "(" expression_list ")"的转换/减少冲突。 我该如何解决这个冲突?

编辑:我知道我可以使用优先级攀登来解决这个问题,但我不想这样做,因为这只是表达式语法的一小部分,而且表达式语法的大小会因使用优先级攀升而爆炸。 / p>

1 个答案:

答案 0 :(得分:2)

所呈现的语法中没有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

优先顺序可能会倒退。通常人们希望像调用和索引这样的后缀运算符比算术运算符更紧密地绑定,所以它们应该在最后。否则a+b(7)(a+b)(7),这是非常规的。