简单的C语言解释运行器实现(五)—— 语义分析

本文介绍C语言解释器的语义分析阶段,包括类型定义、类型推导(如二元运算符、赋值运算符的类型推导)、左值类型推导、数组索引检查及函数实现验证。文章通过代码示例解释了如何处理类型匹配、隐式类型转换以及左值检查,确保语义的正确性。
摘要由CSDN通过智能技术生成

上一篇:语法分析
下一篇:生成指令

我们在语义分析阶段完成语法树节点类型的推导,并完成数组维度常量表达式的计算以及数组访问的修改。

定义类型

首先我们需要明确有哪些类型,我们简化的C语言只有如下类型:int, char, short, bool, long, double, float, void, pointer。还可以通过组合组合出很多类型出来,比如多维的指针,多维的数组

关于类型定义相关代码,请参照
https://github.com/huanghongxun/Compiler/blob/master/compiler/type_base.h
https://github.com/huanghongxun/Compiler/blob/master/compiler/type_primitive.h
https://github.com/huanghongxun/Compiler/blob/master/compiler/type_array.h
https://github.com/huanghongxun/Compiler/blob/master/compiler/type_pointer.h

我们对每个类型起一个标记符方便我们判断类型是否相等,比如int的助记符是iconst int的助记符是Kidouble的助记符是dint[32][32]的助记符是A32_A32_iint const*const*的助记符是PKPKiP表示指针,K表示指向常量,所以意思是[指向[指向[常整数]的常量指针]的指针])等。这个助记符的由来可以使用c++的typeid(i).name()查看。

对于typedef,仅仅是一个alias而已,我们在记录类型的时候记录一下就好。

类型推导

C语言是强类型语言,我们在操作变量的时候必须确认运算符两侧的类型是否合法,比如指针不能和指针相加,但可以相减,结构体和其他类型的变量都不能运算,布尔类型以及无符号类型不能取负,整数与整数的除法和浮点数的除法的行为不同等。有这么多理由,我们必须要实现类型推导。
我们在初期可以限定类型必须为int来跳过类型推导以便迅速实现一个可用的解释器,不过要实现更高级的功能类型推导是不可缺少的。

首先我们一开始已经能知道语法树部分节点的类型,一般是常量和变量,还有函数调用的返回值的类型。我们根据这些已知的类型进行推导。

二元运算符的类型推导

对于一个语法树节点,如果我们知道节点子树的类型和运算符(这里只讨论二元运算符),那么会有2种情况,分别是类型相同和类型不同。对于类型不同的情况,我们需要做类型转换使得类型匹配,我们在匹配类型的时候先推导出两种类型的公共超类型,比如intdouble的公共超类型是doublecharbool的公共超类型是int(小于int的类型计算都规约到int再计算)(经过我的试验发现long long int

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值