背景:上一篇介绍了hive执行和运行过程。这一篇将对antlr进行介绍,讲解hive是如何将sql转化成AST tree 的。

hive借助Antlr定义SQL的词法规则和语法规则,完成SQL词法,语法解析,将SQL转化为抽象语法树AST Tree。HiveSql后续的编译过程全都基于AST Tree,所以我们想要完整理解hive sql的编译过程,需要前置了解一下antlr是怎么工作的




hive语句解析器 hive源码解析_hive语句解析器


词法分析器(Lexer):词法分析器的工作是分析量化那些本来毫无意义的字符流,将他们翻译成离散的字符组(也就是一个一个的Token),供语法分析器使用。

语法分析器(Parser):语法分析器将把收到的Tokens组织起来,并转换成语法规则定义的所允许的结构。

树分析器(TreeParser):树分析器可以用于对语法分析生成的抽象语法树进行遍历,并能执行一些相关的操作。

antlr环境准备

  • 下载antlr :ANTLRWorks 1.5开发
  • 运行antlrworks-1.5.1.jar。

准备代码


grammar


  • 点击debug按钮运行。


hive语句解析器 hive源码解析_hive_02

debug


  • 点击按钮,看到如下图说明运行成功了。


hive语句解析器 hive源码解析_hive_03

运行

这就是antlr解析的原理。通过提前定义好识别字符流的词法规则和用于解析token流的语法分析规则。然后,antlr会根据我们提供的语法文件自动生成相应的词法/语法分析器。利用他们讲输入的文本进行编译,最后转化为抽象的语法书AST Tree。

idea集成antlr

  • plugins下载antlr组件


hive语句解析器 hive源码解析_hive_04

idea安装antlr

  • idea创建Demo.g4文件
grammar Demo;
//parser
prog:stat
;
stat:expr|NEWLINE
;

expr:multExpr(('+'|'-')multExpr)*
;
multExpr:atom(('*'|'/')atom)*
;
atom:'('expr')'
    |INT
    |ID
;
//lexer
ID:('a'..'z'|'A'..'Z')+;
INT:'0'..'9'+;
NEWLINE:'r'?'n';
WS:(' '|'t'|'n'|'r')+{skip();};
//expr;


1、点击右键Demo.g4,选择Configure ANTLR,配置output路径。


hive语句解析器 hive源码解析_用c++自制词法分析器_05

configure antlr

hive语句解析器 hive源码解析_hive_06

配置output

  • pom.xml文件配置
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>hive</artifactId>
        <groupId>org.apache.hive</groupId>
        <version>2.1.1</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>antlr-my</artifactId>

    <dependencies>

        <dependency>
            <groupId>org.antlr</groupId>
            <artifactId>antlr4-runtime</artifactId>
            <version>4.8</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hive</groupId>
            <artifactId>hive-exec</artifactId>
            <version>2.1.1</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.antlr</groupId>
                <artifactId>antlr4-maven-plugin</artifactId>
                <version>4.3</version>
                <executions>
                    <execution>
                        <id>antlr</id>
                        <goals>
                            <goal>antlr4</goal>
                        </goals>
                        <phase>none</phase>
                    </execution>
                </executions>
                <configuration>
                    <outputDirectory>src/test/java</outputDirectory>
                    <listener>true</listener>
                    <treatWarningsAsErrors>true</treatWarningsAsErrors>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>


  • 点击generate antlr recognizer 后可以看到生成了这些文件


hive语句解析器 hive源码解析_hive_07


添加java文件运行调用antlr文件,验证你的运算。并可以查看ASR Tree。


/**


通过 命令行 find . -name "*.g" 查找hive源码文件。

基本可以确定了 ql文件下面就是需要找到这几个文件。解析sql

  • HiveLexer.g 是做词法分析的,定义了所有用到的token
  • HiveParser.g 是做语法解析的
  • FromClauseParser.g from从句语法解析
  • SelectClauseParser.g select 从句语法解析
  • IdentifiersParser.g 自定义函数的解析


hive语句解析器 hive源码解析_java词法分析_08


hive源码中语法文件之间的关系


hive语句解析器 hive源码解析_hive遍历_09


查看HiveParser.g文件有一行import信息


hive语句解析器 hive源码解析_hive语句解析器_10


查看hive源码Driver类,可以看出ParseDriver.parse方法获取AST Tree信息


hive语句解析器 hive源码解析_java词法分析_11


idea创建AstTreeTest测试类打印ast tree信息


public


AstTree信息


hive语句解析器 hive源码解析_hive语句解析器_12


看到这里,基本就是AST Tree生成的全部过程。