【问题标题】:Does association and precedence declarations in yacc solve the issues of an ambiguous grammar?yacc 中的关联和优先级声明是否解决了语法不明确的问题?
【发布时间】:2021-07-20 04:07:31
【问题描述】:

假设我们有以下模棱两可的语法:

expr -> expr OP 表达式

expr -> (expr)

expr -> NUM

OP -> +

OP -> -

OP -> *

OP -> /

声明的具体内容

%left + -

%left * /

在 yacc 中做吗?它们会帮助解析器解决歧义问题而无需更改语法吗?

【问题讨论】:

  • 在这种情况下,不会,因为在归约到OP时已经丢失了第一个运算符的优先级
  • 那么,如果我们为每个操作员使用不同的产品,它会起作用吗?

标签: yacc context-free-grammar


【解决方案1】:

yacc 优先级指令允许程序员以有限的方式指定如何解决语法中的移位/减少冲突。准确了解它们的工作原理(以及它们如何实现“正常”优先级规则)需要相当了解移位/归约解析的工作原理。

在高层次上,移位/归约解析的工作原理是识别与输入中规则的 RHS 相对应的模式,并用表示规则 LHS 的符号“替换”这些模式。目标是最终用与语法的顶级符号匹配的单个符号替换整个输入。更详细地说,当它看到输入的每个符号时,它要么移动该符号(读取它并将其推入堆栈),要么减少规则——将与规则的 RHS 匹配的符号从堆栈中取出并替换为LHS 的单个符号。在任何步骤中,如果堆栈顶部的符号与任何规则的 RHS 匹配,则解析器可以移位或归约 —— 决定执行哪一个基本上是 yacc 所做的解析器构造的全部工作。当它无法决定(从语法)时,它会报告移位/减少冲突。 (当栈顶匹配两个不同规则的 RHS 时,也会发生 reduce/reduce 冲突)。

优先规则的工作方式是提供一种解决这些移位减少冲突的编程方式——程序员可以为令牌和规则提供“优先级”,并且每当发生移位/减少冲突时,如果令牌和所涉及的规则具有优先级,冲突将以优先级更高的规则解决。

当您使用%left/%right 指令时,它会设置令牌的优先级。规则从规则 RHS 中的第一个标记或从显式的 %prec 指令获得优先级。

使用上面的语法,标记可以有优先级,但expr: expr OP expr 规则存在问题。由于它在 RHS 上没有标记(只是非终端),因此无法以这种方式获得优先级,因此您需要使用 %prec 提供优先级,但这也不起作用,因为没有单一的优先级遵守这条规则。

如果您将规则拆分为多个规则(去掉 OP 并为每个运算符设置一个单独的规则),那么一切正常,因为每个规则可以有不同的优先级。

【讨论】:

  • 这让我明白了,非常感谢您的回答。
猜你喜欢
  • 1970-01-01
  • 2014-09-01
  • 1970-01-01
  • 2013-08-03
  • 2011-11-14
  • 2011-07-25
  • 1970-01-01
  • 2021-03-17
  • 1970-01-01
相关资源
最近更新 更多