原创

如何实现语义分析中的类型检查

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://daichen.blog.csdn.net/article/details/102519051

之前曾写过一篇语义分析的概念性介绍: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遍历树结点时:

  1. 叶子结点:所谓叶子结点包括函数名、表名、列名、数字字符串等字面量等。当Visit叶子结点时,统一的操作就是去Scope里Resolve符号,返回符号的类型。比如函数名就返回函数的类型,列名就返回该列的类型,数字的字面量就返回数字类型。
  2. 中间结点 :中间结点包括SQL里的各种语法结构,JOIN、IN、EXISTS、函数、操作符等等。因为叶子结点已经返回其类型,所以中间结点要做的就是类型检查。比如叶子结点返回了函数及其参数的类型,那中间结点就让把入参类型传给函数类型,让其去检查实际的入参类型是否与其函数定义中的参数类型相符。符合的话就返回函数的返回值类型给上一层,继续做类型检查。

有了这样统一的模型,几乎所有类型检查都可以用一致的方式去完成,从简单的函数和操作符,到JOIN、IN、EXISTS、UNION、MINUS等等更复杂的运算。可以说,这就是抽象的力量。在一个优雅的理论模型中,所谓的Special Case应该是非常少的。如果你的系统里有很多特例,那也许是你没有找到对的模型。

文章最后发布于: 2019-10-12 13:48:20
展开阅读全文
0 个人打赏
私信求帮助

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览