如何实现语义分析中的类型检查
Posted cdai
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何实现语义分析中的类型检查相关的知识,希望对你有一定的参考价值。
之前曾写过一篇语义分析的概念性介绍:https://daichen.blog.csdn.net/article/details/100097850。最近,终于开发完了一套基于SQL的语义分析器,算是对之前学习到的理论的一次工程实践。本文只是点出一下实践时的一些关键点和经验,具体细节还请看这里的设计文档:https://github.com/opendistro-for-elasticsearch/sql/blob/master/docs/dev/SemanticAnalysis.md。
类型检查作为语义分析的重要组成部分,其最关键的组件就是类型系统。简单来说,类型系统就是各种函数、运算符的类型声明,比如SQL里的数学函数LOG,它的入参是一个数字,返回值也是一个数字。类型系统面对的第一个挑战就是各种特殊类型,比如泛型、变长参数列表、重载、命名参数等。而第二个挑战就是如何与语法树结合在一起完成类型检查。对于SQL来说,如果我们把数据库表的Schema看作是变量的定义的话,整个类型检查就可以统一地以下面这种方式进行,当语法树的Visitor遍历树结点时:
- 叶子结点:所谓叶子结点包括函数名、表名、列名、数字字符串等字面量等。当Visit叶子结点时,统一的操作就是去Scope里Resolve符号,返回符号的类型。比如函数名就返回函数的类型,列名就返回该列的类型,数字的字面量就返回数字类型。
- 中间结点 :中间结点包括SQL里的各种语法结构,JOIN、IN、EXISTS、函数、操作符等等。因为叶子结点已经返回其类型,所以中间结点要做的就是类型检查。比如叶子结点返回了函数及其参数的类型,那中间结点就让把入参类型传给函数类型,让其去检查实际的入参类型是否与其函数定义中的参数类型相符。符合的话就返回函数的返回值类型给上一层,继续做类型检查。
有了这样统一的模型,几乎所有类型检查都可以用一致的方式去完成,从简单的函数和操作符,到JOIN、IN、EXISTS、UNION、MINUS等等更复杂的运算。可以说,这就是抽象的力量。在一个优雅的理论模型中,所谓的Special Case应该是非常少的。如果你的系统里有很多特例,那也许是你没有找到对的模型。
以上是关于如何实现语义分析中的类型检查的主要内容,如果未能解决你的问题,请参考以下文章
python实现算术表达式的词法语法语义分析(编译原理应用)