第8章 语法制导翻译与中间代码生成.

Slides:



Advertisements
Similar presentations
2014 年浙江省数量资料 华图网校 刘有珍 数字推理 年份题量数字规律 三级等差 2. 和递推 3. 幂次修正 4. 倍数递推 5. 倍数递推 6. 特殊差级 7. 倍数递推 8. 倍数递推 9. 积递推 10. 分数数列
Advertisements

12 届减数分裂复习(蔡志敬) 给你一双翅膀,让你自由翱翔!. ※真核细胞分裂的方式 有丝分裂 无丝分裂 减数分裂.
第五章 企业所得税、个人所得税.
欢迎您来到 心理课堂! 一首歌 1.
九十五年國文科命題知能 研習分享.
司 法 考 试 题 2002年——2009年.
2011年会计初级职称全国统考 初级会计实务 教案 主讲:高峰 2010年12月.
诚信为本、操守为重、坚持准则、不做假账 第 九 章 会 计 报 表.
服务热线: 菏泽教师招聘考试统考Q群: 菏泽教师统考教育基础模拟题解析.
编 译 原 理 指导教师:杨建国 二零一零年三月.
第五章 语法制导的翻译 赵建华 南京大学计算机系 2010年3月.
第四章 決策敘述 4-1 if 4-2 if..else 4-3 case 4-4 綜合範例.
江苏省2008年普通高校 招生录取办法 常熟理工学院学生处
氧气的制法 装置 原理 练习 随堂检测.
1.6 中国人口迁移.
习题与试题 认真复习,重点是掌握基本概念。基本概念掌握了,相当一部分试题的解就有了
第五章 经纪业务相关实务.
第一章 C语言概述 计算机公共教学部.
清仓处理 跳楼价 满200返160 5折酬宾.
财经法规与会计职业道德 (3) 四川财经职业学院.
第六章 中间代码生成 赵建华 南京大学计算机系.
第2章 LR分 析 法 LR分析法是一种自下而上进行规范归约的语法分析方法,LR指“自左向右扫描和自下而上进行归约”。LR分析法比递归下降分析法、LL(1)分析法和算符优先分析法对文法的限制要少得多,对大多数用无二义的上下文无关文法描述的语言都可以用LR分析器予以识别,而且速度快,并能准确、及时地指出输入串的任何语法错误及出错位置。LR分析法的一个主要缺点是,若用手工构造分析器则工作量相当大,因此必须求助于自动产生LR分析器的产生器。
第五章 电流和电路 制作人 魏海军
 第20讲 中国的交通.
第一章 民法概述 一、民法概念 P4 二、民法的调整对象 三、民法的分类 四、民法的渊源 P10 五、民法的适用范围(效力范围)
第七章 财务报告 财务报告 第一节 财务报告概述 一、财务报告及其目标: 1、概念:财务报告是指企业对外提供的反映企业某一特定日期
线索一 线索二 复习线索 专题五 线索三 模块二 第二部分 考点一 高考考点 考点二 考点三 配套课时检测.
第6讲 近代中国的新方向—— 五四运动至新中国成立.
发展心理学 王 荣 山.
行程設計、登山計畫與山難留守 講師:張志湧.
动物激素的调节及其在农业生产中的应用(B级)
编译原理与技术 中间代码生成 2018/9/17 《编译原理与技术》讲义.
Part5语法分析 授课:胡静.
第四章第一节 增值税法律制度2 主讲老师:梁天 经济法基础.
第七章 财务报告 主讲老师:王琼 上周知识回顾.
第八章 符号表 符号表的作用: 一致性检查和作用域分析; 辅助代码生成..
Class 2 流程控制-選擇敘述與迴圈.
CH6.属性文法语法制导翻译 《程序设计语言编译原理》 陈火旺等编著 2000年第3版
C++Primer 3rd edition 中文版 Chap 5
编译原理与技术 第7章 中间代码生成 3学时.
属性文法和语法制导翻译 授课:胡静.
张沛老师带你玩转国际英标.
6 下标变量的中间代码生成 下标:数组;变量: 下标变量:即数组分量: 简单变量:id,其地址可查到;
Part5语法分析 授课:胡静.
8章 习题 1. 设有表达式A*(B*C-A)≤B+C∧D a.试写出逆波兰式中间代码。 b.试写出三元式中间代码。 c.试写出树中间代码。
7.4 布尔表达式和控制流语句 布尔表达式有两个基本目的 计算逻辑值 c = (a > b) && a > 1
第五章 语法分析——自下而上分析 自上而下分析法(Top-down) 自下而上分析法(Bottom-up) 国防科技大学计算机系602教研室.
中间代码生成.
语义分析概述 符号表 第六章 语义分析.
数 学 新课标(沪科) 九年级下册.
第六章 中间代码生成 主要内容 常见的中间代码结构 语法制导方法概论 四元式中间代码生成过程.
第1讲 C语言基础 要求: (1) C程序的组成 (2) C语言的标识符是如何定义的。 (3) C语言有哪些基本数据类型?各种基本数
计算机算法基础 周中成 苏州科技学院应用数学系 2019/4/18.
第四章 自顶向下语法分析方法 语法分析的主要工作:是识别由词法分析给出的单词 序列是否是给定的正确句子(程序)。
第六章 语法制导的翻译 本章内容 介绍一种语义描述方法:语法制导的翻译,介绍语法制导的翻译的实现方法。
经济法基础习题课 主讲:赵钢.
第五章 相交线与平行线 三线八角.
1. 求真空中一长为L、总电量为q的均匀带电细直线杆延长线上的电场强度。
第3 语言翻译问题 [学习目标]:学习和掌握语言的语法的基本概念和基本要素,理解翻译的步骤;学习和掌握BNF文法。
课前注意 课前注意 大家好!欢迎加入0118班! 请注意以下几点: 1.服务:卡顿、听不清声音、看不见ppt—管家( ) 2.课堂秩序:公共课堂,勿谈与课堂无关或消极的话题。 3.答疑:上课听讲,课后答疑,微信留言。 4.联系方式:提示老师手机/微信: QQ:
第十章 优化 网上教学系统: : 编译原理 第十章 优化 网上教学系统: : 编译原理.
C++语言程序设计教程 第2章 数据类型与表达式 第2章 数据类型与表达式 制作人:杨进才 沈显君.
基础会计.
本节内容 Lua基本语法.
第四章 语法分析 南京大学计算机系 戴新宇
坚持,努力,机会留给有准备的人 第一章 四大金融资产总结 主讲老师:陈嫣.
中级会计实务 ——第一章 总论 主讲:孙文静
编译原理 第一章 编译程序概述 第二章 PL/0编译程序的实现 第三章 文法和语言 第四章 词法分析 第五章 自顶向下语法分析方法
第三章 流程控制 程序的运行流程 选择结构语句 循环结构语句 主讲:李祥 时间:2015年10月.
PASCAL语言 吉林大学计算机科学与技术学院.
Presentation transcript:

第8章 语法制导翻译与中间代码生成

8.1 属性文法 语法分析后的源程序==>语义处理 静态语义是对程序约束的描述,这些约束无法通过抽象语法规则来妥善地描述,实质上就是语法规则的良形式条件,它可以分为类型规则和作用域/可见性规则两大类 动态语义 程序单位描述的计算 编译程序的语义处理工作 1 静态语义审查,即验证语法结构合法的程序是否有意义 2 生成中间代码

静态语义审查 (1)类型检查。根据类型相容性要求,验证程序中执行的每个操作是否遵守语言的类型系统的过程,编译程序必须报告不符合类型系统的信息。 (2)控制流检查。控制流语句必须使控制转移到合法的地方。例如,在C语言中break语句使控制跳离包括该语句的最小while、for或switch语句。如果不存在包括它的这样的语句,则就报错。

(3)一致性检查。在很多场合要求对象只能被定义一次。例如Pascal语言规定同一标识符在一个分程序中只能被说明一次,同一case语句的标号不能相同,枚举类型的元素不能重复出现等等。 (4)上下文相关性检查。比如,变量名字必须先声明后引用; (5)名字的作用域分析 解释执行动态语义 (计算)生成代码(中间代码或目标代码)

E → T1+T2 | T1 or T2 T → num|true|false 对输入串 2+6 语法树如图: 例:有文法G[E]: E E{T1.t=T2.t} {T1.t=int} T T T{T2.t=int} + T + 2 6 2 6

类型检查的属性文法: E → T1+T2 {T1.t=int AND T2.t=int} E → T1 or T2 {T1.t=bool AND T2.t=bool} T → num {T.t:=int} T → true {T.t:=bool} T → false {T.t:=bool}

属性文法A(attribute grammar)是一个三元组:A=(G,V,F),其中 G:是一个上下文无关文法, 属性文法,语法制导翻译 属性文法A(attribute grammar)是一个三元组:A=(G,V,F),其中 G:是一个上下文无关文法, V:有穷的属性集,每个属性与文法的一终结符或非终结符相连, F:关于属性的属性断言或谓词集.每个断言与一个产生式相联.而此断言只引用该产生式左端或右端的终结符或非终结符相联的属性

例如:定义表达式的文法如下: EE+E E(E) En 给出定义表达式值的属性文法。 我们为文法符号E引进属性符号val,用E.val表示E的值,属性计算规则以赋值语句的形式给出,附在每个产生式后,并用大括号括起来。为了明确E的不同出现位置,用上角标区别。终结符n的值是词法分析程序提供的,这里用n.lex表示。下面给出属性文法: EE1+E2 {E.val := E1.val +E2.val} E(E1) {E.val := E1.val } En {E.val := n.lex} 属性文法的主要思想有两点: 首先对于每个文法符号引进相关的属性符号; 其次对于每个产生式写出属性值计算的规则。

属性文法:允许为每个终结符和非终结符配备一些属性的文法.它既能描述程序设计语言的语法,又为其语义描述提供了手段. 属性文法由D.E.Knuth于1968年引进.后来才被用于编译程序的设计。 属性有不同的类型,可以象变量一样地被赋值。赋值规则附加于语法规则之上。赋值与语法同时进行,赋值过程就是语义处理过程。在推导语法树的时候,诸属性的值被计算并通过赋值规则层层传递。有的从语法规则左边向右边传,有的从右边向左边传。语法推导树最后完成时,就得到开始符号的属性值。也就是整个程序的语义.

例如定义表达式值的属性文法, E.val是一个综合属性的例子: 属性分为两种:继承属性和综合属性. inherited and synthesized(derived)attribute 继承属性的计算规则由顶向下, 综合属性的计算规则由底向上. 例如定义表达式值的属性文法, E.val是一个综合属性的例子: EE1+E2 {E.val := E1.val +E2.val} E(E1) {E.val := E1.val } En {E.val := n.lex} 考虑句子2+(3+1)的求值顺序,将2+(3+1)的语法树结点改为有附加属性的结点(这样的树称为带注释的语法树): E.val=6 E.val=2 + E.val=4 n.lex=2 ( E.val=4 ) E.val=3 + E.val=1 n.lex=3 n.lex=1

例8.1 一个简单台式计算器的定义 综合属性val 产 生 式 语 义 规 则 Print(E.val) E E1+T E T 例8.1 一个简单台式计算器的定义 综合属性val 产 生 式 语 义 规 则 L E Print(E.val) E E1+T E.val:=E1.val+T.val E T E.val:=T.val T T1 * F T.val:=T1.val  F.val T F T.val:=F.val F (E) F.val:=E.val F digit F.val:=digit.lexval

3*5+4的带注释的分析树 只使用综合属性. L 3*5+4的带注释的分析树 E.val=19 E.val=15 T.val=4 F.val=4 F.val=5 T.val=3 * digit.lexval=4 F.val=3 digit.lexval=5 digit.lexval=3 3*5+4的带注释的分析树

继承属性 一个结点的继承属性值是由此结点的父结点和/或兄弟结点的某些属性来决定的。 例8.2 添加标识符类型的语义描述: 继承属性type 例8.2 添加标识符类型的语义描述: 继承属性type 产生式 语 义 规 则 D TL L.type:=T.type T int T.type=integer T real T.type:=real L  L1,id L1.type:=L.type addtype(id.entry,L.type) L id addtype(id.entry,L.type)

. . 继承属性(续) Real id1,id2,id3的带注释的语法树 D T.type=real L.type= real real ,

8.2 语法制导概论 属性文法:描述语义规则。一个属性文法包含一个上下文无关文法和一系列语义规则,这些语义规则附在文法的每一个产生式上。 语法制导翻译:在语法分析的同时,执行语义子程序: 1 检查静态语义 2 翻译(生成)中间(目标)代码

基于属性文法的处理过程即语法制导翻译是这样的: 对符号串进行语法分析,构造语法树,然后根据需要构造属性依赖图,遍历语法树并在语法树的各结点按语义规则进行计算。 8.2.1 计算语义规则 属性依赖图是一个有向图,用于描述分析树中的属性和属性间的互相依赖关系。 对于编译程序来讲,在单遍扫描中完成语义翻译工作非常重要。

8.2.2 S-属性文法和自下而上翻译 一般的属性文法的翻译器很难建立,然而L-属性文法的翻译器很容易建立。 L-属性文法的一个特例叫S-属性文法。 S-属性文法是只含有综合属性的属性文法。 8.2.3 L-属性文法在自下而上分析中实现 L-属性文法允许一次遍历就计算出所以的属性值。

8.3 中间代码的形式 编译程序的总任务是把源语言的程序代码(源代码)翻译成目标语言的程序代码(目标代码)。 有些编译程序直接把源代码翻译目标代码,而有些编译程序首先把源代码翻译成一种中间语言的程序代码(中间代码),再生成目标代码。

中间代码的特点: ① 中间代码与机器无关,编译程序易于移植。 ② 中间代码级进行优化较为容易。 常见的中间代码形式有逆波兰式,三元式,四元式,树等。 语法制导 翻译方法可分为 非语法制导

语法制导方法是一种形式化方法。它严格依赖于产生式结构。 在产生语法制导翻译程序时,完全根据文法的产生式来生成的,有时为了达到语法制导的目的,不得不对现有产生式做一些修改,这也是语法制导方法的特点。

中间代码 概述 何谓中间代码( Intermediate code) (Intermediate representation) (Intermediate language) 是源程序的一种内部表示 复杂性介于源语言和目标机语言之间 中间代码的作用: 使编译程序的逻辑结构更加简单明确 利于进行与目标机无关的优化 利于在不同目标机上实现同一种语言 中间代码的形式: 逆波兰式、四元式、三元式、间接三元式、树

中间代码按照其与高级语言和机器语言的接近程度,可以分成以下三个层次: 中间代码的层次 中间代码按照其与高级语言和机器语言的接近程度,可以分成以下三个层次: 高级:最接近高级语言,保留了大部分源语言的结构。 中级:介于二者之间,与源语言和机器语言都有一定差异。 低级:最接近机器语言,能够反映目标机的系统结构,因而经常依赖于目标机。

不同层次的中间代码举例 源语言 (高级语言) 中间代码(高级) 中间代码(中级) 中间代码(低级) float a[10][20]; a[i][j+2]; t1 = a[i, j+2] t1 = j + 2 t2 = i * 20 t3 = t1 + t2 t4 = 4 * t3 t5 = addr a t6 = t5 + t4 t7 = *t6 r1 = [fp - 4] r2 = [r1 + 2] r3 = [fp - 8] r4 = r3 * 20 r5 = r4 + r2 r6 = 4 * r5 r7 = fp – 216 f1 = [r7 + r6]

8.3.1 逆波兰式 运算符跟在所有运算对象的后面的表示法写出的式子称为后缀法或逆波兰法。 例子: 中缀表示:a+b 后缀表示:ab+ 前缀表示:+ab 若用post(E)表示中缀式E的逆波兰式 则当E=E1T时有:

POS(E)=POS(E1)||POS(T)|| 其中“||”表示串的“捻接”。 POS(F)=POS(E) F=(E) POS(F)=I F=I POS(T)=POS(T(1))||POS(F)||/ T=T(1)/F POS(T)=POS(T(1))||POS(F)||* T=T(1)*F POS(T)=POS(F) T=F POS(E) =POS(E(1))||POS(T)||- E=E(1)-T POS(E)=POS(E(1))||POS(T)||+ E=E(1)+T POS(E)=POS(T) E=T 逆波兰式 中缀式

例子: pos(A+B*C)=pos(A)||pos(B*C)||+=ABC*+ pos(A*B+c)=pos(A*B)||pos(C)||+=AB*C+ 处理原则: 运算对象出现的顺序与原来的相同 运算符按实际运算顺序出现。 运算符紧跟在运算对象的后面出现,并且没有括号。

逆波兰式的优点:转换为逆波兰式的语言中间形式后,容易实现中间代码的翻译或目标指令。 逆波兰式的生成: ① 运算对象向左移动 ② 运算符与栈顶比较优先数 ③ 括号处理:左括号进栈,起间隔作用;右括号与左括号匹配抵消。

运算对象 波兰表达式 表达式 . 运算符 . 退栈 进栈 . . 运算符栈

例子:a*(b+c/d)abcd/+*的推导 . # .

a *(b+c/d)# . # .

a (b+c/d)# . * # .

a b+c/d)# . ( * # .

ab +c/d)# . ( * # .

ab c/d)# . + ( * # .

abc /d)# . + ( * # .

abc d)# . / + ( * # .

abcd )# . / + ( * # .

abcd/ )# . + ( * # .

abcd/+ )# . ( * # .

abcd/+ # . * # .

abcd/+* # . # .

abcd/+* . . .

动画演示

8.3.2 表达式的三元式和树 一、三元式 三元式的一般形式: i:(ω,OPR1,OPR2) i是三元式编号,不同三元式不能有相同编号。 ω是运算符部分。 OPR1和OPR2是运算对象部分。

(*, b, c) b*c (*, b, d) b*d (+, (1),(2)) b*c+b*d 例子: a:=b*c+b*d的相应三元组 (*, b, c) b*c (*, b, d) b*d (+, (1),(2)) b*c+b*d (:=,(3), a) a:=b*c+b*d 例子:tri(A*B+C) =tri(A*B)||TRI(c)||2:(+,①≥,C) =1:(*, A,B) A*B 2:(+,①,C) A*B+C

tri(A*B+C/D)= 1:(*, A, B) A*B 2:(/, C, D) C/D 3:(+,①,②) A*B+C/D tri(A∨B∧X≠Y+1∨(X≥0∨B)∧D)=1:(+, Y, 1) Y+1 2:(≠,X,①) X≠Y+1 3:(∧,B,②) B∧X≠Y+1 4:(∨,A,③) A∨B∧X≠Y+1

5:(≥, X, 0) X≥0 6:(∨,⑤, B) X≥0∨B 7:(∧,⑥, D) (X≥0∨B)∧D 8:(∨,④,⑦) 二、树 二目运算对应二叉树,多目运算对应多叉树。三元式可以用二叉树表示。

(-,c, d ) c-d (*,b,(1)) b*(c-d) (+,a,(2)) a+b*(c-d) (/,e, f ) e/f (-,(3),(4)) 该题的树结构如下:

c d - + / * a b e f 1 2 3 4 5 该树的根后序为:abcd-*+ef/-,为该式的逆波兰式。

8.3.3 四元式 四元式的一般形式是: (ω,OPR1,OPR2,RESULT) 其中ω是运算符。 OPR1和OPR2是第一,二分量, RESULT是运算结果变量名。 例: 求a:=b*c+b*d 的四元式

FOUR(T) RES(E)=RES(T) 1)(*,b,c,T1) b*c 2)(*,b, d,T2)b*d 3)(+,T1,T2,T3)b*c+b*d 4)(:=,T3,-,a) 下面是表达式四元式的形式定义。 FOUR(T) RES(E)=RES(T) 1.E=T 四元式 中缀式 FOUR(E1) 2.E=E1+T

FOUR(T) (+,RES(E1),RES(T),TEMP) RES(E)=TEMP(临时变量) 空 RES(F)=ID 7.F=I 类似于2 6.T=T1/F 5.T=T1*F FOUR(F) RES(T)=RES(F) 4.T=F 3.E=E1-T

(-,A,B,T1)A-B (*,C,T1,T2)C*(A-B) (+,B,T2,T3)B+C*(A-B) (*,A,T3,T4) FOUR(E) RES(F)=RES(E) 8.F=(E) 例:设有表达式A*(B+C*(A-B))则有 (-,A,B,T1)A-B (*,C,T1,T2)C*(A-B) (+,B,T2,T3)B+C*(A-B) (*,A,T3,T4)

引进一过程GENQT: GENQT(ω):BEGIN RESULT:=NEWTEMP; QT[J]:=(ω,SEM[S-2],SEM[S-1],RESULT); SEM[S-2]:=RESULT; J:=J+1; S:=S-1 END 语法制导翻译算法如下:

空 F->(E) SEM[s]:=EADDR(id);s:=s+1 F->I GENQT(/) T->T/F GENQT(*) T->T*F T->F GENQT(-) E->E-T GENQT(+) E->E+T E->T 语义子程序 产生式

8.4 类型检查与类型转换 例:a+b 3+5=8 3.2+5=3.2+5.0=8.2 3+’T’=? 例:设有一表达式X*2+a*(i+1)/(j+1)其中i和j为整形变量,其它为实型变量,则产生的四元式如下:

1.(tran,2,—, T1) 2.(r*, x,T1, T2) x*2 3.(i+, i, 1, T3) i+1 4.(tran,T3,—,T4) 5.(r*, a, T4,T5) a*(i+1) 6.(i+, j, 1, T6) j+1 7.(tran,T6,—, T7) 8.(r/, T5, T7, T8)a*(i+1)/(j+1) 9.(r+, T2, T8, T9)

8.5 语句的中间代码及其语法制导生成 循环语句只考虑While型循环语句。所要考虑的语句文法如下: Gs:S→i:=E | if E then S | if E then S else S | while E do S | begin B end | goto l | l:S B→S | B; S

下面是语句四元式的形式定义: four(E) (then, res(E),—,—) four(S1) (ifend,—,—,—) S≡if E then S1 (=:,res(E), —,i) S≡i:=E 四元式 源代码

(while,—,—,—) Four(E) (do res(E),—,—) four(S1) S≡while E do S1 four(E) (then,res(E),—,—) (else,—,—, —) four(S2) (ifend,—,—,—) S≡if E then S1 else S2

four(S) B≡S (label,—,—,l) four(S1) S≡l:S1 four(B1) Four(S) B≡B1;S (goto,—,—,l) S≡goto l four(B) S≡begin B end whend(,—,—,—)

例:设有语句 if X=Y+1 then X:=X*Y else while X≠0 do begin X:=X-1;Y:=Y+2 end 则其四元式如下: 1.(+, Y, 1, T1) Y+1 2.(=, X, T1, T2) X=Y+1 3.(then,T2, — ,—) 4.(*, X, Y, T3) X*Y 5.(=:, T3, —, X ) X:=X*Y 6.(else,—, —, —)

8.(≠, X , 0, T4) X≠0 9.(do, T4, —, —) 10.(-, X, 1, T5) X-1 7.(while,—, —, —) 8.(≠, X , 0, T4) X≠0 9.(do, T4, —, —) 10.(-, X, 1, T5) X-1 11.(=:, T5, —, X) X:=X-1 12.(+, Y, 2, T6) Y+2 13.(=:, T6, —, Y) Y:=Y+2 14.(whend, —, —, —) 15.(ifend, —, —, —)

语法制导用的新文法可设计如下: Gs‘:S→Assig E | Ifthen S | Ifelse S | Whido S | begin B end | goto l | Label S Assigi:= Ifthenif E then

Ifelse Ifthen S else Whido  While E do While while Label l: B→S| B; S

8.6 复合变量的中间代码 及其语法制导生成 在Pascal中,变量形式定义是: V→id | V[E] | V.id ClASS POINT a tp: L tp’ u l LOW UP CTP ClEN

下面考虑域选择变量V.id情形。 其中tp’是成分类型的TYPEL地址,L是成分类型的长度。 若用typ(V)和addr(V)表示变量V的类型(TYPEL地址)和V的始地址,则有: addr(V[E])=addr(V)+(E-l)*L 其中 l=AINFL[TYPEL[tp].TPOINT].LOW L=AINFL[TYPEL[tp].TPOINT].CLEN 下面考虑域选择变量V.id情形。

addr(V.id)=addr(V)+off(typ(V),id) 设tpy(V)=tp,且TYPEL[tp].TCLASS=d.这是tp指向一个记录类型的内部表示: ClASS POINT d tp: RINFL 若用V.id中的id去查RINFL部分可得到id关于该记录的区距off。若用off (tp,id)表示id 关于tp记录的区距,则有: addr(V.id)=addr(V)+off(typ(V),id)

例:设有PASCAL说明: TYPE at=ARRAY[1..10]OF[1..5]OF integer; rt=RECORD d:real; a:at; b:at END; VAR c,g:at;r,u:rt; 则有:addr(c[i])=cº+(i-1)*5 addr(c[i][j])=cº+(i-1)*5+(j-1)*1 addr(u.a)=uº+1 addr(u.a[i])=uº+1+(i-1)*5

vfour(V): addr(V)=>T 下面考虑V[E]和V.id情形的四元式。变量目标的任务是计算变量的地址,于是其四元式可描述如下: vfour(V): addr(V)=>T 其中vfour表示变量的四元式。 变量的目标代码不一定要彻底计算出变量的地址并将它存于临时变量中。如果没有方便的目标代码,则计算X:=V[E]的过程大致是:

1) Addr(V)=>T1 2) Value(E)T2 3) T1+ T2T3 4) @ T3X 但如果有方便的目标代码,则计算过程可以是: 1) Addr(V)T1 2) Value(E)T2 3) T2[T1]T3

V[E]的四元式结构可设计如下: vfour(V[E]):vfour(V) efour(E) (—,eres(E),l,T1) (*,T1,L,T2) ([],vres(V),T2,T) eres(E)是表示E的结果变量。 vres(V)是表示V变量的地址所在的变量 l和L分别为数组的下界和成分类型长度。

域选择变量V.id的四元式可设计如下: vfour(V.id) : vfour(V) (., vres(V),off,T) 用efour(E)形式表示现在表达式的四元式,eres(E)也类似。其中的vres(v)和efour(E)分别为SEM[s-2]和SEM[s-1],而l和L则可按下法求出: tp:=SYMBL[SEM[S-2]].TYPE l:=AINFL[TYPEL[tp]].LOW L:=AINFL[TYPEL[tp].CLEN 域选择变量V.id的四元式可设计如下: vfour(V.id) : vfour(V) (., vres(V),off,T)

例:假定有前例的说明,则有: vfour(c[i]) : 1.(—, i, 1, T1) 2.(*, T1,5, T2) 3.([], c, T2,T3) vfour(c[i][j]): 1. vfour(c[i]) 4.(—, j, 1,T4) 5.(*, T4,1,T5) 6.([], T3,T5,T6) vfour(u.a[i]): 1.(., u,off,T1) 2.(—,i, 1, T2) 3.(*, T2,5, T3) 4.([],T1, T3,T4)

例:设有说明部分 VAR x,i,j:integer; B:boolean a:ARRAY[1...10]OF[1...5]OF integer; b:ARRAY[1...5] OF integer 则下列语句 a[i][j]:=b[b[i]] a[i]:=b 的四元式部分如下: I.1.(—, i, l, T1) 2.(*, T1,5, T2) 3.([], a, T2,T3) a[i]

4.(—, j, 1, T4) 5.(*, T4, 1, T5)可省 6.([], T3, T5, T6) a[i][j] 7.(—, i, 1, T7) 8.(*, T7, 1, T8)可省 9.([], b, T8, T9) b[i] 10.(—, T9, 1, T10) 11.(*, T10,1, T11)可省 12.([], b, T11, T12) b[b[i]] 13.(=:, T12,—, T6)a[i][j]:=b[b[i]]

II. 1.(—,i, 1, T1) 2.(*, T1,5, T2) 3.([],a, T2,T3) a[i] 4.(=:,b, —,T3) a[i]:=b

(act,eres(En), βn,OFF(Xn)) 8.7 过程语句的中间代码及其语法制导生成 过程语句调用的四元式结构: g(E1,E2,…En) efour(E1) efour(E2) . efour(En) (act,eres(E1), β1,OFF(X1)) (act,eres(E2), β2,OFF(X2)) (act,eres(En), βn,OFF(Xn)) (call,EADDR(g),—,—)

当Xi为赋值形参时,βi部分为1,当Xi为引用型形参时, βi部分为0 。 如果是函数调用,那么最后一条为: (call,EADDR(g),—,NEWT) 在上述四元式中,Xi(i=1,2,..,n)为g的形参名。OFF(Xi)表示形参Xi的off值。

例:设有如下说明部分 则有:f(x,g(a[i])*3,y+2.5) TYPE arr=ARRAY[1...10] OF integer; VAR x,y:real; i:integer; a:arr; FUNCTION f(VAR.Y1:real; Y2:integer;Y3:real):real; BEGIN…………………………………END; FUNCTION g(VAR Z:integer):integer; BEGIN…………………………………END 则有:f(x,g(a[i])*3,y+2.5)

1.(—, i, 1, T1) 2.(*. T1, 1, T2) 3.([], a, T2, T3) a[i] 4.(act, T3, 0, 4) 5.(call,g, —, T4) g(a[i]) 6.(*, T4, 3, T5) g(a[i])*3 7.(+, y, 2.5,T6) y+2.5 8.(act, x, 0, 4) f(x,g(a[i]*3, y+2.5) 9.(act, T5, 1, 5) 10.(act, T6, 1, 6) 11.(call,f, —, T7)

例:原文法为i(E,E……E) S i(L) L E|L,E 用语法制导把文法改写如下: S List) list Head E list list,E Head  i(

8.8 说明的中间代码及其语法制导生成 标号说明,常量定义,类型定义,变量说明部分不产生目标代码,因此不用产生中间代码。 设有过程说明:PROCEDURE f( ); LABELDECPART CONSTDEFPART TYPEDEFPART VARDECPART PFDEC1;……PFDECn; PFBODY

则其四元式结构可设计如下: (proc,f,Noff,Moff) dfour(PFDEC1) dfour(PEDEC2) ……… dfour(PEDECn) sfour(PFBODY) (procend,—,—,—) 其中Noff和Moff为f的NOFF和MOFF值,并且Moff部分以后还会变。最终它表示过程所需单元个数+1。

(proc,f,Noff,Moff1) 例:设有过程说明 PROCEDURE f(VAR x,y:real); CONST pai=3.14; TYPE arr=ARRAY[1..10]OF real; VAR x1:reaL;a:arr; FUNCTION h(X0:integer) :real; BEGIN h:=x0/2 END BEGIN x:=y+pai; a[2]:=1.2*x END 则其四元式如下: (proc,f,Noff,Moff1)

(func, h, Noff2,Moff2) (/, x0, 2, T1) x0/2 (=:, T1 ,—, h) h:=x0/2 (funcend, —, —, —) (+, y, pai, T2) y+pai (=:, T2, —, x) x:=y+pai (—, 2, 1, T3) (*, T3, 1, T4) ([], a, T4, T5) a[2] (*, 1.2, x, T6) 1.2*x (=: T6, —, T5) a[2]:=1.2*x (procend,—, —, —)