【问题标题】:yacc shift/reduce conflict with empty rulesyacc shift/reduce 与空规则的冲突
【发布时间】:2017-05-23 16:56:04
【问题描述】:

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

为什么会有 shift/reduce 和 reduce/reduce 冲突。

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

问题 1. yacc 如何处理上面链接中描述的状态机和“前瞻令牌”的空规则。

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

提前感谢您的帮助。

【问题讨论】:

    标签: bison yacc


    【解决方案1】:

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

    你说的是非终结符OPTIONS代表任意正数的OPTION非终结符,而OPTION非终结符可以是C或空。

    由于OPTION 可以为空,因此空输入中可以有任意数量的OPTION。两个空的 OPTIONs 看起来与 153 个空的 OPTIONs 完全相同。此外,两个C 标记之间可以有任意数量的空OPTIONs。

    所以你的语法有歧义,bison 报告解析冲突。

    如果您想将OPTIONS 定义为任意数量的OPTIONs,包括零个OPTIONs,那么就这么说吧:

    options: %empty
           | options option
    option : 'C'
    

    【讨论】:

    • yacc: e - "test.y" 第 13 行,语法错误 %empty yacc -V yacc - 1.9 20070509
    • @abdullam:在旧版本的野牛或野牛以外的 yacc 实现上,不要使用%empty。只需将其省略,或使用/* EMPTY */ 或其他一些注释(如您的语法)。
    • 所以老版本的冲突无法摆脱?
    • 请再次阅读我之前的评论。不要使用%empty。把它放在外面。或者用评论替换它。
    • 如果我将其省略,则 OPTIONS 成为必需项(不能为空)。如果我把 /* 空 */ 然后我有 s/r 冲突。所以我想答案在我的 yacc 版本中,如果我想让选项成为非强制性的,我必须忽略 s/r 冲突。对吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多