理论教育 编译器设计之路:实现类型相容性

编译器设计之路:实现类型相容性

时间:2023-11-04 理论教育 版权反馈
【摘要】:前面已经讲述了类型相容的相关基础理论,本小节将分析Neo Pascal的相关源代码实现。在Neo Pascal表达式处理中,类型等价被视作一种特殊的类型相容问题,所以不作专门讨论。Pascal的用户自定义类型与C语言的类型别名是一脉相承的。在大多数语言中,类型相容都是基于实际类型讨论的,即忽略了那些类型别名信息后的实质类型。在Pascal语言中,与类型等价相比,类型相容的条件要宽松得多。

编译器设计之路:实现类型相容性

前面已经讲述了类型相容的相关基础理论,本小节将分析Neo Pascal的相关源代码实现。在Neo Pascal表达式处理中,类型等价被视作一种特殊的类型相容问题,所以不作专门讨论。下面,就来看看Neo Pascal是如何验证类型相容的。

程序6-1 Type.cpp

第4~5行:调用了GetOpType函数获取操作数的实际类型。有两种方式可以获取操作数类型:1、m_iDetailType栈的栈顶元素。2、根据m iLink属性获得变量信息表表项,再由变量信息表表项的m_iTypeLink获取变量的类型信息。无论使用哪种方式,都必须解决一个问题,那就是用户自定义类型的处理。Pascal的用户自定义类型与C语言的类型别名是一脉相承的。例如:

【声明6-5】

在C或Pascal中,通常认为i与i的类型是相容的。虽然,i存在多重的类型别名定义,但是,这丝毫不应该影响编译器的判断。在大多数语言中,类型相容都是基于实际类型讨论的,即忽略了那些类型别名信息后的实质类型。在Pascal语言中,与类型等价相比,类型相容的条件要宽松得多。稍后将给出GetOpType函数的具体实现。

第6行:调用SearchTypeSysTbl函数检索类型系统表TypeSysTbl。前面,笔者已经介绍了类型系统表的作用。类型相容是基于某一特定的运算符讨论的,否则一切是徒劳的。这里的Op就是运算符单词的ID,是由词法分析器生成的。

下面,再来看看GetOpType函数的实现。(www.daowen.com)

程序6-2 Type.cpp

第3~4行:操作数是常量,则返回常量的类型。

第5~6行:操作数为空,则返回T_NONE。

第7~8行:操作数是指针,则返回T_POINTER。

第9~23行:操作数是变量,则返回其实际类型。读者可能注意到了,Neo Pascal分别从两个来源获取类型信息。m_iDetailType栈仅在表达式翻译过程中有效。实际上,确实存在一些变量根本不需要进行表达式翻译。在这种情况下,它们的m_iDetailType自然是空的,但并不能因此而不允许进行类型相容的验证,例如,for的循环变量。为了安全起见,所以同时考虑了两个类型来源。当然,优先考虑m_iDetailType栈顶元素。仅在某些特殊情况下,当m_iDetailType栈空时,再从变量信息表取相应的类型信息。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈