现在的位置: 首页 > 综合 > 正文

(基于Java)编写编译器和解释器-第10章:类型检查-第一部分

2012年02月29日 ⁄ 综合 ⁄ 共 2777字 ⁄ 字号 评论关闭

在本章,你将会包含类型检查,完成第9张工作。如今你可以把Pascal变量申明为各种类型,你必须确保当这些变量出现在语句中的时候,它们的类型必须与它们的操作符兼容。如第1章所说的那样,语法检查是语义分析的一部分。

==>> 本章中文版源代码下载:svn co http://wci.googlecode.com/svn/branches/ch10/ 源代码使用了UTF-8编码,下载到本地请修改!

方法和目标

本章的目标是在前端集成类型检查。方法是将类型检查加到语句解析器中,以便在解析语句过程中可以用到。针对第5章开发的语法检查器搞了个新的版本,用来验证你的成果。

类型检查

让我们从intermediate.typeimpl包中的TypeChecker类开始。这个类附带的静态方法实现了类型兼容规则,可以被语句解析器用来执行语法检查。清单10-1 展示了检查具体类型的各种方法。

   1: /**

   2:  * 检查类型是否一个整数

   3:  * @param type 被检查类型说明

   4:  * @return true/false

   5:  */

   6: public static boolean isInteger(TypeSpec type)

   7: {

   8:     return (type != null) && (type.baseType() == Predefined.integerType);

   9: }

  10:  

  11: /**

  12:  *  检查二元操作符的两个类型都是否是整数

  13:  * @param type1 第一个被检查的类型

  14:  * @param type2 第二个被检查的类型

  15:  * @return true/false

  16:  */

  17: public static boolean areBothInteger(TypeSpec type1, TypeSpec type2)

  18: {

  19:     return isInteger(type1) && isInteger(type2);

  20: }

  21:  

  22: /**

  23:  * 检查类型是否一个实数,即计算机里面的浮点数

  24:  * @param type 被检查类型

  25:  * @return true/false

  26:  */

  27: public static boolean isReal(TypeSpec type)

  28: {

  29:     return (type != null) && (type.baseType() == Predefined.realType);

  30: }

  31:  

  32: /**

  33:  * 检查类型是否是整数或者实数,也就是一个实数系内的数

  34:  * @param type 被检查类型

  35:  * @return true/false

  36:  */

  37: public static boolean isIntegerOrReal(TypeSpec type)

  38: {

  39:     return isInteger(type) || isReal(type);

  40: }

  41:  

  42: /**

  43:  * 检查两个类型中至少有一个是实数,这个即计算机里面的数系扩大。比如INT+DOUBLE=DOUBLE

  44:  * @param type1 第一个被检查类型

  45:  * @param type2 第二个被检查类型

  46:  * @return true/false

  47:  */

  48: public static boolean isAtLeastOneReal(TypeSpec type1, TypeSpec type2)

  49: {

  50:     return (isReal(type1) && isReal(type2)) ||

  51:            (isReal(type1) && isInteger(type2)) ||

  52:            (isInteger(type1) && isReal(type2));

  53: }

  54:  

  55: /**

  56:  * 检查类型是否布尔类型

  57:  * @param type 被检查类型

  58:  * @return true/false

  59:  */

  60: public static boolean isBoolean(TypeSpec type)

  61: {

  62:     return (type != null) && (type.baseType() == Predefined.booleanType);

  63: }

  64:  

  65: /**

  66:  * 检查参加布尔二元运算如&&,|| 的两个类型是否都是布尔数。

  67:  * @param type1 第一个被检查类型

  68:  * @param type2 第二个被检查类型

  69:  * @return true/false

  70:  */

  71: public static boolean areBothBoolean(TypeSpec type1, TypeSpec type2)

  72: {

  73:     return isBoolean(type1) && isBoolean(type2);

  74: }

  75:  

  76: /**

  77:  * 检查类型是否一个字符类型

  78:  * @param type 被检查类型

  79:  * @return true/false

  80:  */

  81: public static boolean isChar(TypeSpec type)

  82: {

  83:     return (type != null) && (type.baseType() == Predefined.charType);

  84: }

清单10-2 展示了TypeChecker类中的两个兼容方法

   1: /**

   2:  * 检查赋值两端的类型是否兼容,即左值是否能被右值兼容

   3:  * @param targetType 左值类型

   4:  * @param valueType 右值类型

   5:  * @return true可以赋值/false不能赋值

   6:  */

   7: public static boolean areAssignmentCompatible(TypeSpec targetType,

   8:                                               TypeSpec valueType)

   9: {

  10:     if ((targetType == null) || (valueType == null)) {

  11:         return false;

  12:     }

  13:  

  14:     targetType = targetType.baseType();

  15:     valueType  = valueType.baseType();

  16:  

  17:     boolean compatible = false;

  18:  

  19:     // 类型一样,ok

  20:     if (targetType == valueType) {

  21:         compatible = true;

  22:     }

  23:  

  24:     // 左实数,右整数,ok

  25:     else if (isReal(targetType) && isInteger(valueType)) {

  26:         compatible = true;

  27:     }

  28:  

  29:     // 字符串对字符串,赋值没问题

  30:     else {

  31:         compatible =

  32:             targetType.isPascalString() && valueType.isPascalString();

  33:     }

  34:  

  35:     return compatible;

  36: }

  37:  

抱歉!评论已关闭.