《《语义分析中》PPT课件.ppt》由会员分享,可在线阅读,更多相关《《语义分析中》PPT课件.ppt(19页珍藏版)》请在三一办公上搜索。
1、第05章 语义分析,主要内容:语义分析基础 符号表 类型分析 声明和执行体的语义分析,5.3 类型分析,5.3.1 类型的等价性和相容性类型的等价性 1)按名等价:type tp=array1.10of integer;var a,b:tp;则称a,b是相同类型的变量 2)结构等价:type tp1=array1.10of integer;type tp2=array1.10of integer;var a:tp1;b:tp2;则称a,b是相同类型的变量,类型的相容性:主要有:1)运算分量类型的相容性;2)赋值语句左右类型的相容性;3)形参和实参类型的相容性;类型分析的作用:构造类型的内部表示
2、,进行类型检查。分析过程:读Token序列,识别出各种类型,类型检查,返回类型内部表示的地址。,5.3.2 类型分析的总控算法,功能:类型检查,Ptr返回类型的内部表示地址。Void TypeProcess(Ptr)switch(token.class)case ID:NameTYPE(Ptr);break;/类型名 case ENUM:EnumTYPE(Ptr);break;/枚举类 case ARRAY:ArrayTYPE(Ptr);break;/数组类 case RECORD:RecordTYPE(Ptr,0,null);break/记录类 case UNION:UnionTYPE(Pt
3、r,0,null);break;/联合类 case POINTER:PointerTYPE(Ptr);break;/指针类 default:error();next_token();return;,5.3.3 类型名分析,形式:id/*类型标识符*/处理子程序:void NameType(Ptr)FindEntry(token.seman,total,Entry,Present);/查符号表 if(Present=flase)error;/无声明错 if(Entrykind)!=typeKind error;/非类型标识符 Ptr=Entry idType;,如:VAR id:t;,5.3.4
4、 枚举类型分析,形式:(id1,idn)分析任务:1)扫描及检查枚举类型的语义错误;2)构造该类型的内部表示,用Ptr指针指向它;3)构造枚举常量标识符的符号表项。,例:设枚举类型(a,b),则首先产生枚举类型的内部表示,其中EntryList表示一个指针,指向枚举表。,其次,在符号表区里为常量a和b构造相应表项如下:,处理子程序:void EnumType(Ptr)list=nil;L0:next_token();/读表的下一个元素 Link(list,token.seman);/连接到内部枚举表 next_token();if(token.class=“,”)goto L0;Ptr:=(e
5、numSize,enumTy,List);/生成枚举类型的内部表示,m=0;L1:name=first(List);/取List的首元素 List=tail(List);/去掉List的首元素 Enter(name,(Ptr,constKind,m),entry,present);/建立符号表项 if(present)error();m=m+1;if(List!=“nil”)goto L1;,如:(a,b)的符号表EntryList:,5.3.5 数组类型分析,形式:arrayc1.c2 of T 算法要点:扫描C1时把其值计算到Low中;扫描C2时把其值计算到Up中;扫描T时构造出其内部结点
6、(由ElemPtr指向);构造数组结点:Ptr:=(size,arrayTy,Low,Up,ElemPtr),实现算法:,void ArrayType(Ptr)/array C1.C2 of T next_token();/读“”next_token();Low=token.seman;/处理下标 next_token();/读“.”next_token();Up=token.seman;/处理上标 next_token();next_token();/读“of”if(LowUp)errorTy;new(ElemPtr);next_token();TypeProcess(EelemPtr);/
7、处理元素类型 Sizes:=(Up-Low+1)(*ElemPtr.Size);/求本类型长度 Ptr:=(size,arrayTy,Low,Up,ElemPtr);/生成数组类型的内部表示,5.3.6 记录类型分析,形式:record id1:Type1;idn:Typen end 分析任务:扫描记录类型部分,检查其语义错误;Ptr:=(RecordSize,recordTy,RBody);其中RBody指向域表,域表元素是四元组(域名,类型,偏移量,Next);,域偏移量:1)初始:off:=0;2)固定体:id:T Offset(id):=off;off:=off+size(T);3)计
8、算记录大小:RecordSize:=off;,例:RT=record a:array0.9 of integer;r:record b:boolean;u:real end;m:integer end,分析算法:,Void RecordType(TYPE Ptr,int off,FIELDS RBody);L:new(FTPtr);/生成域类型结点地址 next_token();/读域名id next_token();/读“:”next_token();TypeProcess(FTPtr);/构造域类型 Off=Off+FTPtr.Size;/修改off FieldNode=(token.se
9、man,FTPtr,Off,nil);/构造域的内部结点 LinkField(RBody,FieldNode);/链表 if(token.class=“;”)goto L;/处理下一个域 Ptr=(off,recordTy,RBody);/构造记录结点,5.3.7 联合类型分析,形式:union id1:Type1;idn:Typen end 分析任务:扫描联合类型部分,检查其语义错误;Ptr:=(UnionSize,unionTy,unionBody);其中UnionBody指向域表,域表元素是三元组(域名,类型,Next);域偏移量:每个域的偏移量均为0;联合体空间:联合域共享空间,其大小
10、由最大域空间确定。,分析算法:,Void UnionType(TYPE Ptr,int off,FIELDS UBody);L:new(FTPtr);/生成域类型结点地址 next_token();/读域名id next_token();/读“:”next_token();TypeProcess(FTPtr);/构造域类型 FieldNode=(token.seman,FTPtr,nil);/构造域的内部结点 LinkField(RBody,FieldNode);/链表 MFS=MAXMFS,FTPtr.Size;/修改MFS if(token.class=“;”)goto L;/处理下一个域
11、 Ptr=(MFS,unionTy,UBody);/构造联合结点,5.3.8 指针类型分析,语法形式:Type pointer T;变量说明:var x:pointer T;相当于C的 T*x;分析任务:扫描指针类型部分,并检查其语义错误;Ptr:=(PoinSize,PoinTy,Ptr0),其中Ptr0指向指针基类型。,实现算法:,void PointerTYPE(Ptr)new(Ptr0);next_token();/读基类型T TypeProcess(Ptr0);/分析基类型T Ptr:=(PoinSize,PoinTy,Ptr0);/生成指针,5.3.9 递归类型分析,类型定义:type tid=tid;焦点问题:由于类型定义tid中有对自己的引用,所以分析类型tid时无法查到标识符tid;递归示例:二叉树的定义:type tree=record elem:integer;left:pointer tree;right:pointer tree end,内部表示:,
链接地址:https://www.31ppt.com/p-5606376.html