《语义分析与中间代码生成课件.ppt》由会员分享,可在线阅读,更多相关《语义分析与中间代码生成课件.ppt(126页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、语义分析与中间代码生成第1页,此课件共126页哦2023/4/112第6章语义分析与中间代码生成6.1 中间代码的形式中间代码的形式6.2 声明语句的翻译声明语句的翻译6.3 赋值语句的翻译赋值语句的翻译6.4 类型检查类型检查6.5 控制结构的翻译控制结构的翻译6.6 回填回填6.7 switch语句的翻译语句的翻译6.8 过程调用和返回语句的翻译过程调用和返回语句的翻译6.9 输入输出语句的翻译输入输出语句的翻译6.10 本章小结本章小结第2页,此课件共126页哦2023/4/1136.1 中间代码的形式中间代码的作用中间代码的作用过渡:经过语义分析被译成中间代码序列过渡:经过语义分析被译
2、成中间代码序列中间代码的形式中间代码的形式中间语言的语句中间语言的语句中间代码的优点中间代码的优点形式简单、语义明确、独立于目标语言形式简单、语义明确、独立于目标语言便于编译系统的实现、移植、代码优化便于编译系统的实现、移植、代码优化常用的中间代码常用的中间代码语法树语法树(6.3.5节节)逆波兰表示、三地址码逆波兰表示、三地址码(三元式和四元式三元式和四元式)、DAG图表示图表示第3页,此课件共126页哦2023/4/1146.1.1 逆波兰表示中缀表达式的计算顺序不是运算符出现的自中缀表达式的计算顺序不是运算符出现的自然顺序,而是根据运算符间的优先关系来确然顺序,而是根据运算符间的优先关系
3、来确定的,因此,从中缀表达式直接生成目标代定的,因此,从中缀表达式直接生成目标代码一般比较麻烦。码一般比较麻烦。波兰逻辑学家波兰逻辑学家J.Lukasiewicz于于1929年提出了年提出了后缀表示法,其优点为:表达式的运算顺序后缀表示法,其优点为:表达式的运算顺序就是运算符出现的顺序,它不需要使用括号就是运算符出现的顺序,它不需要使用括号来指示运算顺序。来指示运算顺序。第4页,此课件共126页哦2023/4/1156.1.1 逆波兰表示例例6.1 下面给出的是一些表达式的中缀、前缀下面给出的是一些表达式的中缀、前缀和后缀表示。和后缀表示。中缀表示中缀表示前缀表示前缀表示 后缀表示后缀表示a+
4、b+abab+a*(b+c)*a+bc abc+*(a+b)*(c+d)*+ab+cd ab+cd+*a:=a*b+c*d:=a+*ab*cd abc*bd*+:=第5页,此课件共126页哦2023/4/1166.1.2 三地址码所谓三地址码,是指这种代码的每条指令最多所谓三地址码,是指这种代码的每条指令最多只能包含三个地址,即两个操作数地址和一个只能包含三个地址,即两个操作数地址和一个结果地址。结果地址。如如x+y*z三地址码为:三地址码为:t1:=y*z t2:=x+t1三地址码中地址的形式:三地址码中地址的形式:名字、常量、编译器生成的临时变量。名字、常量、编译器生成的临时变量。第6页,
5、此课件共126页哦2023/4/1176.1.2 三地址码例例6.2 赋值语句赋值语句a:=(-b)*(c+d)-(c+d)的三地址码的三地址码如图如图6.1所示所示 t1:=minus bt2:=c+dt3:=t1*t2t4:=c+dt5:=t3-t4a:=t5图图6.1 a:=(-b)*(c+d)-(c+d)的三地址码的三地址码第7页,此课件共126页哦2023/4/1186.1.2 三地址码1形如形如x:=y op z的赋值指令;的赋值指令;2形如形如x:=op y的赋值指令;的赋值指令;3形如形如 x:=y的复制指令;的复制指令;4无条件跳转指令无条件跳转指令goto L;5形如形如
6、if x goto L(或或if false x goto L)的条件跳转指令;的条件跳转指令;6形如形如if x relop y goto L的条件跳转指令;的条件跳转指令;6.过程调用和返回使用如下的指令来实现:过程调用和返回使用如下的指令来实现:param x用来指明参数;用来指明参数;call p,n和和y=call p,n用来表示过程调用和函数调用;用来表示过程调用和函数调用;return y表示过程返回;表示过程返回;8形如形如x:=yi和和xi:=y的变址复制指令;的变址复制指令;9形如形如x:=&y、x:=*y和和*x:=y的地址和指针赋值指令。的地址和指针赋值指令。第8页,此
7、课件共126页哦2023/4/119四元式四元式是一种比较常用的中间代码形式,它由四个域组成,分四元式是一种比较常用的中间代码形式,它由四个域组成,分别称为别称为op、arg1、arg2和和result。op是一个一元或二元运是一个一元或二元运算符,算符,arg1和和arg2分别是分别是op的两个运算对象,它们可以是的两个运算对象,它们可以是变量、常量或编译器生成的临时变量,运算结果则放入变量、常量或编译器生成的临时变量,运算结果则放入result中。中。图图6.2(a)图图6.1中三地址码的四元式表示中三地址码的四元式表示第9页,此课件共126页哦2023/4/1110三元式为了节省临时变量
8、的开销,有时也可以使用只有三个域的三元式来表示三为了节省临时变量的开销,有时也可以使用只有三个域的三元式来表示三地址码。三元式的三个域分别称为地址码。三元式的三个域分别称为op,arg1和和arg2,op,arg1和和arg2的的含义与四元式类似,区别只是含义与四元式类似,区别只是arg1和和arg2可以是某个三元式的编号可以是某个三元式的编号(图图6.2(b)中用圆括号括起来的数字中用圆括号括起来的数字),表示用该三元式的运算结果作为,表示用该三元式的运算结果作为运算对象。运算对象。图图6.2(b)图图6.1中三地址码的三元式表示中三地址码的三元式表示第10页,此课件共126页哦2023/4
9、/1111生成三地址码的语法制导定义第11页,此课件共126页哦2023/4/11126.1.3 图表示 类似于表达式的抽象语法树一样,在类似于表达式的抽象语法树一样,在dag(directed acyclic graph)中,每个中,每个节点对应一个运算符,代表表达式的一个子表达式,其子节点则与节点对应一个运算符,代表表达式的一个子表达式,其子节点则与该运算符的运算对象相对应,叶节点对应的是变量或者常量,可以该运算符的运算对象相对应,叶节点对应的是变量或者常量,可以看成是原子运算。看成是原子运算。利用利用dag可以很容易地消除公共子表达式可以很容易地消除公共子表达式例例6.3 表达式表达式a
10、+a*(b-c)-(b-c)/d的的dag如图如图6.5所示。所示。图图6.5 a+a*(b-c)-(b-c)/d的的dag图图第12页,此课件共126页哦2023/4/1113生成dag的语法制导定义产生式产生式语义规则语义规则 E E1+TE.node:=mknode(+,E1.node,T.node)E E1-TE.node:=mknode(-,E1.node,T.node)E TE.node:=T.node T T1*FT.node:=mknode(*,T1.node,F.node)T T1/FT.node:=mknode(/,T1.node,F.node)T FT.node:=F.n
11、ode F (E)F.node:=E.node F idF.node:=mkleaf(id,id.entry)F numF.node:=mkleaf(num,num.val)第13页,此课件共126页哦2023/4/11146.2 声明语句的翻译声明语句的作用声明语句的作用为程序中用到的变量或常量名指定类型为程序中用到的变量或常量名指定类型 类型的作用类型的作用 类型检查:类型检查的任务是验证程序运行时的行为是否遵守语言的类型检查:类型检查的任务是验证程序运行时的行为是否遵守语言的类型的规定,也就是是否符合该语言关于类型的相关规则。类型的规定,也就是是否符合该语言关于类型的相关规则。辅助翻译:
12、编译器从名字的类型可以确定该名字在运行时所需要辅助翻译:编译器从名字的类型可以确定该名字在运行时所需要的存储空间。在计算数组引用的地址、加入显式的类型转换、选的存储空间。在计算数组引用的地址、加入显式的类型转换、选择正确版本的算术运算符以及其它一些翻译工作时同样需要用到择正确版本的算术运算符以及其它一些翻译工作时同样需要用到类型信息。类型信息。编译的任务编译的任务在符号表中记录被说明对象的属性在符号表中记录被说明对象的属性(种别、类型、相对地址、作种别、类型、相对地址、作用域用域等等),为执行做准备,为执行做准备第14页,此课件共126页哦2023/4/11156.2.1 类型表达式类型可以具
13、有一定的层次结构,因此用类型类型可以具有一定的层次结构,因此用类型表达式来表示。类型表达式的定义如下:表达式来表示。类型表达式的定义如下:1基本类型是类型表达式。基本类型是类型表达式。典型的基本类型包括典型的基本类型包括boolean、char、integer、real及及void等。等。2类型名是类型表达式。类型名是类型表达式。3将类型构造符将类型构造符array应用于数字和类型表达式所应用于数字和类型表达式所形成的表达式是类型表达式。形成的表达式是类型表达式。如果如果T是类型表达式,那么是类型表达式,那么array(I,T)就是元素类就是元素类型为型为T、下标集为、下标集为I的数组类型表达
14、式。的数组类型表达式。4如果如果T1和和T2是类型表达式,则其笛卡尔乘积是类型表达式,则其笛卡尔乘积T1T2也是类型表达式。也是类型表达式。第15页,此课件共126页哦2023/4/11166.2.1 类型表达式5类型构造符类型构造符record作用于由域名和域类型所形成的作用于由域名和域类型所形成的表达式也是类型表达式。记录表达式也是类型表达式。记录record是一种带有命是一种带有命名域的数据结构,可以用来构成类型表达式。例如,名域的数据结构,可以用来构成类型表达式。例如,下面是一段下面是一段Pascal程序段:程序段:type row=recordaddress:integer;lexe
15、me:array1.15 of charend;var table:array 1.10 of row;该程序段声明了表示下列类型表达式的类型名该程序段声明了表示下列类型表达式的类型名row:record(integerarray(1.15,char)第16页,此课件共126页哦2023/4/11176.2.1 类型表达式6如果如果T是类型表达式,那么是类型表达式,那么pointer(T)也是类型表达也是类型表达式,表示式,表示“指向类型为指向类型为T的对象的指针的对象的指针”。函数的类型可以用类型表达式函数的类型可以用类型表达式DR来表示。考虑如来表示。考虑如下的下的Pascal声明:声明:
16、function f(a,b:char):integer;其定义域类型为其定义域类型为charchar,值域类型为,值域类型为pointer(integer)。所以函数。所以函数f的类型可以表示为如下的类型可以表示为如下的类型表达式:的类型表达式:charcharpointer(integer)7.类型表达式可以包含其值为类型表达式的变量。类型表达式可以包含其值为类型表达式的变量。第17页,此课件共126页哦2023/4/11186.2.2 类型等价许多许多类型检查的规则类型检查的规则都具有如下的形式:都具有如下的形式:if两个类型表达式等价两个类型表达式等价then返回一种特定类型返回一种特
17、定类型else返回返回type_error。如果用图来表示类型表达式,当且仅当下列条件之一成立时,如果用图来表示类型表达式,当且仅当下列条件之一成立时,称两个类型称两个类型T1和和T2是是结构等价结构等价的:的:T1和和T2是相同的基本类型;是相同的基本类型;T1和和T2是将同一类型构造符应用于结构等价的类型上形成的;是将同一类型构造符应用于结构等价的类型上形成的;T1是表示是表示T2的类型名。的类型名。如果将类型名看作只代表它们自己的话,则上述条件如果将类型名看作只代表它们自己的话,则上述条件中的前两个将导致类型表达式的中的前两个将导致类型表达式的名字等价名字等价两个类型表达式名字等价当且仅
18、当它们完全相同两个类型表达式名字等价当且仅当它们完全相同 第18页,此课件共126页哦2023/4/11196.2.3 声明语句的文法 P prog id(input,output)D;SD D;D|List:T|proc id D;SList List1,id|idT integer|real|array C of T1|T1|record DC num C|D 程序说明部分的抽象程序说明部分的抽象S 程序体部分的抽象程序体部分的抽象T 类型的抽象,需要表示成类型表达式类型的抽象,需要表示成类型表达式C 数组下标的抽象数组下标的抽象第19页,此课件共126页哦2023/4/1120语义属性、
19、辅助过程与全局变量的设置文法变量文法变量T(类型类型)的语义属性的语义属性type:类型类型(表达式表达式)width:类型所占用的字节数:类型所占用的字节数辅助子程序辅助子程序enter:将变量的类型和地址填入符号表中:将变量的类型和地址填入符号表中array:数组类型处理子程序:数组类型处理子程序全局变量全局变量offset:已分配空间字节数,用于计算相对地址:已分配空间字节数,用于计算相对地址第20页,此课件共126页哦2023/4/11216.2.4 过程内声明语句的翻译P offset:=0 DDD;DDid:T enter(id.name,T.type,offset);offset
20、:=offset+T.widthTinteger T.type:=integer;T.width:=4Treal T.type:=real;T.width:=8Tarray num of T1 T.type:=array(num.val,T1.type);T.width:=num.val*T1.widthTT1 T.type:=pointer(T1.type);T.width:=4PMDM offset:=0 第21页,此课件共126页哦2023/4/1122例 x:real;i:integer 的翻译enter(x,real,0)offset=0offset=0offset=8offset=
21、8T.type=realT.type=realT.width=8T.width=8offset=12offset=12T.type=integerT.type=integerT.width=4T.width=4enter(i,integer,8)Did:TDid:T enter(id.name,T.type,offset);offset:=offset+T.widthenter(id.name,T.type,offset);offset:=offset+T.width第22页,此课件共126页哦2023/4/1123例 x:real;i:integer 的翻译Poffset:=0Doffset
22、:=0D;Doffset:=0 x:Tenter(x,T.type,offset);offset:=offset+T.width;Doffset:=0 x:realT.type:=real;T.width:=8 enter(x,T.type,offset);offset:=offset+T.width;Dx:real(x,real,0);offset:=8;Dx:real(x,real,0);offset:=8;i:T enter(id.name,T.type,offset);offset:=offset+T.widthx:real(x,real,0);offset:=8;i:integerT
23、.type:=integer;T.width:=4enter(i,T.type,offset);offset:=offset+T.widthx:real(x,real,0);i:integer(i,integer,8);offset:=12第23页,此课件共126页哦2023/4/11246.2.5 嵌套过程中声明语句的翻译所讨论语言的文法所讨论语言的文法P prog id(input,output)D;S D D;D|id:T|proc id D;S 语义动作用到的函数语义动作用到的函数mktable(previous):创建一个新的符号表;:创建一个新的符号表;enter(table,na
24、me,type,offset)addwidth(table,width):符号表的大小;:符号表的大小;enterproc(table,name,newtable)在在table指向的符号表中为指向的符号表中为name建立一个新表项;建立一个新表项;第24页,此课件共126页哦2023/4/1125P prog id(input,output)M D;S addwidth(top(tblptr),top(offset);pop(tblptr);pop(offset)M t:=mktable(nil);push(t,tblptr);push(0,offset)D D1;D2D proc id;N
25、 D1;S t:=top(tblptr);addwidth(t,top(offset);pop(tblptr);pop(offset);enterproc(top(tblptr),id.name,t)Did:T enter(top(tblptr),id.name,T.type,top(offset);top(offset):=top(offset)+T.widthN t:=mktable(top(tblptr);push(t,tblptr);push(0,offset)6.2.5 嵌套过程中声明语句的翻译第25页,此课件共126页哦2023/4/1126program sort(input,o
26、utput);var a:array0.10 of integer;x:integer;procedure readarray;var i:integer;begin aend;procedure exchange(i,j:integer);begin x:=ai;ai:=aj;aj:=x;end;procedure quicksort(m,n:integer);var k,v:integer;function partition(y,z:integer):integer;var i,j:integer;begin a v exchange(i,j)end;begin end;begin en
27、d;例 一个带有嵌套的pascal程序(图6.11)第26页,此课件共126页哦2023/4/1127表表 头头空空sortoffsettblptrtoptop0第27页,此课件共126页哦2023/4/1128表表 头头空空sortoffsettblptrtoptop40a array 0第28页,此课件共126页哦2023/4/1129x integer 40a array 0表表 头头空空sortoffsettblptrtoptop44第29页,此课件共126页哦2023/4/1130表表 头头空空sortreadarrary表表 头头offsettblptrtoptop440a arr
28、ay 0 x integer 40第30页,此课件共126页哦2023/4/1131表表 头头空空sortreadarrary表表 头头 offsettblptrtoptop444a array 0 x integer 40i integer 0第31页,此课件共126页哦2023/4/1132表表 头头空空sortreadarrary表表 头头 4 offsettblptrtoptop44a array 0 x integer 40i integer 0readarray指向指向readarray第32页,此课件共126页哦2023/4/1133表表 头头空空sortreadarrary表表
29、 头头 4 offsettblptr44a array 0 x integer 40i integer 0readarray指向指向readarrayexchange表表 头头toptop0第33页,此课件共126页哦2023/4/1134表表 头头空空sortreadarrary表表 头头 4 offsettblptr44a array 0 x integer 40i integer 0readarray指向指向readarrayexchange表表 头头 0toptopexchange指向指向exchange第34页,此课件共126页哦2023/4/1135表表 头头空空sortreada
30、rrary表表 头头 4 offsettblptr44a array 0 x integer 40i integer 0readarray指向指向readarrayexchange表表 头头 0toptopexchange指向指向exchange表表 头头quicksort0第35页,此课件共126页哦2023/4/1136表表 头头空空sortreadarrary表表 头头 4 offsettblptr44a array 0 x integer 40i integer 0readarray指向指向readarrayexchange表表 头头 0toptopexchange指向指向exchan
31、ge表表 头头quicksort4k integer 0第36页,此课件共126页哦2023/4/1137表表 头头空空sortreadarrary表表 头头 4 offsettblptr44a array 0 x integer 40i integer 0readarray指向指向readarrayexchange表表 头头 0toptopexchange指向指向exchange表表 头头quicksort8k integer 0v integer 4第37页,此课件共126页哦2023/4/1138表表 头头空空sortreadarrary表表 头头 4 offsettblptr44a a
32、rray 0 x integer 40i integer 0readarray指向指向readarrayexchange表表 头头 0toptopexchange指向指向exchange表表 头头quicksort8k integer 0v integer 4表表 头头partition0第38页,此课件共126页哦2023/4/1139表表 头头空空sortreadarrary表表 头头 4 offsettblptr44a array 0 x integer 40i integer 0readarray指向指向readarrayexchange表表 头头 0toptopexchange指向指
33、向exchange表表 头头quicksort8k integer 0v integer 4表表 头头partition4i integer 0第39页,此课件共126页哦2023/4/1140表表 头头空空sortreadarrary表表 头头 4 offsettblptr44a array 0 x integer 40i integer 0readarray指向指向readarrayexchange表表 头头 0toptopexchange指向指向exchange表表 头头quicksort8k integer 0v integer 4表表 头头partition8i integer 0j
34、 integer 4第40页,此课件共126页哦2023/4/1141表表 头头空空sortreadarrary表表 头头 4 offsettblptr44a array 0 x integer 40i integer 0readarray指向指向readarrayexchange表表 头头 0toptopexchange指向指向exchange表表 头头quicksort8k integer 0v integer 4表表 头头 8partitioni integer 0j integer 4partition第41页,此课件共126页哦2023/4/1142表表 头头空空sortreadar
35、rary表表 头头 4 offsettblptr44a array 0 x integer 40i integer 0readarray指向指向readarrayexchange表表 头头 0toptopexchange指向指向exchange表表 头头 8quicksortk integer 0v integer 4表表 头头 8partitioni integer 0j integer 4partitionquicksort第42页,此课件共126页哦2023/4/1143表表 头头 44空空sortreadarrary表表 头头 4 offsettblptra array 0 x int
36、eger 40i integer 0readarray指向指向readarrayexchange表表 头头 0toptopexchange指向指向exchange表表 头头 8quicksortk integer 0v integer 4表表 头头 8partitioni integer 0j integer 4partitionquicksort第43页,此课件共126页哦2023/4/11446.2.6 记录的翻译空间分配空间分配设置首地址和各元素的相对地址设置首地址和各元素的相对地址大于所需的空间大于所需的空间(对齐对齐)例:例:struct Node float x,y;struct
37、node*next;node;048第44页,此课件共126页哦2023/4/11456.2.6 记录的翻译符号表及有关表格处理符号表及有关表格处理为每个记录类型单独构造一张符号表为每个记录类型单独构造一张符号表将域名将域名id的信息的信息(名字、类型、字节数名字、类型、字节数)填入到该填入到该记录的符号表中记录的符号表中所有域都处理完后,所有域都处理完后,offset将保存记录中所有数据将保存记录中所有数据对象的宽度总和对象的宽度总和T.type通过将类型构造器通过将类型构造器record应用于指向该记应用于指向该记录符号表的指针获得录符号表的指针获得第45页,此课件共126页哦2023/4
38、/11466.2.6 记录的翻译T record D endT record L D endT.type:=record(top(tblptr);T.width:=top(offset);pop(tblptr);pop(offset)L t:=mktable(nil);push(t,tblprt);push(0,offset)第46页,此课件共126页哦2023/4/11476.3 赋值语句的翻译翻译的需求翻译的需求充分了解各种语言现象的语义充分了解各种语言现象的语义包括:控制结构、数据结构、单词包括:控制结构、数据结构、单词充分了解它们的实现方法充分了解它们的实现方法目标语言的语义目标语言的
39、语义了解中间代码的语义了解中间代码的语义了解运行环境了解运行环境第47页,此课件共126页哦2023/4/1148辅助子程序与语义属性设置辅助子程序辅助子程序gencode(code),emit(code):产生一条中间代码:产生一条中间代码newtemp:产生新的临时变量:产生新的临时变量lookup:检查符号表中是否出现某名字:检查符号表中是否出现某名字语义属性设置语义属性设置中间代码序列:中间代码序列:code地址:地址:addr下一条四元式序号:下一条四元式序号:nextquad第48页,此课件共126页哦2023/4/11496.3.1 简单赋值语句的翻译S id:=E p:=loo
40、kup(id.name);if p nil thengencode(p,:=,E.addr)else error E E1+E2E.addr:=newtemp;emit(E.addr,:=,E1.addr,+,E2.addr)E E1 E.addr:=newtemp;emit(E.addr,:=,uminus,E1.addr)E (E1)E.addr:=E1.addr E id p:=lookup(id.name);if p nil then E.addr:=p else error 第49页,此课件共126页哦2023/4/1150临时名字的重用大量临时变量的使用对优化有利大量临时变量的使用
41、对优化有利大量临时变量会增加符号表管理的负担大量临时变量会增加符号表管理的负担也会增加运行时临时数据占的空间也会增加运行时临时数据占的空间E E1+E2的动作产生的代码的一般形式为的动作产生的代码的一般形式为计算计算E1到到t1计算计算E2到到t2t3:=t1+t2()()()()临时变量的生存期像配对括号那样嵌套或并列临时变量的生存期像配对括号那样嵌套或并列第50页,此课件共126页哦2023/4/1151基于临时变量生存期特征的三地址代码x:=a b+c d e f语语 句句 计数器计数器c的值的值 0$0:=a b 1$1:=c d 2$0:=$0+$1 1$1:=e f 2$0:=$0
42、$1 1 x:=$0 0引入一个计数引入一个计数器器c,它的初值,它的初值为为0。每当临时。每当临时变量仅作为运变量仅作为运算对象使用时,算对象使用时,c减去减去1;每当;每当要求产生新的要求产生新的临时名字时,临时名字时,使用使用$c并把并把c增增加加1。第51页,此课件共126页哦2023/4/11526.3.2 数组元素的寻址数组元素引用的翻译数组元素引用的翻译完成上下界检查完成上下界检查生成完成相对地址计算的代码生成完成相对地址计算的代码目标目标x:=yi 和和 yi:=xy为数组地址的固定部分为数组地址的固定部分相当于第相当于第1个元素的个元素的地址,地址,i是相对地址,不是数组下标
43、是相对地址,不是数组下标数组说明的翻译数组说明的翻译符号表及有关表格符号表及有关表格(内情向内情向量量)的处理的处理维数、下标上界、下标下界、维数、下标上界、下标下界、类型等类型等首地址、需用空间计算首地址、需用空间计算按行存放、按列存放按行存放、按列存放影影响具体元素地址的计算响具体元素地址的计算第52页,此课件共126页哦2023/4/1153数组元素地址计算行优先一维数组一维数组Alow1:up1 (nk=upk-lowk+1)addr(Ai)=base+(i-low1)*w=(base-low1*w)+i*w=c+i*w二维数组二维数组Alow1:up1,low2:up2;Ai1,i2
44、addr(Ai1,i2)=base+(i1-low1)*n2+(i2-low2)*w=base+(i1-low1)*n2*w+(i2-low2)*w=base-low1*n2*w-low2*w+i1*n2*w+i2*w=base-(low1*n2-low2)*w+(i1*n2+i2)*w=c+(i1*n2+i2)*wA1,1,A1,2,A1,3 A2,1,A2,2,A2,3第53页,此课件共126页哦2023/4/1154数组元素地址计算的翻译方案设计下标变量访问的产生式下标变量访问的产生式L idElist|idElist Elist,E|E为了使数组各维的长度为了使数组各维的长度n在我们将
45、下标表达式合在我们将下标表达式合并到并到Elist时是可用的,需将产生式改写为:时是可用的,需将产生式改写为:L Elist|idElist Elist,E|idE第54页,此课件共126页哦2023/4/1155数组元素地址计算的翻译方案设计 L Elist|id Elist Elist,E|idE目的目的使我们在整个下标表达式列表使我们在整个下标表达式列表Elist的翻译过程中随的翻译过程中随时都能知道符号表中相应于数组名时都能知道符号表中相应于数组名id的表项,从而的表项,从而能够了解登记在符号表中的有关数组能够了解登记在符号表中的有关数组id的全部信息。的全部信息。于是我们就可以为非终
46、结符于是我们就可以为非终结符Elist引进一个综合属性引进一个综合属性Elist.array,用来记录指向符号表中相应数组名字,用来记录指向符号表中相应数组名字表项的指针。表项的指针。第55页,此课件共126页哦2023/4/1156数组元素地址计算的翻译方案设计属性属性Elist.array,用来记录指向符号表中相应数组名字,用来记录指向符号表中相应数组名字表项的指针。表项的指针。Elist.ndim,用来记录,用来记录Elist中下标表达式的个数,即中下标表达式的个数,即数组的维数。数组的维数。Elist.addr,用来临时存放,用来临时存放Elist的下标表达式计算出的下标表达式计算出来
47、的值。来的值。函数函数limit(array,j),返回,返回nj第56页,此课件共126页哦2023/4/11576.3.3 带有数组引用的赋值语句的翻译S Left:=EE E+EE (E)E LeftLeft ElistLeft idElist Elist,EElist idE第57页,此课件共126页哦2023/4/1158赋值语句的翻译模式Leftid Left.addr:=id.addr;Left.offset:=null ElistidE Elist.addr:=E.addr;Elist.ndim:=1;Elist.array:=id.addr ElistElist1,E t:=
48、newtemp;m:=Elist1.ndim+1;gencode(t,:=,Elist1.addr,limit(Elist1.array,m);gencode(t,:=,t,+,E.addr);Elist.array:=Elist1.array;Elist.addr:=t;Elist.ndim:=mLeft Elist Left.addr:=newtemp;Left.offset:=newtemp;gencode(Left.addr,:=,base(Elist.array),invariant(Elist.array);gencode(Left.offset,:=,Elist.addr,w)i
49、1*n2(i1*n2)+i2(i1*n2)+i2)*wbase-(low1*n2-low2)*w第58页,此课件共126页哦2023/4/1159赋值语句的翻译模式E Left if Left.offset=null then/Left是简单变量是简单变量 /E.addr:=Left.addr else begin E.addr:=newtemp;gencode(E.addr,:=,Left.addr,Left.offset,)endE E1+E2 E.addr:=newtemp;gencode(E.addr,:=,E1.place,+,E2.addr)E (E1)E.addr:=E1.add
50、r S Left:=E if Left.offset=null then/Left是简单变量是简单变量/gencode(Left.addr,:=,E.addr)else gencode(Left.addr,Left.offset,:=,E.addr)(i1*n2)+i2)*w+(base-(low1*n2-low2)*w)(i1*n2)+i2)*w+(base-(low1*n2-low2)*w)第59页,此课件共126页哦2023/4/1160例:设A是一个1020的整型数组 w=4 S:=Left.place:=xLeft.offset:=nullxE.addr:=t4Left.addr:=