语句的语义取决于其语法结构和相关符号;前者说明了了要“做什么”,后者说明了操作“什么对象”。所以即使语法结构正确的,如果被操作的对象不合法,语句也是不合法的。语言一般有很多语义规则,有些是运行时的(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,如何计算表达式的类型

下面的表格说明了类型计算规则。

Subexpression Result Type
true,false boolean
!«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;
}

《Language Implementation Patterns》之 强类型规则的更多相关文章

  1. 《Language Implementation Patterns》之 解释器

    前面讲述了如何验证语句,这章讲述如何构建一个解释器来执行语句,解释器有两种,高级解释器直接执行语句源码或AST这样的中间结构,低级解释器执行执行字节码(更接近机器指令的形式). 高级解释器比较适合DS ...

  2. 《Language Implementation Patterns》之 数据聚合符号表

    本章学习一种新的作用域,叫做数据聚合作用域(data aggregate scope),和其他作用域一样包含符号,并在scope tree里面占据一个位置. 区别在于:作用域之外的代码能够通过一种特殊 ...

  3. 《Language Implementation Patterns》之访问&重写语法树

    每个编程的人都学习过树遍历算法,但是AST的遍历并不是开始想象的那么简单.有几个因素会影响遍历算法:1)是否拥有节点的源码:2)是否子节点的访问方式是统一的:3)ast是homogeneous或het ...

  4. 《Language Implementation Patterns》之 构建语法树

    如果要解释执行或转换一段语言,那么就无法在识别语法规则的同时达到目标,只有那些简单的,比如将wiki markup转换成html的功能,可以通过一遍解析来完成,这种应用叫做 syntax-direct ...

  5. 《Language Implementation Patterns》之 增强解析模式

    上一章节讲述了基本的语言解析模式,LL(k)足以应付大多数的任务,但是对一些复杂的语言仍然显得不足,已付出更多的复杂度.和运行时效率为代价,我们可以得到能力更强的Parser. Pattern 5 : ...

  6. 《Language Implementation Patterns》之 语言翻译器

    语言翻译器可以从一种计算机语言翻译成另外一种语言,比如一种DSL的标量乘法axb翻译成java就变成a*b:如果DSL里面有矩阵运算,就需要翻译成for循环.翻译器需要完全理解输入语言的所有结构,并选 ...

  7. 《Language Implementation Patterns》之 符号表

    前面的章节我们学会了如何解析语言.构建AST,如何访问重写AST,有了这些基础,我们可以开始进行"语义分析"了. 在分析语义的一个基本方面是要追踪"符号",符号 ...

  8. Saga的实现模式——进化(Saga implementation patterns – variations)

    在之前的几个博客中,我主要讲了两个saga的实现模式: 基于command的控制者模式 基于事件的观察者模式 当然,这些都不是实现saga的唯一方式.我们甚至可以将这些结合起来. 发布者——收集者 回 ...

  9. Saga的实现模式——观察者(Saga implementation patterns – Observer)

    https://lostechies.com/jimmybogard/2013/03/11/saga-implementation-patterns-observer/ 侵删. NServiceBus ...

随机推荐

  1. CSS3动画以及animation事件

    1.CSS3动画以及animation事件的定义 animation :name duration timing-function delay iteration-count direction an ...

  2. 关于CI框架访问数据库类提示Call to undefined function mysqli_init()

    大家好,我曾经是ASP.NET MVC的践行者,现在是PHP,同时也是CodeIgniter框架的初学者和践行者,当时由于项目原因,我被迫给自己打满鸡血,满怀激情的选用Yii2,Lavarel5,Co ...

  3. 伯克利推出世界最快的KVS数据库Anna:秒杀Redis和Cassandra

    天下武功,唯快不破. 伯克利 RISE 实验室推出了最新的键值存储数据库 Anna,提供了惊人的存取速度.超强的伸缩性和史无前例的一致性保证.Jeff Dean 说,当一个系统增长到十倍规模时,就需要 ...

  4. Windows Live Writer 2014版绿色版制作及主题获取

    前年才建好博客的时候就尝试用Windows Live Writer(WLW)写博客,用的是直接在网上找到的一个WLW 2009绿色美化版.但因为当时WLW获取的博客主题是主页的,预览的时候特别不爽,就 ...

  5. 简单的同步Socket程序服务端

    首先,Socket是.Net提供的 System.Net.Sockets命名空间的Scoket类为网络通信提供了一套丰富的方法和属性 服务器按照Socket的基本流程 先创建Socket 在用Bind ...

  6. Spring MVC注解式开发

    MVC注解式开发即处理器基于注解的类开发, 对于每一个定义的处理器, 无需在xml中注册. 只需在代码中通过对类与方法的注解, 即可完成注册. 定义处理器 @Controller: 当前类为处理器 @ ...

  7. python web开发-flask读取txt文件内容

    某些情况下,需要读取flask网站要目录下的txt文件.但是直接在flask网站的目录下创建一个文件是无法访问的.从网站找了一些资料,最终发现通过写一个方法返回txt内容比较简单方便,不过此方法适用于 ...

  8. ajax利用FormData异步文件提交

    通常情况下,我们上传文件都会使用form表单来提交文件.但有时候,我们会有异步提交文件的需求,在这种情况下,我们就需要新建一个Formdata来提交文件,后台如果使用的是PHP的话可以使用$_FILE ...

  9. poj-1005-l tanink i need a houseboat

    Description Fred Mapper is considering purchasing some land in Louisiana to build his house on. In t ...

  10. VMware 下快速克隆出多个 Linux 环境

    念念不忘,必有回响 好好工作,好好吃饭,困了倒头就睡:吃你认为好吃的,吃到饱:买贵的,你想买的:去玩去野: 就这样. 为什么要克隆多个 Linux 系统? 因为要玩阿. 其实也不是了,就是为了折腾嘛, ...