Parsing 解释这种转变以减少冲突
下面是一个非常简化的Bison XML语法:Parsing 解释这种转变以减少冲突,parsing,bison,yacc,Parsing,Bison,Yacc,下面是一个非常简化的Bison XML语法: head : NODE_START NAME atts | NODE_START NAME ; element : head NODE_CLOSE NODE_END | head NODE_END anys NODE_START NODE_CLOSE NAME NODE_END | head NODE_END NODE_START NODE_CLOSE NAME NODE_END
head : NODE_START NAME atts
| NODE_START NAME
;
element : head NODE_CLOSE NODE_END
| head NODE_END anys NODE_START NODE_CLOSE NAME NODE_END
| head NODE_END NODE_START NODE_CLOSE NAME NODE_END
;
text : TEXT
;
comment : NODE_START COMMENT_START COMMENT_END NODE_END
;
cdata : NODE_START CDATA_START CDATA_END NODE_END
;
attr : NAME EQUALS value
;
value : QUOTED
| APOSED
;
atts : attr atts
| attr
elt : element
| comment
| cdata
any : elt
| text
;
elts : elt elts
| elt
;
anys : text elts anys
| elts
| text
;
s : any
| PROLOG any
;
所谓的冲突是规则anys->text
当我查看相应的输出时:
State 35
21 anys: text elts . anys
NODE_START shift, and go to state 1
TEXT shift, and go to state 2
head go to state 4
element go to state 5
text go to state 25
comment go to state 7
cdata go to state 8
elt go to state 26
elts go to state 27
anys go to state 42
我如何理解这里的冲突?1。解释转储文件
如果查看.output文件的开头,您将看到以下内容:
Rules useless in parser due to conflicts
23 anys: text
State 26 conflicts: 1 shift/reduce
State 27 conflicts: 1 shift/reduce
第一个警告告诉您,由于解析冲突的解决(语法中的其他地方)使规则无法使用,因此生产anys:text
被完全删除。(因此,它是“无用的”。)接下来的两行告诉你在哪里可以找到冲突:在州26和州27
因此,你引用的规则不是“所谓的冲突”,你引用的状态与冲突无关(事实上,我不知道你为什么关注它。)
在有冲突的州,您将看到,例如:
State 26
21 anys: text . elts anys
23 | text .
NODE_START shift, and go to state 1
NODE_START [reduce using rule 23 (anys)]
head go to state 4
element go to state 5
comment go to state 7
cdata go to state 8
elt go to state 27
elts go to state 35
冲突由具有两个或多个不同操作的前瞻(在本例中为节点\u START
)指示。括号中的操作(在本例中为[使用规则23(anys)减少)]
)由bison的冲突解决机制消除(在没有优先声明的情况下,如果存在移位操作,则选择移位操作,否则选择生产编号最小的缩减操作)
state dumps应该清楚地说明为什么规则anys:text
变得无用。在这两种可以减少的情况下,都存在“减少班次”冲突,最好采取“减少班次”行动
2.改变的原因减少了冲突
问题是anys:text elts anys
。考虑一个由三个代码组成的输入> ELT < /代码> s。这可以被解析为一个由两个elt
组成的elt
,然后是一个由单个elt
组成的elt
,反之亦然。这种模糊性导致了冲突的转移
该产品的另一个问题是,它不允许elts
以文本
结尾(除非它只包含单个文本
)
更好的定义应该是简单的
anys: any | anys any
注意:您使用的是自底向上的解析器,右递归(字面上)是一种反模式。如上所述以左递归方式编写列表将限制解析器堆栈的使用,并导致senantic操作按预期顺序(即从左到右)运行。除非您有非常特殊的需求,否则您应该避免正确的递归。那么您想要一个关于如何调试
yacc
输出的解释吗?@G_V这可能很有趣,但我更感兴趣的是理解它在说什么冲突,什么和什么之间的冲突?@G_V这是否意味着冲突在这两者之间应该采取什么行动:移动还是减少?在这种情况下,它甚至不能正确报告位置…@G_V事实上,没关系,我想出来了。太好了!你能把解决方案作为你自己问题的答案发布并接受吗?