解析 – 确定性无上下文语法与无上下文语法?

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

无上下文语法和确定性无上下文语法之间有什么区别?我特别在阅读解析器如何用于CFG的解析器是O(n ^ 3),并且编译器对于DCFG来说是O(n),并且并不真正理解时间复杂度的差异是如何的那么好(更不用说我是仍然混淆了使CFG成为DCFG的特征.

非常感谢你提前!

最佳答案 从概念上讲,它们很容易理解.无上下文语法是可以用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()解析器没有问题.

点赞