《编译原理》词法分析实验报告模板课程上机.docx
- 文档编号:4415440
- 上传时间:2022-12-01
- 格式:DOCX
- 页数:15
- 大小:57.25KB
《编译原理》词法分析实验报告模板课程上机.docx
《《编译原理》词法分析实验报告模板课程上机.docx》由会员分享,可在线阅读,更多相关《《编译原理》词法分析实验报告模板课程上机.docx(15页珍藏版)》请在冰豆网上搜索。
《编译原理》词法分析实验报告模板课程上机
实验报告
课程名称编译原理
实验项目设计与实现一个词法编译器
实验仪器PC机一台
北京信息科技大学
信息管理学院
(课程上机)实验报告
实验名称
设计与实现一个词法编译器
实验地点
3-603
实验时间
2011.11.23
1.实验目的:
结合讲授内容,设计与实现一个简单词法编译器,通过本实验加深对词法分析程序的功能及实现方法的理解。
2.实验内容:
设计与实现一个简单词法编译器。
具体内容是产生一个二元式文本文件,扩展名为txt,可将Pascal程序(测试程序)分解成为一个一个的单词及类别。
3.实验要求:
(1)掌握和实现词法分析器的功能:
输入源程序,输出单词符号(二元式表示)。
二元式
(单词流)
源程序
(字符流)
词法分析器
输入输出
(2)单词符号的分类:
关键字:
是由程序语言定义的具有固定意义的标识符。
标识符:
用来表示各种名字,如变量等。
常数:
常数的类型有整型,实型等。
运算符:
算术运算符,关系运算符,逻辑运算符。
界限符:
逗号,分号等。
(3)实验步骤:
1、确定词法分析器的接口关系;
2、设计算法参考教材图2.5。
4.实验准备:
1:
pc机一台;
2:
VC++编译器
5.实验过程:
1,分析问题
输入源程序,输出单词符号(二元式表示)。
二元式
(单词流)
源程序
(字符流)
词法分析器
输入输出
2,算法步骤:
:
将文件中每行读入的字符串存入数组buffer[100],不跳过空格;
:
利用构造函数传递数组,和每行的长度length;
:
调用成员函数scan,i=0,while(i : if(isletter(),接收完成后比较是否为关键字,不是则将其存入标示符id[50][10]中; : elseif(isdigit()),接收完成后存入cst[50][10]中; : elseif为界符,比较符,运算符,输出对应的二元编码; : 接受完毕,输出id[50][10]--标示符,cst[50][10]--常数,列表; 3: 程序代码 #include #include #include intm=0; intn=0; intx[50],y[50];//存放对应常数表和字母表每列的长度。 char*reservechar[]={"PROGRAM","CONST","VAR","INTEGER","LONG","PROCEDURE", "IF","THEN","WHILE","DO","READ","WRITE","BEGIN","END","ODD"};//指针数组地址每次加1读取下一个字符串 //关键字表 charid[50][10];//符号表 charcst[50][10];//常数表 classScanner { private: inti,j;//指针 intlength; charch,buffer[100],strtoken[20]; public: Scanner(charstr[],intn);//构造函数 intisdigit();//判断是否整数 intisletter();//首字母的判断 intreserve();//对stroken进行关键字表的查找,返回其编码值 intinsertid();//将stroken中的标识符插入符号表,返回在符号表中的位置 intinsertconst();//将stroken中的常数插入常数表,返回在常数表中的位置 voidgetchar();//将下一输入字符读到ch中,指针后移一字符位置 voidgetbc();//保证ch是一个非空白字符 voidconcat();//将ch连接到字符串stroken的末尾 voidretract();//置ch为空白字符,指针前移一字符位置 voidscan(); }; Scanner: : Scanner(charstr[],intn)//构造函数 { strcpy(buffer,str); length=n; i=j=0; } intScanner: : isdigit()//判断是否整数 { if(ch>='0'&&ch<='9') return1; else return0; } intScanner: : isletter()//首字母的判断 { if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')) return1; else return0; } voidScanner: : getchar()//将下一输入字符读到ch中,指针后移一字符位置 { ch=buffer[i]; i++; } voidScanner: : getbc()//保证ch是一个非空白字符 { while(ch=='') getchar(); } voidScanner: : concat()//将ch连接到字符串stroken的末尾 { strtoken[j]=ch; j++; } voidScanner: : retract()//置ch为空白字符,指针前移一字符位置 { i--; } intScanner: : reserve()//对stroken进行关键字表的查找,返回其编码值 { inti,flag=0; for(i=0;i<15;i++) { if((strncmp(reservechar[i],strupr(strtoken),j)==0)&&(j! =1))//比较出错第一个interger和i无法区分 { flag=1; break; } } if(flag==1)returni+1; elsereturn0; } intScanner: : insertid()//将stroken中的标识符插入符号表,返回在符号表中的位置 { for(inta=0;a id[m][a]=strtoken[a]; x[m]=j; m++; returnm; } intScanner: : insertconst()//将stroken中的常数插入常数表,返回在常数表中的位置 { for(inti=0;i cst[n][i]=strtoken[i]; y[n]=j; n++; returnn; } voidScanner: : scan() { while(i { j=0;//自动清0,让strtoken重置 intcode,value; getchar();//{ch=buffer[i];i++;} getbc();//{while(ch=='')getchar();} if(isletter())//如果打头的是字母 { while(isletter()||isdigit()) { concat();//将ch连接到字符串stroken的末尾 getchar(); } retract();//{i--;} code=reserve();//检测是否是关键字 if(code==0)//如果扫描到的是标识符 { value=insertid(); cout<<"<字母位置,"< } elsecout<<"<"< } elseif(isdigit())//如果打头的是数字 { while(isdigit()) { concat(); getchar(); } retract(); value=insertconst(); cout<<"<数字位置,"< } elseif(ch=='+') cout<<"<16__+,*>"<<'\n'; elseif(ch=='-') cout<<"<17__-,*>"<<'\n'; elseif(ch=='*') cout<<"<18--*,*>"<<'\n'; elseif(ch=='/') cout<<"<19--/,*>"<<'\n'; elseif(ch=='=') cout<<"<20--=,*>"<<'\n'; elseif(ch=='<') { getchar(); if(ch=='>') cout<<"(21--<>,*)"<<'\n'; elseif(ch=='=') cout<<"(23--<=,*)"<<'\n'; else { retract(); cout<<"(22--<,*)"<<'\n'; } } elseif(ch=='>') { getchar(); if(ch=='=') cout<<"(25-->=,*)"<<'\n'; else { retract(); cout<<"(24-->,*)"<<'\n'; } } elseif(ch=='.') cout<<"<26--.,*>"<<'\n'; elseif(ch==',') cout<<"<27--,,*>"<<'\n'; elseif(ch==';') cout<<"<28--;,*>"<<'\n'; elseif(ch==': ') { getchar(); if(ch=='=') cout<<"<30--: =,*>"<<'\n'; else { retract(); cout<<"<29--: *>"<<'\n'; } } elseif(ch=='(') cout<<"<31--(,*>"<<'\n'; elseif(ch==')') cout<<"<32--),*>"<<'\n'; elsecout<<"出错"<<'\n'; } } voidmain(void) { fstreamfile; file.open("D: \\pl.txt",ios: : in||ios: : nocreate);//以只读方式打开 file.unsetf(ios: : skipws);//不跳过文本中的空格 charbuffer[100];//缓冲区定义 cout<<"扫描结果如下所示"<<'\n'; while(file.getline(buffer,100))//while每次接收一行字符。 { ScannerSS(buffer,strlen(buffer)); SS.scan(); } cout<<"标识符表如下: \n"<<"编号\t"<<"值\n"; for(inti=0;i { cout< for(intj=0;j cout< cout<<'\n'; } cout<<"常数表如下: \n"<<"编号\t"<<"值\n"; for(i=0;i { cout< for(intj=0;j cout< cout<<'\n'; } } 4: D: \\pl.txt文件内容 varn,i,j,num,s: integer; a: array[0..maxint]ofinteger; begin readln(n); fori: =1tondo read(a[i]); s: =0; fori: =1tondo begain end. writeln(s); End. 5: 程序运行结果 6: 校验试验结果正确。 6.实验总结: 词法分析程序的设计思路比较清晰,但是对于其中实现的细节还不是很熟练,比如C++文件的读取操作,string函数的使用,二维数组的使用,以及函数调用过程中变量值的改变等等。 经过自己精心修改,终于初步完成了词法的分析程序,其中可能还存在不足,希望自己能够逐渐掌握程序设计的脉路。 说明: 1.实验名称、实验目的、实验内容、实验要求由教师确定,实验前由教师事先填好,然后作为实验报告模版供学生使用; 2.实验准备由学生在实验或上机之前填写,教师应该在实验前检查; 3.实验过程由学生记录实验的过程,包括操作过程、遇到哪些问题以及如何解决等; 4.实验总结由学生在实验后填写,总结本次实验的收获、未解决的问题以及体会和建议等; 5.源程序、代码、具体语句等,若表格空间不足时可作为附录另外附页。"<<'\n';//如果扫描到的是关键字
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译原理 编译 原理 词法 分析 实验 报告 模板 课程 上机