合肥工业大学 编译原理实验报告.docx
- 文档编号:23333808
- 上传时间:2023-05-16
- 格式:DOCX
- 页数:63
- 大小:146.04KB
合肥工业大学 编译原理实验报告.docx
《合肥工业大学 编译原理实验报告.docx》由会员分享,可在线阅读,更多相关《合肥工业大学 编译原理实验报告.docx(63页珍藏版)》请在冰豆网上搜索。
合肥工业大学编译原理实验报告
合肥工业大学编译原理实验报告
合肥工业大学计算机与信息学院
编译原理实验报告
专业:
学号:
姓名:
指导老师:
完成时间:
实验一词法分析设计
一、实验目的
通过本实验的编程实践,使学生了解词法分析的任务,掌握词法分析程序设计的原理和构造方法,使学生对编译的基本概念、原理和方法有完整和清楚的理解,并且能够正确和熟练地运用。
二、实验环境
Windows8.1、VisualStudio2013、C++
三、实验原理
(1)实验数据结构说明
stringstr[40]存储string
intstrcount存储string的数目
stringname存储type名
Table()构造函数
~Table()析构函数
Table
voidsetname(stringstrTemp)设置name值
stringgetname()获取name值
voidupdate(stringstrTemp)添加strTemp的值
voidinit(stringfilename)初始化table
intsearch(stringstrTemp)在table中查询strTemp
stringvalue存储分析单词的值
inttypeType的编号
intpointer单词的位置
OutToken
stringtyname存储在表中位置
intline分析单词的行的值
introw分析单词的列的值
OutToken(stringval,intt,intp,stringtn,int有参数构造函数l,intr)
~OutToken()析构函数friendostream&operator<<(ostream&output,重载<<函数OutToken&ot)
TableKeywordType1:
C++关键字TableSeperatorType2:
分界符TablesumoperatorType3:
算术运算符TablereloperatorType4:
关系运算符TableconstantType5:
常数TableidentifierType6:
标识符OutTokenouttoken二元式TokenAnalyzer
TokenAnalyzer()构造函数~TokenAnalyzer()析构函数voidinittable()初始化表voiddisplay()输出所有单词二元式voidstrsearch(stringstrin,intline,introw)分析strinvoidreadcode()读取源代码
(2)实验算法描述
1)词法分析设计流程图
2)词法分析程序框图
3)统计字符位置程序框图
四、实验内容
使用C++语言实现对C++语言字集的源程序进行词法分析。
通过输入源程序从左到右对字符串进行扫描和分解,依次输出各个单词的内部编码及单词符号自身值;若遇到错误则显示ERROR,然后跳过错误部分继续显示;同时进行标识符登记符号表的管理。
词法分析设计主要工作:
(1)从源程序中读取字符
(2)统计行数和列数用于错误单词的定位
(3)删除空格类字符,包括回车、制表符空格
(4)按拼写单词,并用(内码,属性)二元式来表示,(属性值—Token的
机内表示)
(5)如果发现错误则报告出错
(6)根据需要是否填写标识符供以后各阶段使用
单词的基本分类:
(1)关键字:
由各程序语言具有的固定意义的标识符(保留字例)
(2)标识符:
用以表示各种名字的变量名、数组名、函数名
(3)常数:
任何数值常数
(4)运算符:
+、-、*、/
(5)关系运算符:
<、<=、=、>、>=、<>、|
(6)分界符:
;、,、(、)、[、]、{、}
五、实验要求
1、编程时注意编程风格:
空行的使用、注释的使用、缩进的使用等2、标识符填写的符号表需提供给编译程序的以后各阶段使用3、根据测试数据进行测试。
测试实例分为三部分:
(1)各种合法输入
(2)各种组合输入
(3)有记号组成的句子
4、词法分析程序设计要求输出形式
单词二元序列类型位置(行,列)
for(1,for)关键字(1,1)
六、实验结果
(1)分析代码
(2)分析结果
七、实验总结
通过此次实验的编程实践加强了自己对词法分析的任务的理解,在一定
程度上初步掌握了词法分析程序设计的原理和构造,并且在对编译的基本概
念、原理和概念方法有更清楚的认识。
在实验过程中自己对词法分析程序中
的算法理解出现了一定的偏差,认为其中的标识符是程序执行之前必须都由
自己手动构造,导致自己在程序的验收阶段出现了问题。
事实上,在词法分
析程序中,若识别的字符串是首字符字母,则在关键字表中查询是否存在,
如果不存在则将新造入标识符表中。
对于在源代码中注释问题,由于本程序
是以行为单位从TXT文件中读取代码,当自己将注释的判断程序放置扫描每
一行的动作前,导致了添加在有效合法语句后的注释语句全部被分析为
Error,所以之后将判断注释的语句放置在以一个单位取字符串之前,当某
一行的字符串中含有//或/*时,则将其后的字符串全部忽略,即跳出本行的
后续的分析步骤,重新执行下一行的代码读取和分析操作。
八、实验代码
#include
#include
#include
#include
usingnamespacestd;
classTable
{
private:
stringstr[40];
intstrcount;
stringname;
public:
Table();
~Table();
voidsetname(stringstrTemp);
stringgetname();
voidupdate(stringstrTemp);
voidinit(stringfilename);
intsearch(stringstrTemp);};
Table:
:
Table()
{
for(inti=0;i<40;i++)
str[i]="";
strcount=0;
name="";
}
Table:
:
~Table()
{
}
voidTable:
:
setname(stringstrTemp){
name=strTemp;
}
stringTable:
:
getname()
{
returnname;
}
voidTable:
:
update(stringstrTemp){
str[++strcount]=strTemp;}
voidTable:
:
init(stringfilename){
stringstrin;
ifstreaminfiles(filename);
if(!
infiles)
cout<<"打开"< while(getline(infiles,strin)) update(strin); infiles.close(); } intTable: : search(stringstrTemp){ for(inti=1;i<=strcount;i++) { if(str[i]==strTemp) returni; } return0; } classOutToken { private: stringvalue; inttype; intpointer; stringtyname; intline; introw; public: OutToken(stringval="",intt=0,intp=0,stringtn="",intl=0,intr=0); ~OutToken(); friendostream&operator<<(ostream&output,OutToken&ot); }; OutToken: : OutToken(stringval,intt,intp,stringtn,intl,intr) { value=val; type=t; pointer=p; tyname=tn; line=l; row=r; } OutToken: : ~OutToken(){ } ostream&operator<<(ostream&output,OutToken&ot){ if(ot.type! =0) output< : left)< <<"("< (2)< (2)<<","< (2)< <<")" < <<"("< else output< : left)< < < <<"("< returnoutput; } classTokenAnalyzer { private: Tablekeyword; Tableseperator; Tablesumoperator; Tablereloperator; Tableconstant; Tableidentifer; OutTokenouttoken[100]; intoutcount; public: TokenAnalyzer(); ~TokenAnalyzer(); voidinittable(); voiddisplay(); voidstrsearch(stringstrin,intline,introw); voidreadcode(); }; TokenAnalyzer: : TokenAnalyzer(){ keyword.setname("关键字"); seperator.setname("分界符"); sumoperator.setname("运算符"); reloperator.setname("关系运算符"); constant.setname("常数"); identifer.setname("标识符"); outcount=0; } TokenAnalyzer: : ~TokenAnalyzer(){ } voidTokenAnalyzer: : inittable(){ seperator.init("seperator.txt"); reloperator.init("reloperator.txt"); sumoperator.init("sumoperator.txt"); constant.init("constant.txt"); keyword.init("keyword.txt"); } voidTokenAnalyzer: : display() { for(inti=1;i<=outcount;i++) cout< } voidTokenAnalyzer: : strsearch(stringstrin,intline,introw){ if((strin[0]>='a'&&strin[0]<='z')||(strin[0]>='a'&&strin[0]<='z')) { if(keyword.search(strin)) outtoken[++outcount]=OutToken(strin,1,keyword.search(strin), keyword.getname(),line,row); else { if(identifer.search(strin)) outtoken[++outcount]=OutToken(strin,6,identifer.search(strin), identifer.getname(),line,row); else { identifer.update(strin); outtoken[++outcount]=OutToken(strin,6,identifer.search(strin), identifer.getname(),line,row); } } } else { if(strin[0]>='0'&&strin[0]<='9') { if(constant.search(strin)) outtoken[++outcount]=OutToken(strin,5,constant.search(strin), constant.getname(),line,row); else { constant.update(strin); outtoken[++outcount]=OutToken(strin,5,constant.search(strin), constant.getname(),line,row); } } else { if(seperator.search(strin)) outtoken[++outcount]=OutToken(strin,2,seperator.search(strin), seperator.getname(),line,row); else { if(reloperator.search(strin)) outtoken[++outcount]=OutToken(strin,4,reloperator.search(strin), reloperator.getname(),line,row); else { if(sumoperator.search(strin)) outtoken[++outcount]=OutToken(strin,4, sumoperator.search(strin),sumoperator.getname(),line,row); else outtoken[++outcount]=OutToken(strin,0,0,"ERROR",line,row); } } } } } voidTokenAnalyzer: : readcode() { ifstreaminfile("code.txt"); if(! infile) cout<<"打开失败~"< stringstrin; intline; introw; line=0; while(getline(infile,strin)) { line++; row=0; if(strin! ="") { stringstrtemp=""; while(strin[0]==''&&strin.length()>1) strin=strin.substr(1,strin.length()); if(strin[0]=='/'&&strin[1]=='/') continue; if(strin=="") strin=""; while(strin! =""&&strin! =strtemp) { row++; if(strin.find("")) strtemp=strin.substr(0,strin.find("")); else strtemp=strin; if(strin[0]=='/'&&strin[1]=='/') continue; strsearch(strtemp,line,row); if(strin.find("")) strin=strin.substr(strin.find("")+1,strin.length()); while(strin[0]==''&&strin.length()>1) strin=strin.substr(1,strin.length()); if(strin=="") strin=""; } } } infile.close(); } voidmain(void) { TokenAnalyzerT; T.inittable(); T.readcode(); T.display();} 实验二LL (1)分析文法一、实验目的 通过完成预测分析法的语法分析程序,了解预测分析法和递归子程序法的区别和联系。 使学生了解语法分析的功能,掌握语法分析程序设计的原理和构造方法,训练学生掌握开发应用程序的基本方法。 有利于提高学生的专业素质,为培养适应社会多方面需要的能力。 二、实验环境 Windows8.1、VisualStudio2013、C++ 三、实验原理 (1)实验数据结构说明 存储栈符号charcharstack[30] 存储的符号个数intcount Stack()构造函数 ~Stack()析构函数Stack voidpush(charch)将ch压栈 voidpop()栈顶出栈 chargettop()将栈顶元素弹栈返回 voiddisplay()打印栈内容 charTerminalSymbol[20]终结符 charNonTerminalSymbol[20]非终结符 charlinechar[20]M表行表头 charrowchar[20]M表列表头 LLAnalyzerintM[20][20]状态表 stringGrammar[20]文法 stringFirstset[20]First集 stringFollowset[20]Follow集 stackchars符号栈 LLAnalyzer()构造函数~LLAnalyzer()析构函数voidinit()初始化 voidinitM()初始化M表intsearch(chararray[],charch)查询ch返回位置voidreadfile()读取文法存入Grammar中stringgetfirst(charch)生成字符ch的First集stringgetfirststr(stringstr)生成字符串strFirst集voidsetfirstset()所有文法生成First集stringgetfollow(charch)生成字符ch的First集stringlinkstring(stringstr,stringstrt)两字符串不同的符连接stringchartostring(charch)字符转换成字符串返回voidsetfollow()生成所有文法Follow集voidsetM()生成M表intsearchstr(stringarray[],stringstrt)查询字strt返回位置boolLanalyzer(stringstrin)文法分析voidpushstring(intstrno)产生式逆序压栈 (2)实验算法思想描述 1)LL (1)文法程序框图 四、实验内容 (1)根据某一文法编制调试LL (1)分析程序,以便对任何输入的符号串进行分析 (2)构造预测分析表,并利用分析表和一个栈来实现对上述程序设计语言的分析程序 (3)分析法的功能是利用LL (1)控制程序根据显示栈顶内容、向前看符号以及LL (1)分析表,对输入符号串自上而下的分析过程 五、实验要求 1、编程时注意风格: 空行的使用释缩进等。 2、如果遇到错误的表达式,应输出提示信息。 3、对下列文法,用LL (1)分析法对任意输入的符号串进行分析 (1)E->TG (2)G->+TG|—TG (3)G->ε (4)T->FS (5)S->*FS|/FS (6)S->ε (7)F->(E) (8)F->i 输出格式 步骤分析栈剩余输入串所用产生式动作 0#Ei+i*i#初始化 六、实验结果 (1)构建First和Follow集 (2)构建状态转移表M (3)LL (1)分析测试实例 1)正确实例 2)错误实例 七、实验总结 通过完成预测LL (1)分析法的语法分析程序,自己了解了预测分析法 和递归子程序法的区别和联系。 使自己了解了语法分析的功能,掌握语法分 析程序设计的原理和构造方法,并且使自己对基本的程序应用的开发具有更 进一步的理解。 但是在此次编程实验中,由于自己对First集的构建算法理 解上出现了一定的失误,导致前期的实验中总是达不到自己预测的输出,后 通过断点调试一步一步找出了程序中的错误。 八、实验代码 #include #include #include #include usingnamespacestd; classstack { private: charcharstack[30]; intcount; public: stack(); ~stack(); voidpush(charch); voi
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 合肥工业大学 编译原理实验报告 合肥 工业大学 编译 原理 实验 报告
![提示](https://static.bdocx.com/images/bang_tan.gif)