2017-01-19 47 views
0

对于不LL(1)LR(1)一个人如何可以尝试找出是否某些数量n存在使得语法可LL(n)LR(n)语言?如何识别文法是否是LR(N),LL(N)

通过查看LR(0)项目的规范集合来检查语法是否为LR(0)。然后,假设它不是LR(0),可以通过引入lookahead符号来检查它是否为LR(1)。我的简单推理告诉我,为了检查它是否为LR(2),您可能必须使前瞻包含接下来的两个符号而不是一个。对于LR(3),您必须考虑三个符号等。

即使这种情况,即使我怀疑它,但我很难想出如何才能识别(或甚至获得提示) n,或其不存在,对此,特定语法可以是LR(n)和/或LL(n),而不从任意向上检查LR(m)

回答

3
  1. 如果语言是LR(ķ)的一些ķ > 1,那么它是LR(1)。 (当然,这对于语法来说并非如此。)也就是说,如果您有一种语言的LR(语法),那么您可以机械地构造一个LR(1)语法,它允许您恢复原始语法分析树。这不是LL(k); LL(k)语言是LL(k +1)语言的严格子集。

  2. 你提议确实将让您决定一个语法是否是LR(ķ)一段给定的K(或LL(ķ))的测试。不幸的是,除了您提出的连续搜索之外,没有办法计算出可能的最小值,并且不能保证搜索将永远不会终止。

  3. 尽管在一般情况下问题很难(或不可能),但通常可以通过考虑表现出冲突的语法状态的可能有效后继者来针对特定语法进行回答。

在大多数现实世界的语法中,只会有一些冲突,因此可以手动检查冲突状态。一般而言,需要找出导致冲突状态的路径以及可能的延续。在很多情况下,很明显,解析冲突可以用更多的前瞻来解决。

这将失败的一大类语法是一组模糊语法。对于任何的模糊语法都不能是LR(k)(或LL(k))k。同样,语法是否含糊不清的问题不是可确定的,而是存在有效的启发式方法,其中一些包含在商业产品中。

同样,通过视觉检查(如上所述),或者通过将大量有效文本提供给GLR解析器(比如由野牛制作的解析器),直到在真实世界的语法中找到歧义常常很容易,直到报道含糊不清。(或者,您可以使用直接算法从语法中枚举有效文本,并查看文本是否在枚举中出现两次。)

这里有几个可能相关的SO问题来说明分析技术。我相信还有更多。

A yacc shift/reduce conflict on an unambiguous grammar

Bison reduce/reduce situation

yacc shift-reduce for ambiguous lambda syntax

How to understand and fix conflicts in PLY

+0

你能否详细说明一点NO3一点?人们应该寻找继任者的特征是什么?另外,关于LL语法可以做些什么? –

+0

如果我测试语法并发现它不是LR(1),LR(2),LR(3)(...),那么在某些时候我应该开始寻找可以帮助构建一个案例的特定特征这个语法可能根本不是LR。这样的特征是否会存在?如果是,他们会是什么样子?如果可能的话,类似的情况对于LL案件是可行的吗? –

+0

@Eternal_Light:我试图解决你的问题,但我担心它仍然是非特定的。 SO中有非LR(1)语法的例子,其中大多数都带有“我如何解决这个冲突”这个问题,并且其中很多已经在答案中进行了分析。我通常不会打扰LL的冲突,所以我在那里帮不了你; LL解析器更常见的是要求无界的前瞻,通常的解决方案是切换到LR解析器。 – rici