1、词法分析程序构造原理与实现技术实验报告文档词法分析程序构造原理与实现技术实验报告变更说明日期版本变更位置变更说明作者2014/4/91.0初稿生成房皓2014/4/91.0完善截稿房皓一、 实验目的:本实验的目的在于在教师的引导下以问题回朔与思维启发的方式,使学生在不断的探究过程中掌握编译程序设计和构造的基本原理和实现技术,启迪学生的抽象思维、激发学生的学习兴趣、培养学生的探究精神和专业素养,从而提高学生发现问题、分析问题和解决问题的能力。2、实验内容:实验项目 完成以下正则文法所描述的Pascal 语言子集单词符号的词法分析程序。字母 字母 数字数字 数字 + * ; ()=* = : /该
2、语言的保留字:begin end if then else for do while and or not设计说明 (1)该语言大小写不敏感;(2)字母为a-z A-Z,数字为0-9;(3)可以对上述文法进行扩充和改造;(4) /*/为程序的注释部分。设计要求 (1)给出各单词符号的类别编码;(2)词法分析程序应能发现输入串中的错误;(3)词法分析作为单独一遍编写,词法分析结果为二元式序列组成的中间文件;(4)设计两个测试用例(尽可能完备),并给出测试结果。3、实验环境:操作系统:Windows 7软件: VC+6.04、程序功能描述: 给出了各单词符号的类别编码; 词法分析程序能够对给出的文
3、件中的输入串做出正确的词法; 词法分析程序能发现文件输入串中的错误; 词法分析结果为二元式序列组成的中间文件; 词法分析程序能兼容注释并能发现文件注释未关闭的错误五、数据结构设计:六、程序结构描述: 设计方法:本程序采用从文件读取字符串,根据已有文法、词法的构成及规定对字符串进行词法分析,其种类主要包括保留字、标识符、无符号数字、字符等,将分析的结果写入另一个文件。程序规定的单词符号及其种别码见下表:单词符号及其种别码表单词符号种别码单词符号 种别码begin1无符号整数13end2+14If3-15then4 *16else5;17for6(18do 7)19while8=20and921o
4、r 10=22not 1123标识符 12=2425:=26/27/*28*/29 主要函数说明:lookup():每调用一次,就以TOKEN中的字符串查保留字表,若查到,就将相应关键字的类别码赋给整型变量c;否则将c置为0;main():主函数;scanner():扫描函数,完成程序的主要功能,包括读字符串、分析处理、分析处理等。 函数调用关系说明:main()函数调用scanner()函数;scanner()函数调用lookup()函数。 执行框图:1) 总体结构图:2)扫描程序结构框图:七、 实验过程结果截图: 测试用例一: 结果一: 测试用例二: 结果二:八、 实验总结: 实验心得:通
5、过本次实验我锻炼了自己的上机操作能力及编程能力,并对理论知识有了进一步的了解。本实验基本思路比较清晰,用较为简单的算法就能实现;解决实验中遇到的问题也花费了一部分时间,我增长了处理关于文件错误的能力; 实验中遇到的问题:主要问题就是在读取文件时对文件末尾的判断预处理,有两个问题花费了大部分时间,一个是在回退时要判断是否为文件末尾,若是则不需要回退;另外一个就是要先读取一个字符再用feof(fp)来判断是否为文件尾,且两个应紧密相连; 程序的自我评价:此程序实现了要求中的所有功能,并增加了对注释的一些操作,但因编程能力的欠缺,其中有的地方不免有些繁杂,还有一些潜藏的问题,需要进一步测试来时程序变
6、得更加具有健壮性。九、 程序清单:/*课题名称:词法分析程序构造原理与实现技术作者:房皓 进修生 13410801最后修改时间:2014.4.9 19:47*/*单词符号及其分类编码单词符号 种别码 单词符号 种别码begin 1 无符号整数 13end 2 + 14if 3 - 15then 4 * 16else 5 ; 17for 6 ( 18do 7 ) 19while 8 = 20and 9 21or 10 = 22not 11 23标识符 12 = 24 25 := 26 / 27 /* 28 */ /29/*/#include#include#include#includeusin
7、g namespace std;/int lookup(char *str)/每调用一次,就以TOKEN中的字符串查保留字表,若查到,就将相应关键字的类别码赋给整型变量c;否则将c置为0 char*letter11=begin,end,if,then,else,for,do,while,and,or,not;/保留字 int i; for(i=0;i11;i+) if(strcmp(str,letteri)=0) /比较是否相同 return i+1; /若相同,返回相应的种别码 return 0;/int scanner(FILE *fp) char TOKEN20; FILE *fp_ou
8、t=fopen(result.txt,w); char ch; int i=0,c; int zhushi=0; /zhushi等于0表示当前不是注释,zhushi=1表示当前及以后的都是注释 ch=fgetc(fp); while(!feof(fp) /判断文件结束 if(zhushi=0) i=0; if(ch= |ch= ) else if(isalpha(ch) /是否为字母 ch=tolower(ch); /转换成小写 TOKEN0=ch; i+; ch=fgetc(fp); while(isalnum(ch) /数字或字母 if(isalpha(ch) ch=tolower(ch)
9、; TOKENi=ch; i+; ch=fgetc(fp); TOKENi=0; if(ch!=EOF) /经验证,若没有此判断,遇到文件结尾仍返回的话,则 fseek(fp,-1L,1); /ch的值永远为文件最后一个字符 c=lookup(TOKEN); /查找保留字 if(c=0) fprintf(fp_out,(%d,%s),12,TOKEN); /标识符 printf(%d,%s)n,15,TOKEN); /标识符 else fprintf(fp_out,(%d,%s),c,TOKEN); /保留字 printf(%d,%s)n,c,TOKEN); /保留字 else if(isdi
10、git(ch) /是否为数字 TOKEN0=ch; ch=fgetc(fp); i+; while(isdigit(ch) TOKENi=ch; i+; ch=fgetc(fp); TOKENi=0; if(ch!=EOF) fseek(fp,-1L,1); fprintf(fp_out,(%d,%s),13,TOKEN); /无符号整数 printf(%d,%s)n,16,TOKEN); /无符号整数 else switch(ch) case: if(!feof(fp) ch=fgetc(fp); if(ch=) fprintf(fp_out,(%d,%s),24,=); printf(%d
11、,%s)n,24,) fprintf(fp_out,(%d,%s),25,); printf(%d,%s)n,25,); else if(ch!=EOF) fseek(fp,-1,1); fprintf(fp_out,(%d,%c),23,); printf(%d,%c)n,23,: if(!feof(fp) ch=fgetc(fp); if(ch=) fprintf(fp_out,(%d,%s),22,=); printf(%d,%s)n,22,=); else if(ch!=EOF) fseek(fp,-1,1); fprintf(fp_out,(%d,%c),21,); printf(%
12、d,%c)n,21,); break; case+: fprintf(fp_out,(%d,%c),14,+); printf(%d,%c)n,14,+); break; case-: fprintf(fp_out,(%d,%c),15,-); printf(%d,%c)n,15,-); break; case*: fprintf(fp_out,(%d,%c),16,*); printf(%d,%c)n,16,*); break; case;: fprintf(fp_out,(%d,%c),17,;); printf(%d,%c)n,17,;); break; case(: fprintf(f
13、p_out,(%d,%c),18,(); printf(%d,%c)n,18,(); break; case): fprintf(fp_out,(%d,%c),19,); printf(%d,%c)n,19,); break; case/: if(!feof(fp) ch=fgetc(fp); if(ch=*) zhushi=1; /zhushi=1; fprintf(fp_out,(%d,%s),28,/*); printf(%d,%s)n,28,/*); else if(ch!=EOF) fseek(fp,-1,1); fprintf(fp_out,(%d,%c),27,/); print
14、f(%d,%c)n,27,/); break; case: if(!feof(fp) ch=fgetc(fp); if(ch=) fprintf(fp_out,(%d,%s),26,:=); printf(%d,%s)n,26,:=); else if(ch!=EOF) fseek(fp,-1,1); break; default: fprintf(fp_out,(%s,%c),非法字符,ch); printf(%s,%c)n,非法字符,ch); break; ch=fgetc(fp); if(zhushi=1) /该部分为检查注释是否结束,若结束,则令shuzhi=0; if(ch=*) i
15、f(!feof(fp) ch=fgetc(fp); if(ch=/) fprintf(fp_out,(%s,%s),注释结束,*/); printf(%s,%s)n,注释结束,*/); zhushi=0; ch=fgetc(fp); else if(ch!=EOF) fseek(fp,-1,1); ch=fgetc(fp); if(zhushi=1) /没有关闭注释 fprintf(fp_out,(%s),程序有错误,注释没有关闭!); printf(%s)n,程序有错误,注释没有关闭!); fclose(fp_out); return 1;/int main() FILE *fp=fopen(input.txt,r); scanner(fp); fclose(fp); return 1;
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1