zoukankan      html  css  js  c++  java
  • 《Language Implementation Patterns》之 强类型规则

    语句的语义取决于其语法结构和相关符号;前者说明了了要“做什么”,后者说明了操作“什么对象”。所以即使语法结构正确的,如果被操作的对象不合法,语句也是不合法的。语言一般有很多语义规则,有些是运行时的(dynamic semantics),比如“不能除以零”、“不能越界访问数组”;有些是编译时的(static semantics)。运行时&编译时的界限取决于具体的语言,python是动态类型的语言,所有的值编译时都不会指定类型,解释器在运行时检查类型和执行语义规则;C++则是另一个极端,所有的值必须有静态的类型,运行时不做检查;java既有静态类型检查,又在运行时检查类型。无论动态的或静态的类型检查,只要能阻止不相容的类型操作,语言就是“类型安全”的。

    本章讲述了如何实施静态类型规则,将会讨论一下几种模式:

    • Pattern 20 Computing Static Expression Types,保证类型安全的第一步是计算表达式的类型;
    • Pattern 21 Automatic Type Promotion, 将操作数的类型提升至相同或相容的类型;
    • Pattern 22 Enforcing Static Type Safety,检查类型相容性,保证类型安全;
    • Pattern 23 Enforcing Polymorphic Type Safety, 面向对象类型语言里面的对象类型相容,多态的引用类型;
      下面分别讲述这些模式,以类c语言的规则为样例。

    Pattern 20 Computing Static Expression Types

    展示了在显示声明类型的语言,比如C,如何计算表达式的类型
    下面的表格说明了类型计算规则。

    SubexpressionResult Type
    true,falseboolean
    !«expr »boolean
    f(«args»)函数f的返回类型
    «expr» bop «expr»bop代表二元运算符,因为两侧的操作数的类型是一致的,所以可以选取左侧操作数的类型为表达式类型
    «expr» relop «expr»boolean,relop是代表关系操作符

    实现
    假设我们已经构建了AST,和scope tree,进行类型计算就是另一轮AST遍历,可以通过Tree Pattern Matcher技术来寻找表达式节点并计算类型。
    具体的实现代码请参考原书。

    Pattern 21 Automatic Type Promotion

    描述了如何自动、安全地提升数学运算操作数的类型
    类型提升将单个运算符的所有操作数提升至相同类型或相容类型,这本质上是CPU对操作数的要求。编程语言能够自动地转换类型,只要“转换“不丢失信息;比如4可以安全地转换成4.0,而4.5不能转换成4;这种安全的类型转换被称之为”类型提升”,因为它拓宽了类型。
    这里有一个简单的方式描述类型提升规则;首先将类型按最“窄”到最“宽”进行排序,然后如果i&ltj,我们可以进行从TYPEi到TYPEj的提升。

    为了实现类型提升,需要两个函数,第一个是根据运算符和运算数类型返回结果类型;第二个从运算符和目标类型判断是否需要对操作数执行类型提升。

    resultType(type1, op, type2)
    resultType(char, "<", int) == boolean
    resultType(char, "+", int) == int
    resultType(boolean, "<", boolean) == void
    
    promoteFromTo(type, op, destination-type)
    promoteFromTo(char, "+", int) == int
    promoteFromTo(int, "+", int) == null
    

    结果void意味着该表达式不合法,null意味着不需要类型转换。按这个规则,表达式’a’+3+4.2的类型提升可以表示为(float)((int)’a’+3)+4.2,AST如图:

    每个节点都知道自己的求值类型,提升类型。
    具体的java实现代码,请参考原书。

    Pattern 22 Enforcing Static Type Safety

    通过静态检查,发现表达式或语句里面类型不相容的类型
    概括起来,类型相容包含两个方面:

    • 对操作数类型,操作符是有定义的,即resultType(operandtype1, op, operandtype2) != void;
    • 如果我们需要一个类型T的值,那么提供的值必须是T或可以被提升为T。

    在Pattern 21的基础上增加类型检查不是困难,只要出现void都意味着类型不相容;对于点操作符,函数调用,return语句等需要特殊处理。
    具体的实现代码,请参考原书。

    Pattern 23 Enforcing Polymorphic Type Safety

    检查对象引用赋值的类型相容性
    对象类型引用赋值的相容性判断如下:

    public class PointerType extends Symbol implements Type {
        public boolean canAssignTo(Type destType) {
            // if not a pointer, return false
            if ( !(destType instanceof PointerType) ) return false;
            // What type is the target pointing at?
            Type destTargetType = ((PointerType)destType).targetType;
            Type srcTargetType = this.targetType;
            // if this and target are object pointers, check polymorphism
            if ( destTargetType instanceof ClassSymbol &&
                 this.targetType instanceof ClassSymbol )
            {
                ClassSymbol thisClass   = (ClassSymbol)srcTargetType;
                ClassSymbol targetClass = (ClassSymbol)destTargetType;
                // Finally!  Here it is: the polymorphic type check :)
                return thisClass.isInstanceof(targetClass);
            }
            // not comparing object pointers; types we point at must be the same
            // For example: int *p; int *q; p = q;
            return srcTargetType == destTargetType;
        }
    }
    /** Return true if 'ancestor' is this class or above in hierarchy */
    public boolean isInstanceof(ClassSymbol ancestor) { 
        ClassSymbol t = this;
        while ( t!=null ) {
            if ( t == ancestor ) return true;
            t = t.superClass;
        }
        return false; 
    }
    
  • 相关阅读:
    CSS揭秘三(形状)
    CSS揭秘(二背景与边框)
    js数组去重
    Iterator
    ES6数据结构set
    JS浏览器对象(BOM)
    JS 数据类型转换
    js的cookie,localStorage,sessionStorage
    (html+css)云道首页
    蓝桥杯-基础练习 01字串-C语言-5层循环法
  • 原文地址:https://www.cnblogs.com/longhuihu/p/4006521.html
Copyright © 2011-2022 走看看