1、 学院(系)名称:计算机工程系姓名 学号 专业班级 实验项目 实验一:词法分析课程名称 编译原理 课程代码 0310243实验时间2013 年 4 月 28 日 第 1、2 节2013 年 5 月 7 日 第 1 、2 节实验地点 第一教学楼 1508批改意见 成绩教师签字: 实验内容:实现标准 C 语言词法分析器实验目的:1掌握程序设计语言词法分析的设计方法;2掌握 DFA 的设计与使用方法;3掌握正规式到有限自动机的构造方法;实验要求:1单词种别编码要求基本字、运算符、界符:一符一种;标识符:统一为一种;常量:按类型编码;2词法分析工作过程中建立符号表、常量表,并以文本文件形式输出;3词法
2、分析的最后结果以文本文件形式输出;4完成对所设计词法分析器的功能测试,并给出测试数据和实验结果;5为增加程序可读性,请在程序中进行适当注释说明;6整理上机步骤,总结经验和体会;7认真完成并按时提交实验报告。实验步骤:1.基本思想:从源程序中依次读入字符并解析,与关键字、运算符、结束符进行比较,得出其中的关键字,并将它存入到数组中去。2.程序源代码:#include#include#include#define MaxSize1 17/关键字的个数#define MaxSize2 20/运算符的个数#define MaxSize3 4/结束符的个数/数据结构struct TNodechar va
3、lue20; /存放标识符的值int number; /存放标识符的种别码char description20;/描述KeyWordsMaxSize1,OperationMaxSize2,EndOperationMaxSize3;/存放关键字的数组char *WordsBuffMaxSize1=“const“,“long“,“float“,“double“,“void“,“main“,“if“,“else“,“then“,“break“,“int“,“char“,“include“,“for“,“while“,“printf“,“scanf“;/存放运算符的数组char *OperationB
4、uffMaxSize2=“+“,“-“,“*“,“/“,“+=“,“-=“,“*=“,“+“,“-“,“,“=“,“0)if(isChar(buff0)/是标识符strcpy(Variablecount1.value,buff);Variablecount1.number=count1;strcpy(Variablecount1.description,“标识符“);count1+;/计数器加一i=0;/清空缓冲区else if(isDigit(buff0)/是常量strcpy(Constcount2.value,buff);Constcount2.number=count2;strcpy(C
5、onstcount2.description,“常量“);count2+;/计数器加一i=0;/清空缓冲区else/缓冲区为空!/处理回车符与换行符nextchar0=fgetc(in);else if(isEndOperation(nextchar0)!=-1)buffi=0;a=isKeyWords(buff);if(a!=-1Table1count.number=KeyWordsa.number;strcpy(Table1count.description,KeyWordsa.description);strcpy(temp,KeyWordsa.value);count+;/计数器加一i
6、=0;/清空缓冲区else if(i0)if(isChar(buff0)/是标识符strcpy(Variablecount1.value,buff);Variablecount1.number=count1;strcpy(Variablecount1.description,“标识符“);count1+;/计数器加一i=0;/清空缓冲区else if(isDigit(buff0)/是常量strcpy(Constcount2.value,buff);Constcount2.number=count2;strcpy(Constcount2.description,“常量“);count2+;/计数
7、器加一i=0;/清空缓冲区else/缓冲区为空!nextchar0=fgetc(in);else if(a=isOperation(nextchar)!=-1)/首先输出缓冲区中的数据buffi=0;a=isKeyWords(buff);if(a!=-1Table1count.number=KeyWordsa.number;strcpy(Table1count.description,KeyWordsa.description);第 10 页 共 13 页count+;/计数器加一i=0;/清空缓冲区else if(i0)if(isChar(buff0)/是标识符strcpy(Variable
8、count1.value,buff);Variablecount1.number=count1;strcpy(Variablecount1.description,“标识符“);count1+;/计数器加一i=0;/清空缓冲区else if(isDigit(buff0)/是常量strcpy(Constcount2.value,buff);Constcount2.number=count2;strcpy(Constcount2.description,“常量“);count2+;/计数器加一i=0;/清空缓冲区else/缓冲区为空!/处理运算符op0=nextchar0;nextchar0=fg
9、etc(in);if(nextchar0!=)if(isOperation(nextchar)!=-1)op1=nextchar0;if(a=isOperation(op)!=-1)/输出双目运算符strcpy(Table1count.value,Operationa.value);Table1count.number=Operationa.number;strcpy(Table1count.description,Operationa.description);count+;/计数器加一/读取下一个字符nextchar0=fgetc(in);第 11 页 共 13 页else/错误的双目运算
10、符strcpy(Table1count.value,op);Table1count.number=-1;strcpy(Table1count.description,“未定义的运算符“);count+;/计数器加一/读取下一个字符nextchar0=fgetc(in);else/输出一元运算符op1=0;a=isOperation(op);strcpy(Table1count.value,Operationa.value);Table1count.number=Operationa.number;strcpy(Table1count.description,Operationa.descrip
11、tion);count+;/计数器加一return count;void main()inputKeyWords(WordsBuff,MaxSize1);inputOperation(OperationBuff,MaxSize2);inputEndOperation(EndOperationBuff,MaxSize3);FILE *in,*out;bool Flag=true;while(Flag)printf(“源文件的位置:C :input.txtn“);if(in=fopen(“C:input.txt“,“r“)=NULL)printf(“读取源文件失败!n“);exit(0);if(o
12、ut=fopen(“C:out.txt“,“w“)=NULL)printf(“打开文件失败!n“);第 12 页 共 13 页exit(0);int MaxSize=start1(in);printf(“关键字及运算符n“);fprintf(out,“关键字及运算符n“);outputInfo(Table1,MaxSize);outInfoToFile(Table1,MaxSize,out);printf(“标识符表:n“);fprintf(out,“标识符表:n“);outputInfo(Variable,count1);outInfoToFile(Variable,count1,out);
13、printf(“常量表:n“);fprintf(out,“常量表:n“);outputInfo(Const,count2);outInfoToFile(Const,count2,out);Flag=false;fclose(in);fclose(out);3.测试用例:int a=3;double b=4;int c;if(ab)c=a;elsec=b;4.测试结果:第 13 页 共 13 页5.心得体会:通过这次实验,我对编译原理这门专业必修课有了进一步的深层次了解,把 理论知识应用于实验中,实验过程中对于转义字符,结束符、欠缺了考虑,在多次的调试和改进中最终完善了程序,而在调试过程中学习的知识得到了完善和补充,对词法分析器的理解更进一步。 也让我重新熟悉了 C+语言的相关内容, 加深了对 C+ 语言知识的深化和用途的理解。