Antlr (ANother Tool for Language Recognition) 是一款强大的语法分析器生成工具,可用于读取、处理、执行和翻译结构化的文本或者二进制文件。它被广泛应用于学术领域和工业生产实践,是众多语言、工具和框架的基石。我们可以使用Antlr来开发DSL(Domain Specific Language,领域特定语言),或者一些实用工具,比如配置文件读取器、遗留代码转换器和Json解析器等等。
作为Antlr入门的第一章,我们的目标是大体上知道Antlr能做什么。为此,我们需要先安装Antlr,并编写运行我们的第一个程序“Hello World”.
1. 安装Antlr插件
打开IDEA,在File—Settings—Plugins中,安装ANTLR v4 grammar plugin插件。

2. 第一个项目—“Hello World”
新建一个Maven项目,在pom文件中添加如下依赖:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | <dependencies> <dependency> <groupId>org.antlr</groupId> <artifactId>antlr4-runtime</artifactId> <version>4.8-1</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.antlr</groupId> <artifactId>antlr4-maven-plugin</artifactId> <version>4.8-1</version> <executions> <execution> <id>antlr</id> <goals> <goal>antlr4</goal> </goals> <phase>none</phase> </execution> </executions> <configuration> <outputDirectory>src/test/java</outputDirectory> <listener>true</listener> <treatWarningsAsErrors>true</treatWarningsAsErrors> </configuration> </plugin> </plugins> </build> |
新建一个.g4文件,用来编写要识别语言的词法规则和语法规则,比如这里我们的文件名为Hello.g4
1 2 3 4 5 | grammar Hello; // 定义一个名为Hello的语法,名字与文件名一致 r : 'Hello' ID // 定义一个r规则,匹配一个关键字Hello和紧随其后的标识符ID | 'hello' ID; // "|"是备选分支的分隔符 ID : [a-z]+; // 定义ID标识符,由小写字符组成 WS : [ \t\r\n]+ -> skip; // 忽略空格、Tab、换行以及\r (Windows) |
然后我们就可以使用Antlr工具来将该语法文件转换成可以识别该语法文件所描述语言的程序。这句话有点拗口,举个例子来说的话,就是给定一个识别JSON的语法,antlr工具将会根据该语法生成一个程序,此程序可以通过antlr运行库来识别输入的JSON,即输入的字符串是否符合JSON格式。
不过在此之前,我们需要先配置下生成的程序输出路径,右键Hello.g4,找到Configure ANTLR

接着配置文件的输出路径和目录

接着我们就可以使用antlr工具来将语法文件转换成可以识别该语法文件所描述语言的程序了。
右键Hello.g4,点击Generate ANTLR Recognizer,接着可以看到目录下面生成了许多文件

其中HelloLexer是词法分析器,HelloParser是语法分析器,HelloVistor和HelloListener是两种遍历树的机制,分别是访问者模式和监听器模式。有关Antlr概念与术语的部分,我们第二章在讲,这里了解个大概就行。
最后,我们就可以来编写主程序来调用上诉代码了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | import hello.HelloLexer; import hello.HelloParser; import org.antlr.v4.runtime.ANTLRInputStream; import org.antlr.v4.runtime.CommonTokenStream; public class HelloMain { public static void run(String expr) throws Exception{ // 对每一个输入的字符串,构造一个 ANTLRStringStream 流 in ANTLRInputStream input = new ANTLRInputStream(expr); // 用 in 构造词法分析器 lexer,词法分析的作用是将字符聚集成单词或者符号 HelloLexer lexer = new HelloLexer(input); // 用词法分析器 lexer 构造一个记号流 tokens CommonTokenStream tokens = new CommonTokenStream(lexer); // 再使用 tokens 构造语法分析器 parser,至此已经完成词法分析和语法分析的准备工作 HelloParser parser = new HelloParser(tokens); // 最终调用语法分析器的规则 r(这个是我们在Hello.g4里面定义的那个规则),完成对表达式的验证 parser.r(); } public static void main(String[] args) throws Exception{ String[] testStr={ "Hello world", "hello world", "hi world" }; for(String s : testStr){ System.out.println("Input: " + s); run(s); } } } |
最后运行结果如下:

除了以上方式,我们还可以使用文法可视化工具来测试语法规则
- 在Hello.g4中选择一个语法规则比如r,右键选择Test Rule r
- 在ANTLR Preview中输入要校验的文本,比如hello world

右边我们就可以看到生成的语法分析树