目标代码的生成第8章

合集下载

LGY_BY08语法制导翻译和中间代码生成

LGY_BY08语法制导翻译和中间代码生成

表达式文法 E—>T+T| T or T T—>n | b 1 2 ET + T 1 {T .type = int 2 1 T .type= T .type E.type :=int} 1 2 E T or T 1 {T .type = bool 2 1 T .type= T .type E.type :=bool} T n { T.type := int} T b { T.type := bool}
赖国勇 20
2013-7-27
8.2
属性赋值

属性有不同的类型,可以象变量一样地被赋值。



赋值规则附加于语法规则之上。 赋值与语法分析同时进行,赋值过程就是语义处理过 程。 在推导语法树的时候,诸属性的值被计算并通过赋值 规则层层传递。 有的从语法规则左边向右边传,有的从右边向左边传。 语法推导树最后完成时,就得到开始符号的属性值, 也就是整个程序的语义。
8.1
确定标识符类型的语义描述


(1)P→D;E (2)D→D;D (3)D→id:T {addtype (id. Entry, T. type)} (4)T→char {T. Type:= char} (5)T→integer {T. Type:= integer} (6)T→↑T1 {T. Type:= pointer (T1. type)} (7)T→array [num]of T1
2013-7-27
赖国勇
9
8.1
解释执行动态语义

(计算)生成代码(中间代码或目标代码)
2013-7-27
赖国勇
10
8.1
如 if B then S1 else S2

第十一章目标代码生成

第十一章目标代码生成
码中访问存储单元的次数。
这两个问题直接影响代码的执行速度。
基本问题
➢代码生成器的输入 ➢目标程序 ➢选择适当的代码指令 ➢寄存器分配方案 ➢计算顺序
例:考察下面中间代码序列 G1:
T1 := A+B T2 := A- B F := T1 * T2 T1 := A- B T2 := A – C T3 := B - C T1 := T1 * T2 G := T1 * T3
T1 := E/F T2 := D + T1 T3 := G + T2 T4 := C * T3 T5 := H * T4 T6 := B + T5 T7 := A + T6 T8 := I * J T9 := T7 + T8
最优的目标代码:
LD R0, E
DIV R0, F
ADD R0, G
MUL R0, H
T3 := B-C ; T2 := A- C ; S1 := A – B ; T1 := S1 *
T2;
G := T1 * T3; S2 := A + B ; F := S2 * S1 。如前所 述按后一个中间代较好理解,这里不再重述课 本内容。
T4 := E-F LD R0, E R0 中
SUB R0, F
T5:=T3* T4 MUL R1, R0 R1中
储器中
LD R0, T2
W:=T2/T5 DIV R0, R1 R0中
储器中
ST R0, W
R0含 T4
T4 在
R1含 T5
T5 在
R0含T2 T2在R0和存
R0含W
W在
W在R0和存
第十二章并行编译基础
目标代码一般有以下三种形式:

第8章符号表与错误处理

第8章符号表与错误处理

第8章 符号表与错误处理
8.2.1 语法错误的校正 对源程序错误的处理通常有两类不同方法:一类是
对错误进行适当的修补,以便编译工作能够继续下去; 另一类是跳过有错误的那个语法成分,以便把错误限制 在一个尽可能小的局部范围内,从而减少因某一错误而 引起的一连串假错。第二类方法又称为错误的局部化法。
1.单词错误的校正 词法分析的主要任务是把字符串形式的源程序转换 为一个单词系列。由于每一类单词都可以用某一正规式 表示,因而在识别源程序中的单词符号时,通常采用一 种匹配最长子串的策略。如果在识别单词的过程中发现 当前余留的输入字符串的任何前缀都不能和所有词型相 匹配,
第8章 符号表与错误处理
首先讨论自上而下分析中的错误校正问题。在语
法分析过程的每一时刻,总可以把源程序输入符号串
a1 a2…an划分为如下形式:
a1a2 …an= w1aiw2
(8.1)
其中w1是已经扫描和加工过的部分,ai为现行输入 符号,而w2则是输入串的余留部分。假定编译程序现 在发现了源程序中的一个语法错误,这对自上而下分
在多数编译程序中不是采用“最小海明距离法”来校 正错误,而是采用一种更为简单、有效的方法。这种方法 的依据是程序中所有错误多半属于下面几种情况之一:
第8章 符号表与错误处理
(1) 拼错了一个字符; (2) 遗漏了一个字符; (3) 多写了一个字符; (4) 相邻两字符颠倒了顺序。 通过检测这四种情况,编译程序可查出源程序中 大部分的拼写错误。对这些错误进行简单的检测与校 正的方法为: (1) 从符号表中选出一个子集,使此子集包含所有 那些可能被拼错的符号; (2) 检查此子集中的各个符号,看是否可按上述四 种情况之一把它变为某一正确的符号,然后用它去替 换源程序中的错误符号。

编译原理第三版课后习题答案

编译原理第三版课后习题答案

编译原理第三版课后习题答案编译原理是计算机科学中的一门重要课程,它研究的是如何将高级程序语言转换为机器语言的过程。

而《编译原理》第三版是目前被广泛采用的教材之一。

在学习过程中,课后习题是巩固知识、提高能力的重要环节。

本文将为读者提供《编译原理》第三版课后习题的答案,希望能够帮助读者更好地理解和掌握这门课程。

第一章:引论习题1.1:编译器和解释器有什么区别?答案:编译器将整个源程序转换为目标代码,然后一次性执行目标代码;而解释器则逐行解释源程序,并即时执行。

习题1.2:编译器的主要任务是什么?答案:编译器的主要任务是将高级程序语言转换为目标代码,包括词法分析、语法分析、语义分析、中间代码生成、代码优化和目标代码生成等过程。

第二章:词法分析习题2.1:什么是词法分析?答案:词法分析是将源程序中的字符序列划分为有意义的词素(token)序列的过程。

习题2.2:请给出识别下列词素的正则表达式:(1)整数:[0-9]+(2)浮点数:[0-9]+\.[0-9]+(3)标识符:[a-zA-Z_][a-zA-Z_0-9]*第三章:语法分析习题3.1:什么是语法分析?答案:语法分析是将词法分析得到的词素序列转换为语法树的过程。

习题3.2:请给出下列文法的FIRST集和FOLLOW集:S -> aAbA -> cA | ε答案:FIRST(S) = {a}FIRST(A) = {c, ε}FOLLOW(S) = {$}FOLLOW(A) = {b}第四章:语义分析习题4.1:什么是语义分析?答案:语义分析是对源程序进行静态和动态语义检查的过程。

习题4.2:请给出下列文法的语义动作:S -> if E then S1 else S2答案:1. 计算E的值2. 如果E的值为真,则执行S1;否则执行S2。

第五章:中间代码生成习题5.1:什么是中间代码?答案:中间代码是一种介于源代码和目标代码之间的表示形式,它将源代码转换为一种更容易进行优化和转换的形式。

目标代码生成

目标代码生成

四元式
目标代码 RVALUE AVALUE
T=A−B U=A−C V=T+U D=V+U
MOV AX, A SUB AX, B MOV BX, A SUB BX, C
ADD AX, BX
ADD AX, BX
AX含有T
AX含有T BX含有U AX含有V BX含有U
AX含有D
T在AX中
T在AX中 U在BX中 V在AX中 U在BX中
处理完基本块中所有的四元式后,对现行只在 某寄存器中的每个变量,如果它在基本块出口之后 是活跃的,则要用MOV指令把它在寄存器中的值存 放到数据区以它命名的内存单元中。
第7章 目标代码生成
为进行这一工作,我们利用寄存器描述数组 RVALUE来决定其中哪些变量的现行值在寄存器中, 再利用地址描述数组AVALUE来决定其中哪些变量 的现行值尚不在其内存单元中,最后利用活跃变量 信息来决定其中哪些变量是活跃的。例如,由例7.2 的表7.2查RVALUE栏可知:U和D的值在寄存器中, 而从AVALUE栏知U和D的值都不在内存单元中, 又由例7.1表7.1知,D在基本块出口之后是活跃变量, 所以,在表7.2所生成的目标代码后面还要生成一条 目标代码:
第7章 目标代码生成
例如,一C语言语句为A=(B+C)*D+E,把它翻 译为四元式G:
T1=B+C T2=T1*D A=T2+E 如果不考虑代码的效率,可以简单地把每条中 间代码(四元式)映射成若干条目标指令,如将x=y+z 映射为:
MOV AX, y /*AX为寄存器*/
ADD AX, z
MOV x, AX 其中,x、y、z均为数据区的内存变量。
例7.1 考察基本块: (1) T=A−B (2) U=A−C (3) V=T+U (4) D=V+U

第08章语法制导翻译和中间代码生成

第08章语法制导翻译和中间代码生成
28
常用的中间语言
• 三地址代码(四元式) 三地址代码(四元式) • 语法结构树(三元式) 语法结构树(三元式) • 后缀式
特点
• 形式简单、语义明确、便于翻译 形式简单、语义明确、 • 独立于目标语言
29
三元式和树形表示
• 每个三元式由三个部分组成,分别是:算符op, 每个三元式由三个部分组成,分别是:算符op, op 第一运算对象ARG1和第二运算对象ARG2 ARG1和第二运算对象ARG2。 第一运算对象ARG1和第二运算对象ARG2。运算 对象可能是源程序中的变量, 对象可能是源程序中的变量,也可能是某个三 元式的结果,用三元式的编号表示。 元式的结果,用三元式的编号表示。 • 表达式的树形表示很容易实现:简单变量或常 表达式的树形表示很容易实现: 数的树就是该变量或常数自身,如果表达式e1 数的树就是该变量或常数自身,如果表达式e1 e2的树分别为T1和T2,那么e1+e2 e1*e2, 的树分别为T1 e1+e2, 和e2的树分别为T1和T2,那么e1+e2,e1*e2, e1的树分别为 的树分别为: -e1的树分别为:
9
–lexval 是单词 digit 的属性 lexval
例8-3 3*5+4 的
语法树与属性计算
L Print(19) E.val=19
E.val=15 T.val=15 T.val=3 F.val=3 digit.lexval=3 *

T.val=4 F.ቤተ መጻሕፍቲ ባይዱal=4
F.val=5 dgit.lexval=5
• 用中间语言过渡的好处: 用中间语言过渡的好处:
–便于编译系统的实现、移植、代码优化 便于编译系统的实现、移植、 便于编译系统的实现

编译第8章

编译第8章
–是一种接近形式化的语义描述方法 –长于描述静态语义、短于描述动态语义 –每个语法符号有相应的属性符号 –每个产生式有相应的计算属性的规则:
• 属性变量=属性表达式
1、属性文法定义
属性文法(attribute grammar)是一个三元 组:A=(G,V,F),其中 G:是一个上下文无关文法 V:有穷的属性集,每个属性与文法的一个终结符或非 终结符相连,这些属性代表与文法符号相关信息, 如它的类型、值、代码序列、符号表内容等等 .属 性与变量一样,可以进行计算和传递。属性加工 的过程即是语义处理的过程。 F:关于属性的属性断言或一组属性的计算规则(称为 语义规则) . 断言或语义规则与一个产生式相联,只 引用该产生式左端或右端的终结符或非终结符相 联的属性.
addtype
id3
addtype
例5-4:real id1,id2,id3 的分析树和属性计算
8.3 中间代码的形式
何谓中间代码: 源程序的一种内部表示,不依赖目标机的 结构,易于机械生成目标代码的中间表示。 为什麽要此阶段 逻辑结构清楚; 利于不同目标机上实现同一种语言; 利于进行与机器无关的优化; 这些内部形式也能用于解释;
• 语义处理
–例:变量的存储分配 –例:表达式的求值 –例:语句的翻译(中间代码的生成)
• 总目标:生成等价的中间代码
语义处理方法
• 对应每一个产生式编制一个语义子程序, 当一个产生式获得匹配时,调用相应的 语义子程序实现语义检查与翻译。 • 在产生式的右部的适当位置,插入相应 的语义动作,按照分析的进程,执行遇 到的语义动作。
8)若把语义子程序改成产生某种中间代 码的动作,就能在语法分析制导下,随 着分析的进展逐步生成中间代码。 9)若把语义子程序改成产生某种机器的 汇编语言指令,就能随着分析的进展逐 步生成某机器的汇编语言代码。

《编译原理》教学大纲

《编译原理》教学大纲

《编译原理》教学大纲一、课程概述编译原理是计算机科学与技术专业的一门重要课程,也是软件工程领域的基础课程之一、本课程通过对编译器的原理和实现技术的学习,使学生掌握编译器的设计和实现方法,培养学生独立解决实际问题的能力。

二、教学目标1.理解编译器的基本原理和工作流程;2.掌握常见编译器的构建方法和技术;3.能够设计和实现简单的编译器;4.培养分析和解决实际问题的能力。

三、教学内容和教学进度1.第一章:引论1.1编译器的定义和分类1.2编译器的基本工作流程2.第二章:词法分析2.1编译器的基本结构2.2词法单元的定义和识别方法2.3正则表达式和有限自动机3.第三章:语法分析3.1语法分析的基本概念3.2语法规则的定义和表示方法3.3自顶向下的语法分析方法3.4自底向上的语法分析方法4.第四章:语义分析4.1语义分析的基本概念4.2属性文法和语法制导翻译4.3语义动作和符号表管理5.第五章:中间代码生成5.1中间代码的定义和表示方法5.2基本块和控制流图5.3三地址码的生成方法6.第六章:优化6.1优化的基本概念和原则6.2常见的优化技术和方法6.3编译器的优化策略7.第七章:目标代码生成7.1目标代码生成的基本原理7.2目标代码的表示方法和存储管理7.3基本块的划分和目标代码生成算法8.第八章:附加主题8.1解释器和编译器的比较8.2面向对象语言的编译8.3并行编译和动态编译四、教学方法1.理论教学与实践相结合,注重教学案例的分析和实践;2.引导学生主动探索,注重培养学生的自主学习能力;3.激发学生的兴趣,鼓励学生提问和讨论。

五、考核方式1.平时成绩:包括课堂测验、作业和实验报告等;2.期末考试:闭卷笔试,主要考查学生对编译原理的理论知识和实践能力的掌握程度。

六、参考教材1.《编译原理与技术》(第2版),龙书,机械工业出版社,2024年2.《现代编译原理-C语言描述》(第2版),谢路云,电子工业出版社,2024年七、参考资源1. 实验环境:Dev-C++、gcc、llvm等2.相关网站:编译原理教学网站、编译器开源项目等八、教学团队本课程由计算机科学与技术学院的相关教师负责教学,具体安排详见教务处发布的教学计划。

《编译原理》教学大纲

《编译原理》教学大纲

《编译原理》教学大纲大纲说明课程代码: 3225003总学时: 64 学时(讲课 48 学时,实验16 学时)总学分: 4课程类别:学科基础课适用专业 : 计算机科学与技术(专业)预修要求: C 语言程序设计、 C++ 程序设计、数据结构课程的性质、任务及地位:《编译原理》是计算机科学与技术专业的一门重要基础课。

通过对该课程的学习,使学生掌握编译过程中的相关原理和编译技术,让学生能初步进行编译程序的开发和维护,同时促进提高学生开发软件的能力。

教学目的与基本要求:本课程的目的,通过向学生讲述编译系统的结构、工作流程及编译程序各部分的设计原理和实现技术,使学生既掌握编译技术理论的基础与基本知识,也具有设计、实现、分析和维护编译程序等方面的初步能力。

本课程理论性较强。

因授课对象为工科学生,所以在强调编译系统的构造原理和实现方法的同时,为培养学生的实际工作能力,通过上机实践进一步加深学生对课堂教学内容的理解。

目的是要使学生牢固掌握相关的基本理论和基本方法,并能初步利用上述理论和方法解决简单实际问题。

教学方法和教学手段的建议:在教学方法上,贯彻理论联系实际、“精讲、多练”的原则,进行案例式、启发式的教学,对于一些实际性较强的问题要多采用课堂讨论等方式,以提高学生的思辨能力和学习的主动性;引导学生读书、理解、体悟、运用相结合;提高学生的学习兴趣与热情,培养与发挥学生的提出、分析及解决问题的能力。

教学手段:运用多媒体教学手段 +黑板 +上机实验的手段。

采取课堂讲授、课堂讨论、课后练习与自学等形式。

大纲的使用说明:大纲对课程性质、目的等作简单说明,同时列出各章节要学习的知识点、重点、难点,便于教学时教授重点的安排和学生自学安排。

大纲正文第一章引论学时: 4 学时(讲课 4 学时,实验 0 学时)了解编译的概念;理解编译程序的各组成部分及功能。

本章讲授要点:介绍程序设计语言与编译程序间的关系,主要内容包括:各级程序设计语言的定义、源程序的执行、编译程序的构造、编译程序的分类、形式语言理论与编译实现技术的联系。

计算机导论-第8章 软件工程

计算机导论-第8章  软件工程
软件开发完成后,客户会对项目成果做出 评价,给出修正建议。在此基础上进入第二圈 螺旋,再次进行制定计划、风险分析、实施开 发和客户评估等工作。假如风险过大,开发者 和用户无法承受,项目有可能终止。多数情况 下,软件开发过程是沿螺旋线的路径连续进行 的,自内向外,逐步延伸,最终得到一个用户 满意的软件版本。
10
8.1.2 软件生命周期
5.软件测试
在软件分析、设计和程序编写过程中,难免有各种各样的错误,需要通过测试来查找 和修改,以保证软件的质量。其主要工作如下。
(1)单元测试 查找各模块在功能和结构上存在的问题并加以纠正。 (2)集成测试 将已测试通过的模块按照一定顺序组装起来进行测试。 (3)有效性测试 按照规定的各项需求,逐项进行测试,判断已开发的软件是否合格,能否交付用户使 用。
21
8.1.3 软件开发模型
4.螺旋模型
螺旋模型的思想是:使用原型 及其他方法来尽可能地降低风险。 它在软件开发的每个阶段,都增加 了一个风险分析过程。螺旋模型结 合了快速原型模型的迭代性质和瀑 布模型的系统性和可控性特点,适 用于大型软件的开发。螺旋模型由 4部分组成:制定计划、风险分析、 实施开发、客户评估,如图8-5所 示。在笛卡尔坐标的4个象限上分 别表达了4个方面的活动。
特别地,从经济学的意义上来说,考虑到软件庞大的维护费用远比软件开发费用要 高,因而开发软件不能只考虑开发期间的费用,而应考虑软件生命周期内的全部费用。 因此,软件生命周期的概念就变得特别重要。
6
8.1.2 软件生命周期
同任何事物一样,软件也有一个孕育、诞生、成长、成熟、衰亡的生存过程。软件生 命周期是指一个计算机软件从功能确定、设计,到开发成功投入使用,并在使用中不断地 修改、增补和完善,直到停止使用该软件的全过程。

大数据的Python基础课件第8章 函数设计与应用

大数据的Python基础课件第8章  函数设计与应用

#关键参数
14
8.2.4 可变长度参数
>>> def demo(a, b, c, *p): print(a, b, c) print(p)
>>> demo(1, 2, 3, 4, 5, 6) 123 (4, 5, 6) >>> demo(1, 2, 3, 4, 5, 6, 7, 8) 123 (4, 5, 6, 7, 8)
15
8.2.4 可变长度参数
>>> def demo(**p): for item in p.items(): print(item)
>>> demo(x=1, y=2, z=3) ('y', 2) ('x', 1) ('z', 3)
16
8.3 变量作用域
>>> def demo(): global x x=3 y =4 print(x, y)
20
8.4 lambda表达式
>>> from functools import reduce >>> reduce(lambda x,y:x*y, data[0]) #第一行所有数字相乘 0 >>> reduce(lambda x,y:x*y, data[1]) #第二行所有数字相乘 171018396981432000 >>> list(map(lambda row:row[0], data)) #获取每行第一个元素 [72, 28, 32, 22, 90] >>> list(map(lambda row:row[data.index(row)], data))

第8章符号表与错误处理

第8章符号表与错误处理
第8章 符号表与错误处理
8.1 符号表 8.2 错误处理 习题八
8.1 符 号 表
8.1.1 符号表的作用 在编译程序工作的过程中,需要不断收集、记录、查证 和使用源程序中的一些语法符号(简称为符号)的类型和特征等 相关信息。为方便起见,一般的做法是让编译程序在其工作 过程中建立并保存一批表格,如常数表、变量名表、数组内 情向量表、过程或子程序名表及标号表等,将它们统称为符 号表或名字表。符号表中的每一项包括两个部分:一部分填 入名字(标识符);另一部分是与此名字有关的信息,这些信息 将全面地反映各个语法符号的属性以及它们在编译过程中的 特征,诸如名字的种属(常数、变量、数组、标号等)、名字的 类型(整型、实型、逻辑型、字符型等)、特征(当前是定义性 出现还是使用性出现等)、给此名字分配的存储单元地址及与 此名语义有关的其他信息等。
下面,我们给出建造满足上述要求符号表的算法。为了使各 分程序的符号表登记项连续地排列在一起,并结合当扫描具有嵌 套分程序结构的源程序时总是按先进后出的顺序来扫描其中各个 分程序的特点,可设置一个临时工作栈,每当进入一层分程序时, 就在这个栈的顶部预造该分程序的符号表,而当遇到该层分程序 的结束符END时(此时该分程序的全部登记项都出现在栈的顶部 ), 再将该分程序的全部登记项移至正式符号表中。建立符号表的算
号表中找到此标识符,则从表中取出有关的信息并作相应的处理;
为了实现上述查、填表功能,可以按如下方式组织符号表: (1) 分层组织符号表的登记项,使各分程序的符号表登记项 连续地排列在一起,而不许为其内层分程序的符号表登记项所 分割。
(2) 建立一个“分程序表”,用来记录各层分程序符号表的 有关信息。分程序表中的各登记项是在自左至右扫描源程序中 按分程序出现的自然顺序依次填入的,且对每一分程序填写一 个登记项。因此,分程序表各登记项的序号也就隐含地表征了 各分程序的编号。分程序表中的每一登记项由三个字段组成: OUTERN 字段用来指明该分程序的直接外层分程序的编号; COUNT字段用来记录该分程序符号表登记项的个数;POINTER 字段是一个指示器,它指向该分程序符号表的起始位置。

第8章 汇编语言程序开发与调试

第8章  汇编语言程序开发与调试
第8章 汇编语言程序开发与调试
第8章 汇编语言程序开发与调试
8.1 汇编语言程序开发过程 8.2
第8章 汇编语言程序开发与调试
8.1 汇编语言程序开发过程
返回本章首页
第8章 汇编语言程序开发与调试
汇编语言开发过程
(1)编写程序,建立扩展名为.asm的汇编源程
序文件。
(2)对源程序进行汇编,生成目标文件(.obj)。
;------------------- 子程序ASCII结束--------------------------------------------
另外,对于大多数汇编语言程序都需通过调试才能检验 程序执行结果的。下面我们讨论汇编语言程序的调试方法。
返回本节
第8章 汇编语言程序开发与调试
8.2 汇编语言程序的调试方法
命令来调试程序。
返回本节
第8章 汇编语言程序开发与调试
3. DEBUG的主要命令
在输入提示符“-”后,键入?,然后回车,可以显示 DEBUG命令一览表。下面介绍其中得主要命令。 (1) 显示存储单元的命令D(DUMP),格式为:
-D[address]或_D[range]
例如,按指定范围显示存储单元内容的方法为: -d 100 120 18E4:0100 c7 06 04 02 38 01 c7 06-06 02 00 02 c7 06 08 02 G ...8.G.....G ... 18E$:0110 02 02 bb 04 02 e8 02 00-CD 20 50 51 56 57 8B 37.. ; .. h ..M PQVW. 7 18E4:0120 8B
图 8-7 编译界面
第8章 汇编语言程序开发与调试
同样直接输入demo.obj即可。在连接过程中 会提示我们是否需要生成映像文件.map和库文 件.lib,如下图8-8所示。一般不需要,可以直接 键入Enter跳过去。

编译原理第八章 符号表

编译原理第八章  符号表
• 需要做作用域分析!
8.3 名字的作用范围(Fortran)
• Fortran 局部、全局
• 执行时过程(函数)不
Name
Information
嵌套,局部区域只有一
···

个现行段;
···
部 • 编译时,尽管查填符号
表过程只限于局部,但
考虑到地址分配的全局
性,需将每个程序段符
号表保存在外存中,采
• 定长方式 • 间接方式 (1)名字的间接存储 (2)信息的间接存储
Name ● ●
Information
如何组织
方式
6 S A MP L E 3 S U M
Name
Information ● ●
数组信息表 维数 首地址 维1
内情向量表
··· ···
以数组为例 维n
如何组织
• 对于名称:把所有标识符都存放在一个 独立的字符串数组,主栏只放一个指示 器和一个整数(名字的长度)
var f, g: real; procedure B3(y:real) const b=5; procedure B4 … end B4 end B3
end B2 end B1
8.3 名字的作用范围 (Pascal)
top
(14)…
B4 (13)…
0
h (12)… 13
sp b (11)…
12
y (10)…
最近使用优先查找 (链头)
较难
中 排序整理 折半查找
二叉树
较难
中 构造排序树,查找时 依子树次序逼近。
杂凑(哈希

表)
高 杂凑函数: 名称于位置的映射 基于计算的查找。
数据结构的知识

济南大学练习自测题

济南大学练习自测题

第一章绪论1、填空题(1)程序设计语言中参数传递的方式有_________、_________、_________和_________。

(2)符号表的构造和处理方法有_________、_________和_________。

2、什么是源程序?什么是目标程序?3、画图说明编译程序主要由哪几个主要部分组成?各部分的功能是什么?第二章文法和语言1、一:文法G1: E→ET+|T T→TF*|F F→FP↑|P P→E|i(1)试证明符号串TET+*i↑是G1的一个句型(要求画出语法树). (2)写出该句型的所有短语,简单短句和句柄.2、已知文法G2: T→T*F|F F→(T)|i(1)试给出语句(i*i)#的自上而下分析过程(填下表); (2)画出对应的语法树,指出每一步归纳的句柄.3、已知文法G(E) E→T|E+T T→F|T*F F→(E)|i (1)给出句型(T *F+i)的最右推导及画出语法树;(2)给出句型(T *F+i)的短语、素短语。

4、写一个文法,使其语言是奇数集,且每个奇数不以0开头。

5、目标代码有哪几种形式?生成目标代码时通常应考虑哪几个问题?6、已知文法G(S) S→a|∧|(T) T→T,S|S 写出句子((a,a),a)的规范归约过程及每一步的句柄。

7、生成语言l={albmclanbn l>=0,m>=1,n>=2 }的文法是什么?它是chomsky那一型文法?8、设有字母表A1={a,b,…,z},A2={0,1,…,9},试回答下列问题: (1) 字母表A1上长度为2的符号串有多少个? (2) 集合A1A2含有多少个元素? (3) 列出集合A1 (A1∪A2)*中的全部长度不大于3的符号串。

9、设已给文法G=(VN,VT,P,S),其中: VN={S} VT={a1,a2,…,an,∨,∧,~, [,]} P={S→ai|i=1,2,…,n}∪{S→~S,S→[S∨S],S→[S∧S]},试指出此文法所产生的语言。

编译原理简明教程(第2版)[冯秀芳,崔冬华,段富][电子教案] 第14章

编译原理简明教程(第2版)[冯秀芳,崔冬华,段富][电子教案] 第14章

14.3
面向对象的动态存储分配
14.3.1 对象的存储区管理方式
对象的存储管理采用了3种模型:静态存储区管理、栈式存 储区管理、堆式存储区管理。 在静态模型中,程序装入或开始执行时为所有对象一次分配 所有空间,一个实体在整个软件运行过程中最多只能与一个运 行时对象联系。 在栈式模型中,一个实体在运行时可以相继与多个对象联系, 它以先进后出的方式分配和释放对象。 在堆式模式中,存储分配是完全动态的,对象通过显式的请 求动态创建,堆式模型最具有通用性,它是面向对象的计算所 需要的。
14.1.1 面向对象语言的基本特征
1. 对象之间通过消息相互通信
2. 封装 3. 继承 4. 多态性
14.1 概述
14.1.2 类和成员的属性构造
声明类的文法规则:
(1) dec→classdec (2) classdec→ class class_id {memberspec}| class class_id : class_id {memberspec} (3) memberspec→ memberdec memberspec | memberdec (4) memberdec→accessspec : type var ;| accessspec:funcdec; (5) accessspec→private | protected | public (6) type→comtype|classtype (7) classtype→ID (8) var→ID|ObjDef (9) funcdec→type ID (paramlist); | type ID (paramlist) funcbody; |ID (paramlist);|ID (paramlist) procbody;

ARM嵌入式系统第8章ARMADS集成开发环境

ARM嵌入式系统第8章ARMADS集成开发环境
•ARM嵌入式系统第8章ARMADS集 成开发环境
创建工程
ADS中的CodeWarrior是集管理、编辑、编译、 链接于一体的集成开发环境。用户可以利用工 程管理的思想组织项目开发中的源文件、库文 件、头文件和其他相关的输入输出文件。
工程能够将所有的源码文件有机地组织在一起, 并决定最终生成文件存放的路径,输出的格式 等。
AXD调试环境_查看反汇编代码
•ARM嵌入式系统第8章ARMADS集 成开发环境
使用JTAG仿真器来调试程序
使用AXD可以完成对程序的软件仿真调 试,但要完成硬件仿真和调试功能,则 需要通过JTAG仿真器实现ARM处理器与 主机的通信联络。
•ARM嵌入式系统第8章ARMADS集 成开发环境
使用JTAG仿真器来调试程序
•ARM嵌入式系统第8章ARMADS集 成开发环境
初始化存储器
通常ARM处理器都集成有SDRAM控制器。程序的在线 调试实际上是要将程序代码通过JTAG仿真器下载到处 理器的SDRAM空间执行,但是SDRAM在初始化上电时 并不能直接访问,必须配置它的刷新计数值、刷新时 间、刷新使能等才可以访问。
初始化存储器就是设置ARM处理器的某些寄存器,实 现对SDRAM存储空间映射的初始化过程。
EELIOD系统硬件决定了在进行JTAG调试时,一上电 SDRAM并没有初始化,故不能直接访问,下载程序前 需要先进行SDRAM的初始化工作。
•ARM嵌入式系统第8章ARMADS集 成开发环境
初始化存储器
ARMulaor可以提供指令执行时内部寄存器状况 及执行周期,可以进行应用程序的性能分析, 这样就为软硬件并行开发提供了极大的方便。
•ARM嵌入式系统第8章ARMADS集 成开发环境
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
生符先号前指已令编和译利好用的宏其机他制程来序帮模助块生。成常代用码的,编目译前程不序少大编多译采程用 序采这用种这可种浮代动码的形代式码。形式。
8.1.2 目标代码
本章采用汇编语言代码作为目标代码,但不针对某种特 定的目标机指令系统或汇编语言来生成目标代码,而是假设 有一台计算机,其指令系统等均按某种需要而设定,为教学 目的往往采取这种虚拟机目标代码形式。
2.按真转编写程序
8.2.2 虚拟机的汇编指令
3.按假转编写程序
8.3 从中间代码生成目标代码
8.3.1 从逆波兰表示生成目标代码 8.3.2 从四元式序列生成目标代码
8.3.1 从逆波兰表生成目标代码
从表达式的逆波兰表示生成相应的目标代码的算法可给出如下。 首先设立一个运算分量栈(栈),用来存放暂时不能处理的运算 分量的名(即工作单元地址)以及中间运算结果的名(即存放中间结 果的工作单元地址或累加器AC)。 其具体算法步骤如下。 从左到右扫描所给定的逆波兰表达式中的每个符号: 若扫描到运算分量,则将其下推入运算分量栈。 若扫描到运算符,按该运算符是几目运算,把运算分量栈 中相应个数的栈顶元素取出,生成该运算相应的目标代码,此后 栈上退去相应个数的运算分量,运算结果存放在“AC”中,把“AC” 标志入运算分量栈。 如此继续,直到整个逆波兰表达式处理完毕为止。
该虚拟机是一台地址单累加器的计算机,用“AC”表示该 累加器;设OP为操作码,d为地址,则指令: 0P d
表示 AC OP d=>AC
即累加器AC中的内容与d中的内容进行某种运算,结果送 到累加器AC中;其内存容量足够大;提供了21条符号汇 编指令。
8.2.2 虚拟机的汇编指令
虚拟机的汇编指令如表8.1所示。
各种代码的形式
• 中间代码: 后缀式,三地址代码,四元式 • 符号表中的项:名字,类型,嵌套深度,偏移
量 • 目标代码:绝对机器代码,可重定位代码,汇

代码生成器的输出必须是正确和高质量的 产生最优化代码的问题是不可判定的
目标代码的生成
目标代码生成是编译程序的最后一个工作阶段。它取先行阶段所产 生的源程序的中间语言或优化后的中间语言表示作为输入,产生等价的 目标代码作为输出,如下图8.1所示。
如果对X:=a[10]语句不采用填地址指令,其程序为 100 CLA <10> 101 ADD <<a[0]>> 102 STO M 103 ICA M 104 STO X
其中M为临时工作单元变量,用来存放<a[10]>,第103条指令使用间接取的方式,实现了X: = a[10]。
8.2.2 虚拟机的汇编指令
目标代码生成程序的输入、输出
编译程序的最终输出是目标代码,这在编译程序的代码 生成阶段完成,也可在语义分析阶段生成。一般地,代码生 成部分称为代码生成程序。代码生成程序的功能是为源程序 生成与之等价的目标机器代码。也就是说,其输入是由先行 端产生的源程序的中间表示,输出是目标代码。
假定在代码生成前,编译的先行端已扫描、分析和翻译 源程序,成为足够详细的中间表示,这样,中间语言中名字 的值可以表示为目标机器能够直接操作的量(位、整数、实 数、指针等),还假定必要的类型检查与插入类型转换等已 完成,不仅语法上正确,语义也是正确的,这样代码生成阶 段可以认为它的输入是正确的。
对于目标机器,如果有多个寄存器可供目标程序运行时使用,在编
译时根应据采访用问合内理存的数方来法定分义配每这条些指寄令存的器执。行把代运价算,数则据对存于放以在下寄的存一器中些,操
将作会 有减其少相访应问的内执存行的代次价数: ,从而可以提高执行速度。
分配操中作不码是把寄存器操平作均数分l 配给各个操变作量数使2用,而是从可执用行的代寄价存
② 检查达栈有式无进元行素语。法若没语有义,分则析当。前运算符入栈,然后转回到步骤①检查下一 个栈为,符了然号;后处否转理回则简步检单骤查起①运算,见符否,则的规转优定到先被步级。骤处③若理。当的前简的单比栈表顶达的式大的,前则当后前都运有算符入 特殊符号“#”,即呈下列形式:
③ 检查当前符号和栈顶元素。若当前符号是“)”,而栈顶元素是“(”,则“(”上
8.2.2 虚拟机的汇编指令
1.填地址指令
设有一维数组a: array[m..n]of integer; 其元素有a[m], a[m+1], … , a[i], … , a[n],一共需要n-m+1个存储单元: <a[m]>,<a[m+1]>,…,<a[i]>,…,<a[n]> 一般有存储单元: <a[i]>=<a[m]>+i-m 由于<a[0]>=<a[m]-m,所以有<a[m]>=<a[0]>+m。从而对于一维数组的存储单
器中分出几O个P ,固定分配寄给存几器个简单变量寄使存用器。按照什么标准来l分配呢? 为此引入一个术语:指令寄的存执器行代价,并规内定存访单问元内存一次的代价2为1。
寄存器
寄存器间接地址
2
寄存器
内存间接地址
3
寄存器分配
基于以上原因,分配中尽可能把变量值保留在寄存器中,当一个寄 存器的值不再需要时,该寄存器可以收回留作他用,但这只有对程序做 了全面的数据流分析后才能确定,这种分析要做大量的额外工作不太实 际,在寄存器的分配中常常以基本块为单位进行。
图8.1 目标代码生成过程
目标代码生成程序中的有关问题
对于一个好的代码生成程序,要求其使所生成的目标 代码尽可能地短,并能较充分地发挥目标计算机可用资源的 效率。如充分利用计算机的寄存器或变址器,以节省访问内 存的时间,尽可能使用执行速度较快的指令,存储管理合理, 等等。
熟悉目标机器和它的指令系统是设计一个好的代码生 成程序的先决条件,但在代码生成的一般性讨论中,不能对 目标机器细节描述到足够详细的程度,以便对一个完整的语 言产生好的代码。本章不以某一台具体的计算机做背景,只 是针对一个假想的计算机模型——虚拟机给出生成目标代码 的算法。
下面就以一种虚拟机指令系统来讨论目标代码的生成。
寄存器分配
通常,计算机存储之间不直接打交道,而是通过寄存器。寄存器可 以用来保存中间计算结果,而且运算对象在寄存器中的指令一般比运算 对象在内存的指令短些,执行速度也快些,因此,充分利用寄存器对生 成高质量目标代码尤其重要。寄存器的分配也自然成为目标代码生成中 的主要问题。
运行时的存储管理
通常所见到的计算机都是冯·诺依曼体系结构的,其特征是 变量——存储字,即用变量来仿效存储字,变量名实际上是 存储字的名字。
对于编译程序来说,必须对源程序中出现的变量与常量分 配运行时刻的存储空间,这一工作由先行端的分析和代码生 成程序共同完成。另从符号表的信息可以确定一个名字(标识 符)所代表数据对象在过程数据区中的相对地址。为了存储分 配的正确实现,除了必须考虑标识符的作用域问题外,还必 须考虑字边界对齐问题,即对于字节编址的计算机,必须注 意对于不同类型的量所分配存储区域的起始地址都必须符合 边界要求。
8.3.1 从逆波兰表生成目标代码
例如,对于逆波兰表达式:
所生成的目标代码为
ห้องสมุดไป่ตู้ab*cd+e/-
CLA a MPY b
具体生成目标代码处理过程如表8.2所示ST。O M
CLA c
ADD d
DIV e
SUB M
8.3.1 从逆波兰表生成目标代码
又如,对于逆波兰表达式:
所生成的目标代码为
aQbc*-d/
下推入栈,最后转回步骤②重复处理当前运算符。另外,在形成目标代码时 应注意“AC”有无被别的量占用,并进行相应处理。
元,有公式: <a[i]>=<a[0]>+i 其中<a[0]>称为数组的假头,<a[m]>称为数组的真头。
8.2.2 虚拟机的汇编指令
例如,有赋值语句:
X:=a[10]
设数组a为单块连续存放方式存放,<a[0]>为假头,则<a[10]>=<a[0]>+10。
假设指令编号从100开始,于是汇编指令编写的程序为 100 CLA <10> 101 ADD <<a[0]>> 102 STA l03 103 CLA 104 STO X
在一个基本块内,按照中间语言代码的顺序,逐个基本块产生目标 代码。生成的目标代码应尽可能将运算的结果存放在寄存器中,直到该 寄存器必须用来存放别的变量或基本块结束为止。这样可以减少基本块 访问内存的次数,从而提高运行速度。
如果把寄存器分配给某些变量,则该变量在定值前每引用一次,将 可少访问一次内存,从而可节省执行代价1;如果某变量在基本块中被定 值,且出基本块后还要被引用,则把寄存器固定分配给该变量,可省去 把它保存到内存单元的操作,从而节省执行代价2。
退栈并转#<回简第单一表步达;若式当>#前是“#”,栈项也是“#”,则处理完毕,算法结束。
若不是上述两种情况则转到步骤④。
④ 应根并的据把目与栈标顶“运代运#算”码算视分,符为量然的优后栈性先同质(栈时(数单退)为目,栈0或相和的双栈应运目。算算运运法算符算符如。结)下果从同存。栈时放顶引在取进“一运A个C”或算中两,符个并栈分把(量“栈生A)C成”标相志
SGN a STO M
具体生成目标代码的处理过程如表8.3所CL示A 。b
MPY c
ISU M
DIV d
8.3.1 从逆波兰表生成目标代码
① 从上左面到右首扫先描把简简单单表达表式达中式的改每造个符成号中。间若语扫言描到的运逆算波分兰量形时就式下,推然入栈, 若扫描后到由运逆算波符兰(包表括达括号式和生“成#”目)时标就代转码到②。,实如际此中一也直扫常描把下两去步,合直到整 个表达为式一扫步描,结根束为据止运。算符优先数的大小关系,直接对简单表
相关文档
最新文档