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组件,有需要的人可以看看源码。
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):fieldaftervalue
地理边框聚类(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';
EQ: '=';
NE: '!=';
BOOLOR: '||'|'|'; // 使BOOLOR与||或者|等价
BOOLAND: '&&'|COMMA|'&';
//CONSTRUCTORS
DOT: '.' -> mode(

本文介绍了Antlr4的基本概念和使用方法,包括如何安装插件、定义DSL语法、生成代码文件以及遍历抽象语法树。通过示例展示了如何将查询语句转换为Elasticsearch DSL,适用于理解语法解析器的工作原理和实践应用。
最低0.47元/天 解锁文章
5155

被折叠的 条评论
为什么被折叠?



