首页 理论教育 编译原理与实践:变量说明语句翻译成果

编译原理与实践:变量说明语句翻译成果

时间:2023-11-17 理论教育 版权反馈
【摘要】:在C或Pascal等高级语言的语法中,一个过程或函数的所有说明语句是作为一个组统一进行处理的,它们被安排在同一数据区中,利用所设置的一个栈offset来实现相对地址的跟踪。表6-8变量说明语句的翻译模式上述模式给出了在一遍扫描中对数据进行处理的方法。对于变量说明语句“D→id:T”,就把id填入在当前符号表中,这时栈tblptr保持不变,而栈offset的栈顶值增加了T.width。

编译原理与实践:变量说明语句翻译成果

在C或Pascal等高级语言的语法中,一个过程或函数的所有说明语句是作为一个组统一进行处理的,它们被安排在同一数据区中,利用所设置的一个栈offset来实现相对地址的跟踪。然而我们知道,很多程序语言允许过程嵌套,当过程A中嵌入过程B时,则应暂停过程A的处理,转而处理过程B。这种变量说明语句的处理过程可以通过表6-8中的翻译模式来实现。

表6-8 变量说明语句的翻译模式

上述模式给出了在一遍扫描中对数据进行处理的方法。其中,栈tblptr用来保存各个外层过程的符号表指针;S表示各类可执行语句,如for语句、if语句等,由于这里仅考虑说明语句的处理,因此并没有给出S语句的产生式定义;T表示类型语句,含有两个综合属性type和width,分别表示名字的类型和名字的域宽(即该类型名字所占用的存储单元个数),如上述模式中假定整数域宽为4,实数域宽为8,指针类型域宽为4,一个数组的域宽可以通过把数组元素的数目与一个元素的域宽相乘来获得。

在该模式中,用到了如下四个函数调用,具体功能如下:

(1)mktable(previous):创建一张新符号表,并返回一个指向新表的指针。参数previous指向一张先前创建的符号表,比如该嵌入过程的外围过程符号表等。指针previous的值放在新符号表的表头中,表头中还可存放一些诸如过程嵌套深度等其他信息。

(2)addwidth(table,width):在指针table所指的符号表表头中填入该表中所有名字占用的总宽度。

(3)enter(table,name,type,offset):在指针table所指的符号表中为名字name建立一个新的表项,并将类型type、相对地址offset的值填入该项中。

(4)enterproc(table,name,newtable):在指针table所指的符号表中为过程name建立一个新的表项,参数newtable用来指向过程name的符号表。

在表6-8所定义的翻译模式中,假定每一个过程都对应着一张独立的符号表,这种符号表可用链表实现。非终结符号P产生一系列的说明语句,在处理第一条说明语句之前,利用产生式M→ε的语义动作创建一张新的符号表,并将该表入栈,同时置offset栈顶为0。以后每次遇到一个新的名字,便将该名字填入符号表中,并置相对地址为当前offset栈顶之值,然后更新offset栈顶值为原值与该名字所表示的数据对象的域宽之和。需要注意的是,当碰到过程说明“D→proc id;ND1;S”时,将通过产生式N→ε所对应的语义动作创建一张新的符号表,有关D1中的所有说明项都将填入此符号表内。新表有一个指针指向刚好包围该嵌入过程的外围过程的符号表,而由id表示的过程名字则作为该外围过程的局部名字出现。(www.xing528.com)

下面通过一个例子来说明上述翻译模式的工作过程。

如图6-11所示,程序sort中含有3个嵌套过程,分别是readarray、exchange和quicksort,而过程quicksort中又进一步嵌套了过程partition。按照表6-8所定义的翻译模式进行处理将产生图6-12所示的链式符号表,其中,过程readarray、exchange和quicksort的符号表表头中有指针指向其外围过程sort的符号表,而另一过程partition的符号表表头中的指针则指向了quicksort的符号表。

图6-11 含有嵌套过程的源程序

图6-12 嵌套过程的符号表

比如,当处理过程partition中的说明语句时,栈tblptr中将包括指向sort、quicksort以及partition的符号表的指针,而指向当前过程partition的符号表的指针处于栈顶位置;另一个栈offset中则存放着各嵌套过程的当前相对地址,其栈顶元素为当前处理过程partition的下一个局部名字的相对地址。

对于变量说明语句“D→id:T”,就把id填入在当前符号表中,这时栈tblptr保持不变,而栈offset的栈顶值增加了T.width。当开始执行产生式“D→proc id;ND1;S”右边的语义动作时,由D1产生的所有名字占用的总宽度便是offset的栈顶值,它由过程addwidth记录下来;同时,栈tblptr及offset的栈项值被弹出,返回到外层过程中的说明语句继续处理,并在此时把过程的名字id填入到其外围过程的符号表中。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈