1

那里有很多信息,但这些信息都不能真正帮助像我这样的菜鸟。我阅读了很多关于上下文无关语言和下推自动化的文章。现在我试图了解某些事物在代码中的外观。

假设我们定义了一种语言,例如:

 L = {am bn | m >= n} 

给我们以下生产规则:

 S -> B   | ^
 B -> aBb | A
 A -> aA  | a

这在伪代码中到底是什么样子的?我假设所有生产规则都是定义为 S1 的 1 个状态,或者它们都是单独的状态?无论哪种方式我都不知道,如果有人可以帮助我了解这是如何工作的,那就太好了。

我知道我们分析输入的字符,并根据我们得到的输入,应用其中一条规则将符号推入我们的 PDA 堆栈。

4

1 回答 1

0

有多种方法可以将 CFG 转换为进行实际解析的代码,每种方法都有其优点和缺点。

一些算法,如 CYK 算法、Unger 算法和(我个人最喜欢的)Earley 算法可以将任意 CFG 和字符串作为输入,然后使用动态编程来确定该字符串的解析树(如果存在)。这些算法的操作与典型的下推自动机不同,因为它们通过填写值表来工作,同时一次处理一个字符。

一些解析算法,尤其是 LR(1) 和一般的 LR 解析器家族,更直接地维护解析堆栈并使用有限状态控制来驱动解析器。但是,LR(1) 解析器不能处理所有可能的 CFG——它们只能处理确定性 CFG——但是像 GLR 解析器这样的变体可以通过基本上并行运行多个堆栈来处理所有语法。编译器生成工具 bison 和 yacc 在这个系列中生成解析器,如果您看看它们的输入文件是如何工作的,您就会了解 CFG 是如何在软件中编码的。

LL(1) 解析器和简单回溯解析器自上而下工作,通常使用堆栈(通常是运行时调用堆栈)来解析输入字符串。但是,他们无法处理所有语法。ANTLR 解析器生成器生成这个系列的解析器。

Packrat 解析器通过使用修改过的 CFG 来工作,这些 CFG 对尝试的优先级进行编码。使用这些解析器的代码往往会密切反映语法的形状。解析器组合器是另一种现代技术,其中解析逻辑看起来很像 CFG。

如果您有兴趣了解这方面的更多信息,我建议您参加编译器课程或阅读 Grune 和 Jacobs 的“Parsing Techniques: A Practical Guide”。

于 2017-08-29T15:49:33.557 回答