《编译原理实验报告2-词法分析程序的设计.pdf》由会员分享,可在线阅读,更多相关《编译原理实验报告2-词法分析程序的设计.pdf(9页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、-.实验 2词法分析程序的设计一、实验目的一、实验目的掌握计算机语言的词法分析程序的开发方法。二、实验容二、实验容编制一个能够分析三种整数、标识符、主要运算符和主要关键字的词法分析程序。三、实验要求三、实验要求1、根据以下的正规式,编制正规文法,画出状态图;标识符(|)*十进制整数八进制整数运算符和界符关键字0|((1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9)*)0(1|2|3|4|5|6|7)(0|1|2|3|4|5|6|7)*十六进制整数 0 x(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)(0|1|2|3|4|5|6|7|8|9|a|
2、b|c|d|e|f)*+-*/=();ifthenelsewhiledo2、根据状态图,设计词法分析函数int scan(),完成以下功能:1)从文本文件中读入测试源代码,根据状态转换图,分析出一个单词,2)以二元式形式输出单词其中单词种类用整数表示:0:标识符1:十进制整数2:八进制整数3:十六进制整数运算符和界符,关键字采用一字一符,不编码其中单词属性表示如下:标识符,整数由于采用一类一符,属性用单词表示运算符和界符,关键字采用一字一符,属性为空3、编写测试程序,反复调用函数scan(),输出单词种别和属性。四、实验环境四、实验环境PC 微机DOS 操作系统或 Windows 操作系统Tu
3、rbo C 程序集成环境或 Visual C+程序集成环境五、实验步骤五、实验步骤1、根据正规式,画出状态转换图;-.可修编.-.空白字母01字母或数字非字母与数字2*09193非 17 与 x05x17609或af09或af89非数字4*07非 07*7*10非 09 与 af+或或*或/或 或=或(或)或;11ifthenelsewhiledo122、根据状态图,设计词法分析算法;观察状态图,其中状态 2、4、7、10(右上角打了星号)需要回调一个字符。声明一些变量和函数:ch:字符变量,存放最新读进的源程序字符。strToken:字符串变量,存放构成单词符号的字符串。GetChar():
4、子函数,将下一输入字符读到ch 中,搜索指示器前移一字符位置。GetBC():子函数,检查 ch 中的字符是否为空白。若是,则调用 GetChar()直至 ch中进入一个非空白字符。Concat():子函数,将 ch 中的字符连接到 strToken 之后。IsLetter():布尔函数,判断 ch 中的字符是否为字母。IsDigit():布尔函数,判断 ch 中的字符是否为数字。Reserve():SearchOp():整型函数,对 strToken 中的字符串查找保留字表,若它是一个保留字整型函数,对 ch 查找运算符和界符,若它是一个运算符或界符,则则返回它的编码,否则返回0。返回它的编
5、码,否则返回0。Retract():子函数,将搜索指示器回调一个字符位置,将ch 置为空白字符。ProError():关键字保存在字符数组中,定义编码为相对数组首地址的位置+1。保留子表顺序如下:if,then,else,while,do ,则相应编码为:1,2,3,4,5。运算符和界符保存在字符数组中,编码定义与关键字相同,顺序如下:+,-,*,/,=,(,),;,编码为:110。-.可修编.错误处理函数。-.二元表单词标识符十进制整数八进制整数十六进制整数运算符和界符关键字算法如下:ch=;GetBC();if(IsLetter()while(IsLetter()|IsDigit()Con
6、cat();Retract();If(Reserve()else if(1 =ch&ch=9)while(IsDigit()Concat();Retract();printf(,strToken);GetChar();if(ch=1&ch=0&ch=7)Concat();GetChar();else if(ch=0)GetChar();printf(,strToken);单词种类0123单词自身单词自身属性单词自身单词自身单词自身单词自身-strToken=”;GetChar();elseprintf(,strToken);Retract();printf(,strToken);else if
7、(ch=x)GetChar();Concat();GetChar();Retract();printf(,strToken);else-.可修编.while(IsDigit()|ch=a&ch=f)-.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)char ch;do ch=GetCh
8、ar(fp);while(ch=|ch=t|ch=n);return ch;void Concat(charch,charstrToken)char str2;str0=ch;str1=0;strcat(strToken,str);int IsLetter(charch)回1,否则返回0int flag=0;if(ch=a&ch=0&ch=9)flag=1;return flag;-/读取文件的字符直至ch不是空白/将ch中的字符连接到strToken之后/布尔函数,判断ch中的字符是否为字母,是返/布尔函数,判断ch中的字符是否为数字,是返.可修编.-.int Reserve(charstr
9、Token)int code=0,i;char keyWord66=if,then,else,while,do;for(i=0;i 5;i+)if(strcmp(strToken,keyWordi)=0)int SearchOP(charch)int code=0,i;char OP11=+,-,*,/,=,(,),;for(i=0;i 10;i+)if(ch=OPi)char Retract(FILE*fp,charch)空白字符ch=;void ProError()return;/错误处理函数printf(输入错误!n);fseek(fp,-1L,1);returnch;/子函数,将搜索指
10、示器回调一个字符位置,将ch置为code=i+1;break;/整型函数,对strToken中的字符串查找运算符和界符,若它是一个运算符或界符,则返回它的编码,否则返回0code=i+1;break;/整型函数,对strToken中的字符串查找保留字表,若它是一个保留字则返回它的编码,否则返回0return code;return code;FILE*scan(FILE*fp)char ch;char strToken10;strToken0=0;/置strToken为空串/先读取一个非空白的字符ch=GetBC(fp);/输出单个二元式if(feof(fp)returnfp;/判断文件尾,是
11、则返回调用程序-.可修编.-.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(ch=1&ch=9)/判断十进制整数while(IsDigit(ch)Concat(ch,strToken);ch=GetChar(fp);ch=Retract(fp,ch);printf(n,strToken)
12、;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=GetChar(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);-.可修编.
13、-.elseif(SearchOP(ch)/出错ProError();/判断运算符和界符printf(n,ch);else returnfp;4、编制测试程序(主函数main);#includeusingnamespace std;#defineNULL 0int main()FILE*fp;if(fp=fopen(C:UsersAdministratorDesktopCode.txt,r)=NULL)/以只读方式打开文件,失败则退出程序printf(词法分析结果如下:n);/若不是文件尾则执行循环fclose(fp);/关闭文件fp=NULL;/避免指向非法存fp=scan(fp);/输出单
14、词种类、属性的二元式printf(file can not open!);exit(0);while(!feof(fp)5、调试程序:读入文本文件,检查输出结果。-.可修编.-.六、测试数据六、测试数据输入数据:编辑一个文本文件 program.txt,在文件中输入如下容:,-正确结果:-.可修编.if data+920 x3fthendata=data+01;elsedata=data-01;-.七、实验报告要求七、实验报告要求实验报告应包括以下几个部分:1、词法的正规式描述;2、变换后的状态图;3、词法分析程序的数据结构与算法。八、思考题八、思考题1、词法分析能否采用空格来区分单词?答:不
15、能,因为程序的语法里有包括:;,(,)等界符或连接符号存在,这些符号符与单词的连接无空格,用空格区分单词将无法保证程序语法的正确。2、程序设计中哪些环节影响词法分析的效率?如何提高效率?答:本程序在判断关键字时,是在完成对标志符的识别后,判断该标识符是否是保留字,若是则判断为关键字,这种情况下,导致每次识别完一个标识符,都要查询保留字表,会影响效率,可在识别标识符的程序段中添加对关键字的识别,如首字母的特别判断或遇到数字跳过关键字的判断等。另外,程序的实现是通过在主函数中循环调用scan()函数来输出二元式,一次调用就输出一个二元式,可以考虑使用堆栈,先将读来的数据压栈,再进行识别,这样比重复调用函数效率更高,而且也不必使用文件指针来回调字节,用堆栈会更方便更安全准确,省去不少程序段。-.可修编.