词法分析器(含完整源码)_第1页
词法分析器(含完整源码)_第2页
词法分析器(含完整源码)_第3页
词法分析器(含完整源码)_第4页
词法分析器(含完整源码)_第5页
已阅读5页,还剩19页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、词法分析实验报告一、实验目的与要求:1、了解字符串编码组成的词的内涵, 感觉一下字符串编码的方法和解读2 、了解和掌握自动机理论和正规式理论在词法分析程序和控制理论中的应用二、实验内容:构造一个自己设计的小语言的词法分析器:1 、这个小语言能说明一些简单的变量识别诸如begin , end, if , while 等保留字;识别非保留字的一般标识符(有下划线、字符、 数字, 且第一个字符不能是数字)。 识别数字序列(整数和小数); 识别 := , <=, >=之类的特殊符号以及;, (, )等界符。2、相关过程(函数):Scanner() 词法扫描程序,提取标识符并填入displa

2、y 表中3 、这个小语言有顺序结构的语句4 、这个小语言能表达分支结构的语句5 、这个小语言能够输出结果总之这个小语言词法分析器能提供以上所说明到的语法描述的功能三、实验步骤:1、测试评价( 1 ) 、测试1 :能说明一些简单的变量,如关键字、一般标识符、界符等;( 2) 、测试2:能输出结果:单词符号(内码形式)、各种信息表( 如符号表、常量表等) ;( 3) 、测试程序:var x,y,z;beginx:=2;y:=3;if (x+5>=y*y) thenbeginz:=y*y-x;z:=z+x*x;endelsez:=x+y;prn z;end.(4)、结果:、从键盘读入;部分结果

3、如下:endla少奏i集型下标<0x1*0x1<0x2*0X0 ><0x78x2 )01 ><0x7JF0x2 )<0x20x2 ><0x70x3 ><0x£0x2 ><0x23x3 )<0x70x7 >r»-: esi -F标常量值<0X0,0x2 >(0X1,0x3 >0x2.0x5 >亚里表:壅型变量名称<0x0x>COxl (0x2 烟3 (0x4y> z> x> y>C幡>t>(0x6y>(0x7v

4、>(0x8(0x9y><CTxay>x>K(类型:该标识符所属的类型,如关键字,变量等;下标:该标识符所对应表(如变量标 识符表,常量标识符表等)中其相应的位置,下同)、从文件读入,输出到文件;茸输入读入方式-1:从文件中读.2 1卷盘族输入结束标志位就):1Entei* the input File name *c-Sintest _txtEriteir the out put f lie nrne c:omttest.txtPress any key to continue部分结果如下:FC test in, txt -记事本testout.txt -记事本夏

5、伴(F)镰辑格式)置看OH赛文件(F)编辑(E)格式(6 X(V)帮助(H)var x,n,z;类型下标n(0x1V0x1 c)begin(02W。)(0x7f0x2)x :=2 ;(0x20X1)(0x70x2)H:=3;(0x2V0x2)(0x70X3)if (x+5>-y*y)then(0x1f9x2)(0x2V0x3)begin(0547f触7)10xU)z : =y”-K;(0x3OxD)(0x70x3)Z:-Z+X*K;(0或2f加灯f M7.ftx75或件华)褊辑EJ 格式口)膏春(豆)帮月I文怦F端辕£E)格式查看(U) 帮助(H).类型变量名称(OM0X)(0

6、x1y)(0x2z)(0x3x>(0翼4y)(0x5x)(0x6(0x7y)(0x8z)(Qx9y)(0xay)(GxbX)(OxcZ)(Oxdz)t flVQV,下标 (0X0 (0x1常量值.0X2),触3),岫弓)其他测试及结果如下:请输入演入方式:2if<my_pear80> a: uen* 10nuits : =20;1;从文件中读,2;从健;=5.125i料盘诱(输入结弟标志位*0 ;Di 菩 pldy 表:类型下标C0xiOm><0x7kDk。)<0X3F0X0 5C0x?Bxl>C0x20X15<0x7kBx?5CBx5kX)C0

7、x4,EtxB>C0x7a0x35C0xl,0>1C>C0x3尸Bxl>C0x2,Bx2;C0x7a0X?C0x5n0>45<0x3尸0x2C0x7,0x35常量表.下标 常量值C0X0416,2?C0xl,岫a)32n旭 *14)銮量表:变量名称<0X0m_pe ai*8 0 3C0xla)C0x2nu七零Pi'ess any ke%p tc> tont inue、出错处理;注:若有错误,则只指出错误,不输出各个表;(5)、评价:这个小语言程序基本上能完成词法分析阶段的工作,识别诸如begin , if等保留字;识别非保留字的一般标识符

8、(有下划线、字符、数字,且第一个字符不能是数字)。识别数字序列(整数和小数);识别尸,<=, >=之类的特殊符号以及;,(,)等界符。在扫描源程序串 的同时,能进行一些简单的处理,如删除空格、tab、换行等无效字符,也进行了一些基本的错误处理,如变量长度的判别等。遇到的问题:(a)、判别标识符超过规定长度(20)时,未输出处理结果;(b)、整数长 度过长输出结果仍为整数类型 3; (c)、对于小数如.045,被解释为界符和整数;(d)、对 以数字开头的一般标识符的处理,如100nuts被解释为整数类型和标识符,未给出错误提示。如上测试,出现前两个问题时已报错并输出所在行,而后两个问

9、题待解决。2、对小语言的词法规则(正规式)画出一个确定的有限自动机(见附录2、 3)(见附录1)五、实验中发现的问题和遇到的困难及解决方法:由于以前未曾接触过编译原理,在该实验的设计中,的确遇到一定的困难。主要是display 表结构的设计,由于语法分析和语义分析还未学习,无法站在全局的角度统筹兼顾,在表结构设计时,不知该往表结构体中添加哪些内容,可以为后续的工作做铺垫,这是刚开始就遇到的最大的困难,也是最难的。经过分析,我们在现有局限性的基础上,设计出一种折中的表结构,即在表结构中只添加标识符在其相应表中的对应下表,标记符类型码等关键的几处,这样既能唯一确定一标识符, 达到该实验的要求,同时

10、又为表保留了很好的扩充性,以达到后续实验的要求。表结构设计好后,其余的工作就是提取字符串和写入display 表, 在提取单字符还是双字符组成的运算符时有些麻烦,不过利用数据结构的相关知识也是容易做到。六、总结:词法分析是构造编译器的起始阶段,也是相应比较简单的一个环节。词法分析的主要任务是:根据构造的状态转换图,从左到右逐个字符地对源程序进行扫描,识别开源程序中具有独立含义的最小语法单位符号或单词,如变量标识符,关键字,常量,运算符,界符等。然后将提取出的标识符以内码的形式表示,即用int 类型的数字来表示其类型和在display 表中的位置,而无须保留原来标识符本身的字符串,这不仅节省了内

11、存空间,也有利于下一阶段的分析工作。当然,在扫描源程序串的同时,进行一些简单的处理,如删除空格、tab 、换行等无效字符, 也进行了一些基本的错误处理,如变量长度的判别,有些不合词法规则的标识符判别等。总之,严格说来,词法分析程序只进行和词法分析相关的工作。七、实验感想:通过此次实验,让我了解到如何设计、编制并调试词法分析程序,加深对词法分析原理的理解;熟悉了构造词法分析程序的手工方式的相关原理,使用某种高级语言(例如C+诩言)直接编写此法分析程序。另外,也让我重新熟悉了C+语言的相关内容,加深了对 C+语言的用途的理解。1(代码)#include <iostream>#inclu

12、de <fstream>#include <string>#include <math.h>#include <ctype.h>#include <cstdlib>using namespace std;#define Max 655 / 最大代码长度#define WordMaxNum 256#define DigitNum 256#define MaxKeyWord 32# define MaxOptANum 8# define MaxOptBNum 4# define MaxEndNum 11/ 变量最大个数/ 常量最大个数/

13、关键字数量/ 运算符最大个数 / 运算符最大个数 / 界符最大个数typedef struct DisplayTableint Index; / 标识符所在表的下标int type;/ 标识符的类型int line;/ 标识符所在表的行数char symbol20; / 标识符所在表的名称Table;int TableNum = 0; /display 表的下标char WordWordMaxNum20; / 标识符表char DigitWordMaxNum20; / 数字表int WordNum = 0; / 变量表的下标int DigNum = 0;/ 常量表的下标bool errorFl

14、ag = 0; / 错误标志const char* const KeyWordMaxKeyWord = "and", "array", "begin", "case","char"constant", "do", "else", "end", "false","for", "if",input", "integer","not&

15、quot;, "of","or", "output","packed","procedure",program", "read","real","repeat", "set", "then", "with","prn" /关键字const char OptA = '+','-','*','/&

16、#39;,'=','#','<','>' /const char *OptB = "<=",">=",":=","<>"const char End = '(',')', ',', ''/ 界符"to", "type", "until", "var","while&

17、quot;,单目运算/ 双目运算符'.', '', '', ':', '', '', '"'void error(char str20,int nLine, int errorType) n.cout <<" nError : switch(errorType)case 1:cout << " 第 " << nLine-1 <<" 行 " << str <&l

18、t; errorFlag = 1;break;case 2:cout << " 第 " << nLine-1 <<" 行 " << str << errorFlag = 1;break;case 3:cout << " 第 " << nLine-1 <<" 行 " << str <<变量的长度超过限制!n"小数点错误!n"常量的长度超过限制!n"/errorerror

19、Flag = 1; break;void Scanner(char ch,int chLen,Table tableMax,int nLine) int chIndex = 0;while(chIndex < chLen) / 对输入的字符扫描/*处理空格和tab*/while(chchIndex = ' ' | chchIndex = 9 ) /忽略空格和tab chIndex +; /*处理换行符*/while(chchIndex = 10) / nLine+;chIndex +;遇到换行符,行数加1/*标识符*/if( isalpha(chchIndex) /以字母

20、、下划线开头char str256;int strLen = 0;是字母、下划线while(isalpha(chchIndex) | chchIndex = '_' ) /strstrLen + = chchIndex;chIndex +;不是第一位,可以为数字while(isdigit(chchIndex)/strstrLen + = chchIndex; chIndex +;strstrLen = 0; / 字符串结束符if(strlen(str) > 20) /标识符超过规定长度,报错处理error(str,nLine,1);else int i;for(i = 0

21、;i < MaxKeyWord; i+) /与关键字匹配if(strcmp(str, KeyWordi) = 0) /是关键字,写入table 表中strcpy(tableTableNum.symbol,str);tableTableNum.type = 1; / 关键字tableTableNum.line = nLine;tableTableNum.Index = i;TableNum +;break;if(i >= MaxKeyWord) / 不是关键字tableTableNum.Index = WordNum;strcpy(WordWordNum+,str);tableTab

22、leNum.type = 2; / 变量标识符strcpy(tableTableNum.symbol,str);tableTableNum.line = nLine;TableNum +;常数 */*遇到数字数字和小数点/else if(isdigit(chchIndex)&&chchIndex!='0') /遇到数字else if(isdigit(chchIndex) /int flag = 0;char str256;int strLen = 0;while(isdigit(chchIndex) | chchIndex = '.') / 表记

23、小数点的个数,0 时为整数,1if(chchIndex = '.') /flag时为小数,2 时出错flag +;strstrLen + = chchIndex;chIndex +;strstrLen = 0;if(strlen(str) > 20) /error(str,nLine,3);if(flag = 0)tableTableNum.type = 3; /常量标识符超过规定长度20,报错处理整数if(flag = 1) tableTableNum.type = 4; /小数if(flag > 1)error(str,nLine,2);tableTableNu

24、m.Index = DigNum;strcpy(DigitDigNum +,str);strcpy(tableTableNum.symbol,str);tableTableNum.line = nLine;TableNum +;/*运算符 */elseint errorFlag; / 用来区分是不是无法识别的标识符,0 为运算符,1 为界符char str3;str0 = chchIndex;str1 = chchIndex + 1;str3 = 0;for(int i = 0;i < MaxOptBNum;i+)/MaxOptBNum) if(strcmp(str,OptBi) = 0

25、)errorFlag = 0;tableTableNum.type = 6;strcpy(tableTableNum.symbol,str);tableTableNum.line = nLine;tableTableNum.Index = i;TableNum +;chIndex = chIndex + 2;break;if(i >= MaxOptBNum)for( int k = 0;k < MaxOptANum; k+) if(OptAk = chchIndex) errorFlag = 0;tableTableNum.type = 5;tableTableNum.symbol

26、0 = chchIndex;tableTableNum.symbol1 = 0;tableTableNum.line = nLine;tableTableNum.Index = k;TableNum +;chIndex +;break;/*界符 */for(int j = 0;j < MaxEndNum;j +) if(Endj =chchIndex) errorFlag = 1;tableTableNum.line = nLine;tableTableNum.symbol0 = chchIndex;tableTableNum.symbol1 = 0;tableTableNum.Inde

27、x = j;tableTableNum.type = 7;TableNum +;chIndex +;/*算符、界符其他无法识别字符*/if(errorFlag != 0 && errorFlag != 1) /开头的不是字母、数字、运char str256;int strLen = -1;strstrLen + = chchIndex;chIndex +;while(*ch != ' ' | *ch != 9 | chchIndex != 10)/ strstrLen + = chchIndex;chIndex +;strstrLen = 0;tableTabl

28、eNum.type = 8;strcpy(tableTableNum.symbol,str);tableTableNum.line = nLine;tableTableNum.Index = -2;TableNum +;void Trans(double x,int p) /int i=0;/while(i<p)if(x=0)/break;/elseint k=int(x*16); /x=x*16-int(k); /if(k<=9)cout<<k;elsecout<<char(k+55);i+;把十进制小数转为16 进制控制保留的有效位数如果小数部分是0则退

29、出循环取整数部分得到小数部分;int main()ifstream in;ofstream out,outVar,outCon;char in_file_name26,out_file_name26; /读入文件和写入文件的名称char chMax; / 存放输入代码的缓冲区int nLine = 1;/ 初始化行数Table *table = new TableMax;int choice;cout << " 请输入读入方式:1 :从文件中读,2:从键盘读(输入结束标志位#) : n"cin >> choice;switch(choice)int

30、i;/*从文件读取*/case 1:cout<<"Enter the input file name:n"cin>>in_file_name;in.open(in_file_name);if(in.fail() / 打开 display 表读文件失败 cout<<"Inputput file opening failed.n"exit(1);cout<<"Enter the output file name:n"cin>>out_file_name;out.open(out_

31、file_name);outVar.open(" 变量表.txt");outCon.open(" 常量表.txt");if(out.fail() / 打开 display 表写文件失败cout<<"Output file opening failed.n"exit(1);if(outVar.fail() /打开变量表写文件失败cout<<"VarOutput file opening failed.n" exit(1);if(outCon.fail() /打开常量表写文件失败cout<

32、<"ConstOutput file opening failed.n" exit(1);in.getline(ch,Max,'#');Scanner(ch, strlen(ch),table,nLine); /调用扫描函数if(errorFlag = 1) / 出错处理return 0;/*out <<"类型"<<"把结果打印到各个表中 */ "<<"下标"<<endl;for( i = 0; i < TableNum;i +)/打印 d

33、isplayout<< "(0x" <<hex << tablei.type<< ","<<"0xtablei.Index<< ")" <<endl; /在文件 testout.txt 中输出<< hex <<outCon << " 下标" << "" << " 常量值"<< endl;for(i = 0;i &

34、lt; TableNum;i+) /打印常量表(if(tablei.type = 3)(long num1;num1 = atoi(tablei.symbol);outCon<< "(0x" <<hex << tablei.Index << ", num1 << ")" <<endl;)if(tablei.type = 4)(double num2;num2 = atof(tablei.symbol);outCon<< "(0x" <&

35、lt;hex << tablei.Index << ",<< "0x" << hex <<<< "0x" << hex <<num2<< ")" <<endl;)outVar <<" 类型"<<""<< "变量名称"<<endl;for( i = 0; i < WordNum;i +)/打印变量

36、表outVar<< "(0x" <<hex << i<< "" << Wordi << ")" <<endl; / 在文件testout.txt 中输出in.close();/ 关闭文件 out.close(); outVar.close(); outCon.close(); break;/*从键盘输入 */case 2:cin.getline(ch,Max,'#');Scanner(ch, strlen(ch),table,nLine

37、); /调用扫描函数if(errorFlag = 1) return 0;cout << "nDisplay 表:n"cout <<"类型"<<""<<"下标"<<endl; /dosfor( i = 0; i < TableNum;i +)cout<< "(0x" <<hex << tablei.type<< " , tablei.Index<< ")" <<endl;界面下<<&quo

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论