150 likes | 261 Views
类型表达式. 类型的等价性 按名等价: type tp=array[1..10]of integer; var a,b:tp; 则称 a,b 是相同类型的变量 结构等价: type tp1=array[1..10]of integer type tp2=array[1..10]of integer; var a:tp1; b:tp2; 则称 a,b 是相同类型的变量 类型的相容性. 类型相容性. 运算分量类型的相容性; 赋值语句左右类型的相容性; 形参和实参类型的相容性;. 类型相容:
E N D
类型表达式 • 类型的等价性 按名等价:type tp=array[1..10]of integer; var a,b:tp; 则称a,b是相同类型的变量 结构等价:type tp1=array[1..10]of integer type tp2=array[1..10]of integer; var a:tp1; b:tp2; 则称a,b是相同类型的变量 • 类型的相容性
类型相容性 • 运算分量类型的相容性; • 赋值语句左右类型的相容性; • 形参和实参类型的相容性; • 类型相容: • 类型等价则相容 • 整型或整型子界类型与整型、实型相容 • 两个子界类型定义的范围相包含则相容 • 对结构类型,如果同一结构,且子类型 • 相容则相容
类型的分析 • 作用:构造类型的内部表示,类型检查。 • 分析过程:读Token序列,识别出各种类型,类型检查,返回类型内部表示的地址。 array [ 1 .. 10 ] of integer arrKind … low=1 tp1=intPtr … up=10 tp2=intPtr IndexPtr= (1,subTy, intPtr ,1 ,10) … … ElemPtr=intPtr size=(up-low+1) * sizeof (int) aPtr := ( size, arrTy, IndexPtr, ElemPtr )
类型出现的位置: 类型定义 TYPE id = t; 变量声明 VAR id : t; 过/函声明 Proce/Func P(A1:t1,…)(:t) • 类型的种类: name,subrange,enum,array,record,set, file,pointer…… • 类型分析模块: 类型检查,返回类型的内部表示地址Ptr和 Forward
NameType • 形式:id (类型标识符) • 处理思想: 查符号表 无声明错 typekind ? TypePtr 为Ptr的值 Forward:=0
EnumType • 形式:(a1,… ,an) • 处理思想: 生成a1,…an的符号表EntryList: (ai,Ptr,consKind,i),Ptr需回填 生成内部表示: Ptr:=★(enumSize,enumTy,EntryList,n) 回填EntryList中的Ptr值 Forward:=0
SubRangeType • 形式:C1..C2 • 处理思想: 从C1求出其内部类型地址Ptr1和值N1; 从C2求出其内部类型地址Ptr2和值N2; 检查Ptr1=Ptr2,N1 N2; Ptr:=★(subSize,subTy,Ptr1,N1,N2) Forward := 0
ArrayType • 形式:array T0 of T1 • 处理思想: 返回T0,T1的内部表示地址IndexPtr,ElemPtr 判定IndexPtr是否为下标类型 计算size = (IndexPtr↑. Up- IndexPtr↑. Low +1) (ElemPtr↑. Size); Ptr:=★(size,arrayTy,IndexPtr,ElemPtr)
SetType • 形式:set of T • 处理思想: 返回T的内部表示地址BasePtr; 检查BasePtr 是否为有序类型; Ptr:=★(setSize,setTy,BasePtr)
FileType • 形式:file of T • 处理思想: 返回T的内部表示地址compPtr; Ptr:=★(fileSize,fileTy,CompPtr) 返回地址Ptr。
PointerType • 形式:↑Q • 处理思想: 由Q查表,若找到并且Q为类型标识符,其内 部表示指针返回给QEntry,并且令 Forward := 0; 否则QEntry等待回填,令Forward:=QEntry; Ptr:= ★(PoinSize,PoinTy,QEntry);
RecordType • 形式:record 不变体;变体 end • 处理思想: 构造不变体部分内部表示返回地址fixBodyPtr 构造变体部分内部表示返回地址variBodyPtr 计算记录类型长度RecordSize Ptr:=★(Size,recordTy,fixBodyPtr,variBodyPtr)
Offset 原理 • 初始:off := 0; • 不变体:id:T Offset(id):= off; off:= off + size(T) ; • 变体:case u:Tu of Ci: RecBodyi ; Offset(u):= off; off:=off + size(Tu) ; Offset(RecBodyi)=off; offi:=off + sizeof(RecBodyi) off := Max(offi) • RecordSize := off;
FixBody • 形式:FixUnit {; FixBody} FixUnit = id : Type • 处理思想: 构造FixUnit的内部表示结点fixU: fixU := ★(name,tp,off,nil) 如果FixBody部分为空,则fixB := fixU; 否则 重复上述过程构造FixBody部分的内部表 示fixB。 fixB := Link(fixU,fixB);
VariBody • 形式:CaseUnit VariUnits • 处理思想: 构造CaseUnit的内部表示caseU: caseU := ★(name, tp, off); 构造VariUnits的内部表示variUS: variU := ★(c,fixB,variB,nil); variUS:= ★Link(variU,variUS) 变体部分的内部表示variB: variB := ★(caseU, variUS)