golang 解析 sql 从中获取表名
antlr
ANTLR是Another Tool for Language Recognition的简写,是一个用Java语言编写的识别器工具。它能够自动生成解析器,并将用户编写的ANTLR语法规则直接生成目标语言的解析器,它能够生成Java、Go、C等语言的解析器客户端。
作者还维护了很多语法规则其中就有
https://github.com/antlr/grammars-v4/tree/master/sql/mysql
使用
下载最新的jar包
https://www.antlr.org/download/antlr-4.10.1-complete.jar
从github中下载
MySqlLexer.g4
和MySqlParser.g4
执行命令生成go文件 (需要java环境)java -jar antlr-4.10.1-complete.jar -visitor -Dlanguage=Go -o parser MySqlLexer.g4
java -jar antlr-4.10.1-complete.jar -visitor -Dlanguage=Go -o parser MySqlParser.g4
目录结构如下:
├── MySqlLexer.g4 ├── MySqlParser.g4 ├── antlr-4.10.1-complete.jar ├── antlr.go └── parser ├── MySqlLexer.interp ├── MySqlLexer.tokens ├── MySqlParser.interp ├── MySqlParser.tokens ├── mysql_lexer.go ├── mysql_parser.go ├── mysqlparser_base_listener.go └── mysqlparser_listener.go
antlr.go
:
package antlr import ( "github.com/antlr/antlr4/runtime/Go/antlr" logs "github.com/danbai225/go-logs" "strings" "test/antlr/parser" ) type Ml struct { *parser.BaseMySqlParserListener tableNames map[string]struct{} } func (m *Ml) EnterTableName(ctx *parser.TableNameContext) { if m.tableNames == nil { m.tableNames = make(map[string]struct{}) } m.tableNames[ctx.GetText()] = struct{}{} } func (m *Ml) GetTableNames() []string { arr := make([]string, 0) if m.tableNames != nil { for k := range m.tableNames { arr = append(arr, k) } } return arr } func GetTableNames(sql string, sqlType string) []string { tokenStream := antlr.NewCommonTokenStream(parser.NewMySqlLexer(antlr.NewInputStream(strings.ToUpper(sql))), antlr.TokenDefaultChannel) sqlParser := parser.NewMySqlParser(tokenStream) ml := Ml{} switch sqlType { case "dml": antlr.ParseTreeWalkerDefault.Walk(&ml, sqlParser.DmlStatement()) case "ddl": antlr.ParseTreeWalkerDefault.Walk(&ml, sqlParser.DdlStatement()) } return ml.GetTableNames() } func Antlr() { sql := "SELECT without FROM fails" logs.Info(GetTableNames(sql, "dml")) }
通过覆盖实现BaseMySqlParserListener
的EnterTableName
接口
再解析的过程中每个表名节点都将调用这个方法收集表名。
怀念以前用antlr4解析各种防火墙配置语法的时光
求楼主给一个select 的字段名 规则打印。我试了
楼主有antlr 生成的MySQL 代码注释吗好难。看不懂因为没注释