类型表达式
? 类型的等价性
按名等价,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)
? 类型的等价性
按名等价,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)