【问题标题】:Why doesn't YACC generate shift-reduce conflict?为什么 YACC 不产生 shift-reduce 冲突?
【发布时间】:2019-08-26 06:42:31
【问题描述】:

试图了解班次减少冲突并解决它们。

我有以下 YACC 代码,我预计会为此发生 shift-reduce 冲突,但 Bison 不会生成任何此类警告

%%

lang_cons: /* empty */
         | declaraion // SEMI_COLON
         | func
    ;

declaraion : keyword ID
    ; 

func : keyword ID SEMI_COLON
    ; 

keyword : INT
    | FLOAT
    ;

%%

但如果我在第二条规则中取消注释 SEMI_COLON(即 | declaraion SEMI_COLON ),我会遇到移位减少冲突。在这种情况下,我期待减少减少冲突。请帮我理解这个烂摊子!

PS:考虑输入,

    1) int varName
    2) int func; 

【问题讨论】:

  • 您能否指出您期望哪个班次与哪个 reduce 发生冲突,以及您期望与哪两个 reduce 发生冲突?
  • 当 SEMI_COLON 是前瞻标记时,堆栈将具有(关键字和 ID)足以通过规则“声明”或“功能”减少

标签: c parsing bison yacc shift-reduce-conflict


【解决方案1】:

如果你给野牛-v 命令行标志,它将生成一个包含生成状态机的.output 文件,这可能会帮助你了解发生了什么。

请注意,bison 实际上会解析增强语法,它由带有附加规则的语法组成

start': start END

其中END 是一个特殊标记,其代码为0,表示输入结束,start 是您的语法用作开始符号的任何符号。 (这确保了野牛解析器不会在其他有效输入结束时默默地忽略垃圾。)

这使您的原始语法明确;在看到varName 之后,前瞻将是END,在这种情况下declaration 被减少,或者';',这将被移动(当下面的END 为看过)。

在您的第二个语法中,冲突涉及在减少 declaration 或移动分号之间进行选择。如果分号是declaration 的一部分,那么您会看到reduce/reduce 冲突。

【讨论】:

  • 但是我看到了 *.output 文件,每个规则都没有 $end。 $end 仅与 ($accept: lang_cons $end) 一起出现。
  • @VijaymahanteshSattigeri:没有人说增强语法会在每条规则的末尾添加一个标记!正如我所说,它只添加了一条规则。但是添加该规则允许 END 令牌渗透到前瞻中,从而解决否则会出现冲突的情况。看状态机。 (您还可以使用--report=all 来查看所有计算的前瞻;阅读该输出以及对前瞻算法的良好描述,例如在龙书中。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多