通常我们想重构一个无上下文语法来删除左递归。有许多算法来实现这种转换;例如here或here。
无论是否存在左递归,此类算法都将重构语法。这具有负面的副作用,例如从原始语法产生不同的解析树,可能具有不同的关联性。理想情况下,如果绝对必要,语法只会被转换。
是否有算法或工具来识别语法中是否存在左递归?理想情况下,这也可能会对包含左递归的生产规则的子集进行分类。
答案 0 :(得分:2)
有一种用于识别可空的非终端的标准算法,该算法在语法大小上按时间线性运行(见下文)。完成后,您可以在所有非终端A potentially-starts-with B
,A
上构建关系B
。 (事实上,在所有语法符号上构建这种关系更为正常,因为它也用于构造FIRST
集,但在这种情况下,我们只需要投影到非终端上。)
完成此操作后,左递归非终端全部为A
,A potentially-starts-with+ A
为potentially-starts-with+
,其中potentially-starts-with ∘ potentially-starts-with*
为:
{{1}}
您可以使用任何传递闭包算法来计算该关系。
供参考,检测可以为空的非终端。
一旦无法再从工作队列中选择生产,就会识别出所有ε-非终端。
只是为了好玩,可以使用上述算法的微小修改来执行步骤1.我将把它作为练习(它也是龙书中的练习)。同样留下练习是确保上述算法在线性时间内执行的方法。