编编译原理课程设计报告asd_第1页
编编译原理课程设计报告asd_第2页
编编译原理课程设计报告asd_第3页
编编译原理课程设计报告asd_第4页
编编译原理课程设计报告asd_第5页
已阅读5页,还剩26页未读 继续免费阅读

下载本文档

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

文档简介

1、 目录一、开发工具和运行环境 3二、系统需求分析3三、系统详细设计6四、系统实现 11五、调试 25六、系统开发总结30七、附录和参考资料 31一、 开发工具和运行环境运行环境:CPU为P4 1.0GHz以上,内存512M或者更多,硬盘至少50G。二、系统需求分析编译程序完成从源程序到目标程序的翻译工作,是一个复杂的整体的过程。从概念上讲,一个编译程序的整个工作过程是划分成阶段进行的,每个阶段将源程序的一种表示形式转换成另一种表示形式,各个阶段进行的操作在逻辑上是紧密连接在一起的。一般将编译过程划分成词法分析,语法分析,语义分析,中间代码生成,代码优化和目标代码生成六个阶段。词法分析是编译的第

2、一个阶段,它的主要任务是从左至右逐个字符的对源程序进行扫描,产生一个个单词序列,用以语法分析。执行词法分析的程序称为词法分析程序或扫描程序,它所输出的单词符号常采用以下二元式表示:(单词种别,单词自身的值)。根据C语言的说明语句形式,手工构造一个对说明语句进行分析的词法分析程序。该程序能对从键盘输入形如:“const count=10,sum=81.5,char1=f,string1=”hj”, max=169;”的常量说明串进行处理,分析常量说明串中各常量名、常量类型及常量值,并统计各种类型常量个数。a.输入的常量说明串,最后以分号作结束标志“const”判断输入串或文本文件是否为常量说明内

3、容;c.常量名以字母开头,后跟若干个字母,数字或下划线“,”号隔开,也作为常量之间的风格标志e.判断类型 A:字符型常量定义为放在单引号内的一个字符; B:字符串常量定义为放在双引号内所有内容 C:整型常量定义为带或不带+、- 号,不以0开头的若干数字的组合; D:实型常量定义为带或不带+、- 号,不以0开头的若干数字加上小数点再后跟若干数字的组合f.空格处理:A:出现在常量名之间,如(" str 1")报错 B:出现在常量数字之中,如(“23. 32”)报错 其他为符合规则,不处理g.统计并输出串或文件中包含的各种类型的常量个数,如果同常量名相同,看做覆盖,计数只加一次

4、h. 以二元组(类型,值)的形式输出各常量的类型和值;i.根据常量说明串置于高级语言源程序中时可能出现的错误情况,模仿高级语言编译器对不同错误情况做出相应处理。开始输入常量说明串判断const识别标识符判断=识别常量值当前符号为; 结束为,打印输出 报错 三、系统详细设计重要数据定义数据结构定义:1): 基本数据类型和运算符定义typedef enum _unsigned=0, /*无符号整数*/_resunsigned,/*余留无符号整数*/_decimal, /*十进制小数*/_resdecimal, /*余留十进制小数*/_exp, /*指数部分*/_intexp, /*整指数*/_re

5、sexp, /*余留整指数*/_op, /*操作符*/_identifiers,/*标识符*/_char, /*字符*/_string, /*字符串*/_bool /*bool类型*/StatusSet;2): 二元式输出定义typedef struct _WordType Int type; /单词类型 char *value;/值Word;3):整数,实数识别状态转换表定义 int m_switchmapMAXSTATUSMAXSTATUS= -1,_resunsigned,_exp,_decimal,-1,-1,-1,-1,-1,_resunsigned,_exp,_decimal,-1

6、,_resunsigned,-1,-1,-1,_resdecimal,-1,-1,-1,-1,-1,-1,-1,_resdecimal,_exp,-1,-1,_resdecimal,-1,-1,-1,_resexp,-1,-1,_intexp,-1,-1,-1,-1,_resexp,-1,-1,-1,-1,-1,-1,-1,_resexp,-1,-1,-1,_resexp,-1,-1;重要模块1): 外部接口,分析模块入口Analysis()2):初始化状态转换表 InitStatusMap()3): 空格处理函数Removespace(int index);常量名之间出现空格,则清除多余的空

7、格,并返回下一个非空格字符位置 4): 判断类型函数 A:判断是否是字符常量CharValue(int *index, Word *value,int *errorcode); B:判断是否是整数,或符点数IntegerValue(int *index, Word *value,int *errorcode); C:判断是否是一个字符串常量StringValue(int *index, Word *value,int *errorcode); D:判断是否是bool型变量BoolValue(int *index, Word *value,int *errorcode); E: 从当前位置开始找

8、第1个为ch所指的字符,并返回其索引号FindFirstChar(char ch,int index) 5):输入串处理 A): 整型,实型数据识别状态转换函数(DFA状态转换) StatusSwitching(int status, char ch) B): 标识符的获取 NextIdentifiers(int index,char *buf,int *errorcode) (从当前位置开始获取下一个标识符,并返回下一个单词置) C):常量识别函数 NextValue(int index,Word *tmp,int *errorcode) (从当前位置开始获取下一个常量值,并返回下一个单词的

9、位置,调用各 调用各常量识别函数) D): 单词间格符 int FindNextToken(int index); (判断“ ” “,” “;”返回下一个单词间格符的位置) E): 检查标识符定义是否出错 IsIdentifiersCorrect(char *buf) 6): 输出 ShowInfo(char *buf,Word *word,int *errorcode); 程序系统结构报错结束输出判断类型判段Const判断变量名输入词法分析 统计类型每个出现次数数程序流程图报错NY“;”输出结束判断类型判断常量名判断const输入字符串开始说明:1)判断常量名,常量名必须是标识符,定义为字母

10、开头,后跟若干个字母,数字或下线。2)判断类型,A:字符型常量定义为放在单引号内的一个字符;B:字符串常量定义为放在双引号内所有内容C:整型常量定义为带或不带+、- 号,不以0开头的若干数字的组合;D:实型常量定义为带或不带+、- 号,不以0开头的若干数字加上小数点再后跟若干数字的组合。变量类型模块stringcharint 变量类型说明:1:count*为统计类型出现的次数Count4加1Count3加1Count2加1Count1加1YYY报错NNfloatYNN 四、系统实现本系统实现简单的词法分析,对用户输入的数据流分析,并按照integer、float、string、char、boo

11、l类型进行分析统计,并统计各数据类型之和。输入必须以const开头,各赋值语句之间用逗号分隔,语句末尾以分号结束。用户输入数据界面图4-1对用户输入的数据进行分析统计图4-2附:主要代码bool Analysis()int errorcode=0; /用于做常量定义错误标识,0标识没有错误bool cicle=true; /循环标识,为false结束循环int currentstate=0; /当前想要识别的类型,数字,标识符,界符,关键字int index=0; /当前扫描位置char buf6=0; /缓冲区数组int i; /循环变量int j;index=Removespace(ind

12、ex); /清除当前扫描到的空格,并返回第一个非空格字符索引for(i=index,j=0;j<5;i+,j+) /取输入串前5个字符bufj=inputstri;if(strcmp(buf,"const") /判断是否是常量定义关键字const,若不是则输出出错信息,并返回printf("It is not a constant declaration statement!Please input a string again!n");return false;currentstate=1; /识别标识符index=5; /从第6个字符继续对输入

13、串进行扫描char *identifiersbuf=NULL; /用于存放当前扫描到的标识符名字的字符串变量,标识符最长为MAXIDENTIFERSWord value; /用于存放当前扫描到的标识符赋的常量初值的二元式变量value.value=NULL; while(cicle)if(index>=inputstrlen) /是否扫描至输入串结尾,若是结束扫描break;switch(currentstate)case 1:/当前正在识别一个标识符identifiersbuf=(char *)malloc(sizeof(char)* MAXIDENTIFERS);index=Next

14、Identifiers(index,identifiersbuf,&errorcode);currentstate=2; /并标记下一个要识别的是'='break;case 2: /当前正在识别'='index= Removespace(index);if(inputstrindex='=')index+;currentstate=3; / 标识下一个单词需要的是一个常量值else /当前符号不是'=',输出出错提示,并寻找下一个分界符printf("%s(Wrong! You must forget a = f

15、ollowed with a const value to init the const var)n",identifiersbuf);index=FindNextToken(index);currentstate=4;errorcode=-1; /错误以处理,以后忽略break;case 3: /当前识别的是常量值index=NextValue(index,&value,&errorcode);currentstate=4; /需要',',进行下一个变量的定义或者''结束本次定义break;case 4:index=Removespa

16、ce(index);if(inputstrindex=',') /当前符号为','继续循环做下一个变量的定义index+;currentstate=1;else if(inputstrindex='')/当前符号为''结束本次词法分析index+;cicle=false;else/ShowInfo(identifiersbuf,&value,&errorcode);printf("You must foget a ',' or ''n");index=FindNe

17、xtToken(index);currentstate=4;errorcode=-1;/错误以处理,以后忽略ShowInfo(identifiersbuf,&value,&errorcode);break;return true;void InitStatusMap()int switchmapMAXSTATUSMAXSTATUS=/状态转换表数组初始化-1,_resunsigned,_exp,_decimal,-1,-1,-1,-1,-1,_resunsigned,_exp,_decimal,-1,_resunsigned,-1,-1,-1,_resdecimal,-1,-1

18、,-1,-1,-1,-1,-1,_resdecimal,_exp,-1,-1,_resdecimal,-1,-1,-1,_resexp,-1,-1,_intexp,-1,-1,-1,-1,_resexp,-1,-1,-1,-1,-1,-1,-1,_resexp,-1,-1,-1,_resexp,-1,-1;memcpy(m_switchmap,switchmap,sizeof(m_switchmap);/复置到类的成员变量中/ 状态转换函数int StatusSwitching(int status, char ch)/关系转换表,字符对应索引如下/l 0, d 1,e 2,. 3, s(+,

19、-) 4, ' ' 5/其中l表示字母,d表示数字,e为指数标识,.为小数点,s为指数正负号标记,空格' '标示规则中的''int set=-1;switch(ch)case '.':set=m_switchmapstatus3;break;case 'e':set=m_switchmapstatus2;break;case ' ':set=m_switchmapstatus5;break;case '+':set=m_switchmapstatus4;break;case '

20、;-':set=m_switchmapstatus4;break;default:set=m_switchmapstatus1;break;return set;/从当前位置开始获取下一个标识符,并返回下一个单词位置int NextIdentifiers(int index,char *buf,int *errorcode)char ch;int i;int j=0;i=Removespace(index);for(;i<inputstrlen;i+)ch=inputstri;if(ch=' '| ch='' | ch=',' |

21、ch='=')/一直扫描直至遇到界符为止break;bufj+=ch; /将扫描到的字符加入到标识符串中bufj='0'/字符串末尾添零return i;int NextValue(int index,Word *tmp,int *errorcode)/从当前位置开始获取下一个数字,并返回下一个单词的位置int ch;int j;int i=Removespace(index);ch=inputstri;if(CharValue(&i,tmp,errorcode) /先判断是否是字符常量,若是返回,否则继续下一步判断return i;if(StringV

22、alue(&i,tmp,errorcode) /判断是否是字符串常量,若是返回,否则继续下一步判断return i;if(BoolValue(&i,tmp,errorcode) /判断是否是bool常量,若是返回,否则继续下一步判断return i;if(IntegerValue(&i,tmp,errorcode)/判断是否是整数或实数,若是返回,否则标记错误为未知的常量return i;*errorcode=_unkownvalue;return FindNextToken(i); /返回下一个界符',' 和'' 以及空格位置int R

23、emovespace(int index)int i=0;for(i=index;i<inputstrlen;i+)if(inputstri=' ') /顺序清除空格,直到遇到非空格字符continue;else break;return i;void ShowInfo(char *buf,Word *word,int *errorcode)/打印标识符详细信息int len=strlen(buf);if(*errorcode=-1 | len<1)/ errorcode=-1表示定义出错,且以处理,这里不在显示任何信息就返回 *errorcode=0;return

24、; if(!IsIdentifiersCorrect(buf)printf("%s(Wrong! It is not a identifier!)n",buf);if(word->value!=NULL) free(word->value);/*释放常量字符占的空间*/ word->value=NULL;return ;if(IsIdentifyersExist(buf) /判断标识符是否以定义printf("%s(Wrong! %s already defined!)n",buf,buf); if(word->value!=NU

25、LL) free(word->value);/*释放常量字符占的空间*/ word->value=NULL;return ;identifiersarrlen+=buf; /添加新标识符到数组末尾 char ch=buf0;printf("%s",buf);switch(*errorcode) /根据常量识别错误标记,输出常量相应信息case 0: /o表示常量定义没有错误,输出正确结果switch(word->type) case _char:len=strlen(word->value);if(len<2)countchar+;printf

26、("(char,'%s')",word->value);else printf("(Wrong! There are not more than one char in '')");break;case _string:countstr+;printf("(string,"%s") ",word->value);break;case _resexp:case _resdecimal:/浮点型数不能以0开头,如03.3 或 +03.3 都是错误的if( word->v

27、alue0 = '0' && word->value1 != '.' | ( ( word->value0='+' | word->value0 = '-' ) && word->value1 = '0' && word->value2 != '.' ) printf("(Wrong! Float cant't be started with '0')");elsecountfl

28、oat+; printf("(float,%s)",word->value);break;case _resunsigned:if(word->value0='0')printf("(Wrong! The integer cant be started with '0'.)");else countint+; printf("(integer,%s)",word->value);break;case _bool:countbool+;printf("(bool,%s)&quo

29、t;,word->value);break;break;/以一各项都对应各常量定义错误信息的输出case _charerror:printf("(Wrong! Can't Find a right ' to match the left'?)");break;case _integererror:printf("(Wrong! Wrong integer!)");break;case _floaterror:printf("(Wrong! Wrong float value)");break;case _

30、stringerror:printf("(Wrong! Can't Find a right " to match the left")");break;case _unkownvalue:printf("(Wrong! unkown const value)");break;*errorcode=0;printf("n");if(word->value!=NULL) free(word->value);/*释放常量字符占的空间*/ word->value=NULL;bool CharVa

31、lue(int *index, Word *value, int *errorcode) /判断是否是字符常量char ch;int i=*index;int j;int k,t;ch=inputstri;char *buf=(char *)malloc(sizeof(char)*MAXNUMS);if(ch=''') /如果是字符常量,找第一个单引号value->type=_char;j=FindFirstChar(''',i+1); /找第二个单引号if(j=-1) /如果没有匹配的单引号,做错误标记为字符常量定义错误*errorcod

32、e=_charerror;*index= FindNextToken(*index+1); /并返回下一个分界符位置else for( k=i+1,t=0;t<(j-i-1);k+,t+)/单引号匹配成功,从输入串获取两个单引号间的字符 buft=inputstrk; buft='0' value->value=buf;/value.value=m_inputstr.substr(i+1,j-i-1);value->type=_char;*index =j+1;return true;return false;bool IntegerValue(int *in

33、dex, Word *value, int *errorcode)/此处采用DFA状态算法识别整数和实数char ch;char *buf=(char *)malloc(sizeof(char)*MAXNUMS);int t=0;int i=*index;int j; int prestate;int *currentstate=&(value->type);ch=inputstri;*currentstate=_unsigned;if(ch='+' | ch='-')/处理整数实数前面的正负号,如果有的话buft+=ch; i+;for(;i&l

34、t;inputstrlen;i+)/循环进行DFA(确定的有穷自动机)状态转换,识别构成整数或实数的串,直至遇到界符或遇到使DFA分析失败的字符prestate=*currentstate;ch=inputstri;if(ch>='0' && ch<='9' | ch='.' | ch='e' | ch='E')buft+=ch;if(ch='E')buft-1='e'*currentstate=StatusSwitching(*currentstate,

35、ch);/break;else if(_exp=*currentstate && (ch='+' | ch='-')buft+=ch;*currentstate=StatusSwitching(*currentstate,ch);else if(ch=',' | ch='' | ch=' ')*currentstate=StatusSwitching(*currentstate,' ');buft='0'value->value=buf;break;elseif

36、(*currentstate=_unsigned)*errorcode=_unkownvalue;else if(*currentstate=_resunsigned)*errorcode=_integererror;else *errorcode=_floaterror;j=FindFirstChar(',',i);if(j=-1)j=FindFirstChar('',i);if(j=-1)*index= FindNextToken(i);return true;*index=j;return true;if(*currentstate=-1)if(prest

37、ate=_resunsigned)*errorcode=_integererror;else *errorcode=_floaterror;j=FindFirstChar(',',i);if(j=-1)j=FindFirstChar('',i);if(j=-1)*index=FindNextToken(i);return true;*index=j;return true;value->type=*currentstate;*index=i;return true;bool StringValue(int *index, Word *value, int

38、*errorcode)/判断是否赋值为字符串,若是,求出字符串,并返回true,否则返回falsechar ch;int i=*index;int j;int k,t;char *buf=(char *)malloc(sizeof(char)*MAXNUMS);ch=inputstri;if(ch='"')/查找第一个双引号value->type=_string;j=FindFirstChar('"',i+1); /查找第二个双引号if(j=-1)/双引号不匹配*errorcode=_stringerror;*index=FindNex

39、tToken(i+1); /返回下一个分界符标记elsefor(k=i+1,t=0;t<j-i-1;t+,k+)buft=inputstrk;buft='0'value->value=buf;/获取两个双引号间的字符串的值,不包括双引号*index =j+1;return true;return false;bool BoolValue(int *index, Word *value,int *errorcode) /判断是否是bool型常量char ch;int i=*index;int j;char *buf =(char *)malloc(sizeof(ch)

40、*6);if(inputstrlen-*index)<5) /剩余串小于5则,不可能有bool型值truereturn false;for(j=0,i=*index;j<4;j+,i+)bufj=inputstri;bufj='0'if(!strcmp(buf,"true") /当前4个字符是否是bool型值true,若是,则作进一步判断ch=inputstri;if(ch=','| ch='' | ch=' ')/判断下一个字符是否是界符,若不是则不是正确的bool型值*index=i;value

41、->type=_bool;value->value=buf;else*index=FindNextToken(i);*errorcode=_unkownvalue;return true;if(inputstrlen-*index)<6)/剩余串小于5则,不可能有bool型值falsereturn false;buf4=inputstri+;buf5='0'if(!strcmp(buf,"false")/当前5个字符是否是bool型值false,若是,则作进一步判断ch=inputstri;if(ch=','| ch=

42、9;' | ch=' ')/判断下一个字符是否是界符,若不是则不是正确的bool型值*index=i;value->type=_bool;value->value=buf;else*index=FindNextToken(i);*errorcode=_unkownvalue;return true;return false;/ 返回下一个单词间格符(' ',','或者'')第一次出现的位置int FindNextToken(int index)int i,j,k;i=FindFirstChar(' &#

43、39;,index);j=FindFirstChar(',',index);k=FindFirstChar('',index);/根据空格,','和''第一次出现的位置,判断下一个使输入串可能正确的界符的位置if(i<j && i<k && i!=-1 | i!=-1 && j=-1&&k=-1)return i;if(j<i && j<k && j!=-1) | (j!=-1 && i=-1 &

44、amp;& (j<k | k=-1)return j;if(k<i && k<j && k!=-1| k!=-1 && j=-1 && i=-1)return k;return inputstrlen;/ 检查标识符定义是否出错bool IsIdentifiersCorrect(char *buf)int i=0;int len=strlen(buf);char ch=buf0;if(ch>='a' && ch<='z' | ch>=

45、9;A' && ch<='Z' | ch='_')/标识符第一个只能是字母,或下划线for(i=1;i<len;i+)/检查标识符是否只由字母,数字和下划线组成 ch=bufi;if(ch>='0' && ch<='9' | ch>='a' && ch<='z' | ch>='A' && ch<='Z' | ch='_')contin

46、ue;else break;if(i<len) return false;return true;bool IsIdentifyersExist(char *buf)int i;char *tmp;for(i=0;i<arrlen;i+)tmp=identifiersi;if(!strcmp(tmp,buf)break; return i<arrlen; /i小于标识符数组长度,说明buf标识的标识符以经存在int FindFirstChar(char ch,int index)int i;for(i=index;i<inputstrlen;i+)if(inputstr

47、i=ch)break;if(i<inputstrlen) return i;return -1;五、 调试此次调试所利用到的编译环境是Microsoft Visual C+ 6.0 。通过对22组数据的调试测试本程序能正确的得到所要输出的结果。下附调试过程:一、程序调试:1、编译调试结果:2、运行界面:二、数据测试:所用的测试数据:1)const i=.43e2,b=3.4e5,c=1.0e-1,d=1.3e+2,j=2;2)const count=10,sum=81.5,char1='f',max=169,str1="h*54 2.4S!AAsj", char2='',str2="aa!+h"3)const count=10,sum=81.5,char1='f',string1="hj",max=169;4)Aconstt coun

温馨提示

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

评论

0/150

提交评论