龙空技术网

antlr实现解析sql语法树-检测sql是否与数据库字段匹配

小小怪下士的架构攻略 728

前言:

今天各位老铁们对“sql字段和关键字一样怎么办”可能比较看重,兄弟们都想要分析一些“sql字段和关键字一样怎么办”的相关资讯。那么小编在网络上收集了一些对于“sql字段和关键字一样怎么办””的相关知识,希望大家能喜欢,兄弟们一起来了解一下吧!

前言你有没有想过 idea 是如何做到sql 关键字语法高亮的?毫无疑问需要识别出sql 的关键字。antlrantlr 就是这么一个工具,他能够解析sql ,下面我们通过他来实现表名的获取安装

antlr-tools

首先我们下载上面的antlr 工具 , 然后再通过工具分析每种sql 的语法,每种sql的语法需要我们额外准备,你可以自己将sql 的语法编写好,这里我就直接使用官方提供的语法了。

sql语法

bash复制代码 git clone 
在开始sql解析之前,我们先将焦点移到antlr , antlr 是一个语法解析器工具,sql只是其中一个解析,所以我们先开始一段简单的语法解析吧。

安装文档

windows安装上方文档我们移动到windows章节,首先antlr需要java环境,然后将上方我们下载antlr-4.11.1-complete.jar配置到环境变量中。官网也提到了配置环境变量可以在终端中临时配置也可以在系统环境变量中永久配置。临时配置环境变量在终端中执行 SET CLASSPATH=.;C:\Javalib\antlr-4.11.1-complete.jar;%CLASSPATH% 即可在终端中临时设置了变量。永久配置环境变量这样配置只要是新打开的终端都是可以获取到CLASSPATH 这个环境变量的。小结这里需要注意的是,在配置CLASSPATH这个环境变量时必须配置 . , 如果不配置在执行到grun命令时会报错Can't load Hello as lexer or parser。antlr4&&grun因为antrl4基于java包,每次运行要从java调用,为了方便使用写一个批处理文件(.bat文件)放在antlr-4.11.1-complete.jar同一文件夹下,自己命名,我命名为antlr4.bat为了能够访问我们的自定义脚本,这里我们需要将antlr-4.11.1-complete.jar所在目录配置成环境变量。我这里是E:/study/antlr/antlr-4.11.1-complete.jar然后我们就可以在E:\study\antlr的目录下新建一个脚本antlr4.bat , 内容如下

ini复制代码 doskey antlr4=java org.antlr.v4.Tool $* doskey grun=java org.antlr.v4.gui.TestRig $*
这样我们可以执行antlr4.bat命令后就可以在终端执行antlr4&&grun命令了。官网也介绍到我们可以分别为antlr4和grun创建脚本antlr4.bat
erlang复制代码 java org.antlr.v4.Tool %*
grun.bat
ini复制代码 @ECHO OFF SET TEST_CURRENT_DIR=%CLASSPATH:.;=% if "%TEST_CURRENT_DIR%" == "%CLASSPATH%" ( SET CLASSPATH=.;%CLASSPATH% ) @ECHO ON java org.antlr.v4.gui.TestRig %*
测试到了这里我们的antlr4已经安装完成了,那么我们该如何进行语法测试呢?
ini复制代码 grammar Hello;               // 1、定义文法的名字  s  : 'hello' ID ;            // 3、匹配关键字hello和标志符 ID : [a-z]+ ;                // 标志符由小写字母组成 WS : [ \t\r\n]+ -> skip ;    // 4、跳过空格、制表符、回车符和换行符
下面针对语法进行相关解释:定义了 grammar 的名字,名字需要与文件名对应s定义的语法,会使用到下方定义的正则表达式词法定义了空白字符,后面的 skip 是一个特殊的标记,标记空白字符会被忽略。
ini复制代码 grammar Hello; r  : 'hello' ID ; ID : [a-z]+ ; WS : [ \t\r\n]+ -> skip ;
打开终端针对新打开的终端我们执行antlr4 就会执行我们配置的E:\study\antlr\antlr4.bat 脚本。执行完成之后就可以执行内部命令了。通过antlr4 Hello.g4进行语法翻译会生成一些Java类,这些类就是我们用来解析相关文本的工具类。为了能够执行这些Java 我们先 javac编译一下
复制代码 javac Hello*.java
grun解析下面我们通过grun进行demo解析
复制代码 grun Hello r -tree
如下命令就会进行等待我们输入文本。Hello.g4的语法就是 hello [a-z]+ 这个正则,也就是所有的hello开头的文本,中间一个空格后面跟着由小写字母组成的字符的整个文本就会被解析出来。

(注意:^D在 Unix 上表示 control-D 并表示“输入结束”;^Z在 Windows 上使用。)

Linux安装windows是大多数人使用的系统,但是Linux才是最终的服务环境,加之我本身就是Linux作为开发环境,所以Linux安装对于我而言很重要。因为antlr本事就是jar ,得以与java的跨平台所以这里资源两个系统是可以通用的。linux上配置环境变量更方便,我们只需要在~/.bashrc或者~/.zshrc中配置即可

bash复制代码 export CLASSPATH=".:/home/zxhtom/zxh/antlr/antlr-4.11.1-complete.jar:$CLASSPATH"
在终端中给命令创建别名
ini复制代码 alias antlr4='java -Xmx500M -cp "/home/zxhtom/zxh/antlr/antlr-4.11.1-complete.jar:$CLASSPATH" org.antlr.v4.Tool' alias grun='java -Xmx500M -cp "/home/zxhtom/zxh/antlr/antlr-4.11.1-complete.jar:$CLASSPATH" org.antlr.v4.gui.TestRig'
或者我们也可以按照windows方式的命令,其实最终都是执行相同的类
ini复制代码 alias antlr4='java org.antlr.v4.Tool ' alias grun='java org.antlr.v4.gui.TestRig'
export和alias可以同时配置在~/.zshrc中。可视化TestRig充当一款调试工具,官网建议我们将它重命名为grun直接输入grun可以看到其支持的参数。

参数

功能

-tokens

打印出词法符号流

-tree

LISP格式打印分析树,啥叫LISP?

-gui

可视化打印分析树

-ps fiels.ps

以PostScript格式生成可视化语法分析树

-trace

打印规则的名字以及进入和离开该规则时的语法符号

不管是linux还是windows我们都可以通过 -gui的方式进行可视化自定义解析从4.11开始,antlr大约支持10种语言进行语法解析,上面案列中我使用的是Java 语言的解析工具,只需要javac编译一次即可,或者直接将相关的Java代码拷贝到项目中进行调用。下面我们看看如何生成Python语言的解析代码吧。python

复制代码 pip3 install antlr4-python3-runtime
因为是测试python的语法生成,这里就不配置快捷命令了,所以这里使用全命令java -jar ../antlr-4.11.1-complete.jar -Dlanguage=Python3 Hello.g4
ini复制代码 import sys from antlr4 import * from HelloLexer import HelloLexer from HelloParser import HelloParser   def main(argv):     input = FileStream(argv[1])     lexer = HelloLexer(input)     stream = CommonTokenStream(lexer)     parser = HelloParser(stream)     tree = parser.r()     print(tree.toStringTree(recog=parser))  if __name__ == '__main__':     main(sys.argv) 
上述代码就是我们对antlr生成的解析代码的使用,这样我们可以进行自定义的处理。解析Mysql
xml复制代码 <dependency>     <groupId>org.antlr</groupId>     <artifactId>antlr4</artifactId>     <version>4.11.1</version> </dependency>
版本需要保持一致。上一章节中我们通过一个简单的Hello.g4语法进行Java、python等语言的解析代码的生成。上章节也提到antlr是一个语法解析工具,并不仅仅是解析sql , 理论上他能解析所有的语法,比如你自己有一套语法如何让antlr解析呢?你只需要按照antlr的规则用antlr的语言表达出你自己的语法,目前比较规范的就是这个仓库提供的语法解析树了,本次对mysql解析也是使用这个仓库下提供的g4 文件。这个仓库给我们提供了MySqlLexer.g4和MySqlParser.g4两个文件,前者是Mysql的关键词,后者就是Mysql的语法配置。examples是作者给我们提供的Mysql相关的sql 。 我们可以用来测试用。为了方便测试,这里我们将这两个g4文件拷贝到其他目录下执行生成Java解析代码
复制代码 antlr4 MySqlParser.g4 MySqlLexer.g4
两个文件没有先后顺序区别,但是要注意的是不能缺少。笔者就是一开始认为只需要MysqlParser.g4一再在报错。MySqlParser.g4:2595:37: cannot create implicit token for string literal in non-combined grammar: '|'。执行完上述命令后,我们就可以看到我们的Java代码了.这样的代码是没有包名的,好在antlr在生成代码时支持指定包名。antlr4 MySqlParser.g4 MySqlLexer.g4 -package com.github.zxhtom.mysql

作者:zxhtom

链接:

标签: #sql字段和关键字一样怎么办