【发布时间】:2010-04-24 14:58:19
【问题描述】:
我正在做一些小项目,其中涉及对某些事物使用不同的语法,但是有时这些语法非常简单,以至于使用解析器生成器可能有点过头了。
现在,我什么时候应该使用手工解析器,什么时候应该使用解析器生成器?
谢谢,
威廉·范·多恩
【问题讨论】:
我正在做一些小项目,其中涉及对某些事物使用不同的语法,但是有时这些语法非常简单,以至于使用解析器生成器可能有点过头了。
现在,我什么时候应该使用手工解析器,什么时候应该使用解析器生成器?
谢谢,
威廉·范·多恩
【问题讨论】:
除了“针对特定情况使用最简单的方法”之外,没有一成不变的答案。
我的经验是,解析器在其生命周期中往往会变得更加复杂,因此预先使用解析器生成器通常会有所回报。即使语言没有变得更复杂,使用生成器也会迫使您创建语法的正式规范,这本身就很有价值。
缺点是其他程序员可能不知道如何使用生成器,因此其他人很难提供帮助,并且会使您的项目依赖于该生成器。
【讨论】:
当且仅当您非常渴望让解析器即使在速度非常慢的机器上也非常快时,手动编写解析器是值得的。例如,在 this article 关于 Turbo Pascal 从它得名之前的历史中,您可以看到原型如何以及为什么给小型(当时的丹麦)公司“Borland”留下深刻印象,以充分聘请原型的作者(Anders Hejlsberg)开发编译器,并将其作为主要产品推出,我引用...:
我没有抱太大期望 编译密钥 - 然后我是 完全落地!我的测试程序, 编译和链接需要几分钟 使用 Digital Research 的 Pascal MT+, 在我之前编译并运行 可以眨眼!那是一个伟大的 哇哦!
Turbo Pascal 惊人的编译速度——首先来自用汇编语言编码的精心手工编码和高度调整的递归下降解析器——使其能够使用与大多数编译器截然不同的策略:没有单独的编译过程生成对象文件和库,然后是一个链接器将它们组合在一起,Turbo Pascal 1.0 是一个单遍编译器,可以直接将源代码转换为单个可执行二进制文件。
我记得在那个时代的微型个人电脑上同样的惊人体验(当时 Z80、64K 或 RAM,以及两张软盘是 很多;-) -- Turbo Pascal,它的令人惊叹的解析器和 IDE 以及其他一切,与源代码和编译形式的大量程序一起舒适地放入内存中 - 不需要软盘,这意味着程序周转时间存在许多数量级的差异。
如果 Hejlsberg 坚持当时的传统智慧——始终使用解析器生成器——Turbo Pascal 可能永远不会成为商业产品,也绝对不会在 Pascal 世界中取得它所享有的统治地位年。
当然,在当今的典型 PC 上,大多数编译器都不需要如此高的解析速度。可能的例外情况包括必须作为“类解释器”环境的一部分无缝运行的编译器(出于这个原因,Perl 和 Python 等语言的简单编译器通常在很大程度上是手工编码的——这是一种实现选择使它们在 90 年代可行,尽管今天还不清楚它是否仍然需要),或者在非常有限的硬件资源(例如智能手机或低端上网本)上运行的编译器。
在您将编写编译器的绝大多数情况下,这些性能考虑可能都不适用,并且您会更喜欢解析器生成器。
【讨论】:
您的问题标题表明使用语法是可选的。真的不是——即使我要实现一种小型语言,我也会在一张纸上勾勒出语法。
至于何时使用解析器生成器,这真的是个人喜好。例如,许多人相信手写递归下降解析器,而不是使用表驱动的方法。重要的是要熟悉生成器的功能。
不要以为使用解析器生成器会更专业,甚至更简单。 Bjarne Stroustrup 在编写第一个打算使用递归下降的 C++ 编译器时,却被贝尔实验室的一些热心同事说出来,这让他最终懊恼不已。有关详细信息,请参阅《C++ 的设计与演进》第 3.3.2 节。
【讨论】: