对于非LL(1)
或LR(1)
的语言,如何确定是否存在某个数字n
,以便语法可以是LL(n)
或{{ 1}}?
通过查看LR(n)
项的规范集合,检查语法是否为LR(0)
。然后,假设它不是LR(0)
,您可以通过引入先行符号来检查它是否为LR(0)
。我的简单推理告诉我,要检查它是否为LR(1)
,您可能必须使前瞻包含接下来的两个符号而不是一个符号。对于LR(2)
,您必须考虑三个符号等。
即使是这种情况,即使我对此表示怀疑,我也在努力思考一个人如何尝试识别(或甚至暗示)LR(3)
,或者不存在,特定语法可以是n
和/或LR(n)
,而不会从仲裁LL(n)
向上逐步检查。
答案 0 :(得分:3)
如果某个 k > 1的语言是LR( k ),那么它是LR(1)。 (当然,对于语法来说,情况并非如此。)也就是说,如果你有一种语言的LR( k )语法,那么你可以机械地构造一个LR(1)语法,它允许你恢复原始的解析树。 LL( k )不是这样; LL( k )语言是LL( k +1)语言的严格子集。
你建议的测试确实会让你决定一个给定的k(或LL( k <)语法是否为LR( k ) / em>的))。不幸的是,除了您建议的连续搜索之外,无法确定 k 的最小可能值,并且无法保证搜索将终止。
虽然在一般情况下问题很难(或不可能),但通常可以通过考虑表现出冲突的语法状态的可能有效后继来回答特定语法。
在大多数现实世界的语法中,只会发生一些冲突,因此可以对冲突状态进行人工检查。一般而言,需要弄清楚导致冲突状态的路径和可能的延续。在许多情况下,很明显解析冲突可以通过更多的前瞻来解决。
这将失败的一大类语法是一组模糊的语法。对于任何 k ,模糊语法不能是LR(k)(或LL(k))。同样,语法是否含糊不清的问题不是可判定的,但存在有效的启发式方法,其中一些包含在商业产品中。
同样,通过视觉检查(如上所述)或通过将大量有效文本输入GLR解析器(例如由野牛生成的语法)直到找到现实世界语法中的歧义通常很容易。报道含糊不清。 (或者,您可以使用直接算法从语法中枚举有效文本,并查看文本在枚举中是否出现两次。)
以下是一些可能相关的SO问题,用于说明分析技术。我相信还有更多。
A yacc shift/reduce conflict on an unambiguous grammar