简单的C语言编译器

  • 格式:pdf
  • 大小:374.11 KB
  • 文档页数:18

三.概述
经过一段时间的学习,我们在初步掌握了编译器的基本原理以后,设计了一 个具有基本编译功能的编译器。该编译器接受类 C 语言语法的源代码输入,输出结 果是 PC 机的汇编源代码。在捆绑了宏汇编编译器 Masm 后,即可直接生成 MSDOS 下 的二进制可执行文件。为方便起见,以下简称为 C—语言编译器。
由于编译程序本身涉及到词法分析、语法分析、代码生成、错误恢复和优化 等诸多模块,要在实验中做到面面俱到不太可能,所以本编译器不可避免的会存在 各种问题,但作为一个具有基本功能的、可扩充的系统,完全达到了巩固编译原理
的理论知识,并将其运用于实践的目的。
四.背景
编译程序,就是一种具有编撰和翻译功能的程序。人们要用计算机来解决问 题,首先面临的一个问题,就是要告诉计算机解决什么问题,或者告诉计算机如何 解决这个问题。这就涉及到用什么样的语言来描述的问题,人所习惯的自然语言和 计算机认识的机器语言有很大的差别,用机器语言来描述人想解决的问题十分不便, 因而,计算机科学家设计一些人们比较习惯的语言来描述要解决的问题,称之为高 级语言。用语言来描述的问题,统称为程序。然而,用高级语言写的程序,不能被 计算机所直接认识和理解,必须经过等价的转换,变成机器能理解并执行的机器语 言的程序。进行这种等价转换工作的工具,就是编译程序。
则 G 表示一个文法。 乔姆斯基(Noam Chmosky)把文法分成四类:0 型文法又称无约束文法,产生
式的形式为 a→b,a、b 是任意字符串。1 型文法又称上下有关文法,产生式形式为 a→b,且|a|≥|b|。2 型文法又称上下文无关文法(Context-Free Grammar),产生式形式 为 A→a,a∈(VN∪VT)*,A∈VN。3 型文法又称正规文法,它的产生式左部是一个 非终结符号,右部最多只有一个非终结符号且在右部的最左端或最右端。通常程序 设计语言的文法属于 2 型文法,可被下推机(Pushdown Automaton)识别。
可能产生的四元式序列为: (*,_t0,10,m) (-,_t1,z,_t0) (+,_t0,y,_t1) (=,x,_t0)
由于中间语言对后面的代码优化和目标代码生成有密切关系,又和目标机器的 体系结构有关,所以中间语言的选择对于编译器的效率和质量有很大的影响。
1.4 代码优化 代码优化是把中间代码进行变换,以产生更加高效的目标代码。


优化器
IR
代码生成器
IR
目标机器码
图 1 编译器基本结构
1.1 词法分析 词法分析负责对源程序的字符串进行扫描和分解,根据构词法将字符流
(Character Stream)转化成单词流(Token Stream)。 例如对于 C--语句: x = y + z – m * 10;
词法分析的结果是: ID ASSIGN ID ADD ID SUB ID MUL NUM SEMI 构词的规则就是词法,例如标识符(ID)可定义为以字母开头,后面跟零个或任
char[]
字符数组
int[]
整型数组
备注
整型为有符号 16 位数。 字符型为 8 位数。 数组的下标允许为任何合法的表达式。 经过简单扩充后,即可实现长整型,无符 号整型。
支持以下数据操作:
+
加法
-
减法
*
乘法
/
除法
%
取余
++
自加 1
--
自减 1
**
乘方
&, |
位与,位或
^
异或
~
位非
&&,||
逻辑与,逻辑或
ALex 和 AYacc 的表驱动代码隐藏在联接库中。库在程序 LINK 的时候连入 系统中。这在程序编译的效率和灵活性两个方面都有较大贡献。
ALex 和 AYacc 的原代码和和生成的目标代码(C 或 C++)可以建立语句的 对应,这对生成代码的调试提供很大方便。
实验中的编译程序采用将 ALex 和 AYacc 文件转化为 Visual C++格式的代码。 现将程序中使用的联接库中主要类和函数作一介绍。
五.详 细 设 计
1.功能说明
输入: 类 C 语言纯文本源程序。 输出:
·目标机为具有 8086+处理器的 MSDOS 系统下的二进制可执行代 码。
·PC Assembly Language 汇编语言源代码以供分析使用。
本编译程序实现的主要功能如下表所示:
功能
支持以下数据类型:
int
整型
char
字符型

逻辑非
<,>,<=,>=
关系比较运算
==,!=
关系比较运算
<<,>>
算术移位
[+-*/%]=,**=, 多达 12 种赋值
<<=,>>=,&=, 语句
|=,^=,=
支持以关键字_asm 前导的形式为
_asm { … … } 的 嵌 入 汇 编 代 码
(EMBEDED ASSEMBLY)。
对嵌入汇编的支持大大提高的语言的可 用性,一定程度弥补了系统函数较少的缺 憾。
中国好资料 一个简单的 C 语言编译器
一.小组成员
朱嘉俊(3991102161) 王筱(3991102168) 朱杭(3991102162) 朱林(3991102094)
二.运行方式
在 DOS 环境下运行: Cminus.exe <filename> -h
计算机 996 计算机 996 计算机 996 计算机 994
意个字母或数字的序列。词法分析程序就根据词法构造有限自动机来识别每一个单 词,将产生的单词交给语法分析程序。
1.2 语法分析 语法分析模块的任务是根据文法规则把单词序列分解成各类语法单位,识别出
一个一个句子,例如对前面的语句进行语法分析可得到如图 2 的分析树。 如果输入单词不能构成语法树,则说明有语法错误。常见的语法分析方法分为
2.词法分析器(lexer)
2.1 正规式和 DFA ·ε和φ都是Σ上的正规式,它们所表示的正规集分别为{ε}和φ ·任何 a∈Σ,a 是Σ上的一个正规式,它所表示的正规集为{a} ·假定 U 和 V 都是Σ上的正规式,它们所表示的正规集分别记为 L(U)和 L(V),
1.5 目标代码生成 目标代码生成是编译最后一个阶段,它把中间代码转换成汇编指令或可重定位
的目标代码。例如对于前面生成的中间代码,可以产生 IBM PC 汇编指令为: mov ax, m mul ax, 10 mov bx, z sub bx,ax add bx,y mov x, bx 汇编代码经过 Masm 汇编器(Assembler)和连接器(Linker)处理,就产生了可在
IBM PC 机器上运行的二进制代码。
2.形式语言简介
2.1 文法和语言 文法是产生语言的规则,它可定义为:
对于一个四元式 G=(VN,VT,S,P),其中 (1) VN 是非终结符号的有限集合 (2) VT 是终结符号的有限集合,且 VT∩VN= (3) 开始符号 S,S∈VN (4) 一组产生式 P,P 中的每一个产生式都具有如下形式: u→v,u∈(VN∪VT)+且至少要有一个非终结符号,v∈(VN∪VT)*
支持 Label,允许在任何语句前定义 Label 作为控制转移目的地。 for 和 while 语句支持 break, continue 流程 控制。
系统以 main 函数为入口函数。
支持源程序注释。
注释以”//” 或 ”/*” ,”*/”标示。
支持出错提示。
对于嵌入汇编代码的出错提示可以通过 重定向汇编代码编译器的出错信息实现。
用巴科斯范式的形式表示文法的优点是简洁、清楚并容易被理解。
3.编译程序的实现环境 Parse Generator 简介及其使用
编译器生成工具----Parse Generator 基于 Windows 平台,它集成了词法生成器 ALEX 和语法生成器 AYACC,并提供了较为强大的类库。其主要优点体现在以下几 个方面:
自顶向下分析和自底向上分析两大类。在 C--编译器中采用了一种自底向上的方法, 即 LR 方法。
赋值语句
变量
=
表达式
项+Fra bibliotek表达式ID

-
表达式
ID

*

ID
图 2 语法分析树
NUM
1.3 语义分析 这一阶段部分是根据前一阶段产生的语法树,按语言的语义进行翻译,产生四
元式或三元式等中间语言。中间语言可以很方便地转换成目标代码。前面的语法树
可以视一个编译程序为一个 Project,集成 Alex 和 Ayacc 文件的环境有利于 整体调试和开发。且编辑界面友好,利于初学者使用。
.l 文件(lex 文件)和.y 文件(yacc 文件)可生成为标准的 C 原代码,也可 生成 Visual C++和 Borland C++格式的原代码。这对习惯与 BC 或 VC 编程 的程序员,无疑是极大的方便。
类 yylexer ---- 所有词法分析器类的基类 yylexer 类提供由 Alex 生成的 C++词法分析器的一切基本功能。 yylexer 是一个抽象类,要使用它,必须继承出自己的类,并实现抽象函数
yylex 和 yyaction。
C--编译器程序中的词法分析器类是其子类 C_Lexer 类。
语言定义为 L(G)={w|S=>*w,w∈VT*},可见,文法 G 中的 VT 相当于产生语言 的字母表,G 中的一组产生式是产生语言的一组规则;语言 L(G)中的每一个句子 w, 是由 G 的开始符号 S 经推导得到的,完全由终结符号组成的字。非终结符号是引起 推导继续进行的中间符号,在推导进行到某一步时,如果再没有非终结符号留在推 导的结果中,则称推导成功。