2018年10月25日第2卷第10期
现代信息科技
Modern Information Technology Oct.2018
Vol.2No.10
C语言微型编译器的实现
李艳杰,高新阳
(山东华宇工学院,山东德州  253000 )
摘要:计算机之所以识别高级语言,是因为中间有编辑技术把高级语言编译为计算机所识别的语言,最终能在计算机硬件上执行。本文主要论述用C语言编写的微型编译器的实现过程。
关键词:C语言;编译器
中图分类号:TP314  文献标识码:A  文章编号:2096-4706(2018)10-0112-02
Implementation of C Language Mini Compiler
LI Yanjie,GAO Xingyang
(Shandong Huayu University of Technology,Dezhou  253000,China)
Abstract:The reason why computers recognize high-level languages is that editing technology compiles high-level languages into the languages recognized by computers,which can eventually be executed on computer hardware. This paper mainly discusses the implementation process of microcompilers written in C language.
Keywords:C language;compiler
收稿日期:2018-08-31
基金项目:本文为2015年度山东省职业教育教学改革
研究项目“高职软件技术专业课程及课程内容更新机制的实
践研究(项目编号:2015225)”阶段性成果
0  引言
编译技术是计算机语言发展中不可或缺的一部分,也是
计算机科学中比较成熟的一个部分,编译技术的主要思想就
是把一种语言表示的程序转换为另外一种语言表示的逻辑程
序。把不同的高级语言转换成相同的机器语言,最终到硬件c语言编译器怎么用?
计算机上执行,这些转化都涉及编译技术的应用。下面浅谈
一下C语言开发的微型编译器的实现过程。
1  C语言微型编译器的主要功能
C语言微型编译器的主要任务:即是查看用C语言的
规范字符组成的C语言源程序,然后把它们分解为单个具
有独立意义的单词符号(Token),还识别其有关属性再转
换成长度统一的属性字,最后对语义部分进行分解。其实,
C编译器的功能就是执行C源程序代码,识别代码,转换
成属性字,经过语义分解和代码生成,最终得到希望的代码
文件即三地址四元表达式。
此C语言微型编译器实现如下功能:(1)在源程序中识
别出每个单词;(2)绘制LR(1)分析表;(3)把分解的
单词的属性放入构造好的符号表中;(4)把单词转换成属性字,
最终形成二元组属性字流;(5)语义分析程序把符号表进行
加工处理;(6)最终生成目标代码;(7)显示基本出错处理。
2  C语言微型编译器的文件组成
基类Token,它包括了编译器中各种数据类型的定义和
整个编译器均可能使用到的全局变量的定义。ReadCfg类从
文件读取C语言文法,并保存在文法结点Cfg_node中。C
语言文法经总结共有57个产生式,其中终结符(terminal)
31个,存放在set<int>terminal中;非终结符26个,存放
在set<int>nonterminal中。Scanner类是词法分析的类,
成员函数scan()每次返回一个Token字。Grammer类主
要负责大量数据结构的保存和LR(1)分析表的构造,最终
分析表存放在action_中。Lr类包含语法分
析的总控程序,用成员函数analyse()实现对语法的分析,
在语法分析推导或归约的每一步骤中,通过语义规则实现对
属性的计算,以达到对语义的处理。main.c 文件是C编译
器的主程序,它负责整个程序的掌控。C语言微型编译器的
文件组成如表1所示。
表1 C语言微型编译器的文件明细表
.h头文件.cpp源文件模块功能说明
Cfg.h Cfg.cpp文法的定义
Token.h Token.cpp Token字
Scanner.h Scanner.cpp词法分析
Grammer.h Grammer.cpp语法分析表的构造
Lr.h Lr.cpp语法和语义分析
3  C语言微型编译器的相应结构
下面是C语言微型编译器用到的数据结构,这些数据
结构在编译的多个阶段都会用到,一些数据还会被共享。
3.1  一类单词(即记号)
扫描程序会把许多的字符收集到一个记号中,这个记号
会以符号的形式表示,源程序的记号集可以用一个枚举数据
第10期
113
类型的值代表。字符串本身或由此派生出的其他信息也会保留。在C 编译器中扫描程序一次只需要生成一个记号,这时会用全局变量来放置记号信息。
3.2  符号集
符号集中的信息与数据类型、变量、常量以及函数等有关。编译器会与它的整个过程进行交互:分析程序——扫描程序——标识符输入到表格中的语义分析程序;数据类型和其他语义信息是由语义分析程序增加的;代码生成阶段和优化阶段也会生成正确而恰当的代码。为了使访问、删除和插入等符号表操作都比常规操作更有效,所以编译的全程中对符号表的访问非常频繁。
3.3  项目(item )
在文法G 中,某个右部标上“点号”的产生式,再放置一个向前所搜符号a ,成为LR (1)项目。每个LR (1)项目集簇由若干状态组成,每个状态由若干项目组成。因此,对于构建项目集簇,项目的操作相当频繁,如何表示和处理项目成为构造分析表的重点。
3.4  中间代码(intermediate code )
根据优化的类型和中间代码的类型,字符串数组、指针数组、临时文本文件或是结构的连接列表都可以是该代码。对于进行复杂优化的编译器,需要选择允许简单重组的中间代码表示。
4  主要实现
词法分析、语法分析、语义分析、代码生成是C 编译器的四个过程,这四个过程分别用不同的程序模块来实现。经过编译之后,生成三地址的四元表达式目标代码,在整个编译过程中,这四个阶段分别承担了不同的翻译任务。
4.1  词法分析阶段
C 语言微型编译器的此阶段会把源程序翻译成有序字符文件,然后将其扫描分解为若干个同类单词。这
与自然语言中的单词类似:即字符序列。比如if 和while 是关键字(keyword ),它们是字母的固定串,在该语言中具有特定的含义;用户定义的字符串是标识符,是由一个字母开头并由字母和数字组成。源程序字符串是词法分析程序的输入,与源程序等价的符号序列是输出。作为词法分析程序的符号可以有各种不同的内部表现形式,原则是不同的符号能彼此区别开且有唯一的表示。
4.2  语法分析阶段
语法分析是编译过程的核心,分析的任务是根据语法规
则分析源程序的语法结构,并在分析过程中,对源程序进行语法检查,如果语法没有错误,则给出正确的语法结构,为语义分析和代码生成做准备。目前语法分析方法有多种多样,大致分为自顶而下和自底而上两大类。自顶而下又分为LL (1)分析方法和递归下降分析方法。自底而上又分为简单优先文法、算符优先文法、LR (K )分析方法。
LR (K )分析方法是1965年由D.Knuth 先生提出的一种自底而上的语法分析方法。自底而上的分析方法就是移进-规约的过程。LR (K )分析法能根据分析栈的当前内容以及向前看输入串的K 个字符来决定分析动作移进还是规约。
LR (K )分析方法适用范围较广,分析速度较快,并且能准确及时地发现语法错误。由于LR (K )分
析方法对文法限制很少,因而大多数能用上下文无关文法描述的程序设计语言都可用LR 分析法进行有效分析,而且LR 分析效率不亚于自顶向下分析法、算法优先分析法,及其他
“移进-规约”分析法。因此,LR 分析法是当前最一般的语法分析方法。对于一般使用的程序设计语言的文法而言,若手工构造分析程序,则工作量太大,而且K 越大,构造越复杂,实现越困难。因此,综合考虑,本实验采用LR (1)分析方法进行语法分析。
4.3  语义分析阶段
语义分析就是分析语法结构含义,表示成中间语言或生成目标指令。语义分析部分以语法分析部分的输出作为输入,输出则是中间代码甚至目标代码。语义分析的过程即计算编译过程中所需的附加语义信息。计算上下文无关文法和标准语法分析算法以外的信息都包括在内,所以,它不是语法。被翻译程序与语义信息的计算的最终含义或语义密切相关,由于编译器完成的语义分析是在程序执行之前予以明确的,即语义分析也可称作静态语义分析。在一个典型的静态类型的语言中,语义分析的任务通常包括构造符号表、记录声明中建立的名字的含义、在表达式和语句中进行类型推断和类型检查、在程序的不同作用域范围内判断变量的合法性。
通常,有两类语义分析:正确性分析是第一类分析,即根据编程语言的语义规则判定程序的正确性,并使它能正确执行。不同的语言语义分析是不同的。比如像在LISP 和Smalltalk 这类动态制导的语言中,
可能完全没有静态语义分析;而在Ada 或C 这类语言中就有很强的静态语义分析需求,程序必须提交执行。优化性分析是第二类分析,是由编译程序执行的用于提高翻译程序执行效率的分析。这一类分析通常包括对“最优化”或代码改进技术的实现。
4.4  生成中间代码
最后的过程是中间代码生成,用来生成针对特定目标的代码,即源代码语义的忠实体现。本文采取三地址格式的四元式来表示中间代码。四元式是一种更接近于目标代码的中间语言形式。由于这种形式的中间语言便于优化处理,因此是一种普遍采用的中间代码形式。需要说明的是,虽然本实验未做优化处理,但考虑到扩展性,仍然采用了这种四元式的中间代码形式。
这种四元式代码包括两个运算分量的地址和结果地址,所以也称为“三地址代码”。需要指出的是,每个四元式只能有一个运算符,所以一个复杂的表达式须由多个四元式构成的序列来表示。
总之,C 语言微型编译器的实现必须要有这四个阶段。
参考文献:
[1] 付立平,赵彩虹.编译原理教学改革的探讨与实践 [J].黑龙江教育(理论与实践),2015(1):77-78.
[2] 徐媛媛.C 语言编译器的设计与实现 [J].黑龙江科技信息,2015(10):154.
作者简介:李艳杰(1978.12-),女,汉族,山东德州人,教师,中级,硕士。研究方向:数据挖掘技术。
李艳杰,等:C 语言微型编译器的实现

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。