前语

  • 你有没有想过 idea 是怎么做到sql 关键字语法高亮的?毫无疑问需求识别出sql 的关键字。

antlr

  • antlr 便是这么一个东西,他能够解析sql ,下面咱们经过他来完结表名的获取

装置

antlr-tools

  • 首先咱们下载上面的antlr 东西 , 然后再经过东西分析每种sql 的语法,每种sql的语法需求咱们额定准备,你能够自己将sql 的语法编写好,这儿我就直接运用官方供给的语法了。

sql语法

git clone https://github.com/antlr/grammars-v4.git
  • 在开端sql解析之前,咱们先将焦点移到antlrantlr 是一个语法解析器东西,sql仅仅其间一个解析,所以咱们先开端一段简略的语法解析吧。

装置文档

windows装置

  • 上方文档咱们移动到windows章节,首先antlr需求java环境,然后将上方咱们下载antlr-4.11.1-complete.jar装备到环境变量中。官网也说到了装备环境变量能够在终端中暂时装备也能够在系统环境变量中永久装备。

暂时装备环境变量

  • 在终端中履行 SET CLASSPATH=.;C:\Javalib\antlr-4.11.1-complete.jar;%CLASSPATH% 即可在终端中暂时设置了变量。

如何检测sql的合法性?获取语法树后结合Spring 的 AOP 我可以对sql为所欲为

永久装备环境变量

如何检测sql的合法性?获取语法树后结合Spring 的 AOP 我可以对sql为所欲为

  • 这样装备只要是新翻开的终端都是能够获取到CLASSPATH 这个环境变量的。

小结

  • 这儿需求注意的是,在装备CLASSPATH这个环境变量时有必要装备 . , 如果不装备在履行到grun指令时会报错Can't load Hello as lexer or parser

如何检测sql的合法性?获取语法树后结合Spring 的 AOP 我可以对sql为所欲为

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

如何检测sql的合法性?获取语法树后结合Spring 的 AOP 我可以对sql为所欲为

  • 然后咱们就能够在E:\study\antlr的目录下新建一个脚本antlr4.bat , 内容如下
doskey antlr4=java org.antlr.v4.Tool $*
doskey grun=java org.antlr.v4.gui.TestRig $*
  • 这样咱们能够履行antlr4.bat指令后就能够在终端履行antlr4&&grun指令了。官网也介绍到咱们能够分别为antlr4grun创建脚本

antlr4.bat

java org.antlr.v4.Tool %*

grun.bat

@ECHO OFF
SET TEST_CURRENT_DIR=%CLASSPATH:.;=%
if "%TEST_CURRENT_DIR%" == "%CLASSPATH%" ( SET CLASSPATH=.;%CLASSPATH% )
@ECHO ON
java org.antlr.v4.gui.TestRig %*

测验

  • 到了这儿咱们的antlr4现已装置完结了,那么咱们该怎么进行语法测验呢?
grammar Hello;        // 1、界说文法的姓名
​
s  : 'hello' ID ;      // 3、匹配关键字hello和标志符
ID : [a-z]+ ;        // 标志符由小写字母组成
WS : [ \t\r\n]+ -> skip ;  // 4、越过空格、制表符、回车符和换行符
  • 下面针对语法进行相关解释:
  1. 界说了 grammar 的姓名,姓名需求与文件名对应
  2. s界说的语法,会运用到下方界说的正则表达式词法
  3. 界说了空白字符,后边的 skip 是一个特殊的符号,符号空白字符会被忽略。
grammar Hello;
r  : 'hello' ID ;
ID : [a-z]+ ;
WS : [ \t\r\n]+ -> skip ;

翻开终端

  • 针对新翻开的终端咱们履行antlr4 就会履行咱们装备的E:\study\antlr\antlr4.bat 脚本。履行完结之后就能够履行内部指令了。

如何检测sql的合法性?获取语法树后结合Spring 的 AOP 我可以对sql为所欲为

  • 经过antlr4 Hello.g4进行语法翻译

如何检测sql的合法性?获取语法树后结合Spring 的 AOP 我可以对sql为所欲为

  • 会生成一些Java类,这些类便是咱们用来解析相关文本的东西类。为了能够履行这些Java 咱们先 javac编译一下
javac Hello*.java

grun解析

  • 下面咱们经过grun进行demo解析
grun Hello r -tree
  • 如下指令就会进行等候咱们输入文本。Hello.g4的语法便是 hello [a-z]+ 这个正则,也便是一切的hello开头的文本,中间一个空格后边跟着由小写字母组成的字符的整个文本就会被解析出来。

如何检测sql的合法性?获取语法树后结合Spring 的 AOP 我可以对sql为所欲为

如何检测sql的合法性?获取语法树后结合Spring 的 AOP 我可以对sql为所欲为

(注意:^D在 Unix 上表明 control-D 并表明“输入完毕”;^Z在 Windows 上运用。)

Linux装置

  • windows是大多数人运用的系统,可是Linux才是终究的服务环境,加之我本身便是Linux作为开发环境,所以Linux装置对于我而言很重要。
  • 由于antlr本事便是jar ,得以与java的跨平台所以这儿资源两个系统是能够通用的。
  • linux上装备环境变量更方便,咱们只需求在~/.bashrc或许~/.zshrc中装备即可
export CLASSPATH=".:/home/zxhtom/zxh/antlr/antlr-4.11.1-complete.jar:$CLASSPATH"
  • 在终端中给指令创建别名
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方法的指令,其实终究都是履行相同的类
alias antlr4='java org.antlr.v4.Tool '
alias grun='java org.antlr.v4.gui.TestRig'
  • export和alias能够一起装备在~/.zshrc中。

可视化

  • TestRig充当一款调试东西,官网建议咱们将它重命名为grun

如何检测sql的合法性?获取语法树后结合Spring 的 AOP 我可以对sql为所欲为

  • 直接输入grun能够看到其支撑的参数。
参数 功能
-tokens 打印出词法符号流
-tree LISP格式打印分析树,啥叫LISP?
-gui 可视化打印分析树
-ps fiels.ps 以PostScript格式生成可视化语法分析树
-trace 打印规矩的姓名以及进入和脱离该规矩时的语法符号
  • 不管是linux还是windows咱们都能够经过 -gui的方法进行可视化

如何检测sql的合法性?获取语法树后结合Spring 的 AOP 我可以对sql为所欲为

自界说解析

  • 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
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

<dependency>
  <groupId>org.antlr</groupId>
  <artifactId>antlr4</artifactId>
  <version>4.11.1</version>
</dependency>
  • 版别需求保持一致。
  • 上一章节中咱们经过一个简略的Hello.g4语法进行Javapython等言语的解析代码的生成。上章节也说到antlr是一个语法解析东西,并不仅仅是解析sql , 理论上他能解析一切的语法,比方你自己有一套语法怎么让antlr解析呢?你只需求依照antlr的规矩用antlr的言语表达出你自己的语法,现在比较规范的便是https://github.com/antlr/grammars-v4.git这个库房供给的语法解析树了,本次对mysql解析也是运用这个库房下供给的g4 文件。

如何检测sql的合法性?获取语法树后结合Spring 的 AOP 我可以对sql为所欲为

  • 这个库房给咱们供给了MySqlLexer.g4MySqlParser.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代码了.

如何检测sql的合法性?获取语法树后结合Spring 的 AOP 我可以对sql为所欲为

  • 这样的代码是没有包名的,好在antlr在生成代码时支撑指定包名。antlr4 MySqlParser.g4 MySqlLexer.g4 -package com.github.zxhtom.mysql

如何检测sql的合法性?获取语法树后结合Spring 的 AOP 我可以对sql为所欲为

点赞保藏,下次直接查找,不丢掉