编译原理 类型检查.ppt

求任何类型列表长度的ML程序 fun length(lptr) = if null(lptr) then 0 else length(tl(lptr)) + 1; 可应用于任何类型的列表 length([“sun”, “mon”, “tue”]); length([10, 9, 8]); 递归函数 列表为空? 列表剩余部分 * PPT课件 6.6.2 类型变量 a, b, …,表示未知类型 重要应用:不要求标识符先声明后使用的语言中,检查标识符使用的一致性 类型变量表示未声明标识符的类型 若类型变量发生变化,不一致! 若一直未变化,一致!同时得到标识符类型 类型推断,type inference 根据语言结构的使用方式判定其类型 * PPT课件 例6.8 type link = ^cell; procedure mlist(lptr : link; procedure p); begin while lptr nil do begin p(lptr); lptr := lptr^.next end end; p:参数情况未知,不完整的过程类型 由p(lptr)? p参数为link类型,p的类型为link?void 其他使用方式均会导致type_error * PPT课件 例6.9 function deref(p); begin return p^; end; 扫描第一行,p的类型未知,用b表示 第三行,^应作用于指针,因此p为某未知基本类型a的指针类型,b=pointer(a) 因此函数deref类型为:pointer(a)?a * PPT课件 6.6.3 包含多态函数的语言 用 表示“对所有类型” deref类型的精确描述: length: list(integer)?integer list(list(char))?integer :全称量词(universal quantifier)? 它所施用的类型变量称为由它约束(bound) * PPT课件 文法定义 P ? D ; E D ? D ; D | id : Q Q ? type_varible . Q | T T ? T ‘?’ T | T × T | unary_constructor ( T ) | basic_type | type_varible | ( T ) E ? E (E) | E , E | id 程序例: deref : q : pointer(pointer(integer)); deref(deref(q)) * PPT课件 多态函数类型检查 每个结点两个标签:子表达式和类型表达式 下标o:外层deref,i:内存deref * PPT课件 类型检查规则的特点 不同位置出现的同一多态函数可具有不同类型的参数。 derefo参数为二重指针,而derefi的参数为一重指针。 关键在于 的解释,对不同deref,约束的类型变量a所代表的意义是不同的。 对多态函数的每次出现,都赋予不同的类型变量,而不再使用 ——上例中用ao、ai分别对应外层和内层deref * PPT课件 类型检查规则的特点(二) 类型表达式中存在变量,因此要重新考虑类型等价的概念 类型为s?s’的函数E1施用于类型为t的E2,仅判定s和t是否等价是不够的,要对它们进行“一致化”(unify) 适当替换类型变量,检查是否有可能达到结构等价 上例:将ai替换为pointer(integer),则 pointer(ai)与pointer(pointer( integer))等价 * PPT课件 类型检查规则的特点(三) 需要某种机制记录一致化的影响 一个类型变量可出现在表达式的多个位置 若s和s’的一致化使得变量a表示类型t,则在整个类型表达式中,它都应表示t 上例: ai作用域为derefi(q),因此可用来一致化derefi和q 而ao为不同类型变量,因此表示不同类型不违反本规则 * PPT课件 回路问题(续) 将递归定义的类型名替换为类型表达式,类型图中会产生回路 * PPT课件 例6.4 C语言避免回路 对除记录之外的类型使用结构等价 struct cell { int info; struct cell *next; }; C语言要求类型名在使用前声明 例外:未定义记录类型的指针 回路:只可能是记录指针引起 结构等价判定遇到记录类型停止:只有名字相同的记录才认为类型相同 * PPT课件 6.4 类型转换 x+i,x为实型,i为整型 不同保存格式,不同加法指令 转换为相同类型进行运算 语言定义指定转换方法 赋值:转换为左部类型 表达式:int?real 类

文档评论(0)

1亿VIP精品文档

相关文档