写在前面的话:
此文档是对伟大的Terence
Parr的著作《the definitive antlr4 reference》的翻译本。致敬!欢迎转载,请注明原地址,请尊重劳动成果。翻译有误的地方,欢迎指正。
欢迎进入ANTLR的世界!
ANTLR V4是一款您能够用来阅读。处理,运行,或转化成结构化的文本或二进制文件的强大的解析生成器。它在学术界和工业界被广泛地用来建立各种语言。工具和框架。推特搜索使用ANTLR的查询解析,一天超过2,000,000,000多个查询。Hive。Pig,数据仓库以及hadoop的分析系统的语言都是用了ANTLR。Lex
Machina用ANTLR从合乎规则的文本中进行信息抽取。
Oracle在SQL
developer ide 及其迁移工具中用到了ANTLR。NetBeans
IDE用ANTLR解析C++。Hibernate中HQL语言用ANTLR搭建OR映射框架。
除了这些大牌,高知名度的项目。你能够建立各种实用的工具,如配置文件的读取。遗留代码转换器,Wiki标记的渲染器以及JSON解析器。我为关系数据库映射创建的一些小工具,描写叙述3D虚拟。并注入分析代码转换为Java源码,我甚至为演讲做了一个简单的DNA模式匹配的样例。
通过语法的语言描写叙述,ANTLR能够生成这样的语言解析器并自己主动生成解析树(一种代表语法怎样去匹配输入的的数据结构)。
ANTLR也可自己主动生成树的walkers。你能够訪问那些树的节点来运行应用程序特定的代码。
版本号作为參考,同一时候也用它来解决语言识别问题的一个指导。你将学习怎样做例如以下的事情:
•从给出的样例中和參考手冊中去识别语法的语言模式,学以致用。
终于达到建立自己语法的要求。
•从简单的语言(如JSON)一直到复杂的编程语言(像R语言)慢慢去构建语法,你将会解决Python和XML一些棘手的识别问题。
•基于那些语法通过walking自己主动生成的解析树来实现语言应用。
•为特定应用领域自己定义识别错误处理方法和错误报告。
•通过在语法中嵌入Java代码实现对解析的绝对控制。
与教科书的偏理论不同。本书以案例驱动的讨论是为了使内容更加详细形象,方便你为建立自己的语言应用提供一些工具集。
这本书是为谁写的
这本书是专门针对有兴趣学习怎样建立数据的读取器,语言解释与转换的程序猿们。
这本书的内容就是怎样用ANTLR去构建这些事情。当然,但你一般要了解词法分析器和解析器的知识。
刚開始学习的人和专家都须要用这本书来高效地使用ANTLR
V4。在你看到第三部分高级主题的内容之前,你最好通过看前面几章来获得关于ANTLR的一些经验。读者也应该了解一些Java方面的知识。
ANTLR V4为什么这么酷
ANTLR的V4版本号有一些重要的新功能,能够让学习少走一些弯路,使开发语法和语言应用更加easy。最重要的一点是,ANTLR
V4欣然接受你定义的每个语法(对于间接左递归来说是例外)。ANTLR在翻译你的语法成为可运行文件、可读分析的代码的时候是没有语法冲突或出现模糊警告的情况。
假设你给你的ANTLR生成的解析器一个有效输入,不管多么复杂的语法,解析器都将正确识别。当然。这首先依赖于你确保语法对问题是准确的描写叙述。
ANTLR解析器使用了我跟Sam
Harwell开发的一个全新的解析技术,称为Adaptive LL(*)或者说是ALL(*)。
ALL(*)是V3的LL(*)技术的一个扩展,在生成的解析器运行之前,动态地完毕语法分析而不是之前的静态分析。由于ALL(*)解析器获取实际的输入序列,他们总是能想出怎样通过适当地编织语法去识别序列。
而相比静态分析,必须考虑到全部可能的(无限长)输入序列。
实际上,使用ALL(*)意味着你不必扭曲你的文法去迎合其它大多数解析器生成器工具的基本分析策略,包含ANTLR
V3。假设你以前为ANTLR V3的模糊警告或在yacc中的一个降低或者降低的冲突而伤透脑筋的话。那么ANTLR
V4正是你想要的。
小知识:yacc,Yet
AnotherCompiler Compiler,是Unix/Linux上一个用来生成编译器的编译器(编译器代码生成器)。yacc生成的编译器主要是用C语言写成的语法解析器(Parser),须要与词法解析器Lex一起使用,再把两部份产生出来的C程序一并编译。
yacc本来仅仅在Unix系统上才有。但现时已普遍移植往Windows及其它平台。
下一个新特点,ANTLR V4大大简化了用于匹配的语法结构的语法规则,比方像编程语言算术表达式。表达式须要用ANTLR文法(用递归下降分析器去手动识别)来指定已然成了一件麻烦的事情。识别表达式的最自然的语法对像ANTLR
V3这样传统的自上而下的分析器生成器来说是无效的。
如今。用antlr V4。你能够用例如以下这种规则去匹配表达式:
expr : expr'*'
expr // match subexpressions joined with '*'operator
| expr'+'
expr // match subexpressions joined with '+' operator
| INT // matches simple integer atom
;
像expr这种自引用的规则就是递归,特别是,左递归由于在其选择至少一个马上指向本身。
ANTLR V4自己主动重写了左递归规则,如把expr变成一个非左递归等价物。
唯一的限制是,左递归在规则引用自己必须是直接的。不可能指向于还有一个可替代规则方案。
除了这两个语法相关的改进。使ANTLR V4构建语言应用程序更easy。
ANTLR生成的解析器自己主动建立输入的方便表示。称为解析树。这样应用程序能够依据自己的兴趣去遍历触发代码片段。此前,V3用户不得不添加施工作业的语法树。
除了自己主动构建树,ANTLR
V4还能够在listener和visitor模式实现中自己主动生成解析树的遍历器。
listener类似于XML文档处理XML解析器触发的SAX事件的响应对象。
ANTLR V4学习easy得多,由于那些新功能是不能从V3继承的。
•最大的变化是,V4不再强调在语法中中嵌入的动作(代码)。取而代之的是listener和visitor。方便从应用程序代码中解耦语法。没有嵌入的动作,你也能够在不同的应用程序复用相同的语法而不用又一次编译生成语法分析器。ANTLR仍然同意嵌入的动作,但这样做是V4的高级应用。
这种行为须要控制的最高水平,而且是以失去语法复用成本为代价的。
•由于ANTLR自己主动生成语法分析树和树的遍历器,你不须要在V4建立树文法。你能够使用visitor这样熟悉的设计模式取代。
这意味着,一旦你已经学会了ANTLR语法。你能够回到舒适和熟悉的Java编程语言领域去实现实际的语言应用。
• ANTLR V3的LL(*)分析策略是弱于V4的ALL(*)。所以V3有时依靠回溯法来正确解析输入短语。回溯非常难通过生成的解析器去调试文法由于解析器解析同样的输入可能会出现多次(由于递归的存在)。并且回溯对解析器遇到无效输入时非常难反馈惬意的错误信息。
ANTLR V4,是我在读研究生时绕的一个小弯的成果,一晃都有二十五年了。我想我要改变我的座右铭咯。
Why program by hand in fivedays what you can spend twenty-five years of your life automating?
年来我终于如愿。如今,那些时光已近模糊。
这本书讲了什么
本书分为四个部分。
•
第一部分介绍了ANTLR。提供了一些语言背景知识,而且带你開始一场ANTLR的性能之旅。你会初尝语法的滋味。知道用它能做些什么。
•
第二部分是通过提供的语法和树遍历器的组合使用,来进行语法设计、构建语言应用。
•
第三部分開始向你展示怎样自己定义分析器的错误处理。接下来。您将学习怎样在语法中嵌入动作,由于有时候它比在构建树并去遍历要简单和更有效的多。相关的动作,你也会学到怎样使用语义predicatesto去改变分析器行为来处理一些具有挑战性的识别问题。最后一章攻克了一些具有挑战性的语言识别问题,如Python
中XML和上下文敏感的换行符识别。
•
第四部分是參考部分,并列出了ANTLR语法的元语言和执行依赖库的使用规则。
在这本书中全部样例的源码是在线可用的。假设你正在阅读本文这个版本号的书,或者仅仅想获取一个完整的代码包,你能够点开在本书的站点。
你能找到重点讨论的关键要素和书中大多数的的代码段。下载后注意,全部文件头部都有版权声明,输入的文件也是一样。如在listener子文件夹下的t.properties。在使用它们作为输入前。请移除版权申明。电子版的读者也能够从本书中粘贴和复制。不显示版权声明的代码,例如以下所看到的:
listeners/t.properties
user="parrt"
machine="maniac"
很多其它关于ANTLR在线学习
在http://www.antlr.org站点上。你会发现ANTLR的下载接口,ANTLRWorks2图形用户界面(GUI)的开发环境,文档,预建的文法。实例。文章。和文件共享区。技术支持邮件列表是对新手来说是很有优点的。
Terence Parr
旧金山大学, 2012
年11月