繁体   English   中英

优先级/关联性实现

[英]Precedence/associativity implmentation

我目前正在实现一个 LR(k) 解析器解释器,只是为了好玩。

我正在尝试实现优先级和关联性。

当谈到如何为“动作”部分分配关联性和优先级时,我有点卡住了,即减少的优先级和关联性应该是什么。

如果我们有产品

E -> 
  | E + E { action1 }
  | E * E { action2 } 
  | (E)   { action3 }
  | ID    { action4 }

应该很清楚,action1 应该与 + 具有相同的关联性和优先级,而 action2 应该与 * 具有相同的关联性和优先级。 但总的来说,我们不能仅仅假设生产中的规则只有一个具有优先级的符号。 一个玩具例子

E -> E + E - E { action }

其中 - 和 + 是一些任意运算符,具有一些优先级和关联性。 该动作是否应该与 - 相关联,因为它在最后一个 E 之前?

我知道如何在班次/减少之间进行选择的规则,这不是我所要求的。

由 yacc(和许多衍生产品)实现的经典优先算法使用每个产生式中的最后一个非终结符来定义其默认优先级。 这并不总是生产所需的优先级,因此解析器生成器通常还为其用户提供一种机制,用于明确指定生产的优先级。

这种优先级 model 已被证明是有用的,虽然它并非没有问题 - 见下文 - 它可能是简单解析器生成器的最佳实现,只是因为它的怪癖至少被记录在案。

这个约定延续了优先级是非终端(或“运算符”)的一个特征的想法。 如果您正在构建运算符优先级解析器,那是有效的,但它不对应于 LR(k) 解析。 充其量,这是一个粗略的近似值,可能会产生高度误导。

如果底层语法确实是运算符优先语法——也就是说,没有产生式有两个连续的终结符并且推算的优先关系是明确的——那么它可能是一个可接受的近似值,尽管值得注意的是运算符优先关系不是传递的,所以它们通常不能被概括为单调的比较。 但是 yacc 样式优先级的许多用法都超出了这个范围,甚至会导致严重的语法错误。

问题在于,将优先级建模为标记之间的简单传递比较可能会导致优先级声明被用于消除歧义(从而隐藏)不相关的冲突。 简而言之,在 LR 解析中使用优先级声明基本上是一种 hack。 这是一个有用的技巧,有时是有益的——正如你所说,它可以减少状态的数量和单位减少的频率——但需要谨慎对待。

确实,有人提出了基于语法重写的优先级替代 model。 (例如,参见 Ali Afroozeh 等人在 2013 年发表的论文,“运算符优先规则的安全规范”)。 此 model 更加精确,但部分由于这种精度,它不适合(错误)用于其他目的,例如解决悬空冲突。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM