yacc转移/减少与空规则的冲突

时间:2017-05-23 16:56:05

标签: bison yacc

test.y

%%
TOP :
    OPTIONS
  ;

OPTIONS :
    OPTION
  | OPTIONS OPTION
  ;

OPTION :
   /*no option is possible*/
  | 'C'
  ;
%%

yacc -v test.y

y.output包含以下内容

   0  $accept : TOP $end

   1  TOP : OPTIONS

   2  OPTIONS : OPTION
   3          | OPTIONS OPTION

   4  OPTION :
   5         | 'C'

0: shift/reduce conflict (shift 1, reduce 4) on 'C'
state 0
    $accept : . TOP $end  (0)
    OPTION : .  (4)

    'C'  shift 1
    $end  reduce 4

    TOP  goto 2
    OPTIONS  goto 3
    OPTION  goto 4


state 1
    OPTION : 'C' .  (5)

    .  reduce 5


state 2
    $accept : TOP . $end  (0)

    $end  accept


3: reduce/reduce conflict (reduce 1, reduce 4) on $end
3: shift/reduce conflict (shift 1, reduce 4) on 'C'
state 3
    TOP : OPTIONS .  (1)
    OPTIONS : OPTIONS . OPTION  (3)
    OPTION : .  (4)

    'C'  shift 1
    $end  reduce 1

    OPTION  goto 5


state 4
    OPTIONS : OPTION .  (2)

    .  reduce 2


state 5
    OPTIONS : OPTIONS OPTION .  (3)

    .  reduce 3


State 0 contains 1 shift/reduce conflict.
State 3 contains 1 shift/reduce conflict, 1 reduce/reduce conflict.


3 terminals, 4 nonterminals
6 grammar rules, 6 states

为什么会改变/减少和减少/减少冲突。

我已经阅读了yacc解析器如何在http://dinosaur.compilertools.net/yacc/的“Parser如何工作”部分中工作,但我不明白yacc如何处理空规则。似乎它试图在任何地方使用空规则。

问题1. yacc如何处理状态机的空规则interms和上面链接中描述的“look ahead token”。

问题2.我如何摆脱冲突并仍然保持语法的“逻辑”?

事先感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

当然,它试图使用“无处不在”的空规则。它正在做你告诉它做的事。

您所说的是非终端OPTIONS代表OPTION个非终端的任意正数,OPTION非终端可以是C或空的。

由于OPTION可以为空,因此空输入中可以有任意数量的OPTION。两个空OPTION看起来与153空OPTION完全相同。更重要的是,两个C令牌之间可以有任意数量的空OPTIONS

所以你的语法含糊不清,野牛报告解析冲突。

如果您想将OPTION定义为任意数量的OPTION s,包括零options: %empty | options option option : 'C' s,那么只需说明:

-DEIGEN_HAS_RVALUE_REFERENCES=0