Parser 简介
Parser 是编译器里面的基础部分,包括词法分析和语法分析。核心目的是把文本式的代码解析成结构化的 AST(Abstract Syntax Tree 抽象语法树),交给后续的程序来处理。属于编译的第一步,也是所有代码格式化,代码高亮,以及提示器等工具的必要部件。
SQL 作为数据库领域的通用标准,他的 Parser 自然是不会少的,所以99% 的场景都不需要我们自己实现 Parser。
本文针对 SQL语言的分析场景,整理了几个有参考意义的 SQL Parser,供学习和使用。
应用级项目
SQLGlot
SQLGlot是一个强大的 Python 分析器,支持了 21 种 SQL 方言。支持这些方言的互相转译。而且还有很多很牛逼的功能,比如在数组上执行 SQL,还可以做 SQL 的优化改写。是学习SQL 编译的好项目。
https://github.com/tobymao/sqlglot
Tokern
Tokern 是一个 Python 的开源数据库管理包。Parser只是其中一部分,他还可以做字段级数据血缘分析 data lineage。还可以做数据分类,查找数据库和文件系统中的 PII (Personally identifiable information 个人身份信息)和 PHI (Protected health information 受保护的健康信息),是基于正则表达啥的字段名分析和抽样数据的 NLP 方法。
JSQLParser
JSQLParser是Java 语言下一个我比较喜欢的开源选择。一个原因是我个人需要实现一个血缘分析的工具,他官方仓库提供了一个 net.sf.jsqlparser.util.TablesNamesFinder 类,用来分析 SQL 语句涉及的源表,可以作为表级数据血缘的实现方式,也算提供了一种 vistor 模式的示例代码。另外一个被我喜欢的原因是使用了 JavaCC 构建的,并提供了构建源码,也可以作为 JavaCC 的学习项目。缺点是支持的方言没有很多,只有主流的几款 OLTP 数据库,没有 OLAP 的数据库。
JSQLParser 还提供了完整的 BNF语法图,可以清晰的查看当前支持的语法,也可以作为SQL 学习的工具。
https://github.com/JSQLParser/JSqlParser
Alibaba Druid
阿里云出品的,核心定位是数据库连接池。功能非常强大,包括连接池管理,防注入,当然也包含了 visitor 模式的 parser。阿里的程序员功力确实好,他这个 parser 不是用生成器构建的,而是手写的。手写 parser 的好处是方便 debug和更友好的报错信息,缺点当然也是代码产出比较依赖人的功力。
但这我不是很喜欢这个项目,一个原因是文档看着很 low,没啥系统性,完全是一堆 QA 清单。另一个原因是他功能太多了,如果只需要做 SQL 的解析,过于臃肿。
https://github.com/alibaba/druid
Hive Parser
Apache Hive 官方仓库里面的解析器方法。 Java语言。https://github.com/apache/hive/blob/master/ql/src/java/org/apache/hadoop/hive/ql/parse/ParseUtils.java
官方仓库还提供了一份 parser 生成器的Antlr源码,用来自动生成 parser。
https://github.com/apache/hive/blob/master/hplsql/src/main/antlr4/org/apache/hive/hplsql/Hplsql.g4
生成器
JavaCC
JavaCC ,意思是 Java Compiler Complier,编译器的编译器,是 Java 生态的YACC 的替代品。也是我第一个跑通的生成器,参考《初探JavaCC:编译器的编译器(表达式求值)》,因此有一些好感。他的缺点是源文件里面 BNF 和 Java 代码混合着写而且没有明确的标识来说明哪段代码是 Java 的,对于不熟悉的人来说,可能会看起来比较迷惑。好处大概是可以兼具手写 parser 的优点吧。
Antlr
Antlr 本身不是 parser,但他是用于生成Java语言下的 parser 的工具,从几个示例来看,他里面没有 Java 混写的情况,单纯就是定义语法和词法,这才是一个业务解耦的通用工具。Hive 和 Spark 官方的SQL parser 都是他生成的,而且他还提供了一个 Antlr Lab 可以用来生成语法解析的 AST 图像,是学习 parser 的好工具。
其他
https://hackernoon.com/14-open-source-sql-parsers
参考文章
https://www.yinwang.org/blog-cn/2015/09/19/parser
https://www.cnblogs.com/tonglin0325/p/12212866.html