概述

ANTLR(ANother Tool for Language Recognition 另一种语言识别工具)是功能强大的解析器生成器,用于读取,处理,执行或翻译结构化文本或二进制文件。它被广泛用于构建语言,工具和框架。ANTLR通过语法生成可以构建和遍历语法树的语法分析器。(转自官方

下载:https://www.antlr.org/download.html

文档:https://github.com/antlr/antlr4/blob/master/doc/index.md

IDE插件:https://www.antlr.org/tools.html

官方教程:https://github.com/antlr/antlr4/blob/master/doc/getting-started.md

流程

  1. ANTLR定义一个g4的文件类型,编写语法规则文件。

    g4文件是ANTLR生成词法解析规则和语法解析规则的基础。

  2. 使用工具生成解析代码。

  3. 依赖生成的解析代码实现自己的功能。

一. 创建g4文件

简单例子

在一个临时目录下创建Hello.g4文件。在文件中写入以下内容:

1
2
3
4
5
// Define a grammar called Hello
grammar Hello;
r : 'hello' ID ; // match keyword hello followed by an identifier
ID : [a-z]+ ; // match lower-case identifiers
WS : [ \t\r\n]+ -> skip ; // skip spaces, tabs, newlines

注意:定义语法名称需要首字母大写,因为生成的文件和类命名会使用到

二. 生成解析器

1. 安装工具

2. 执行命令

1
antlr4 Hello.g4

三. 解析器源码

依赖

1
2
3
4
5
6
7
8
9
10
11
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr4</artifactId>
<version>4.8</version>
</dependency>

<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr4-runtime</artifactId>
<version>4.8</version>
</dependency>

代码

  • <Grammar>Lexer.java: 词法分析器源码;
  • <Grammar>Parser.java: 语法分析器源码;
  • <Grammar>Listener.java: Listener 接口;
  • <Grammar>BaseListener.java: Listener 默认实现;
  • <Grammar>Visitor.java: Visitor 接口;
  • <Grammar>BaseVisitor.java: Visitor 默认实现;

如何使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public static void main(String[] args) throws Exception {
//代码流
ANTLRInputStream input = new ANTLRInputStream("int a = 12; ");

//使用词法分析器生成Token序列
Java8Lexer lexer = new Java8Lexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);

//使用语法分析器将Token序列串联成AST
Java8Parser parser = new Java8Parser(tokens);
ParseTree tree = parser.expressionName();

//Visito模式或者Listener模式遍历AST
System.out.println("Visitor:");
Java8Visitor evalByVisitor = new Java8BaseVisitor();
evalByVisitor.visit(tree);

//Listener模式遍历AST
System.out.println("Listener:");
ParseTreeWalker walker = new ParseTreeWalker();
Java8Listener evalByListener = new Java8BaseListener();
walker.walk(evalByListener, tree);
}

辅助工具