简单编译器的实现-课时设计.doc_第1页
简单编译器的实现-课时设计.doc_第2页
简单编译器的实现-课时设计.doc_第3页
简单编译器的实现-课时设计.doc_第4页
简单编译器的实现-课时设计.doc_第5页
已阅读5页,还剩17页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

成绩: 课 程 设 计题 目:简单编译器实现学 院:专 业:班 级:组 长:小组成员:指导教师:2014年12月19日一、 课程设计的目的 在学习程序设计语言编译原理课程过程中,结合各章节构造编译程序的基本理论分别完成词法分析器、语法分析器和语义分析器实验,在基本实验完成的基础上,逐步完成课程设计。针对自己的理解和学习,实现一个小编译器括符号表的构造,词法分析,语法分析,目标代码生成等重要子程序,其中词法分析、语法分析及语义分析功能必须完成),并对其进行分析解释和总结,同时将理论与实际应用结合起来,接受软件设计等开发过程的全面训练,从而提高软件开发的能力。二、 课程设计的任务(1)设计符号表确定符号表的组织方式,一般应包括名字栏和信息栏,其中名字栏作为关键字。要考虑能够存储有关名字的信息,并可以高效地完成如下操作:a.查找:根据给定的名字,在符号表中查找其信息。如果该名字在符号表中不存在,则将其加入到符号表中,否则返回指向该名字的指针;b.删除:从符号表中删除给定名字的表项。(2)设计词法分析器设计各单词的状态转换图,并为不同的单词设计种别码。将词法分析器设计成供语法分析器调用的子程序。功能包括:a. 具备预处理功能。将不翻译的注释等符号先滤掉,只保留要翻译的符号串,即要求设计一个供词法分析调用的预处理子程序;b. 能够拼出语言中的各个单词;c. 将拼出的标识符填入符号表;d. 返回(种别码, 属性值)。(3)语法分析器要求用预测分析法、递归下降分析法、算符优先分析法、SLR分析法(几种方法任选),实现对表达式、各种说明语句、控制语句进行语法分析。(4)目标代码生成器能完成指定寄存器个数的情况下将一中间代码程序段翻译成汇编语言目标代码(汇编指令应包括加、减、乘、除),要求指令条数最少的情况下,尽量使用寄存器,尽量少访问内存,这样才能做到运行效率高。三、课程设计要求样本语言为C-语言,实现简单的编译器,其中基本的语句要求必须实现,其余部分可根据自己的实际情况选择实现。对主要代码给予解释和理解注释,各函数和过程应有简要描述,有功能说明,有入口和出口参数说明。四、 简单编译器的实现流程图 主程序= 词法分析程序 语法分析程序 中间代码生成程序 4.2词法分析程序(1) 设计词法分析器设计思想:要求:1. 对单词的构词规则有明确的定义;2. 编写的分析程序能够正确识别源程序中的单词符号;3. 识别出的单词以的形式保存在符号表中;4. 词法分析中源程序的输入以.c格式,分析后的符号表保存在.txt文件中。5. 对于源程序中的词法错误,能够做出简单的错误处理,给出简单的错误提示,保证顺利完成整个源程序的词法分析;6. 输入:由符合规定单词类别结构的各类单词组成的源程序。实现方法:根据加入语义过程的状态转换图直接编写词法分析程序。根据每一组状态转换关系(标识符)组织程序结构,并将所有公共处理过程分别实现即可。在扫描源程序字符串时,一旦识别出关键字、运算符、标识符、无符号常数中之一,即以二元式形式(类别编码,值)输出单词。每次调用词法分析程序,它均能自动继续扫描下去,形成下一个单词。实现过程及主要代码:#include #include #include #include void reading(char* prog); char prog800,token80; char ch; int syn,p,m=0,n,row,sum=0; /关键字存储 char *rwtab20= PROGRAM,VAR,PROCEDURE,BEGIN,END,IF, THEN,ELSE,REPEAT,UNTIL,READ,WRITE, WRITELN,FOR,DO,int,float,double,char,printf; void scaner() for(n=0;n=a&ch=A&ch=0&ch=a&ch=A&ch=Z) tokenm+=ch; ch=progp+; /识别出一个标示符 tokenm+=0; /回退一位 p-; syn=34;/单纯的标示符 for(n=0;n=0&ch=0&ch999999999) syn=-1; elseswitch(ch) case) syn=30; tokenm+=ch; else if(ch=) syn=31; tokenm+=ch; else syn=32; p-; break; case: m=0; m=0; tokenm+=ch; /读取下一个字符 ch=progp+; if(ch=) syn=28; tokenm+=ch; else syn=29; p-; break; case:m=0;tokenm+=ch; ch=progp+; if(ch=) syn=26; tokenm+=ch; else syn=27; p-; break; case+:syn=16;token0=ch;break; case-:syn=17;token0=ch;break; case*:syn=18;token0=ch;break; case/:syn=19;token0=ch;break; case(:syn=20;token0=ch;break; case):syn=21;token0=ch;break; case=:syn=22;token0=ch;break; case,:syn=23;token0=ch;break; case.:syn=24;token0=ch;break; case;:syn=25;token0=ch;break; case#:syn=0;token0=ch;break; casen:syn=-2;break; default: syn=-1;break; void main() p=0; row=1; coutPlease input string:endl; reading(prog); p=0; do scaner(); switch(syn) case 33: cout(syn,sum)endl; break; /输出的是数值 case -1: coutError in row row!endl; break;/输出的是错误信息 case -2: row=row+;break; default: cout(syn,token)endl;break;/输出的是标示符 while (syn!=0);/结束符号时停止执行 /*读取路径下的文件,将文件内容保存到prog中。*/ void reading(char * prog) FILE * in; printf(请输入文件路径:n); char path100,ch; scanf(%s,&path); printf(%sn,path); if(in = fopen(path,r)=NULL) printf(文件无法打开!); exit(0); int i=0; while(!feof(in) ch = fgetc(in); putchar(ch); progi=ch; i+; prog-i=#; fclose(in); 词法分析的运行结果4.3语法分析程序 设计思想:要求:1. 对语法规则有明确的定义;2. 编写的分析程序能够对实验一的结果进行正确的语法分析;3编写的分析程序能够对实验二的结果进行正确的语义分析;4对于遇到的语法、语义错误,能够做出简单的错误处理,给出简单的错误提示,保证语义分析过程;实现方法: 在词法分析识别出单词符号的基础上分析并规定程序的语法结构是否符合语法规则。其工作本质就是按文法的产生式,识别输入符号串是否为一个句子。首先定义语法规则,然后按照规则实现语法分析。实现过程及主要代码:1、 代码主程序#include #include extern int scan();extern int grammar();char Scanin300,Scanout300; /用于接收输入输出文件名FILE *fin,*fout; /用于指向输入输出文件的指针void main()int es=0;es=scan();/调词法分析 if (es0)printf(词法分析有错,编译停止!);elseprintf(词法分析成功!n);if (es=0) es=grammar();/调语法分析if (es=0)printf(语法分析成功!n);elseprintf(语法分析错误!n);词法分析代码#include #include #define keywordSum 8char *keywordkeywordSum= if,else,for,while,do,int,read,write;/下面定义纯单分界符,如需要可添加char singleword50=+-*();,:;/下面定义双分界符的首字符char doubleword10=!;extern char Scanin300, Scanout300; /用于接收输入输出文件名,在TEST_main.c中定义extern FILE *fin,*fout; /用于指向输入输出文件的指针,在TEST_main.c中定义int scan()/词法分析函数 char ch,token40; /ch为每次读入的字符,token用于保存识别出的单词 int es=0,j,n; /es错误代码,0表示没有错误。j,n为临时变量,控制组合单词时的下标等 printf(请输入源程序文件名(包括路径):); scanf(%s,Scanin); printf(请输入词法分析输出文件名(包括路径):); scanf(%s,Scanout); if (fin=fopen(Scanin,r)=NULL) /判断输入文件名是否正确 printf(n打开词法分析输入文件出错!n); return(1);/输入文件出错返回错误代码1 if (fout=fopen(Scanout,w)=NULL) /判断输出文件名是否正确 printf(n创建词法分析输出文件出错!n); return(2); /输出文件出错返回错误代码2 ch=getc(fin); while(ch!=EOF) while (ch= |ch=n|ch=t) ch=getc(fin); if (isalpha(ch) /如果是字母,则进行标识符处理 token0=ch; j=1; ch=getc(fin); while(isalnum(ch) /如果是字母数字则组合标识符;如果不是则标识符组合结束tokenj+=ch; /组合的标识符保存在token中ch=getc(fin); /读下一个字符 tokenj=0; /标识符组合结束 /查保留字 n=0; while (n=keywordSum) /不是保留字,输出标识符fprintf(fout,%st%sn,ID,token); /输出标识符符号else/是保留字,输出保留字fprintf(fout,%st%sn,token,token); /输出保留字符号 else if (isdigit(ch)/数字处理 token0=ch; j=1; ch=getc(fin); /读下一个字符 while (isdigit(ch) /如果是数字则组合整数;如果不是则整数组合结束tokenj+=ch; /组合整数保存在token中ch=getc(fin); /读下一个字符 tokenj=0; /整数组合结束 fprintf(fout,%st%sn,NUM,token); /输出整数符号 else if (strchr(singleword,ch)0) /单分符处理 token0=ch; token1=0; ch=getc(fin);/读下一个符号以便识别下一个单词 fprintf(fout,%st%sn,token,token); /输出单分界符符号 else if (strchr(doubleword,ch)0) /双分界符处理 token0=ch; ch=getc(fin); /读下一个字符判断是否为双分界符 if (ch=) /如果是=,组合双分界符token1=ch;token2=0; /组合双分界符结束 ch=getc(fin); /读下一个符号以便识别下一个单词 else/不是=则为单分界符token1=0; fprintf(fout,%st%sn,token,token); /输出单或双分界符符号 else if (ch=/) /注释处理 ch=getc(fin); /读下一个字符 if (ch=*) /如果是*,则开始处理注释 char ch1;ch1=getc(fin); /读下一个字符doch=ch1;ch1=getc(fin); /删除注释while (ch!=* | ch1!=/)&ch1!=EOF); /直到遇到注释结束符*/或文件尾ch=getc(fin);/读下一个符号以便识别下一个单词 else /不是*则处理单分界符/ token0=/; token1=0; fprintf(fout,%st%sn,token,token); /输出单分界符/ else /错误处理 token0=ch; token1=0; ch=getc(fin); /读下一个符号以便识别下一个单词 es=3; /设置错误代码 fprintf(fout,%st%sn,ERROR,token); /输出错误符号 fclose(fin);/关闭输入输出文件 fclose(fout); return(es); /返回主程序语法分析代码 #include #include #include char token20,token140;/token保存单词符号,token1保存单词值extern char Scanout300; /保存词法分析输出文件名FILE *fp; /用于指向输入输出文件的指针/语法分析程序int grammar()int es=0;if(fp=fopen(Scanout,r)=NULL) printf(n打开%s错误!n,Scanout); es=10;if (es=0)es=program();printf(=语法分析结果!=n);switch(es)case 0: printf(语法分析成功!n);break;case 10: printf(打开文件 %s失败!n,Scanout);break;case 1: printf(缺少!n);break;case 2: printf(缺少!n);break;case 3: printf(缺少标识符!n);break;case 4: printf(少分号!n);break;case 5: printf(缺少(!n);break;case 6: printf(缺少)!n);break;case 7: printf(缺少操作数!n);break;fclose(fp);return(es);/:=/program:=int program() int es=0; fscanf(fp,%s %sn,token,token1); printf(%s %sn,token,token1); if(strcmp(token,)/判断是否 es=1; return(es); fscanf(fp,%s %sn,&token,&token1); printf(%s %sn,token,token1); es=declaration_list(); if (es0) return(es); es=statement_list(); if (es0) return(es); if(strcmp(token,)/判断是否 es=2; return(es); return(es);/:=|/:=/|/该成:=int declaration_list()int es=0;while (strcmp(token,int)=0)es=declaration_stat();if (es0)return(es);return(es);/ :=int ;/:=int ID;int declaration_stat()int es=0; fscanf(fp,%s %sn,&token,&token1);printf(%s %sn,token,token1);if (strcmp(token,ID)return(es=3); /不是标识符fscanf(fp,%s %sn,&token,&token1);printf(%s %sn,token,token1);if (strcmp(token,;) )return(es=4);fscanf(fp,%s %sn,&token,&token1);printf(%s %sn,token,token1);return(es);/:=|/:=|/改成:=int statement_list()int es=0;while (strcmp(token,)es=statement();if (es0)return(es);return(es);/:=|/ |/:= |/ | |int statement()int es=0;if (es=0 & strcmp(token,if)=0)es=if_stat();/if (es=0 & strcmp(token,while)=0)es=while_stat();/if (es=0 & strcmp(token,for)=0)es=for_stat();/可在此处添加do语句调用if (es=0 & strcmp(token,read)=0)es=read_stat();/if (es=0 & strcmp(token,write)=0)es=write_stat();/if (es=0 & strcmp(token,)=0)es=compound_stat();/if (es=0 & (strcmp(token,ID)=0|strcmp(token,NUM)=0|strcmp(token,()=0)es=expression_stat();/return(es);/:= if () else /:= if () else int if_stat()int es=0; /iffscanf(fp,%s %sn,&token,&token1);printf(%s %sn,token,token1);if (strcmp(token,()return(es=5); /少左括号fscanf(fp,%s %sn,&token,&token1);printf(%s %sn,token,token1);es=expression();if (es0) return(es);if (strcmp(token,)return(es=6); /少右括号fscanf(fp,%s %sn,&token,&token1);printf(%s %sn,token,token1);es=statement(); if (es0)return(es);if (strcmp(token,else)=0)/else部分处理fscanf(fp,%s %sn,&token,&token1);printf(%s %sn,token,token1);es=statement(); if (es0) return(es);return(es);/:=while() /:= while () int while_stat()int es=0; fscanf(fp,%s %sn,&token,&token1);printf(%s %sn,token,token1);if (strcmp(token,()return(es=5); /少左括号fscanf(fp,%s %sn,&token,&token1);printf(%s %sn,token,token1);es=expression();if (es0)return(es);if (strcmp(token,)return(es=6); /少右括号fscanf(fp,%s %sn,&token,&token1);printf(%s %sn,token,token1);es=statement();return(es);/:=for(;) /:= for(,)int for_stat()int es=0; fscanf(fp,%s %sn,&token,&token1);printf(%s %sn,token,token1);if (strcmp(token,()return(es=5); /少左括号fscanf(fp,%s %sn,&token,&token1);printf(%s %sn,token,token1);es=expression();if (es0)return(es);if (strcmp(token,;)return(es=4); /少分号fscanf(fp,%s %sn,&token,&token1);printf(%s %sn,token,token1);es=expression();if (es0)return(es);if (strcmp(token,;)return(es=4); /少分号fscanf(fp,%s %sn,&token,&token1);printf(%s %sn,token,token1);es=expression();if (es0)return(es);if (strcmp(token,)return(es=6); /少右括号fscanf(fp,%s %sn,&token,&token1);printf(%s %sn,token,token1);es=statement();return(es);/:=write ;/:=write ;int write_stat()int es=0;fscanf(fp,%s %sn,&token,&token1);printf(%s %sn,token,token1);es=expression();if (es0)return(es);if (strcmp(token,;)return(es=4); /少分号fscanf(fp,%s %sn,&token,&token1);printf(%s %sn,token,token1);return(es);/:=read ;/:=read ID;int read_stat()int es=0;fscanf(fp,%s %sn,&token,&token1);printf(%s %sn,token,token1);if (strcmp(token,ID)return(es=3); /少标识符fscanf(fp,%s %sn,&token,&token1);printf(%s %sn,token,token1);if (strcmp(token,;)return(es=4); /少分号fscanf(fp,%s %sn,&token,&token1);printf(%s %sn,token,token1);return(es);/:= /:= int compound_stat() /复合语句函数int es=0;fscanf(fp,%s %sn,&token,&token1);printf(%s %sn,token,token1);es=statement_list();return(es);/:=;|;/:=;|;int expression_stat()int es=0;if (strcmp(token,;)=0) fscanf(fp,%s %sn,&token,&token1);printf(%s %sn,token,token1);return(es);es=expression();if (es0)return(es);if (es=0 & strcmp(token,;)=0) fscanf(fp,%s %sn,&token,&token1);printf(%s %sn,token,token1);return(es);elsees=4;return(es);/少分号/:=|/:=ID=|int expression()int es=0,fileadd;char token220,token340;printf(aaaaaaaaaaa%sn,token);if (strcmp(token,ID)=0) fileadd=ftell(fp); /记住当前文件位置fscanf(fp,%s %sn, &token2,&token3);printf(%s %sn,token2,token3);if (es0)return(es);if (strcmp(token2,=)=0) /=fscanf(fp,%s %sn,&token,&token1);printf(%s %sn,token,token1);es=bool_expr(); else fseek(fp,fileadd,0); /若非=则文件指针回到=前的标识符printf(%s %sn,token,token1);es=bool_expr();if (es0)return(es);elsees=bool_expr();return(es);/:=|(|=|=|=|!=)/:=/ |(|=|=|=|!=)int bool_expr()int es=0;es=additive_expr();if(es0)return(es);if (strcmp(token,)=0 | strcmp(token,=)=0 |strcmp(token,)=0|strcmp(token,0)return(es);return(es);/:=(+|-)/:=(+|-) int additive_expr()int es=0;es=term();if(es0)return(es);while (strcmp(token,+)=0 | str

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论