解释这种转变 - 减少冲突

时间:2018-02-15 11:10:24

标签: 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
        ;
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 个答案:

答案 0 :(得分:1)

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

冲突由前瞻(在这种情况下为NODE_START)指示,具有两个或更多不同的操作。括号括起来的行动(在这种情况下为[reduce using rule 23 (anys)])被野牛的冲突解决机制(在没有优先权声明的情况下,如果有的话选择转移行动,以及其他减少行动)消除最小的生产数量。)

状态转储应该清楚说明为什么规则anys: text变得无用。在可以减少的两种情况下,都存在减少转移的冲突,并且转移行动是首选。

2。转移减少冲突的原因

问题是anys: text elts anys。考虑一个由三个elt组成的输入。这可以解析为elts,其中包含两个elt s,后跟一个由elts组成的elt,反之亦然。模棱两可导致转移减少冲突。

该制作的另一个问题是它不允许eltstext结尾(除非它只包含一个text

更好的定义是简单的

anys: any | anys any

注意:您使用的是自下而上的解析器,右递归(字面上)是反模式。如上所述以递归方式编写列表将限制解析器堆栈的使用并导致senantic操作以预期的顺序(即从左到右)运行。除非你有非常具体的需求,否则你应该避免正确的递归。