在本章,你将会包含类型检查,完成第9张工作。如今你可以把Pascal变量申明为各种类型,你必须确保当这些变量出现在语句中的时候,它们的类型必须与它们的操作符兼容。如第1章所说的那样,语法检查是语义分析的一部分。
==>> 本章中文版源代码下载:svn co http://wci.googlecode.com/svn/branches/ch10/ 源代码使用了UTF-8编码,下载到本地请修改!
方法和目标
本章的目标是在前端集成类型检查。方法是将类型检查加到语句解析器中,以便在解析语句过程中可以用到。针对第5章开发的语法检查器搞了个新的版本,用来验证你的成果。
类型检查
让我们从intermediate.typeimpl包中的TypeChecker类开始。这个类附带的静态方法实现了类型兼容规则,可以被语句解析器用来执行语法检查。清单10-1 展示了检查具体类型的各种方法。
/**
* 检查类型是否一个整数
* @param type 被检查类型说明
* @return true/false
*/
static boolean isInteger(TypeSpec type)
7: {
return (type != null) && (type.baseType() == Predefined.integerType);
9: }
10:
/**
* 检查二元操作符的两个类型都是否是整数
* @param type1 第一个被检查的类型
* @param type2 第二个被检查的类型
* @return true/false
*/
static boolean areBothInteger(TypeSpec type1, TypeSpec type2)
18: {
return isInteger(type1) && isInteger(type2);
20: }
21:
/**
* 检查类型是否一个实数,即计算机里面的浮点数
* @param type 被检查类型
* @return true/false
*/
static boolean isReal(TypeSpec type)
28: {
return (type != null) && (type.baseType() == Predefined.realType);
30: }
31:
/**
* 检查类型是否是整数或者实数,也就是一个实数系内的数
* @param type 被检查类型
* @return true/false
*/
static boolean isIntegerOrReal(TypeSpec type)
38: {
return isInteger(type) || isReal(type);
40: }
41:
/**
* 检查两个类型中至少有一个是实数,这个即计算机里面的数系扩大。比如INT+DOUBLE=DOUBLE
* @param type1 第一个被检查类型
* @param type2 第二个被检查类型
* @return true/false
*/
static boolean isAtLeastOneReal(TypeSpec type1, TypeSpec type2)
49: {
return (isReal(type1) && isReal(type2)) ||
51: (isReal(type1) && isInteger(type2)) ||
52: (isInteger(type1) && isReal(type2));
53: }
54:
/**
* 检查类型是否布尔类型
* @param type 被检查类型
* @return true/false
*/
static boolean isBoolean(TypeSpec type)
61: {
return (type != null) && (type.baseType() == Predefined.booleanType);
63: }
64:
/**
* 检查参加布尔二元运算如&&,|| 的两个类型是否都是布尔数。
* @param type1 第一个被检查类型
* @param type2 第二个被检查类型
* @return true/false
*/
static boolean areBothBoolean(TypeSpec type1, TypeSpec type2)
72: {
return isBoolean(type1) && isBoolean(type2);
74: }
75:
/**
* 检查类型是否一个字符类型
* @param type 被检查类型
* @return true/false
*/
static boolean isChar(TypeSpec type)
82: {
return (type != null) && (type.baseType() == Predefined.charType);
84: }