Antlr4 自定义实现SparkSQL的解析

作者: 大猪大猪 | 来源:发表于2019-03-03 21:38 被阅读51次

    Antlr4 是一个强大的解析器的生成器,可以用来读取、处理、执行或翻译结构化文本,ANTLR可以从语法上来生成一个可以构建和遍历解析树的解析器,最出名的Spark计算引擎2.x就是用它来解析SQL的,是一个牛到没朋友的家伙。

    IDEA测试

    IDEA语法分析插件
    下载 antlr-v4-grammar-plugin

    插件安装

    antlr-v4-grammar分析插件

    g4语法文件使用的是sparkSQL的SqlBase.g4的文件进行改造的 ArcSql.g4

    右键选中 multiStatement 进行测试

    antlr4

    测试SQL语法树

    antlr4-SQL-测试

    生成解析配置

    antlr4-生成解析代码
    1. 右键ArcSQL.g4文件,在下拉选项Configure ANTLR即可出来。
    2. 第一个Output directory...要写上输出代码的路径。
    3. 比如把它放到当前项目的antlr4的包中/dounine/github/arc/src/main/scala/com/dounine/arc/antlr4
    4. 右键ArcSQL.g4文件,选中Generate ANTLR Recognizer即可生成
    5. 会生成如下几个文件
    ArcSQL.interp
    ArcSQL.tokens
    ArcSQLBaseListener
    ArcSQLBaseVisitor
    ArcSQLLexer
    ArcSQLLexer.interp
    ArcSQLLexer.tokens
    ArcSQLListener
    ArcSQLParser
    ArcSQLVisitor
    

    代码测试

    依赖

    compile group: 'org.antlr', name: 'antlr4', version: '4.7.2'
    

    被动模式(树解析到节点了通知)

    val loadLexer = new ArcSQLLexer(CharStreams.fromString(
          """
            select toUp(name) from log;
          """))
    val tokens = new CommonTokenStream(loadLexer)
    val parser = new ArcSQLParser(tokens)
    val ctx = parser.multiStatement()
    val listener = new ArcSQLBaseListener() {
          override def exitQuerySpecification(ctx: ArcSQLParser.QuerySpecificationContext): Unit = {
            val input = ctx.start.getTokenSource.asInstanceOf[ArcSQLLexer]._input
            val start = ctx.start.getStartIndex
            val stop = ctx.stop.getStopIndex
            val interval = new Interval(start, stop)
            val sqlText = input.getText(interval)
            println("表名 => " + ctx.tableAlias().strictIdentifier().getText)
            println("完整SQL =>" + sqlText)
          }
        }
    ParseTreeWalker.DEFAULT.walk(listener, ctx)
    

    输出(在ctx中还有很多关于sql树信息)

    表名 => log
    完整SQL =>select toUp(name) from log
    

    主动模式(主动去要数据)

    val vistor = new ArcSQLBaseVisitor[Unit] {
    
          override def visitQuerySpecification(ctx: QuerySpecificationContext): Unit = {
            val input = ctx.start.getTokenSource.asInstanceOf[ArcSQLLexer]._input
            val start = ctx.start.getStartIndex
            val stop = ctx.stop.getStopIndex
            val interval = new Interval(start, stop)
            val sqlText = input.getText(interval)
            println("表名 => " + ctx.tableAlias().strictIdentifier().getText)
            println("完整SQL =>" + sqlText)
          }
    }
    vistor.visit(ctx)
    

    相关文章

      网友评论

        本文标题:Antlr4 自定义实现SparkSQL的解析

        本文链接:https://www.haomeiwen.com/subject/jrnmuqtx.html