确定性无上下文语法与无上下文语法?

时间:2014-03-20 02:18:56

标签: parsing programming-languages big-o context-free-grammar context-free-language

我正在阅读我的比较语言课程的笔记,我有点困惑......

无上下文语法和确定性无上下文语法之间有什么区别?我特意阅读解析器如何为CFG编译O(n ^ 3),并且编译器对于DCFG来说是O(n),并且不能真正理解时间复杂度的差异如何可能是那么好(不是提到我仍然对使CFG成为DCFG的特性感到困惑。

提前非常感谢你!

1 个答案:

答案 0 :(得分:2)

从概念上讲,它们很容易理解。无上下文语法是可以用BNF表达的语法。 DCFG是可以编写可行解析器的子集。

在编写编译器时,我们只对DCFG感兴趣。原因是'确定性''粗略地表示在解析中的任何一点应用的下一个规则是由到目前为止的输入和有限量的前瞻确定的。 Knuth在20世纪60年代发明了LR()编译器并证明它可以处理任何DCFG。从那时起,一些改进,特别是LALR(1)和LL(1),已经定义了可以在有限的内存中解析的语法,以及我们可以编写它们的技术。

如果我们知道它是这些语法之一,我们也有从BNF自动派生解析器的技术。 Yacc,Bison和ANTLR是熟悉的例子。

我从来没有见过针对NDCFG的解析器,但是在解析中的任何一点,它都可能需要考虑整个输入字符串以及可以应用的每个可能的解析。不难看出为什么会变得相当大而缓慢。


我应该指出,许多真正的语言并不完美,因为它们不是完全没有上下文,不是明确的或者不符合理想的DCFG。 C / C ++是一个很好的例子,但还有很多其他的。这些语言通常由特殊用途规则处理,例如语义或句法谓词,特殊情况回溯或其他“技巧”。对性能没有影响。


评论指出某些类型的NDCFG是常见的,许多工具提供了一种处理它们的方法。一个常见问题是模棱两可。通过引入简单的本地语义规则来解析模糊语法相对容易,但当然这只能生成一个可能的解析树。 NDCFG的通用解析器可能会产生所有解析树,并且可能允许在某些任意条件下过滤这些树。我不知道其中任何一个。

左递归不是NDCFG的一个特征。它对LL()解析器的设计提出了特殊的挑战,但LR()解析器没有问题。