编译原理课程设计---一个简单编译器的设计与分析
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
摘要
使用过现代计算机的人都知道,多数用户是应用高级语言来实现他们所需要的计算的。现在计算机系统一般都含有不只一个的高级语言的编译程序,对有些高级语言甚至配置了几个不同性能的编译程序,供用户按不同需要进行选择。高级语言编译程序是计算机系统软件最主要的组成部分之一,也是用户最直接关系的工具之一。
计算机上执行一个高级语言程序一般分为两步:第一,用一个编译程序把高级语言翻译成机器语言程序;第二,运行所得的机器语言程序求得计算结果。
通常说的翻译程序是指能够把某一种语言程序转换成另一种语言程序(目标语言程序)。如果源语言诸如Fortran,Pascal,C,Ada或java这样的高级语言,而目标程序是诸如汇编语言或者机器语言这类的低级语言,这样的一个翻译程序就是称为编译程序。
一个编译程序的工作过程一般可以划分为五个阶段:词法分析、语法分析、语义分析与中间代码生成、优化、目标代码生成。每个阶段都是从上一个阶段得到结果,对他进行分析,并且根据一些外部环境(例如符号表等)得到最终的输出结果。要构造一个编译程序,可以按照这样的阶段来分别构造,最后来连调。
现在人们已经建立了多种编制部分编译程序或整个编译程序的有效工具。有些能用于自动生成扫描器(如LEX),有些可以用于自动产生语法分析器(如YACC),有些甚至可以用来自动产生整个的编译程序。这些构造编译程序的工具成为编译程序-编译程序、编译程序产生器或翻译程序书写系统,他们是按照编译程序和目标语言的形式描述而自动产生编译程序的。
编译程序是一极其庞大而又复杂的系统,掌握它比较苦难。但是一旦对其掌握,对以后的程序语言设计,系统软件分析,系统软件设计,形式语言研究等方面都是非常有好处的。
关键字:C语言、、编译、扫描器、语法分析
一、需求分析
给出类C语言(C语言的子集)的词法和语法定义,并根据对应的语法定义写出一些属性文法和语法制导。根据词法和语法的定义,构造一个编译程序,它主要可以完成如下功能:
1、读入某个已经编辑好的类C源程序文件,通过词法分析器,生成二元组,同时检查词法错误;
2、语法分析器将产生的二元组作为输入,进行语法分析,同时检查语法错误;
3、在语法分析同时,利用属性文法和语法制导技术,产生具体的语意动作,并对符号表进行操作;
4、根据语义动作产生整个源程序的四元式序列;
5、将产生的四元式序列连同符号表一起输出,作为编译程序的最终输出结果;
6、对最后的代码优化和目标代码生成要有所考虑,必须留有一定的接口供以后扩展;
7、增大程序的可移植性,努力做到整个系统方便移植。
二、详细算法设计
词法分析程序→语法分析程序→语义分析程序→编译器。
三、流程图
图I 主函数示意图
图II 递归下降分析程序示意图
图III 语句块分析示意图
图IV 语句串分析示意图
图V 语句分析示意图
四、相关函数说明
void scanner(); //扫描
void lrparser();
void staBlock(int *nChain); //语句块
void staString(int *nChain); //语句串
void sta(int *nChain); //语句
void fuzhi(); //赋值语句
void tiaojian(int *nChain); //条件语句
void xunhuan(); //循环语句
char* E(); //Expresiion表达式
char* T(); //Term项
char* F(); //Factor因子
char *newTemp(); //自动生成临时变量
void backpatch(int p,int t); //回填
int merge(int p1,int p2); //合并p1和p2
void emit(char *res,char *num1,char *op,char *num2); //生成四元式五.运行结果
图VI 赋值语句的分析
图VII 条件语句的分析
图VIII 循环语句的分析
图IX 综合
六.编译器使用说明
程序提示用户输入字符串“Please input your source string:”,用户输入字符串并以“#”号结束。回车后,程序显示运行结果。
七.程序清单
#include
#include
#include
#include
char prog[80]; /* 存放所有输入字符 */
char token[8]; /* 存放词组 */
char ch; /* 单个字符 */
int syn,p,m,n,i; /* syn:种别编码 */
double sum;
int count;
int isSignal; /* 是否带正负号(0不带,1负号,2正号) */
int isError;
int isDecimal; /* 是否是小数 */
double decimal; /* 小数 */
int isExp; /* 是否是指数 */
int index; /* 指数幂 */
int isNegative; /* 是否带负号 */
double temp;
int temp2;
int repeat; /* 是否连续出现+,- */
int nextq;
int kk; /* 临时变量的标号 */
int ntc,nfc,nnc,nnb,nna;
char *rwtab[9]={"main","int","float","double","char","if","else","do","while"}; struct{
char result[10]; /* 字符串(字符数组) */
char arg1[10];
char opera[10];
char arg2[10];
}fourCom[20]; /* 结构体数组 */
void scanner(); /* 扫描 */
void lrparser();
void staBlock(int *nChain); /* 语句块 */
void staString(int *nChain); /* 语句串 */
void sta(int *nChain); /* 语句 */
void fuzhi(); /* 赋值语句 */
void tiaojian(int *nChain); /* 条件语句 */
void xunhuan(); /* 循环语句 */
char* E(); /* Expresiion表达式 */
char* T(); /* Term项 */
char* F(); /* Factor因子 */
char *newTemp(); /* 自动生成临时变量 */
void backpatch(int p,int t); /* 回填 */
int merge(int p1,int p2); /* 合并p1和p2 */
void emit(char *res,char *num1,char *op,char *num2); /* 生成四元式 */
void main()
{ p=0;
count=0;
isDecimal=0;
index=0;
repeat=0;
kk=0;
printf("\nPlease input your source string:\n");
do{ch=getchar();
prog[p++]=ch;
}while(ch!='#');
p=0;
isError=0;
scanner();
lrparser();
for(i=1;i {printf("\n%d\t",i);