简单编译器的设计与实现1
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一、课程设计的目的
在学习《程序设计语言编译原理》课程过程中,结合各章节构造编译程序的基本理论分别完成词法分析器、语法分析器和语义分析器实验,在基本实验完成的基础上,逐步完成课程设计。针对自己的理解和学习,实现一个小编译器括符号表的构造,词法分析,语法分析,目标代码生成等重要子程序,其中词法分析、语法分析及语义分析功能必须完成),并对其进行分析解释和总结,同时将理论与实际应用结合起来,接受软件设计等开发过程的全面训练,从而提高软件开发的能力。
二、课程设计的任务
(1)设计符号表
确定符号表的组织方式,一般应包括名字栏和信息栏,其中名字栏作为关键字。要考虑能够存储有关名字的信息,并可以高效地完成如下操作:
a.查找:根据给定的名字,在符号表中查找其信息。如果该名字在符号表中不存在,则将其加入到符号表中,否则返回指向该名字的指针;
b.删除:从符号表中删除给定名字的表项。
(2)设计词法分析器
设计各单词的状态转换图,并为不同的单词设计种别码。将词法分析器设计成供语法分析器调用的子程序。功能包括:
a.具备预处理功能。将不翻译的注释等符号先滤掉,只保留要翻译的符号串,
即要求设计一个供词法分析调用的预处理子程序;
b.能够拼出语言中的各个单词;
c.将拼出的标识符填入符号表;
d.返回(种别码,属性值)。
(3)语法分析器
要求用预测分析法、递归下降分析法、算符优先分析法、SLR分析法(几种方法任选),实现对表达式、各种说明语句、控制语句进行语法分析。
(4)目标代码生成器
能完成指定寄存器个数的情况下将一中间代码程序段翻译成汇编语言目标代码(汇编指令应包括加、减、乘、除),要求指令条数最少的情况下,尽量使
用寄存器,尽量少访问内存,这样才能做到运行效率高。
三、课程设计要求
样本语言为C-语言,实现简单的编译器,其中基本的语句要求必须实现,其余部分可根据自己的实际情况选择实现。对主要代码给予解释和理解注释,各函数和过程应有简要描述,有功能说明,有入口和出口参数说明。
四、简单编译器的实现流程图
五、实现环境
Windows XP操作系统、win-TC运行环境
六、课程设计的详细过程
(1)设计词法分析器
设计思想:
要求:1. 对单词的构词规则有明确的定义;
2. 编写的分析程序能够正确识别源程序中的单词符号;
3. 识别出的单词以<种别码,值>的形式保存在符号表中;
4. 词法分析中源程序的输入以.c格式,分析后的符号表保存在.txt文件中。
5. 对于源程序中的词法错误,能够做出简单的错误处理,给出简单的错误提示,保证顺利完成整个源程序的词法分析;
6. 输入:由符合规定单词类别结构的各类单词组成的源程序。
实现方法:
根据加入语义过程的状态转换图直接编写词法分析程序。根据每一组状态转换关系(标识符)组织程序结构,并将所有公共处理过程分别实现即可。在扫描源程序字符串时,一旦识别出关键字、运算符、标识符、无符号常数中之一,即以二元式形式(类别编码,值)输出单词。每次调用词法分析程序,它均能自动继续扫描下去,形成下一个单词。
实现过程及主要代码:
定义主要函数:
1. char Scanin[100],Scanout[100]; //用于接收输入输出文件名
FILE *fin,*fout; //用于指向输入输出文件的指针
2. //下面定义保留,为简化程序,使用字符指针数组保存所有保留字。
//如果想增加保留字,可继续添加,并修改保留字数目
#define keywordSum 8
char
*keyword[keywordSum]={ "if","else","for","while","do","int","read","w rite"};
3. //下面定义纯单分界符,如需要可添加
char singleword[50]="+-*(){};,:";
4. //下面定义双分界符的首字符
char doubleword[10]="><=!";
5. scanf("%s",Scanin);
printf("请输入词法分析输出文件名(包括路径):");
scanf("%s",Scanout);
6. if ((fin=fopen(Scanin,"r"))==NULL) //判断输入文件名是否正确
{printf("\n打开词法分析输入文件出错!\n");
return(1);//输入文件出错返回错误代码1
}
if ((fout=fopen(Scanout,"w"))==NULL) //判断输出文件名是否正确
{ printf("\n创建词法分析输出文件出错!\n");
return(2); //输出文件出错返回错误代码2
}
7. ch=getc(fin);//读取文件里的一个字符
8. isalpha(ch) //字母判断函数
isalnum(ch)) //数字判断函数
strcmp(token,keyword[n]) //串比较
fprintf(fout,"%s\t%s\n","ID",token); //输出标识符符号到fout指定的文件strchr(singleword,ch) //声明: char *strchr( const char *string, int c ); 实现函数代码:
初始化函数:
init()
{char *key[]={" ","case","char","const","do","double",
"else","float","for","if","int","long","short" }; char *limit[]={" ","(",")",".","!", "*","/","%","+","-",
"=",",",";","{","}","#","'"};
FILE *fp;int i;char c;fp=fopen("key.txt","w");
for(i=1;i<=12;i++)
fprintf(fp,"%s\n",key[i]);
fclose(fp);/*初始化关键字*/
fp=fopen("limit.txt","w");
for(i=1;i<=17;i++)
fprintf(fp,"%s\n",limit[i]); c='"';
fprintf(fp,"%c\n",c);
fclose(fp); /*初始化运算、限界符表*/
fp=fopen("id.txt","w");
fclose(fp); /*初始化标识符表*/
fp=fopen("constant.txt","w");
fclose(fp); /*初始化常数表*/
fp=fopen("output.txt","w");
fclose(fp); /*初始化输出文件*/
}
根据不同命令查表或造表函数:
int find(char *buf,int type,int command)
{ int number=0;FILE *fp; char c; char temp[30]; int i=0;switch(type) {case 1: fp=fopen("key.txt","r");break;
case 2: fp=fopen("id.txt","r");break;
case 3: fp=fopen("constant.txt","r");break;
case 4: fp=fopen("limit.txt","r");
}
c=fgetc(fp);
while(c!=EOF)
{while(c!='\n')
{temp[i++]=c;c=fgetc(fp);}
temp[i]='\0';
i=0;
number++;