Parsing 解决冲突减少冲突
语法问题部分:Parsing 解决冲突减少冲突,parsing,bison,yacc,reduce-reduce-conflict,Parsing,Bison,Yacc,Reduce Reduce Conflict,语法问题部分: expr_var: var_or_ID | expr_var '[' expr ']' | NEW expr_var '(' expr_listE ')' | expr_var '(' expr_listE ')' | expr_var ARROW expr_var | expr_var ARROW '{' expr_var '}' | expr_var DCOLON expr_var | expr_var DCOLON '{' expr_var '}' | '(' expr_
expr_var: var_or_ID
| expr_var '[' expr ']'
| NEW expr_var '(' expr_listE ')'
| expr_var '(' expr_listE ')'
| expr_var ARROW expr_var
| expr_var ARROW '{' expr_var '}'
| expr_var DCOLON expr_var
| expr_var DCOLON '{' expr_var '}'
| '(' expr_var ')'
;
对该问题的描述:
expr_var -> NEW expr_var '(' expr_listE ')' . (rule 87)
expr_var -> expr_var '(' expr_listE ')' . (rule 88)
DCOLON reduce using rule 87 (expr_var)
DCOLON [reduce using rule 88 (expr_var)]
ARROW reduce using rule 87 (expr_var)
ARROW [reduce using rule 88 (expr_var)]
'[' reduce using rule 87 (expr_var)
'[' [reduce using rule 88 (expr_var)]
'(' reduce using rule 87 (expr_var)
'(' [reduce using rule 88 (expr_var)]
$default reduce using rule 87 (expr_var)
每个操作符(箭头、DCOLON…)都是左关联的。运算符NEW是非关联的
如何解决这一冲突?这里的问题是:
new foo(1)(2)
这可以通过两种方式进行分析:
(new foo(1))(2) // call the new object
new (foo(1))(2) // function returns class to construct
其中哪一个(如果有)在语义上是可行的取决于您的语言。可以肯定的是,两者都是有意义的。语法没有提供任何关于语义的提示
因此,您有必要决定哪一个(如果有)是预期的解析,并相应地设计语法
优先级声明不会有帮助,因为优先级仅用于解决移位/减少冲突:优先级关系总是在产品和先行标记之间,而不是在两个产品之间
Bison将解决减少/减少冲突,以利于首次生产,正如在本例中所做的那样。因此,如果语法合法且明确,那么您可以在必要时通过对产品重新排序来选择所需的解析。这将给您留下警告,但您可以使用%expect rr
声明来抑制它
您还可以通过显式修改语法以排除expr\u var
表达式作为调用中的第一个参数和/或排除调用作为new
的第一个参数来抑制一个或另一个解析(或两者)