1

这些工具基本上输入语法和输出代码,将一系列标记处理成更有用的东西,比如语法树。但是这些工具可以改为以库的形式编写吗?生成源代码作为输出的原因是什么?有性能提升吗?对最终用户来说是否更灵活?yacc 和 ANTLR 的作者更容易实现吗?

抱歉,如果问题太模糊,我只是好奇作者做出决定背后的历史原因,以及自动生成的代码在当今环境中的用途。

4

2 回答 2

3

解析器生成器计算出语法规则相互之间的交互,并将结果编译为代码,从而获得了很大的性能优势。

可以构建简单地接受语法并进行解析的解释器;有一些解析器类型(Earley)实际上在这方面相对较好,并且可以在运行时计算语法交互(Earley 解析器无论如何都会这样做)而不是离线然后执行解析算法。

但是你会付出 10 到 100 倍的解析性能损失,并且可能需要很大的存储需求。

如果您只使用非常小的语法进行解析,或者您只解析非常小的文档,这可能无关紧要。但是,许多解析器生成器应用的语法最终变得相当大(人们一直想在语言中添加一些东西),并且它们通常最终会处理相当大的文档。所以现在性能很重要,而且中提琴,人们构建代码生成解析器生成器。

一旦有了工具,即使在简单的情况下也通常更容易使用。所以现在你有了解析器生成器,你甚至可以将它们应用于小语法或解析小文档。

编辑:附录。历史原因很可能是空间和时间需求驱动的早期的系统空间不大(1975 年为 32Kb),运行速度不是很快(同一时间框架为 1 MIPS),而且人们已经拥有很大的源文件。解析器生成器倾向于帮助解决这组问题。解释语法的性能会差到令人无法忍受的地步。

于 2012-06-04T18:18:20.020 回答
3

Ira Baxter为您提供了一组在运行时不处理语法解析的原因。

还有另一个原因。与语法中的每条规则相关的是适当的动作。动作通常是单独语言(例如,C 或 C++)的片段。在运行时解释的语法中的所有动作都必须可映射到程序中适当的东西。一般来说,这是一个失败的提议。片段可以做各种各样的事情,引用堆栈的一部分($$、、$1等)和调用动作(YYACCEPT, ETC)。设计运行时系统以便它可以可靠地与此类片段一起使用将是困难的。您想创建源代码并将其编译成 DSO(动态共享对象)或 DLL(动态链接库)并加载它。这需要客户机器上的编译器,客户可能故意将他们的生产系统设计为无编译器。

于 2012-06-04T20:14:40.473 回答