10西安电子科技大学《编译原理》

上传人:野鹰 文档编号:2735933 上传时间:2017-07-27 格式:PPT 页数:38 大小:553.50KB
返回 下载 相关 举报
10西安电子科技大学《编译原理》_第1页
第1页 / 共38页
10西安电子科技大学《编译原理》_第2页
第2页 / 共38页
10西安电子科技大学《编译原理》_第3页
第3页 / 共38页
10西安电子科技大学《编译原理》_第4页
第4页 / 共38页
10西安电子科技大学《编译原理》_第5页
第5页 / 共38页
点击查看更多>>
资源描述

《10西安电子科技大学《编译原理》》由会员分享,可在线阅读,更多相关《10西安电子科技大学《编译原理》(38页珍藏版)》请在金锄头文库上搜索。

1、1,4.4 声明语句的翻译,声明语句的作用是为可执行语句提供信息,以便于其执行。对声明语句的处理,主要是将所需要的信息正确地填写进合理组织的符号表中。,4.4.1 变量的声明 变量的类型定义与声明,类型定义:为编译器提供存储空间大小的信息变量声明:为变量分配存储空间组合数据的类型定义和变量声明: 定义与声明在一起,定义与声明分离。,定义确定存储空间,声明分配存储空间 简单数据类型的存储空间是已经确定的,如integer可以占4个字节,real可以占8个字节,char可以占1个字节等。 组合数据类型变量的存储空间,需要编译器根据程序员提供的信息计算而定。,2, 变量的类型定义与声明,例:在Pas

2、cal程序中的类型定义与变量声明:先定义后声明:type player = array1.2 of integer; matrix = array1.24 of char;var c, p : player; winner : boolean; display : matrix; movect : integer;定义与声明同时:var c, p : array1.2 of integer; display : array1.24 of char;,强调: 简单变量声明中类型是预定义的; 组合变量声明中类型需自己定义。(定义的两种形式),3, 变量声明的语法制导翻译,(a) 变量声明的文法:

3、D D ; D (1) | id : T (2) T int (3) | real (4) | array num of T (5) | T (6),产生式(5)是数组类型的声明,其中的数组元素个数由num表示,如num可以是5或10等,这是一个简化了的表示方法,它等价于1.5或1.10。 产生式(6)是指针类型的声明,它的宽度(大小)是一个常量。数组元素的类型和指针所指对象的类型可以是任意合法的类型。 此文法可以声明多维数组,如数组A的声明形式可以是:A : array d1 of array d2 of . array dn of integer,多维数组以行为主存储。因为:第一维是有d1

4、个元素的一维数组,每个元素又是一个n-1维的数组;依此类推。,4, 变量声明的语法制导翻译(续1),(b) 填写符号表信息的语法制导翻译,全程量offset:记录当前被处理符号存储的偏移量,初值设为0属性.type和.width:变量的类型和所占据的存储空间过程enter(name, type, offset):为type类型的变量name建立符号表条目,并为其分配存储空间(位置)offset,(1)DD;D(2)Did:T(3)Tint(4)Treal(5)Tarray num of T1(6)TT1,enter(id.name, T.type, offset); offset:=offse

5、t+T.width;T.type:=integer; T.width:=4;T.type:=real; T.width:=8;T.type:=array(num.val, T1.type); T.width:=num.val*T1.width;T.type:=pointer(T1.type); T.width:=4;,5, 变量声明的语法制导翻译(续2),例 声明序列的语法制导翻译: a : array 10 of int; x : int;,序号 归约使用的产生式语义处理结果(1) T1intT1.type=integer T1.width=4(2) T2arraynumof T1T2.ty

6、pe=array(10,integer)T2.width=10*4=40(3) D1id:T2enter(a,array(10),0) offset=40(4) T3intT3.type=integer T3.width=4(5) D2id:T3enter(x,integer,40) offset=44,(2)Did:T enter(id.name, T.type, offset); offset:=offset+T.width;(3)Tint T.type:=integer; T.width:=4;(5)Tarray num of T1 T.type:=array(num.val, T1.t

7、ype); T.width:=num.val*T1.width;(6)TT1 T.type:=pointer(T1.type); T.width:=4;,6,4.4.3 过程的定义与声明,1过程(procedure): 过程头(做什么)过程体(怎么做);函数;主程序2过程的三种形式:过程定义、过程声明和过程调用。,例:Ada过程定义:procedure swap(x,y:in out integer) is - 规格说明 temp : integer; - 体中的声明begin temp := x; x := y; y := temp; - 可执行语句序列end swap;,声明与引用:pro

8、cedure swap(x, y: in out integer); - 过程声明swap(a, b); - 过程调用,3先声明后引用原则 过程定义可以写在对它的引用之后,或者引用时看不到的地方。 在这样的情况下,引用前必须先声明。 而若引用前已经定义,则声明可省略,因为定义已包括了声明。,7,4.4.3.1 左值与右值,形式上,出现在赋值号左边的对象称为左值,右边的称为右值; 实质上,左值必须具有存储空间,而右值可以仅是一个值,没有存储空间。 形象地讲,左值是容器,右值是内容。,(1) const two = 2;- 声明一个值为2的常量two(2) x : integer;- 声明一个类型

9、为整型数的变量x(3) function max(a, b : integer) return integer;- 声明一个返回值类型是整型数的函数max(4) x := two;- 赋值句执行后,x当前值为2(5) x := two + x;- 赋值句执行后,x当前值变为4(6) x := max(two,x)+x;- 赋值句执行后,x当前值变为8(7) 4 := x;- 字面量不能作为左值(8) two := x;- 常量不能作为左值(9) max(two,x) := two;- 函数返回值不能作为左值(10) x+two := x+two;- 表达式的值不能作为左值,8,4.4.3.2

10、参数传递,1形参与实参定义时的参数称为形参(parameter或formal parameter)引用时的参数称为实参(argument或actual parameter)2常见的参数传递形式:(不同的语言提供不同的形式)值调用(call by value)引用调用(call by reference)复写恢复(copy-in/copy-out)换名调用(call by name)3参数传递方法的实质: 实参是代表左值、右值、还是实参本身的正文。,9, 值调用,值调用的特点: 实参的特点:参数传递和过程内对参数的使用原则:,过程内部对参数的修改,不影响作为实参的变量原来的值。,任何可以作为右值

11、的对象均可作为实参。,(1) 过程定义时形参被当作局部名看待,并在过程内部为形参分配存储单元;,(3) 过程内部对形参单元中的数据直接访问。,(2) 调用过程前,首先计算实参并将值(实参的右值)放入形参的存储单元;,10,值调用举例: 值调用(续1),program reference ( input, output); var a, b : integer;begin a:=1; b:=2; swap(a, b); writeln(a=, a); writeln(b=, b)end.,procedure swap(x, y : integer); var temp : integer; be

12、gin temp:=x; x:=y; y:=temp end;,运行结果:a=1b=2,11,等价的C+程序 值调用(续2),/ - 值调用参数传递的演示程序#include void swap(int x, int y) int temp; temp=x; x=y; y=temp;void main () int a(1), b(2); coutbefore: a=a b=bendl; swap(a, b); coutafter: a=a b=bendl;,12, 引用调用,引用调用的特点:实参的特点:参数传递和过程内对参数的使用原则:,过程内部对形参的修改,等价于直接对实参的修改。,必须是

13、左值。,(1) 定义时形参被当作变量地址看待,并在过程内部为形参分配存储单元;,(2) 调用过程前,将作为实参的变量的地址放进形参的存储单元;,(3) 过程内部把形参单元中的数据当作地址,进行间接访问。,13,引用调用举例: 引用调用(续1),program reference ( input, output); var a, b : integer;begin a:=1; b:=2; swap(a,b); writeln(a=, a); writeln( b=, b)end.,procedure swap(var x, y:integer); var temp : integer; begi

14、n temp:=x; x:=y; y:=temp end;,procedure swap(x, y : integer); var temp : integer; begin temp:=x; x:=y; y:=temp end;,运行结果:a=2b=1,14,等价的C+程序 引用调用(续2),/ - 引用调用参数传递的演示程序#include void swap(int &x, int &y) int temp; temp=x; x=y; y=temp;void main () int a(1), b(2); coutbefore: a=a b=bendl; swap(a, b); coutafter: a=a b=bendl;,

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 行业资料 > 其它行业文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号