《编译原理实验报告-词法分析程序的设计.doc》由会员分享,可在线阅读,更多相关《编译原理实验报告-词法分析程序的设计.doc(9页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。
1、. .实验2 词法分析程序的设计一、实验目的掌握计算机语言的词法分析程序的开发法。二、实验容编制一个能够分析三种整数、标识符、主要运算符和主要关键字的词法分析程序。三、实验要求1、根据以下的正规式,编制正规文法,画出状态图;标识符(|)*十进制整数0 | (1|2|3|4|5|6|7|8|90|1|2|3|4|5|6|7|8|9*)八进制整数 01|2|3|4|5|6|70|1|2|3|4|5|6|7*十六进制整数0x0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f*运算符和界符+ - * / = ( ) ;关键字if
2、 then else while do 2、根据状态图,设计词法分析函数int scan( ),完成以下功能:1) 从文本文件中读入测试源代码,根据状态转换图,分析出一个单词,2) 以二元式形式输出单词其中单词种类用整数表示:0:标识符1:十进制整数2:八进制整数3:十六进制整数运算符和界符,关键字采用一字一符,不编码其中单词属性表示如下:标识符,整数由于采用一类一符,属性用单词表示运算符和界符,关键字采用一字一符,属性为空3、编写测试程序,反复调用函数scan( ),输出单词种别和属性。四、实验环境PC微机DOS操作系统或 Windows 操作系统Turbo C 程序集成环境或 Visual
3、 C+ 程序集成环境五、实验步骤1、 根据正规式,画出状态转换图;01字母空白字母或数字非字母与数字3194092非数字5061707非0778x909或af非09与af1011+ 或或* 或/ 或 或= 或 (或 ) 或 ;12if then else while do*非17与x09或af2、 根据状态图,设计词法分析算法;观察状态图,其中状态2、4、7、10右上角打了星号需要回调一个字符。声明一些变量和函数:ch:字符变量,存放最新读进的源程序字符。strToken:字符串变量,存放构成单词符号的字符串。GetChar():子函数,将下一输入字符读到ch中,搜索指示器前移一字符位置。Ge
4、tBC():子函数,检查ch中的字符是否为空白。假设是,那么调用GetChar()直至ch中进入一个非空白字符。Concat():子函数,将ch中的字符连接到strToken之后。IsLetter():布尔函数,判断ch中的字符是否为字母。IsDigit():布尔函数,判断ch中的字符是否为数字。Reserve():整型函数,对strToken中的字符串查找保存字表,假设它是一个保存字那么返回它的编码,否那么返回0。SearchOp():整型函数,对ch查找运算符和界符,假设它是一个运算符或界符,那么返回它的编码,否那么返回0。Retract():子函数,将搜索指示器回调一个字符位置,将ch置
5、为空白字符。ProError():错误处理函数。关键字保存在字符数组中,定义编码为相对数组首地址的位置 + 1。保存子表顺序如下: if ,then,else,while,do ,那么相应编码为:1,2,3,4,5。运算符和界符保存在字符数组中,编码定义与关键字一样,顺序如下: + ,- , * , / , , , = , ( , ) ,;,编码为:110。二元表单词单词种类属性标识符0单词自身十进制整数1单词自身八进制整数2单词自身十六进制整数3单词自身运算符和界符单词自身-关键字单词自身-算法如下:ch= ;strToken=;GetBC();if(IsLetter() while(IsL
6、etter() | IsDigit() Concat();GetChar(); Retract();If(Reserve()printf(, strToken); else printf(, strToken);else if(1 =ch & ch =9) while(IsDigit() Concat();GetChar(); Retract();printf(, strToken) ; else if(ch=0) GetChar();if(ch = 1 & ch = 0 & ch = 7) Concat();GetChar(); Retract();printf(, strToken) ;e
7、lse if(ch=x) GetChar();while(IsDigit() | ch= a & ch=f) Concat();GetChar(); Retract();printf(, strToken);else Retract();printf(“);else if(SearchOp() printf(, ch);else ProError();3、 采用C或C+语言,设计函数scan( ),实现该算法;char GetChar(FILE* fp) /读取文件中的一个字符char ch;ch = fgetc(fp);return ch;char GetBC(FILE* fp) /读取文件
8、的字符直至ch不是空白char ch;do ch = GetChar(fp); while (ch = | ch =t | ch = n);return ch;void Concat(charch ,charstrToken) /将ch中的字符连接到strToken之后char str2;str0 = ch;str1 = 0;strcat(strToken,str);int IsLetter(charch) /布尔函数,判断ch中的字符是否为字母,是返回1,否那么返回0int flag = 0;if (ch = a & ch = 0 & ch = 9)flag = 1;return flag;
9、int Reserve(charstrToken) /整型函数,对strToken中的字符串查找保存字表,假设它是一个保存字那么返回它的编码,否那么返回0int code = 0,i;char keyWord66 = if, then, else, while, do ;for (i = 0; i 5; i+) if (strcmp(strToken, keyWordi) = 0) code = i + 1;break;return code;int SearchOP(charch) /整型函数,对strToken中的字符串查找运算符和界符,假设它是一个运算符或界符,那么返回它的编码,否那么返
10、回0int code = 0, i;char OP11 = +, -, *, /, , =, (, ), ; ;for (i = 0; i 10; i+) if (ch = OPi) code = i + 1;break;return code;char Retract(FILE* fp,charch) /子函数,将搜索指示器回调一个字符位置,将ch置为空白字符ch = ;fseek(fp, -1L, 1);returnch;void ProError( ) /错误处理函数printf(输入错误!n);return;FILE* scan(FILE* fp) /输出单个二元式char ch;ch
11、ar strToken10;strToken0 = 0;/置strToken为空串ch = GetBC(fp); /先读取一个非空白的字符if (feof(fp) returnfp;/判断文件尾,是那么返回调用程序if (IsLetter(ch) /判断标识符while (IsLetter(ch) | IsDigit(ch) Concat(ch, strToken);ch = GetChar(fp);ch = Retract(fp,ch);if (Reserve(strToken) /判断关键字printf(n, strToken);elseprintf(n, strToken);elseif
12、 (ch = 1 & ch = 9) /判断十进制整数while (IsDigit(ch) Concat(ch, strToken);ch = GetChar(fp);ch = Retract(fp, ch);printf(n, strToken);elseif (ch = 0) ch = GetChar(fp);if (ch = 1 & ch = 0 & ch = 7) Concat(ch, strToken);ch = GetChar(fp);ch = Retract(fp, ch);printf(n, strToken);elseif (ch = x) /判断十六进制整数ch = Get
13、Char(fp);while (IsDigit(ch) | ch = a & ch = f) Concat(ch, strToken);ch = GetChar(fp);ch = Retract(fp, ch);printf(n, strToken);else /判断十进制的0ch = Retract(fp, ch);printf(n);elseif (SearchOP(ch) /判断运算符和界符printf(n, ch);else /出错ProError();returnfp;4、编制测试程序主函数main;#includeusingnamespace std;#defineNULL 0in
14、t main( ) FILE* fp; if (fp = fopen(C:UsersAdministratorDesktopCode.txt, r) = NULL) /以只读式翻开文件,失败那么退出程序printf(file can not open!);exit(0);printf(词法分析结果如下:n);while (!feof(fp) /假设不是文件尾那么执行循环fp = scan(fp);/输出单词种类、属性的二元式fclose(fp); /关闭文件fp = NULL;/防止指向非法存5、调试程序:读入文本文件,检查输出结果。六、测试数据 输入数据: , -编辑一个文本文件progra
15、m.txt,在文件中输入如下容:if data+920x3f thendata=data+01;elsedata=data-01;正确结果:七、实验报告要求实验报告应包括以下几个局部:1、词法的正规式描述;2、变换后的状态图;3、词法分析程序的数据构造与算法。八、思考题1、 词法分析能否采用空格来区分单词?答:不能,因为程序的语法里有包括:;, ,等界符或连接符号存在,这些符号符与单词的连接无空格,用空格区分单词将无法保证程序语法的正确。2、 程序设计中哪些环节影响词法分析的效率?如提高效率?答:本程序在判断关键字时,是在完成对标志符的识别后,判断该标识符是否是保存字,假设是那么判断为关键字,这种情况下,导致每次识别完一个标识符,都要查询保存字表,会影响效率,可在识别标识符的程序段中添加对关键字的识别,如首字母的特别判断或遇到数字跳过关键字的判断等。另外,程序的实现是通过在主函数中循环调用scan函数来输出二元式,一次调用就输出一个二元式,可以考虑使用堆栈,先将读来的数据压栈,再进展识别,这样比重复调用函数效率更高,而且也不必使用文件指针来回调字节,用堆栈会更便更平安准确,省去不少程序段。教育之通病是教用脑的人不用手,不教用手的人用脑,所以一无所能。教育革命的对策是手脑联盟,结果是手与脑的力量都可以大到不可思议。. .word.zl.
限制150内