徐冰楠
(天津工业大学计算机科学与软件学院,天津 300387)
一个编译程序的重要性体现在它使得多数计算机用户不必考虑与机器有关的繁琐细节,使程序员和程序设计专家独立于机器,这对于当今机器的数量和种类持续不断地增长的年代尤为重要。
C语言是在20世纪70年代初问世的,但目前仍旧没有一个完整的标准C语言,后由美国国家标准学会制定了一个C语言标准。C语言属于一种结构化语言,易于调试、层次清晰、便于维护,能够按照模块化方式组织程序。在实际应用中,C语言的处理能力和表现能力极强,既有丰富的数据类型和运算符,便于各类复杂数据结构的实现,又可以实现内存物理地址的直接访问,方便于位一级的操作。在计算机系统中,C语言能够实现对系统硬件的操作,集低级语言与高级语言为一体,同时还可以应用于软件的开发。另外,C语言还具有较高的可移植性、高效率等优点,目前已经能够广泛应用于各型各类的计算机中。
编译是从源代码到能直接被计算或者虚拟机执行的目标代码的翻译过程。一般而言,编译器包含着入口点的地址和名字、及外部调用机器代码。编译器是程序员使用的关键工具,以下针对编译器的前端设计进行具体的分析:
(1)词法分析。这个阶段主要是根据相应的词法规则,将源程序中的各个记号一一标记出来,其中,每一个记号所代表着一类的单词,通常情况下,主要涉及到的记号常见的有标识符、关键字、特殊符号、字面量等等,利用词法分析器,输入源程序,输出识别记号符,最终将字号流转化为相应的单词。
(2)语法分析。对于语法分析,在实际应用时,主要根据相应的语法规则而将记号中的结构一一标识出,如句子、短语等,并且在此基础上,构造出能够准确地反映此结构的语法树。
(3)语义分析。在这个过程中,主要是根据语法规则实施语法单元的静态语义检查,比如转换、类型检查等,其最为根本的目的就是可以保证其在语法结构上的合法性。
在实际工作中,要想完成一个完美的编译器是一项较为复杂的事情,要了解语法的构成原理,要灵活掌握C语言语法,要考虑到C语言代码的灵活用法,具体主要从以下几个阶段来完成:
(1)词法分析
在C语言程序中,词法分析作为编译的第一个阶段,又可以被称之为扫描器,其最为主要的任务和目标就是将源程序中的各个字符连接起来,将其中的单词识别出来,与此同时,还要转换成为相应的内部编码,从而更好地应用于语法分析。一般情况下,单词符号的内部编码主要采用二元式来表示,在分析时,主要涉及到的单词类别有二进制、单词之值、分隔符、运算符的编码等,总体上讲,在计算机工作时,扫描器主要用于完成以下的目标和任务:将注释删除;将源程序中的各个符号和单词识别出来,转换为相应的内部编码形式;将无用的回车字符、空白字符删除;及时检查报告中存在的错误,及时进行语法检查。
另外,针对以上工程流程,在进行一些语法程序词法分析时,需要登录识别出的标志符。从工作方式角度来分析,编译流程与语法属于两种接口方式,一种是主要运用词法分析进行子程序的分析,能够有效地运用程序进行调用处理,当需要一个新单词时,就调用一次子程序,且在调用的过程中,还会相应地出现一个具有独立意义的单词;一种是采用词法分析对输出的结果进行分析,将其放置于中间文件上,同时作为一种输入进行程序分析。若是从功能上讲,主要就是将相应的字符源程序进行转换处理,从而变成单词串的形式。
(2)语义分析
将编译程序转换为一种内部表现形式后,我们将该种内部表现形式称之为中间语言或者是中间代码,它含义明确、结构简单,属于一种记号系统。比如一些编译程序,基本上没有中间代码,但是为了在实际应用中,确保机器的独立运行,易于实现目标代码的优化,在许多的编译程序中均设置了中间语言。这种中间语言介于机器语言和源程序语言中,程序相对复杂,而C语言编译器却在很大程度上改变以上现状,其语义分析和语法分析相对成熟,理论和算法比较完善,可仍旧存在的问题是没有公认的形式系统,中间代码仍旧接近于形式化的方法。
(3)语法分析
语法分析主要是以单词串形式的源程序作为分析与输入对象,其最为根本的目标和任务就是为了以设计语言的语法规则为标准,对源程序的语法结构进行具体的分析,根据设计语言的语法规则,对组成这些源程序的语法成分进行分析,如函数、下标变量、各种程序语句、各种表达式等等,并且要通过正确性的语法检查,将中间代码进行阶段处理。当前对于语法的分析主要包括两大类:一类是自顶向下,一种是自底向上。
①自顶向下
在这里试图设定一个输入串,从文法进行处理,构成一棵语法树,自下而下进行构造,若是成功,则文法可以成句;若是没有成功,则不能成句。与此同时,进行语法分析,通常还需要解决相关的障碍问题,具体主要体现在以下方面:一是采用最左推导处理,确保方法中非终结符号的传递,避免语法进入循环状态;二是对符号串进行配置处理,本质上讲,文法所产生的选式属于一个不断试控的过程,因此,必然会出现回溯问题,为此就会导致分析效率下降。因此,为了实现语法分析,则要对程序设计语言及其相关的文法进行分析,从而有效地消除回溯和递归现象。
②自底向上
对于这种形式的语法分析,同样需要给定相应的输入串,运用相应的文法进行处理,采用归约法试图去构成语法树,一般情况主要采用最左归纳法进行处理,以实现自底向上的分析,将输入符号进行逐个的推入处理,并对相应的产生式左部进行替换处理,以有效地完成一次归约,但是在归约时,为了得到更好的顶,则要对形成的新的句柄进行处理,反之,若是处理不达标,那么则要重复上述过程,从而完成最终的归约。但是要注意的一点是根据需要进行了归约处理,必然存在着相应语法错误,那么可以将其中全部输入的符号删除,改变上述格局,进行移进和归约分析,并且在此基础上,不断地寻找一个相应的策略,从而形成有效的语法分析方法。
(4)类型检查
所谓类型检查,就是通过给源程序设定一个表达式,根据类型表达式设置一组相应的规则,将其作为源语言的系统。类型检查的功能和任务就是能够准确地发现程序中的错误功能,如果目标代码既可以保持原有的元素类型,同时也可对元素值进行动态检查,更为重要的是可以避免源程序静态错误的发生。
基于C语言编译器的开发在可行性分析的基础上,进行深入、全面的分析,为此,在这里对C语言的运行情况和编译原理进行具体的分析,具体的功能流程图如图1所示:
图1 C语言编译器流程图
整个C语言框架可以说是整个编译器的前端核心,也是整个前端的入口点,因此,对于本身的不主动符号,所有动作均借助于Visual C++6.0,将其作为一个信息相互交互的过程,比如在编译时,Visual C++6.0的功能不能满足要求,可以对Visual Studio的开发环境进行具体的分析,并且结合目前最流行的Windows平台应用程序开发环境,对集成开发环境(IDE)的界面进行重新设计和组织,使得整个编译器的过程变得更加简单明了。与此同时,对于信息的处理和包装,还可以应用Visual Studio 2010、NET Framework 4.0、Microsoft Visual Studio 2010 CTP(Community Technology Preview--CTP)提供一个相应的规约式,以支持开发面向Windows的应用程序,其大致的过程包括符号信息的处理、编译器的具体动作、信息代码的提供等,结合Microsoft SQL Server、IBM DB2和Oracle数据库,以完成更高层的数据处理与包装,以下通过具体的事例来说明规约式动作的信息提取:
改程序改对后运行结果是327893.2789e+006A,改完后的代码:
通过以上编译,以实现一个符号项,加上每一个符号项各不相同,既可以保证类型的相同,又可以保证信息类别的多样化,最后通过与框架进行整合处理,以提供必要的机制,将其中的字符流转换成为内部代码,排除符号代码外,将其本身所携带的信息进行封装,并与特定的结构同符号一起返回处理。
整个C语言编译器涉及到的主要工作是程序的运行以及支持设计,要针对数据流和控制流进行优化分析,将基于中间代码的数据流结果和控制流结果进行科学处理,确保最后目标的生成。与此同时,整个设计过程中,框架作为运行支持的亮点环节,由于缺乏统一的标准,还需要针对特定的架构设计,设计出一种程序调度开销小、语言特点简洁、代码生成方便的运行环境给予支持。
[1]李松树,姚益平,周家和.YH-2C语言优化编译器的设计[J].计算机工程与科学,2011,(04):70-74.
[2]高陶.面向测控系统的MCL语言编译器设计[D].电子科技大学,2009.
[3]吴江.SQL语言预编译器的构架——基于Linux操作系统[D].北京化工大学,2012.
[4]王昭顺,杨树森,李周芳.嵌入式C02语言编译器的设计与实现[J].计算机应用研究,2011,(07):96-98.
[5]甄真.面向列数据库的SQL语言编译器设计与优化[D].华南理工大学,2012.
[6]姜娜,孔浩.一种支持软件演化过程描述语言的编译器的设计分析[J].绵阳师范学院学报,2013,(02):99-102.
[7]李颖,胡明.基于C语言实现的IDL编译器[J].计算机技术与发展,2013,(03):5-9.
[8]郑阳,付丽君,黄志钢.用于PLC的华P语言编译器设计与实现[J].沈阳理工大学学报,2009,(05):30-33.
[9]王晖,胡宝成,何华灿,王忠,沈绪榜.LSMPP数据并行C语言编译器实现的研究[J].微电子学与计算机,2010,(06):1-5.
[10]史岩,李蜀瑜,丘征,陈长胜.CoSy C语言编译器程序缓冲区溢出研究[J].计算机技术与发展,2012,(06):93-96.