【问题标题】:Left-recursive Grammar Identification左递归语法识别
【发布时间】:2013-10-22 22:31:43
【问题描述】:

我们经常想重构上下文无关文法来移除左递归。有许多算法可以实现这种转换。例如herehere

无论是否存在左递归,此类算法都会重构语法。这具有负面影响,例如从原始语法生成不同的解析树,可能具有不同的关联性。理想情况下,只有在绝对必要时才会转换语法。

是否有一种算法或工具可以识别语法中是否存在左递归?理想情况下,这也可能对包含左递归的生产规则子集进行分类。

【问题讨论】:

    标签: algorithm parsing recursion grammar


    【解决方案1】:

    有一个标准算法用于识别可为空的非终结符,该算法在时间上与语法大小成线性关系(见下文)。完成此操作后,您可以在所有非终端 AB 上构建关系 A potentially-starts-with B。 (事实上​​,在所有语法符号上构建这种关系更为正常,因为它也用于构建 FIRST 集合,但在这种情况下,我们只需要投影到非终结符上。)

    这样做后,左递归非终结符都是A,因此A potentially-starts-with<sup>+</sup> A,其中potentially-starts-with<sup>+</sup> 是:

    potentially-starts-with ∘ potentially-starts-with<sup>*</sup>

    您可以使用任何传递闭包算法来计算该关系。


    作为参考,检测可空的非终结符。

    1. 删除所有无用符号。
    2. 将指针附加到每个产生式,最初位于第一个位置。
    3. 将所有产生式放入一个工作队列中。
    4. 如果可能,请找出符合以下条件之一的产品:
      • 如果产生式的左侧已被标记为 ε 非终结符,则丢弃产生式。
      • 如果指针右侧的标记是终结符,则丢弃该产生式。
      • 如果指针右侧没有标记(即指针位于末尾),则将产生式的左侧标记为 ε 非终结符并丢弃产生式。
      • 如果紧挨着指针右侧的记号是一个已被标记为 ε 非终结符的非终结符,则将指针向右推进一个记号并将产生式返回到工作队列。

    一旦无法从工作队列中选择生产,所有 ε-非终结符都已被识别。

    只是为了好玩,对上述算法稍加修改即可完成步骤 1。我将其留作练习(这也是龙书的练习)。还留作练习的是确保上述算法在线性时间内执行的方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多