前言
JavaCC是Java编程语言中最古老、使用最广泛的解析器生成器之一,但它往往被认为难以使用。有些程序员还没有遇到过解析器生成器范式,因此不熟悉编写规范然后据此生成解析器的过程。其他程序员对使用另一个解析器生成器(譬如古老的lex/yacc的组合)记忆久远,现在需要进一步了解JavaCC的语法和指定文法的能力。即使是用过JavaCC的程序员也可能不确定某些高级功能如何工作或如何有效地调试特定的JavaCC问题。
当我第一次使用JavaCC时,一位同事为我设置了JavaCC文法并编写了一些Ant目标来开始工作。在接下来一年左右的时间里,我偶尔会对文法做一些修改,闭上眼睛,运行Ant和单元测试,并希望一切仍然正常。终于我有一些顿悟(首先是符号化!节点描述符可以使树变得更简单!)并开始真正理解那些迄今为止我尽可能避免使用的大型.jjt文件。在那之后我撰写了更多的文法挂在JavaCC邮件列表上,为JavaCC的源代码库提供了一些修复,并且慢慢地越来越熟悉JavaCC和JJTree。
JavaCC有一定数量的在线文档;在您最喜欢的搜索引擎中输入“JavaCC”将会出现一大堆的结果:文章、博客条目、JavaCC邮件列表的归档、JavaCC站点的文档等等。这些结果中比较有用的一个是“JavaCC FAQ”,它由Theodore Norvell博士维护,包含许多有用的信息。我多次反复阅读此FAQ(常见问题解答),并且总是能从中学到一些新的东西。
尽管有了这些在线文档,但JavaCC看起来仍然无法接近,而且对于更高级的问题的回答可能难以捉摸。这是一个遗憾,因为JavaCC是一个多用途且功能强大的实用程序,可以轻松处理大多数解析作业。更妙的是,有许多现有的JavaCC文法,因此如果你需要处理特定的语言,那么很可能已经存在针对它的JavaCC文法。了解JavaCC如何工作以及如何有效地使用它可以将一个月的项目变成一个可以在一天内解决的问题。
考虑到这一点,让JavaCC更易于访问是我撰写本书的主要动力之一。我的意图是,正在从事解析工作的程序员可以拿起这本书,转到目录或索引,并快速找到几乎任何JavaCC问题的解决方案。无论您是从头开始编写文法还是修改现有文法,我希望您能在这里找到问题的答案。
本书是如何组织的
本书分为十一章和两个附录。
本书的目标读者
我将本书的目标读者定位于使用JavaCC和JJTree来解决解析问题的程序员。但是,如果幸运的话,本书将对很多人有所帮助。从以下几个角度思考您将从本书中得到什么:
概括地说,我认为您会发现学习和使用JavaCC将使您成为更好的程序员。计算机程序是用人类可读的文本编写的,必须有人编写程序将源代码翻译成机器码。JavaCC涵盖了该过程的前端:读取代码、验证和解析,以及生成可用的语法树。这是一个完整的编译器的一半,剩下的就是编写代码生成后端。一旦您对这个过程的机制有了很好的了解,您就会注意到编译器技术被用在各种各样的地方,并且您将能够更有效地为这些工作做出贡献。
未包含内容
本书限于特定的解析器生成器:JavaCC。它旨在为该工具提供一个很好的参考和大量示例。但意味着这不是一本关于编译器构造的书,也不是一本关于解析理论的书。所以您不会看到在那些类型的书中才会出现的讨论;比如,不存在任何从NFA到DFA转换。也没有对诸如乔姆斯基谱系(Chomsky hierarchy)等形式文法的深入讨论。我在参考书目中列入了几本涉及这些领域的参考资料书籍。
当然,如果我认为它能帮助您更多地理解特定的JavaCC特性,那么我将偶尔会深入探讨一些理论。但在大多数情况下,本书仍然坚持实用。
惯例(约定)
代码示例、程序输出以及脚本和程序名称都使用monospace字体编写。各种JavaCC类的名称通常也用monospace表示,例如,“这将生成一个TokenManager接口”。有时,如果一个类在一般意义上被引用,它将使用常规字体,例如,“如果您想要完全控制,您可能需要编写自己的TokenManager。”
第一次使用技术术语时,它是用斜体写的。偶尔我会重复斜体字,如一个术语在书中早期的高层意义上首次使用。
代码示例
有关更新,勘误表和示例代码,请参阅本书的网站:
http://generatingparserswithjavacc.com/
再版说明
这是第二版,因此它与第一版有许多相似之处;书的整体结构和内容大致相同。但是JavaCC 4.1于2008年夏末发布,自那时起已经发布了几个bugfix版本。因此,此版本涵盖了这些新版本中提供的新特性和Bug修复。我试图通过在索引中使用“JavaCC 4.0新增”标记它们来轻松定位这些与JavaCC版本相关的更新,因此您可以翻到后面并查找所有已更改的内容。我还将本书中提到的基础结构和实用程序(Java、Ant、Maven、Eclipse)的更新,以便它们与您在项目中使用JavaCC时可能找到的内容更加匹配。最后,在最近的版本中发现并修复的一些小Bug,我也在这里提到了。
联系我们
我们已经做了很大的努力来确保书中的材料是准确的,但是一些错误可能会在过程中出现。请告诉我们有关错误、令人困惑的内容,或您认为我们可能有兴趣在未来的版本修复的任何其他内容。你可以通过以下方式联系Centennial Books:
Centennial Books
1591 Chapel Hill Drive Alexandria, VA 22304
USA Phone: 703-751-6162
Fax: 703-751-2045
Email:
如有技术问题,请随时直接与作者联系:
致谢
首先,也是最重要的,要感谢我的妻子Alina,感谢她在我日复一日地埋头写这本书的时候所表现出的耐心。感谢我们的孩子(Maria、Tommy、Anna、Sarah、Steven和James)在这段时间里给我们的拥抱。
感谢我的第一版技术评审员:Kenneth Beesley博士、Sophie Quigley和Rémi Koutchérawy。他们填补了许多空白,如果没有他们出色的反馈,这本书的可读性会低得多。剩下的任何错误或遗漏都是我的。
非常感谢Sriram Sankar博士和Sreenivasa Viswanadha撰写和维护JavaCC。他们做了大量的工作来实现JavaCC,消除所有的初始Bug,并优化JavaCC本身和JavaCC生成的代码。他们应该为这个对很多人都非常有用的超级实用工具得到所有的赞誉。还要感谢Paul Cager为发布JavaCC 4.1(及其后续版本)所做的努力;他在实现特性、修复Bug和保持整体运转方面做了大量工作。
感谢Sun Microsystem的Michael Van De Vanter博士在协调JavaCC开源工作方面所做的工作。同样,还要感谢Paul Cager几年前在清理JavaCC许可条款方面所做的工作。
我从JavaCC的用户邮件列表的讨论中获益匪浅。Sankar博士和Sreenivasa Viswanadha博士在那里发布了大量有用的材料。Nathan Ryan博士的帖子非常有用;有一段时间,我浏览了这份清单的档案,并把每一份都重新读了一遍。
其次,要感谢Kenneth Beesley博士撰写的关于JavaCC主题的优秀白皮书;它们对于帮助我理解各种棘手的问题非常有帮助。感谢Theodore Norvell博士撰写和维护JavaCC FAQ,这是我最初学习资料的来源之一。感谢Curtis Dyreson博士建议包含语法测试的章节。感谢Matt Kirkey对本书进行了早期评论和提供的一些有用的反馈。
感谢Nathan Ryan博士对第一版的广泛反馈。还要感谢Nathan Ward和John Wilson在第一版中查找并报告了几个拼写错误。