本节书摘来自华章社区《ANTLR 4权威指南》一书中的第3章,第3.1节ANTLR工具、运行库以及自动生成的代码,作者[美] 特恩斯·帕尔(Terence Parr),更多章节内容可以访问云栖社区“华章社区”公众号查看
3.1 ANTLR工具、运行库以及自动生成的代码
在开始前,我们先浏览一下ANTLR的jar包中的内容。在ANTLR的jar包中存在两个关键部分:ANTLR工具和ANTLR运行库(运行时语法分析)API。通常,当说到“对一个语法运行ANTLR”时,我们指的是运行ANTLR工具,即org.antlr.v4.Tool类来生成一些代码(语法分析器和词法分析器),它们能够识别使用这份语法代表的语言所写成的语句。词法分析器将输入的字符流分解为词法符号序列,然后将它们传递给能够进行语法检查的语法分析器。运行库是一个由若干类和方法组成的库,这些类和方法是自动生成的代码(如Parser,Lexer和Token)运行所必须的。因此,我们完成工作的一般步骤是:首先我们对一个语法运行ANTLR,然后将生成的代码与jar包中的运行库一起编译,最后将编译好的代码和运行库放在一起运行。
构建一个语言类应用程序的第一步是创建一个能够描述这种语言的语法(即合法语句结构的集合)的语法。我们将在第5章中介绍如何编写语法,现在我们先来看下面这个能够满足我们需求的语法。
请将语法文件ArrayInit.g4放入一个单独的文件夹,例如/tmp/array(通过复制-粘贴或者从本书网站下载)。然后我们对它运行ANTLR工具。
3)ArrayInit.tokens:ANTLR会给每个我们定义的词法符号指定一个数字形式的类型,然后将它们的对应关系存储于该文件中。有时,我们需要将一个大型语法切分为多个更小的语法,在这种情况下,这个文件就非常有用了。通过它,ANTLR可以在多个小型语法间同步全部的词法符号类型。更多内容请参阅4.1节中的“语法导入”部分。
4)ArrayInitListener.java, ArrayInitBaseListener.java:默认情况下,ANTLR生成的语法分析器能将输入文本转换为一棵语法分析树。在遍历语法分析树时,遍历器能够触发一系列“事件”(回调),并通知我们提供的监听器对象。ArrayInitListener接口给出了这些回调方法的定义,我们可以实现它来完成自定义的功能。ArrayInitBaseListener是该接口的默认实现类,为其中的每个方法提供了一个空实现。ArrayInitBaseListener类使得我们只需要覆盖那些我们感兴趣的回调方法(详见7.2节)。通过指定-visitor命令行参数,ANTLR也可以为我们生成语法分析树的访问器(参阅7.5节“使用访问器遍历语法分析树”部分)。
接下来,我们将使用监听器来将short数组初始化语句转换为字符串对象,不过在这之前,我们首先使用一些样例输入来验证我们的语法分析器是否能正常进行匹配工作。
ANTLR语法比正则表达式功能更强大
熟悉正则表达式的读者可能会产生疑问,使用ANTLR来解决这么简单的识别问题是不是有点小题大做了?实际上,由于嵌套的花括号结构的存在,正则表达式无法识别这样的初始化语句。正则表达式没有存储的概念,它们无法记住之前匹配过的输入。因此,它们不能将左右花括号正确配对。我们将在5.3节“嵌套模式”部分中予以详细讨论。