本文主要是介绍Antlr4简易快速入门,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
1. 简介
Antlr (ANother Tool for Language Recognition) 是一个强大的 跨语言
语法解析器,可以用来读取、处理、执行或翻译结构化文本或二进制文件。它被广泛用来构建语言,工具和框架。Antlr可以从语法上来生成一个可以构建和遍历解析树的解析器。
2. 谁在使用
- Hive
- Spark
- Oracle
- Presto
- Elasticsearch
3. 常见的语法分析器
- Antlr
- Javacc
- SqlParser (位于
Alibaba
的Druid
库中)
其中Antlr
和Javacc
都是现代的语法解析器,两者都很优秀,其中Antlr
要更胜一筹。而SqlParser
只能解析sql
语句,功能比较单一。
:本人基于Antlr
和SqlParser
分别写了一套elasticsearch-sql
组件,有需要的人可以看看源码。
基于Antlr4的elasticsearch-sql
基于SqlParser的elasticsearch-sql
4. 基本概念
- 抽象语法树 (Abstract Syntax Tree,AST) 抽象语法树是源代码结构的一种抽象表示,它以树的形状表示语言的语法结构。抽象语法树一般可以用来进行
代码语法的检查
,代码风格的检查
,代码的格式化
,代码的高亮
,代码的错误提示
以及代码的自动补全
等等。 - 语法解析器 (Parser) 语法解析器通常作为
编译器
或解释器
出现。它的作用是进行语法检查,并构建由输入单词(Token
)组成的数据结构(即抽象语法树)。语法解析器通常使用词法分析器(Lexer)
从输入字符流中分离出一个个的单词(Token
),并将单词(Token
)流作为其输入。实际开发中,语法解析器可以手工编写,也可以使用工具自动生成。 - 词法分析器 (Lexer)
词法分析
是指在计算机科学中,将字符序列
转换为单词(Token
)的过程。执行词法分析
的程序便称为词法分析器。词法分析器(Lexer)
一般是用来供语法解析器(Parser)
调用的。
5. Antlr4使用方法
(1). 安装
cd /usr/local/lib
wget</span> https://www.antlr.org/download/antlr-4.8-complete.jar
export CLASSPATH=".:/usr/local/lib/antlr-4.8-complete.jar:$CLASSPATH"
antlr4='java -jar /usr/local/lib/antlr-4.8-complete.jar'
grun='java org.antlr.v4.gui.TestRig'
但是本文并不使用这种方式来使用Antlr4
,而是使用插件的方式。
(2). 安装插件
本文使用IDEA作为开发工具,在Preference->Plugins中搜索antlr
然后安装即可。
(3). 定义DSL语法
本文将使用Antlr4
实现一个简化版的Elasticsearch
的查询语法,代替Elasticsearch
的dsl
。
搜索语法定义如下:
单个查询:field
:value
,其中冒号:
和等于号=
表示等于,!=
表示不等于
多个查询:field1
:value1
,field2
:value2
,使用逗号,
或者&&
表示且
的关系,使用||
表示或
的关系
括号:可以使用括号()
将多个条件扩起来
示例:
country:中国,province:湖南,city:张家界
搜索语法的抽象语法树
聚类语法定义如下:
桶聚类(terms):field
去重值计数(cardinality):(field
)
桶聚类分页(composite):field
aftervalue
地理边框聚类(geoBoundingBox):[field
]
桶聚类嵌套子聚类(subAgg):field1
>field2
>field3
多个聚类条件用分号;
隔开
示例:
country;(country);country>province>city;province after 湖南
聚类语法的抽象语法树
(4). 编写Antlr4语法文件
创建SearchLexer.g4文件,定义词法分析器的Token
// 表明SearchLexer.g4文件是词法分析器(lexer)定义文件
// 词法分析器的名称一定要和文件名保持一致
lexer grammar SearchLexer;channels {ESQLCOMMENT,ERRORCHANNEL
}//SKIP 当Antlr解析到下面的代码时,会选择跳过
// 遇到 \t\r\n 会忽略
SPACE: [ \t\r\n]+ -> channel(HIDDEN);
// 遇到 /*! */ 会当作注释跳过
SPEC_ESSQL_COMMENT: '/*!' .+? '*/' -> channel(ESQLCOMMENT);
// 遇到 /* */ 会当作注释跳过
COMMENT_INPUT: '/*' .*? '*/' -> channel(HIDDEN);
// 遇到 -- 会当作注释跳过
// 遇到 # 会当作注释跳过
LINE_COMMENT: (('-- ' | '#') ~[\r\n]* ('\r'? '\n' | EOF)| '--' ('\r'? '\n' | EOF)) -> channel(HIDDEN);// 定义Token,模式为 {field}:{value}
MINUS: '-'; //使MINUS和-等价,以下同理
STAR: '*';COLON: ':'|'\uFF1A';
E
这篇关于Antlr4简易快速入门的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!