刘坚 编译原理基础 学习笔记(5)声明语句的翻译

一、变量的定义和声明  

        1.变量的类型定义与声明
                类型定义为编译器提供储存空间的大小信息,而变量声明为变量分配储存空间
        2.变量声明的语法制导翻译


二、数组变量的声明
数组在符号表中占领与简单变量同样多的域,对于数组的详细信息另外安排内情向量来记录,并且符号表中应有一个指针指向内情向量地址。
        1.静态数组的内情向量
                为了数组元素的引用,数组声明时需要保存的信息包括offset,数组的维数n,每维的成员个数di,type..等等。还需要约定行储存还是列储存。

        2.动态数组的内情向量
                无法在编译时确定动态数组的大小。此时希望程序运行时填写内情向量中的内容,使得需要它们的时候是确定的。按下述方式进行动态数组的储存分配和数组元素地址计算的翻译
                        (1)在编译时给数组分配一个内情向量表区,即讲原来放在编译时的符号表中的内情向量移到运行时的存储空间中
                        (2)编译时加入一段特殊的代码,该代码根据运行时确定的di值填写内情向量,并分配储存区,并填写向量表的各项内容。 


 三、过程的定义&声明

        1.左值和右值
                左值是容器,右值是内容。它们的实质是是否对应储存空间。

        2.参数传递
                (a) 值调用:调用时首先计算形参,并把它的右值传递给被调用过程。过程内部对参数的修改不影响实参变量原来的值
                (b) 引用调用:调用时首先计算实参,并把它的右值传递给被调用过程。过程内部对参数的修改等价于对实参的修改
                (c) 复写-恢复:在过程体中不对实参进行操作,此时与值调用完全相同,过程返回时把操作结果拷贝给实参
                (d) 换名调用:每次对过程的调用,实则是用过程体替换过程调用。用实参中的文字替换体中的形参。(例如在C中是#define,预处理时进行宏替换。)

        3.作用域信息的保存
                (a)过程的作用域:设主程序的嵌套深度d=1,则
                        若过程A直接嵌套定义过程B,则dB=dA+1
                        变量声明时所在过程的嵌套深度被认为是该变量的嵌套深度
                (b)符号表中的作用域信息


        4.记录的域名
                记录把若干个变量或者记录封装在一起形成新的数据类型。所以记录的域名也是嵌套的。


四、算术表达式&赋值句
        1.简单变量的语法制导翻译
                其中 emit(result':='arg1'op'arg2)产生result:=argl op arg2的三地址码指令。

        2.变量的类型转换
                T := itr E 整型转实型,并放在T里
                T := rti E 实型转整型,并放在T里


五、数组元素引用的语法制导翻译
        数组元素的地址由不变部分和可变部分共同确定,可以用变址的方式表示为

CONSPART[VARPART],或者T1[T]

        将不变部分作为基址,而可变部分作为变址,于是取数组元素的值和向数组元素赋值的三地址码可以分别如下所示:
                取值X:=T1[T] 
                赋值T1[T]:=X


六、布尔表达式

        1.数值表示&直接计算的语法制导翻译
                引入一个新的变量nextstat,它总是指向第-一个可用的三地址码序号,每调用一次emit操作nextstat 增值1

        2.短路计算的语法制导翻译
                一旦能确定表达式的真假,就转向对应的代码。需要为布尔表达式E引入两个新的属性和一个产生标号的函数
                属性.true 表达式的真出口
                属性.false 表达式的假出口
                函数newlabel 产生一个标号

        3.拉链&回填
                为了在一次遍历中就确定三地址码的真出口和假出口,我们在三地址码中的转向不确定时,把所有转向同一地址的三地址码拉成一个链,一旦转向的地址确定,则沿着拉链回填地址。为此需要新增两个属性
                        属性.tc 真出口链
                        属性.fc 假出口链
                引入以下函数实现拉链和回填
                        mkchain(i)  为序号为i的三地址码构造一个新链并返回指针
                        merge(p1,p2)  将链p1,p2合并,返回指针
                        backpatch(p,i)  给链p填i值
                引入M->ε,为M引入新的属性.stat记录第一个可用的三地址码的序号


七、控制语句
        1.标号&无条件转移
                标号在一定的作用域仅可定义一次,但可以引用多次。标号定义出现时就把与其相关的内容填进符号表里,标号引用出现时,就根据符号表里的信息生成正确转移地址的三地址码。
在符号表里,为标号设置以下信息域
.                        type 记录标识符的类型,如‘标号’‘未知’
                        .def 若是标号,记录是否定义
                        .addr 标号定义后,作为此标号对应三地址码的序号
                引入fill(entry(id.name),a,b,c)把a,b,c填写到符号表中id.name的type,def,addr中。

        2.条件转移
                条件转移具有if-then结构,if-then-else结构和while-do结构。
                对于if-then结构


                对于if-then-else结构


                对于while-do结构

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
⒈ 题目 分析对象的BNF定义如下: 〈算术表达式〉∷=〈项〉|〈算术表达式〉+〈项〉|〈算术表达式〉-〈项〉 〈项〉∷=〈因式〉|〈项〉*〈因式〉|〈项〉/〈因式〉 〈因式〉∷=〈变量〉│(〈算术表达式〉) 〈变量〉∷=〈字母〉 〈字母〉∷=A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z (a)总程序过程 (b) ( E过程)算术表达式处理 (c)项处理(T过程) (d)因式处理过程)(F过程) (e) (f) 图2-7-5 递归下降法分析表达式之框图 (a) ZC 过程;(b) E 过程;(c) T 过程; (d) F 过程;(e) 函数过程 SYM ;(f) 过程 ADVANCE ⒉ 算法 用递归下降法分析上述算术表达式的框图,如图2-7-5所示。这里,ZC过程为总控程序,主要完成: ⑴ 通知外界键入算术表达式; ⑵ 控制E过程分析算术表达式; ⑶ 根据分析结果之正误,分别通知外界不同的信息。 ZC过程被设计成可以分析无穷多个算术表达式。E、T和F三个过程分别对应〈算术表达式〉、〈项〉和〈因式〉三个产生式的处理。它们用到两个公共过程。一个是函数过程SYM,它负责从输入字符串ST中取出下一个字符,并存入SYM中等待分析。另一个过程ADVANCE负责剔除ST中的首字符。 算法的书写和实现也请参考课堂教学所给出的方法和实例,不一定照搬以上的框图。 ⒋ 小结 ⑴ 实习前的准备 按实习目的和要求,用PASCAL语言编写一个语法分析程序,同时考虑相应的数据结构。 ⑵ 调试 调试例子应包括符合语法规则的算术表达式,以及分析程序能够判别的若干错例。 ⑶ 输出 对于所输入的算术表达式,不论对错,都应有明确的信息告诉外界。 ⑷编写上机实习报告。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值