申优论文 北航本科编译原理大作业
申优论文 北航本科编译原理大作业

How to Design a C++ Object-orientedCompiler罗杨37230118 AbstractThis system is a C++ object-oriented compiler using a extended C0 grammar as the input language. It can generate the assembly code according to the Intel 386 instructions set. You can use the Masm32v10 software to assemble and link the source code to get your 32-bit applications.摘要本系统实现了一个以扩充C0文法为输入语言的采用C++及面向对象思想设计的编译器,可以生成符合386指令集规范的汇编代码,用Masm32v10汇编可生成32位应用程序。
本系统考虑到不同版本的Masm的功能和使用方法的差异,以及用户手工键入汇编,连接命令多有不便,本系统自带了汇编器Ml.exe和连接器link.exe。
正文由于是目标是Windows平台下32位应用程序,有些文法中的功能如输入和输出无法再像16位汇编时调用DOS中断解决,因此对于这些问题我使用Microsoft提供的类似高级语言的设计方法——调用DLL函数来解决。
其实32位汇编语言在函数调用方面已与高级语言相差无异,可以调用系统API,C RunTime甚至是用户DLL中的函数。
本系统是一遍扫描编译程序,采用面向对象的方法进行构建,各个主要部分均抽象成类。
主要的类有:分析器类Parser,符号表管理器类SymbolTableMgr,四元式管理器类QuadrupleMgr,代码生成器类CodeGenerator,错误处理器类ErrorHandler,全局数据流分析器类GDAOptimizer,全局寄存器分配器类GRDOptimizer,局部公共子表达式删除器类CSDOptimizer,以上属于具有明显功能划分和界限区别的―高级类‖,他们的对象在全局main函数中分别构造和删除;系统中还有其它一些既具有数据结构意义又具有功能操作的―中级类‖,它们一般是―高级类‖或―中级类‖的成员,如基本块集合管理器BBSetMgr,由全局数据流分析器类GDAOptimizer构建,并为其它多个优化器类共享;还有一些相对意义上的―低级类‖,它们具有复杂的数据结构,却几乎没有功能操作,通常由―中级类‖或―高级类‖得数组成员进行管理,如项类Item,四元式类Quadruple,其中项类Item代表符号表中的每一项,四元式类Quadruple顾名思义代表一个四元式,并且四元式的三个操作数是指向项Item的指针。
北航最优化方法有关大作业参考

1流量工程问题重述定一个有向网 G=(N,E) ,此中 N 是点集, E 是弧集。
令 A 是网 G 的点弧关矩,即 N×E 矩,且第 l 列与弧里 (I,j) ,第 i 行元素 1 ,第 j 行元素 -1 ,其他元素 0。
再令b m=(b m1 ,⋯,b mN )T,f m =(f m1,⋯ ,f mE )T,可将等式束表示成:Af m=b m本算例一典 TE 算例。
算例网有 7 个点和 13 条弧,每条弧的容量是 5 个位。
别的有四个需求量均 4 个位的源一目的,详细的源点、目的点信息如所示。
里了,省区了未用到的弧。
别的,弧上的数字表示弧的号。
此,c=((5,5 ⋯,5) 1 )T,×13依据上述四个束条件,分求得四个状况下的最决议量x=((x 12 ,x13,⋯ ,x75)1×13 )。
1 网拓扑和流量需求7 节点算例求解算例1(b1=[4;-4;0;0;0;0;0]T)转变为线性规划问题:Minimize c T x1Subject to Ax1=b1x1>=0 利用 Matlab 编写对偶纯真形法程序,可求得:最优解为 x1*=[4 0 0 0 0 0 0 0 0 0 0 0 0] T对应的最优值 c T x1=201.2.2 算例 2(b2=[4;0;-4;0;0;0;0] T)Minimize c T x2Subject to Ax2=b2X2>=0 利用 Matlab 编写对偶纯真形法程序,可求得:最优解为 x2*=[0 4 0 0 0 0 0 0 0 0 0 0 0]T对应的最优值 c T x2=201.2.3 算例 3(b3=[0;-4;4;0;0;0;0] T)MinimizeTc x3Subject to Ax3=b3X3>=0 利用 Matlab 编写对偶纯真形法程序,可求得:最优解为 x3*=[4 0 0 0 4 0 0 0 0 0 0 0 0] T对应的最优值 c T x3=40算例4(b4=[4;0;0;0;0;0;-4]T )Minimize c T x4Subject to Ax4=b4X4>=0利用 Matlab 编写对偶纯真形法程序,可求得:最优解为 x4*=[4 0 0 4 0 0 0 0 0 4 0 0 0] T对应的最优值 c T x4=601.3 计算结果及结果说明算例1(b1=[4;-4;0;0;0;0;0]T)算例 1 中,由 b1 可知,节点 2 为需求节点,节点 1 为供应节点,由节点 1 将信息传输至节点 2 的最短路径为弧 1。
编译原理作业参考答案

第1章引言1、解释下列各词源语言:编写源程序的语言(基本符号,关键字),各种程序设计语言都可以作为源语言。
源程序: 用接近自然语言(数学语言)的源语言(基本符号,关键字)编写的程序,它是翻译程序处理的对象。
目标程序: 目标程序是源程序经过翻译程序加工最后得到的程序。
目标程序(结果程序)一般可由计算机直接执行。
低级语言:机器语言和汇编语言。
高级语言:是人们根据描述实际问题的需要而设计的一个记号系统。
如同自然语言(接近数学语言和工程语言)一样,语言的基本单位是语句,由符号组和一组用来组织它们成为有确定意义的组合规则。
翻译程序: 能够把某一种语言程序(源语言程序)改变成另一种语言程序(目标语言程序),后者与前者在逻辑上是等价的。
其中包括:编译程序,解释程序,汇编程序。
编译程序: 把输入的源程序翻译成等价的目标程序(汇编语言或机器语言),然后再执行目标程序(先编译后执行),执行翻译工作的程序称为编译程序。
解释程序: 以该语言写的源程序作为输入,但不产生目标程序。
按源程序中语句动态顺序逐句的边解释边执行的过程,完成翻译工作的程序称为解释程序。
2、什么叫“遍”?指对源程序或源程序的中间形式(如单词,中间代码)从头到尾扫描一次,并作相应的加工处理,称为一遍。
3、简述编译程序的基本过程的任务。
编译程序的工作是指从输入源程序开始到输出目标程序为止的整个过程,整个过程可以划分5个阶段。
词法分析:输入源程序,进行词法分析,输出单词符号。
语法分析:在词法分析的基础上,根据语言的语法规则把单词符号串分解成各类语法单位,并判断输入串是否构成语法正确的“程序”。
中间代码生成:按照语义规则把语法分析器归约(或推导)出的语法单位翻译成一定形式的中间代码。
优化:对中间代码进行优化处理。
目标代码生成:把中间代码翻译成目标语言程序。
4、编译程序与解释程序的区别?编译程序生成目标程序后,再执行目标程序;然而解释程序不生成目标程序,边解释边执行。
编译原理作业与答案

编译原理独立作业2010.5一、简答题1、 构造一个文法使其生成的语言是不允许0打头的偶正整数集合。
2、文法][E G :T T E T E E -+→,F F T F T T /*→,i E F )(→,构造句型i T T T *+-的语法树,并指出该句型的短语、直接短语、句柄、素短语和最左素短语。
3、 某LL(1)文法的预测分析表如下,请在下述分析过程表中填入输入串( a , a )$ 的分析过程。
4、 文法][S G :R L S =→,R S →,R L *→,i L →,L R →,求增广文法中LR(1)项目集的初态项目集I 0。
5、文法][S G :G G S S ;→,()G G t H →,)(S a H →,求出各非终结符的FISTVT 和LASTVT 集合。
二、分析题:1、构造自动机,使得它能识别字母表{0,1}上以00结尾的符号串,将构造的自动机确定化,并写出相应的正规文法。
2、文法][S G :RT eT S → εDR T → εdR R → bd a D →,写出每个非终结符的FIRST 集和FOLLOW 集,并判断该文法是否为LL(1)文法。
3、若有文法][S G :AB S → εaBa A → εb A b B → (1)试证明该文法是SLR(1) 文法,并构造SLR(1)分析表。
(2)给出输入串aa # 的分析过程。
参考答案一、简答题1、构造一个文法使其生成的语言是不允许0打头的偶正整数集合。
8|6|4|2|ABC Z → 9|8|7|6|5|4|3|2|1→A ε|0|B AB B → |8|6|4|2|0→C2、文法][E G :T T E T E E -+→,F F T F T T /*→,i E F )(→,构造句型i T T T *+-的语法树,并指出该句型的短语、直接短语、句柄、素短语和最左素短语。
短语:T ,T-T ,i ,T*i ,T-T+T*i直接短语:T , i 句柄: T素短语(P72):T-T,i 最左素短语:T-T3 某LL(1)文法的预测分析表如下,请在下述分析过程表中填入输入串( a , a )$ 的分析过程。
北航编译技术在线作业三

北航《编译技术》在线作业三北航《编译技术》在线作业三单选题多选题判断题一、单选题(共14道试题,共56分。
)1.文法G产生的()的全体是该文法描述的语言。
A.句型B.终结符集C.非终结符集D.句子-----------------选择:D2.Chomsky定义的四种形式语言文法中,2型语言文法又称为()文法。
A.短语文法B.上下文无关文法C.上下文有关文法D.正规文法-----------------选择:B3.如果r、s是正规式,则下面()不一定是正规式。
A.rsB.r|sC.r*D.r+s-----------------选择:D4.算符优先分析每次规约的是()。
A.最左短语B.直接短语C.句柄D.最左素短语-----------------选择:D5.最常用的中间代码形式是()。
A.二元式B.三元式C.四元式D.树形表示-----------------选择:C6.文法E→(E)产生的语言是()。
A.空集B.()C.(E)D.((((E))))-----------------选择:A7.下面哪个文法是左递归的()。
A.E→E+T|TB.T→F*TC.E→(E)D.E→a-----------------选择:A8.Σ={0,1}上的正规式(0|1)*表示()。
A.0开头的串B.1开头的串C.有一个0和一个1的串D.由0、1组成的任意串-----------------选择:D9.正规式(a|b)*表示的是()。
A.所有由字母a或b构成的串B.字符串a|bC.字符串(a|b)*D.空串-----------------选择:A10.编译器与要编译的源程序的接口阶段是()。
A.扫描程序B.语法分析程序C.语义分析程序D.代码生成器-----------------选择:A11.有限自动机可以有()个初始状态。
A.一个B.两个C.三个D.多个-----------------选择:A12.语法分析属于编译器的()阶段。
北航计算机学院编译习题讲解

北航计算机学院编译习题讲解习题课 (1-3章)1、复习2、习题讲解北京航空航天大学计算机科学与工程系2008年6月27日1第一章概论(介绍名词术语、了解编译系统的结构和编译过程)北京航空航天大学计算机科学与工程系2008年6月27日21.2 编译过程所谓编译过程是指将高级语言程序翻译为等价的目标程序的过程。
习惯上是将编译过程划分为5个基本阶段:词法分析语法分析语义分析、生成中间代码代码优化生成目标程序北京航空航天大学计算机科学与工程系2008年6月27日 3典型的编译程序具有7个逻辑部分 S.P 词法分析程序符号表管理语法分析程序语义分析、生成中间代码代码优化生成目标程序 O.P 出错处理北京航空航天大学计算机科学与工程系2008年6月27日4第二章? 掌握符号串和符号串集合的运算、文法和语言的定义? 几个重要概念:递归、短语、简单短语和句柄、语法树、文法的二义性、文法的实用限制等。
? 掌握文法的表示:BNF、扩充的BNF范式、语法图。
? 了解文法和语言的分类北京航空航天大学计算机科学与工程系2008年6月27日 5第三章:词法分析3.1 词法分析的功能 3.2 词法分析程序的设计与实现–状态图3.3 词法分析程序的自动生成–有穷自动机、LEX北京航空航天大学计算机科学与工程系2008年6月27日6补充正则文法正则文法 1 2 4 NFA NFA 3 DFA DFA 最小化北京航空航天大学计算机科学与工程系2008年6月27日 75 6 正则表达式正则表达式习题1-3章北京航空航天大学计算机科学与工程系2008年6月27日8第一章2.典型的编译程序可划分为哪几个主要的逻辑部分?各部分的主要功能是什么?北京航空航天大学计算机科学与工程系2008年6月27日91.2 编译过程所谓编译过程是指将高级语言程序翻译为等价的目标程序的过程。
习惯上是将编译过程划分为5个基本阶段:词法分析语法分析语义分析、生成中间代码代码优化生成目标程序北京航空航天大学计算机科学与工程系2008年6月27日 10典型的编译程序具有7个逻辑部分 S.P 词法分析程序符号表管理语法分析程序语义分析、生成中间代码代码优化生成目标程序 O.P 出错处理北京航空航天大学计算机科学与工程系2008年6月27日11P19:4.试证明:A+ =AA*=A*A 证:∵ A*=A0∪A+,A+=A1∪A2∪…∪An∪… 得:A*=A0∪A1∪A2∪…∪An∪… ∴ AA*=A(A0∪A1∪A2∪…∪An∪…)= AA0∪AA1∪AA2∪…∪A An∪… =A∪A2∪A3∪An +1∪… = A+ 同理可得:A*A =(A0∪A1∪A2∪…∪An∪…)A =A0 A∪A1A∪A2A∪…∪AnA∪… = A∪A2∪A3∪An+1∪… = A+ 因此: A+ =AA*=A*A北京航空航天大学计算机科学与工程系2008年6月27日 12P26:1.设G[〈标识符〉]的规则是:〈标识符〉::=a|b|c| 〈标识符〉a|〈标识符〉c| 〈标识符〉0|〈标识符〉1 试写出VT和VN,并对下列符号串a,ab0,a0c01,0a,11,aaa给出可能的一些推导。
编译原理结课论文精选全文

可编辑修改精选全文完整版目录1. 绪论 (2)1.1概述 (2)1.2设计目的 (2)1.3设计题目及要求 (3)2.背景知识 (3)2.1语法制导翻译方法 (3)2.2属性文法 (4)2.3几种常见的中间语言 (4)2.4四元式的简介 (4)3.设计过程 (5)3.1设计思路 (5)3.2实现 (6)4.上机调试运行 (7)4.1代码调试界面及结果 (7)4.2执行及结果 (7)5.注意事项 (8)6.总结 (9)参考文献 (10)附录 (11)1.绪论1.1概述“编译原理”是一门研究设计和构造编译程序原理课程,是计算机各专业的一门重要的专业课。
编译原理这门课程蕴含着计算机学科中解决问题的思路和解决问题的方法,对应用软件和系统软件的设计与开发有一定的启发和指导作用。
“编译原理”是一门实践性很强的课程,要掌握这门课程中的思想,就必须要把所学到的知识应用于实践当中。
而课程设计是将理论与实践相互联系的一种重要方式。
1.2设计目的课程设计是对学生的一种全面综合素质训练,是与课堂听讲、自学和练习相辅相成的必不可少的一个教学环节。
通常,设计题中的问题比平时的练习题要复杂很多,但也更接近实际。
编译原理这门课程安排的课程设计的目的是旨在要求学生进一步巩固课堂上所学的理论知识,深化理解和灵活掌握教学内容,选择合适的数据逻辑结构解决问题,然后编制算法和程序完成设计要求,从而进一步培养学生独立思考问题、分析问题、解决实际问题的能力。
1.3设计题目及要求基于这个学期所学习的内容以及自己所掌握到的知识,本次我所要设计的题目是赋值语句的四元式生成。
要求:(1)设计语法制导生成赋值语句的四元式的算法;(2)编写代码并上机调试运行通过;(3)输入一赋值语句;(4)输出相应的表达式的四元式;2.背景知识2.1语法制导翻译方法语法制导翻译的方法就是为每个产生式配上一个翻译子程序(称语义动作或语义子程序),并在语法分析的同时执行这些子程序。
编译原理作业(答案new)

第3章作业【编辑人:陈芳芳】1.写一文法,使其语言是偶正整数的集合。
要求:(1)允许0打头;(2)不允许0打头。
【解】:(1)允许0打头且含0的偶正整数集合的文法为:N—>(0|D|E)N|(E|0)D—>1|3|5|7|9E—>2|4|6|8(2) 不允许0打头的偶正整数集合的文法为:R—>(D|E)N|EN—>(0|D|E)N|(E|0)D—>1|3|5|7|9E—>2|4|6|82.一个上下文无关文法生成句子abbaa的推导树如下:SA B Sa S B B A aƐ b b a(1)给出该句子的相应的最左推导,最右推导。
(2)该文法的产生式集合P可能有哪些元素?(3)找出该句子的所有短语,简单短语,句柄。
【解】:(1)最左推导:S=>ABS=>aBS=>aSBBS=>aBBS=>abBS=>abbS=>abbAa=>abbaa最右推导:S=>ABS=>ABAa=>ABaa=>ASBBaa=>ASBbaa=>ASbbaa=>Abbaa=>abbaa (2) 产生式集合P:S—>ABS | Aa| ƐA—>aB—>SBB | b(3) 短语:a , Ɛ , b , bb , aa , abbaa直接短语:a , Ɛ , b句柄:a3、给出生成下述语言的上下文无关文法:(1){a n b n a m b m | n, m >= 0}(2){1n0m1m0n | n, m >= 0}【解】:(1)S—>AAA—>aAb | Ɛ(2)S—>1S0 | AA—>0A1 | Ɛ第4章课后作业1. 构造一个状态数最小的DFA,它接受∑={0,1}上所有倒数第二个字符为1的字符串。
【编辑人:胡志高】【解】:(1)构造相应的正规式:(0|1)* 1(0|1)(2)由正规式构造NFA,如下图:(3)NFA转化DFA① T0=ε-closure({0})={0}②运用子集构造法求DFA状态,如下表,其中T0为初态,T2、T3为终态:ε-closure(move(Ti,0))ε-closure(move(Ti,1)) T0={0}{0} {0,1}T1={0,1} {0,2} {0,1,2}T2={0,2} {0} {0,1}T3={0,1,2} {0,2} {0,1,2}③分别用0,1,2,3代表T0,T1,T2,T3,得DFA如下图:(4)最小化DFA①找DFA中等价状态,分析过程如下:P0=({0,1},{2,3})P1=({0},{1},{2},{3})经以上分析可知:0无等价状态。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
How to Design a C++ Object-orientedCompiler罗杨37230118 AbstractThis system is a C++ object-oriented compiler using a extended C0 grammar as the input language. It can generate the assembly code according to the Intel 386 instructions set. You can use the Masm32v10 software to assemble and link the source code to get your 32-bit applications.摘要本系统实现了一个以扩充C0文法为输入语言的采用C++及面向对象思想设计的编译器,可以生成符合386指令集规范的汇编代码,用Masm32v10汇编可生成32位应用程序。
本系统考虑到不同版本的Masm的功能和使用方法的差异,以及用户手工键入汇编,连接命令多有不便,本系统自带了汇编器Ml.exe和连接器link.exe。
正文由于是目标是Windows平台下32位应用程序,有些文法中的功能如输入和输出无法再像16位汇编时调用DOS中断解决,因此对于这些问题我使用Microsoft提供的类似高级语言的设计方法——调用DLL函数来解决。
其实32位汇编语言在函数调用方面已与高级语言相差无异,可以调用系统API,C RunTime甚至是用户DLL中的函数。
本系统是一遍扫描编译程序,采用面向对象的方法进行构建,各个主要部分均抽象成类。
主要的类有:分析器类Parser,符号表管理器类SymbolTableMgr,四元式管理器类QuadrupleMgr,代码生成器类CodeGenerator,错误处理器类ErrorHandler,全局数据流分析器类GDAOptimizer,全局寄存器分配器类GRDOptimizer,局部公共子表达式删除器类CSDOptimizer,以上属于具有明显功能划分和界限区别的―高级类‖,他们的对象在全局main函数中分别构造和删除;系统中还有其它一些既具有数据结构意义又具有功能操作的―中级类‖,它们一般是―高级类‖或―中级类‖的成员,如基本块集合管理器BBSetMgr,由全局数据流分析器类GDAOptimizer构建,并为其它多个优化器类共享;还有一些相对意义上的―低级类‖,它们具有复杂的数据结构,却几乎没有功能操作,通常由―中级类‖或―高级类‖得数组成员进行管理,如项类Item,四元式类Quadruple,其中项类Item代表符号表中的每一项,四元式类Quadruple顾名思义代表一个四元式,并且四元式的三个操作数是指向项Item的指针。
由于这些―低级类‖对象通常代表基本数据,数量众多而又经常在各个高级对象之间传递,为了减少时间空间的开销,本系统对所有的类均采用指针构造,这样需要传递的就不是对象而只是一个指针了,有效地提高了程序的运行效率。
本系统的一个特点是词法分析和语法分析结合,其功能集成在词法与语法分析类Parser 里,虽然本系统整体式面向对象的,但由于词法分析和语法分析本身的特性,Parser类却具有明显的面向过程的特征:各个代表文法子程序的层次关系,中间不断嵌入的词法程序和语义程序(动作符号子程序),这样的体系几乎体现不出面向对象抽象封装的优势,因此我在这部分虽然代码写的很快,调试却花了比写还要长的时间,这的确说明了我前期的程序框架没有设计好,没有一个好的结构的程序,代码量不大时并不会体现出它的缺陷,但是随着规模的扩大,功能的复杂化,程序最后会达到难以维护的程度。
因此我觉得在词法与语法分析方面能构造出一个简便适用的面向对象的模型非常必要。
另外在语法分析方面,考虑到题目中的C0文法并无左递归问题,只有回溯问题。
根据课本,为了消除回溯可以用改写文法或是预读字符的方法。
当时课堂上老师着重讲了改写文法的方法,预读字符的方法只是介绍了一下。
但是我考虑到若改写成等价文法,使规则右部多个候选式首符号集不相交的话,虽然语法分析变得简单了,但改写后的规则中的符号含义变得不明确,本来是语义连贯的动作符号语义子程序,可能因为文法的改写被分到不同的语法递归子程序中,参数传递复杂而繁琐,而且模糊了语义编写时容易出错。
反而给语义分析带来更大的麻烦。
因此我采用预读字符的方法处理回溯问题,由于在预读字符时只是进行语法分析,并没有语义处理,因此不会出现课本上所说的―相关的语义分析工作在回溯时也要推倒重来‖的情况,不难验证,这两种方法在运行速度上并无本质差别。
我认为本系统一个比较突出的亮点是中间代码——四元式的操作数均为指向符号表某一项的指针,也就是说中间代码其实是四元式表加上符号表。
这样做不仅节省空间,而且由于符号表存储了几乎所有的数据结构信息,在代码生成或优化中都非常方便调用。
显然若这样的话,符号表在生成目标代码前是不能释放的,因此没有采用课本上介绍的栈式符号表。
显而易见,进行语义分析时进入和退出过程的动作与堆栈很像,因此本系统的符号表也采用了一个指针pCurrentTable来表示当前栈顶符号表。
因此需要一个对象来管理当前栈顶符号表pCurrentTable。
再者,考虑到不同模块(过程或函数定义)的在变量作用域上具有独立性(即模块外的语句不可访问模块内变量),因此本系统实现了多符号表架构。
前面提到,本系统的―高级类‖之一是符号表管理器类SymbolTableMgr,就是用SymbolTableMgr来管理符号表SymbolTable。
存储方式考虑到符号表之间的严格的层次关系并没有采用符号表数组这样的线性存储方式,而是采用的类似于链式存储的形式。
在这里指针发挥了很大的作用。
按照前面所说,符号表SymbolTable以数组形式拥有项Item,这里项Item设置了一个pChildTable指针,表示子符号表,这个Item实际上就代表函数(过程)定义里的函数(过程)头,它拥有这个函数(过程)所对应的符号表。
然后符号表管理器类SymbolTableMgr 模拟了堆栈的操作——压栈和出栈,即对当前栈顶符号表pCurrentTable进行变更。
为了方便出栈,为每个符号表SymbolTable设置了父项Item,同时又为每个Item设置了父符号表SymbolTable,这样本系统实现的符号表体系实际上类似一个双向链表。
对于单个的符号表,课本上提到,其实编译系统分析过程中很多时间花费在查表建表上,并且提出了多种符号表组织形式,如无序符号表,有序符号表,散列符号表等等。
无序符号表插入操作简单,但查表费时;有序符号表,查表可以用很快的折半查找法,但插入时需要同时移动很多元素,很费时;散列符号表又过于复杂,包括HASH函数的选取等。
因此我借鉴本学期―数据库系统概论‖里介绍到的一种方法来解决插入和查找的时间复杂度问题,这就是索引。
为每一个符号表建立一个Int类型的索引数组,数组内容即为原表项Item数组下标。
这样在插入时,数据插入原表项Item数组末端,更新索引。
查找时直接查找索引即可。
因此插入和查找的时间复杂度都很低。
在中间代码方面,由于考虑到为使涉及四则运算的代码更易实现,选定了符号表项Item 作为四元式的操作数,但是也存在一些问题,有些操作数如符号串,标签,局部常量并不是符号表的内容,并且有着自己特殊的操作,如标签的命名等等。
由于不能存储在符号表中,因此把它们按类分别建立项Item的数组,由四元式管理器QuadrupleMgr拥有。
并且这些Item 的kind属性各不相同,这样就可以实现不同的语义动作,如全局变量显式生成声明语句,实参分配压栈后的地址,局部变量分配运行栈中的地址,全局常量采用类似C++中宏定义的使用方式,局部常量直接常量替换等等。
最后虽然各个操作数的意义大不相同,但至少逻辑格式是统一的,并且通过它的type可以很好地区分不同类型的操作数。
基于以上的优点,这部分的代码完成速度很快,而且质量也有保障。
文法中的条件转移语句中有6种关系操作,即>,<,==,>=,<=,!=,但它们的运算方式其实与普通的四则运算还是很像的,都有两个源操作数和一个目标操作数。
其实在C 语言语义下文法按照这样设计的,根据两个源操作数大小关系决定目标操作数为零还是非零。
因此我的中间代码所使用的指令就有类似的操作,即根据两个源操作数大小关系决定目标操作数为零还是为一。
这样就关系运算就没有必要和跳转指令绑在一起了,也算是一种对文法的扩展吧,当然只是语义上的,语法分析部分如果不符文法还是会报错的。
这里要提到的是由于X86指令集并没有判断大小并赋值的语句,因此上面提到的这些中间代码的指令生成汇编代码时实际上还是采用的判断跳转指令。
虽然本质上并没有避开跳转指令,但是这就实现了中间代码对汇编代码的一层抽象。
还有浮点数处理也是本系统着重实现的功能之一。
虽然文法中的三种数据结构char,int,float实际需要的大小并不一致,虽然int有16位和32位之分,但VC6生成的汇编的int类型是32位的,而float也是32位。
虽然char是8位大小的,为了方便处理考虑,本系统生成的汇编中char按照32位处理,由于文法并不存在数组这样的数据结构,可知这样的设定不会造成明显的空间浪费。
并且,事实上由于CPU内部执行机制的原因,统一大小的数据块通过寄存器和内存间的赋值往往比大小不一的数据块的赋值要快。
这就是为什么有时候VC6生成的汇编代码中的赋值经常取齐为字或双字的原因。
虽然char类型在运算时可以直接按照int类型来处理,毕竟存储格式本质是一样的。
而浮点数就不同了,IEEE定义的单精度浮点类型float的存储格式与int完全不同。
因此在涉及混合类型运算时必须进行格式转换。
可喜的是,386汇编指令集提供了浮点运算和转换的指令,由专门的CPU浮点数运算单元来处理。
因此,针对汇编指令集的情况,构建了两条中间代码指令来完成float转int和int 转float的运算。
因此在遇到混合类型的四则运算时,char和int之间是不需要处理的,若遇到float类型操作数,则它的临操作数若不是float类型也需要格式转换成float。
即对表达式内的表示范围较窄的类型进行隐式提升。
若赋值式的左右操作数类型不一致时,右操作数会强制格式转换成左操作数类型赋值。
浮点数需要在生成的汇编代码里能够运算和类型转换,这主要数针对浮点数变量而言的。
若存在浮点数常量的话,此常量必须在编译时就得到正确的值。
因此本系统在数据转换器类DTS中的ToFloat函数实现了把string类型的实数转换为其对应的string类型的32位浮点数格式,如string―1.234‖转化为string―3F9DF3B6h‖。