资源描述
编译原理课程设计报告 专业: 计算机科学与技术学生姓名: 张金荣指导教师: 孔繁茹完成时间: 2021年10月11日 20112012学年第一学期 10- -目 录第 1 节课程设计目的1第 2 节课程设计要求1第 3 节课程设计内容2第 4 节 状态转换图4第 5 节 实现工具4第 6 节实现函数4第 7 节测试结果5第 8 节实验源代码6第 9 节参考文献9 致谢感设计目的 理解词法分析器的基本功能。词法分析的任务是:从左至右逐个字符地对源程序进行扫描,产生一个个的单词符号(token),把作为字符串的源程序改造成 单词符号串的中间程序。因此,词法分析是编译的基础。理解词法规则的描述方法。程序设计语言一般可以用标识符、关键字、运算符、分隔符、常量、字符串和注释符来描述理解状态转换图及其实现。一个状态转换图可用于识别(或接受)一定的字符。 大多数程序语言的单词符号都可以用转换图予以识别。 转换图非常易于用程序实现,最简单的办法是让每个状态结对应一小段程序。能够编写简单的词法分析器。 2.课程设计的要求手工构造一个简单的词法分析程序, 能够识别标识符、整数、关键字、算符、界符。画出识别单词的状态转换图。(若状态转换图过于复杂,可以只画出主要部分;若依旧复杂,可只识别标识符和整数) 根据状态转换图手工构造词法分析程序。从以下方法中选一: 词法分析器作为独立的一遍。 词法分析结果输出到屏幕上或存入文件。 词法分析器作为一个子程序被语法分析器调用。 每次调用返回一个单词 同时将单词及属性存入符号表 实现状态转换图。从以下方法中选一: 直接转向法 表驱动法四、选做实验 使用缓冲技术3.课程设计内容程序语言的单词符号一般可分为下列五种。(1)关键字 是由程序语言定义的具有固定意义的标志符。本程序定义 char,short,int,unsigned,long,float,double,struct,union,void,enum,const,typedef,auto,static,break,case,continue,default,do,else,for,if,return,switch,while,sizeof,printf,FILE,fopen,NULL,fclose,exit,read,closef,printf为关键字。 (2)标识符 用来表示各种名字,如变量名、数组名、过程名等等。 (3)常数 常数的类型一般有整型、实型、布尔型、文字型等等。例如,100,3.14159。 (4)运算符 如+、-、*、/、=、=、= 等等 (5)界符 如、(、)、;、,、.等等。具体实现过程:用c+编写词法分析程序,从文件中读入预分析的源程序经词法分析将结果写入指定文件中。在设计中预分析文件保存在test.txt中,输出结果保存在result.txt中。本程序实现了将词法分析器作为独立的一遍,词法分析结果存入文件。用直接转向法实现状态转换图。使用缓冲技术。本程序能够识别简单的运算符,界符,常数,标示符和关键字。其中关键字由程序所给的关键字表kt(key table)内容指定。如有未涉及的关键字还可以通过修改程序中表内容扩展。对未定义的字符(不属于界符,运算符和常数)输出 并显示为“其他字符”。文中特别定义了注释符号,换行符号和空格。在程序设计工程中一开始未注意将当前指针后退一位的情况,在输出程序结果时发现一些字符缺漏。通过查资料【1】发现了将指针后移的用法并解决了这个问题。设计过程中牵涉到对文件的使用如c_str(),ios:binary的用法,get()函数的用法,fstream的两个类ifstream和ofstream的用法【2】实现文件的读写操作。为了分析大于4kb的程序本程序使用了著名的双缓冲技术。设计思想如下 4.状态转换图如下 5.实验工具Vc+6.0 ,win7画图工具, 6. 实现函数void get_char (); /用于从buffer读取一个字符到C int letter (int C); /判断是否是字母 int digit (int C); /判断时候是数字或者小数点 int underline (int C); /判断时候是下划线 int reserve (string token); /判断时候是关键字 void retract (); /向前指针向后退一个 void returnout (string str1,string str2); /文件打印7. 结果及测试分析实验代码/ 词法分析程序zhangjinrong/头文件/#include #include #include using namespace std;/关键字/string kt36 =char,short,int,unsigned,long,float,double,struct,union,void,enum,const,typedef,auto,static,break,case,continue,default,do,else,for,if,return,switch,while,sizeof,printf,FILE,fopen,NULL,fclose,exit,read,close,fprintf; / /自定义变量,数组/ifstream infile; /以输入(从硬盘到内存)方式打开文件ofstream outfile; /输出(从内存到硬盘)方式打开文件char buffer1 64; /两个缓冲buffer char buffer2 64;char C; /用于switch分析 string token=; /多个C组成的串 char *startptr,*forwardptr; /buffer的开始指针和向前指针 /函数声明/void get_char (); /用于从buffer读取一个字符到C int letter (int C); /判断是否是字母 int digit (int C); /判断时候是数字或者小数点 int underline (int C); /判断时候是下划线 int reserve (string token); /判断时候是关键字 void retract (); /向前指针向后退一个 void returnout (string str1,string str2); /文件打印 /main () startptr=buffer1; /数组头指针 forwardptr=buffer1; /数组当前指针 buffer1 63=buffer2 63=-1; /数组尾数值为-1 cout输入源文件的路径和文件名:(例: F:1.c)str111; infile.open (str111.c_str (),ios:binary);/二进制文件 cout输入经词法分析后生成文件的路径和文件名:str222; outfile.open (str222.c_str (),ios:trunc);/再次写入覆盖文件已有内容/将文件内容读入第一缓冲区/ for (int i=0;i=62;i+) buffer1 i=infile.get ();/将文件中字符放入第一缓冲区 while (1) token=; /多个C组成的串为空 get_char (); /从数组中传递出一个字符c switch (C) /当首位字符为字母/ case a:case b:case c:case d:case e: case f: case g: case h: case i: case j: case k:case l:case m:case n:case o: case p: case q: case r: case s: case t: case u:case v:case w:case x:case y: case z: case A: case B: case C: case D: case E:case F:case G:case H:case I:case J:case K:case L:case M:case N:case O: case P:case Q:case R:case S:case T:case U:case V:case W:case X:case Y:case Z: while (letter (C)|digit (C)|underline (C) /字母后跟字母或数字或下划线时 token=token+C; get_char (); if (reserve (token)=1) /如果字符串不在关键字表中输出标示符 returnout (关键字,token); else returnout (token,标示符); /如果在关键字表中输出标示符 retract (); /*当token已为关键字时由于执行了get_char()已读取一个字符。 为避免漏掉需回溯一个字符*/ break; / 当首字母为数字时 / case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 0: while (digit (C)=1|C=.) token=token+C; get_char (); returnout (常数,token); retract (); break; /本程序定义为运算符所以考虑不同情况/ case : get_char (); /字符为,=,三种情况 if (C=) returnout (,空格分界符); else retract (); returnout ( :returnout (,运算符);break;/case/ :returnout (/,运算符);break;case( :returnout (,界符); break; case) :returnout (),界符); break;case :returnout (,界符); break;case :returnout (,界符); break; case; :returnout (;,界符); break;case. :returnout (.,界符); break;case, :returnout (,界符); break;case :returnout (,界符); break; case :returnout (,界符); break;/换行和空格/ case : break; case n: caser: /遇到换行符 if (C=n) break; default: outfile Cendl; break; infile.close (); outfile.close (); system (pause); return 0;/双缓冲的实现/void get_char () if (* forwardptr)=-1) /当前指针在缓冲区(不知是那个缓冲区)末尾 if (forwardptr=buffer1+63) /在第一buffer尾,向第二buffer读入数据 for (int i=0;i=62;i+) buffer2 i=infile.get (); forwardptr=buffer2; get_char (); else if (forwardptr=buffer2+63) /在第二buffer尾,向第一buffer读入数据 for (int i=0;i=62;i+) buffer1 i=infile.get (); forwardptr=buffer1; get_char (); else /在不是buffer尾的位置读到了EOF,说明完成了分析 infile.close (); outfile.close (); ofstream out; cout词法分析结果已存入文件夹中=65&C=97)&(C=48)&(C=57) return 1; else return 0;int underline (int C) if (C=_) return 1; else return 0;int reserve (string token) for (int i=0;i=35;i+) if (token=kt i) return 1; return 0;void retract () if (forwardptr=buffer1) /向前指针在buffer头 forwardptr=(buffer2+63); /后退一个字符在第二缓冲区末尾 else if (forwardptr=buffer2) /使向前指针在第二个buffer尾 forwardptr=(buffer1+63); else forwardptr-; void returnout (string str1,string str2) outfile str1 , str2endl;/YANTAN/UNIVERSITY/SC/09/1/1/2009/2550/1128/qq/1013415421/参考文献【1】百度文库fseek用法详解【2】百度文库c和c+文件读写操作【3】程序设计语言编译原理国防 陈火旺【4】词法分析器的设计
展开阅读全文