《合肥工业大学编译原理实验报告(代码版).docx》由会员分享,可在线阅读,更多相关《合肥工业大学编译原理实验报告(代码版).docx(73页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、合肥工业大学编译原理实验报告(代码版) 计算机与信息学院 编译原理 试验报告 专业班级 信息平安 13-1 班 学生姓名及学号 马骏 2022211869课 程 教 学 班 号任课教师李宏芒 实 验 指 导 教 师李宏芒实 验 地 点试验楼机房2022 2022 学年第 二 学期验 试验 1词法分析设计 一、试验目的 通过本试验的编程实践,使学生了解词法分析的任务,驾驭词法分析程序设 计的原理和构造方法,使学生对编译的基本概念、原理和方法有完整的和清晰的 理解,并能正确地、娴熟地运用 二、 试验要求 1、编程时留意编程风格:空行的运用、注释的运用、缩进的运用等。2、将标识符填写的相应符号表须供
2、应给编译程序的以后各阶段运用。3、依据测试数据进行测试。测试实例应包括以下三个部分: 全部合法的输入。 各种组合的非法输入。 由记号组成的句子。4、词法分析程序设计要求输出形式:例:输入 VC+语言的实例程序:If i=0 then n+;a= 3b %);输出形式为:单词 二元序列类型位置(行,列) (单词种别,单词属性)for(1,for ) 关键字(1,1)i( 6,i )标识符 (1,2)= ( 4,= )关系运算符(1,3) 120 ( 5,0 ) 常数(1,4)then( 1,then) 关键字(1,5)n (6,n ) 标识符(1,6)+Error Error (1,7); (
3、2, ; ) 分界符 (1,8)a (6,a )标识符(2,1)= (4,<= ) 关系运算符 (2,2)3bError Error (2,4)%Error Error (2,4)) ( 2, ) )分界符(2,5); ( 2, ; )分界符 (2,6)三、试验内容 用 VC+/VB/JAVA 语言实现对 C 语言子集的源程序进行词法分析。通过输 入源程序从左到右对字符串进行扫描和分解,依次输出各个单词的内部编码及单 词符号自身值;若遇到错误则显示Error,然后跳过错误部分接着显示 ;同时 进行标识符登记符号表的管理。 以下是实现词法分析设计的主要工作:(1)从源程序文件中读入字符。(
4、2)统计行数和列数用于错误单词的定位。(3)删除空格类字符,包括回车、制表符空格。(4)按拼法单词,并用(内码,属性)二元式表示。(属性值——token 的机内 表示)(5)假如发觉错误则报告出错 7(6)依据须要是否填写标识符表供以后各阶段运用。四、试验步骤 1、依据流程图编写出各个模块的源程序代码上机调试。2、 编制好源程序后,设计若干用例对系统进行全面的上机测试,并通过所设计 的词法分析程序;直至能够得到完全满足的结果。3、书写试验报告 ;试验报告正文的内容:功能描述:该程序具有什么功能?程序结构描述:函数调用格式、参数含义、返回值描述、函数功能;函数 之间的调用
5、关系图。具体的算法描述(程序总体执行流程图)。给出软件的测试方法和测试结果。试验总结 (设计的特点、不足、收获与体会)。五、试验截图先创建 salaryfile.txt 文件 输入 If i=0 then n+;a<= 3b %); 六、 核心代码#include<iostream> #include<string> #include<fstream> #include <sstream>using namespace std;const char* salaryfile="salaryfile.txt" const i
6、nt max=40; string idmax="do","end","for","if","printf","scanf","then","while"/ 关键字表 string smax=",","","(",")","","","+","-","*",&
7、quot;/","<","<=","=",">",">=","<>"/ 分界符表 算数运算符表关系运算符表 string kmax;/ 标识符 string cimax;/ 常数 int fjfpoint=5;/ 分界符表尾 int mathpoint=9;/ 算数运算符表尾 int cipointer=0;/ 常数表尾 int idpointer=0;/ 关键字表尾 int kpointer=0;/ 标识符表尾 int fjf;
8、/0 不是分界符 1 是int rowy=1;/ 识别输入行位置 int rowx=1;/ 识别输入列位置int outkey=0;/ 打印限制 0 为数字后有字母 其他可以 void searcht(int i,string m)/ 依据已识别的首字母识别字符串 / cout<<"enter searcht!"<<endl;int x;if(i=0)/ 首字符是字母识别关键字 /cout<<a word!"<<endl; for(x=0;x<max;x+) if(idx=m) cout<<&quo
9、t;(1,"<<idx<<")"<<字 关 键 字 ("<<rowy<<","<<rowx<<")"<<endl; break; if(x=max)/ 不是关键字再识别标识符 for(x=0;x<max;x+) if(kx=m) cout<<"(6,"<<m<<") "<<符 标 识 符 ("<<rowy&
10、lt;<","<<rowx<<")"<<endl; break; if(x=max)/ 标识符表没有时插入标识符 cout<<"(6,"<<m<<") "<<符 标 识 符 ("<<rowy<<","<<rowx<<")"<<endl; kkpointer=m; kpointer+; if(i=1)/ 识别常数/ co
11、ut<<"a number!"<<endl; for(x=0;x<max;x+) if(cix=m) cout<<"(5,"<<x<<")"<<endl; break; if(x=max) cout<<"(5,"<<m<<") 常数 ("<<rowy<<","<<rowx<<")"<<
12、endl;cicipointer=m;cipointer+; if(i=2)/ 识别 分界符 算数运算符关系运算符/ cout<<"a signal!"<<endl; for(x=0;x<max;x+) if(sx=m) break; / x-;if(x<6) fjf=1; if(x>5&&x<10) if(outkey=1) cout<<"(3,"<<sx<<") 符 算 数 运 算 符 ("<<rowy<<&
13、quot;,"<<rowx<<")"<<endl;outkey=0;fjf=0; if(x>9&&x<max-1) if(outkey=1)cout<<"(4,"<<sx<<") 符 关 系 运 算 符 ("<<rowy<<","<<rowx<<")"<<endl;outkey=0;fjf=0; if(x=max) if(out
14、key=1)cout<<"Error Error ("<<rowy<<","<<rowx<<")"<<endl;outkey=0;fjf=0; ; void wordlook(char t,string sn)/ 识别首字符,分类识别字符串 if(t>=48&&t<=57) searcht(1,sn);elseif(t>64&&t<91)|(t>96&&t<123) searcht
15、(0,sn); else searcht(2,sn); void split(string s)/ 分割字符串 / cout<<s<<endl;string nowmax;string sn;int nowpointer=0; int i=0;int x;int sign=2;/ 非法数字标记int diannumber=0;/ 数中点的个数 for(x=0;x<s.length();x+) if(sx>64&&sx<91)|(sx>96&&sx<123)|(sx>=48&&sx<
16、=57)|(x>0&&sx=46&&sign=1)/ 推断数字后跟字母还是字母后有数字 if(i=0)if(sx>=48&&sx<=57) sign=1; else sign=2;else if(sign=1) if(sx>=48&&sx<=57|sx=46) if(sx=46) if(diannumber=0) diannumber+;else sign=0; else sign=0; i+;if(x=(s.length()-1)sn=s.substr(x-i+1,i); if(i>0)/co
17、ut<<sn<<i="<<i<<endl; cout<<sn<<" if(sign=0)/ 数字后有字母的状况 cout<<" ErrorError("<<rowy<<","<<rowx<<")"<<endl;else / 字母开头的字符串 /cout<<" true"<<endl;wordlook(sn0,sn); rowx+;
18、 else if(x>0&&(sx-1>64&&sx-1<91)|(sx-1>96&&sx-1<123)|(sx-1>=48&&sx-1<=57)/ 遇到分界符运算符 假如前面是数字或字母 sn=s.substr(x-i,i); if(i>0) /cout<<sn<<i="<<i<<endl;cout<<sn<<"if(sign=0)cout<<Error Error ("
19、;<<rowy<<","<<rowx<<")"<<endl;else / cout<<" true"<<endl; wordlook(sn0,sn);rowx+; i=0; string ll=s.substr(x,1);/ 推断是运算符还是分界符wordlook(sx,ll);if(fjf=0)/ 是运算符 i+; if(sx+1>64&&sx+1<91)|(sx+1>96&&sx+1<123)
20、|(sx+1>=48&&sx+1<=57)/ 假如后面是数字或字母 sn=s.substr(x-i+1,i);/ cout<<sn<<运算符 i="<<i<<endl;cout<<sn<<"outkey=1;wordlook(sn0,sn);rowx+; i=0; if(fjf=1) if(sx-1>64&&sx-1<91)|(sx-1>96&&sx-1<123)|(sx-1>=48&&sx-1&l
21、t;=57)/ 假如前面是数字或字母else if(i>0)sn=s.substr(x-i,i);/ cout<<sn<<运算符 i="<<i<<endl;cout<<sn<<"outkey=1;wordlook(sn0,sn);rowx+; i=0;cout<<sx<<(2,"<<sx<<") 符 分 界 符 ("<<rowy<<","<<rowx<<
22、")"<<endl;rowx+;/*if(ll="") rowy+;rowx=1;*/ ; int main() int x;string instring;/ 读入一行string sn; /* getline(cin,sn);/ string 带空格输入cout<<sn<<endl;char t=sn0;if(t>=48&&t<=57) searcht(1,sn);else if(t>64&&t<91)|(t>96&&t<123)
23、searcht(0,sn); else searcht(2,sn); */ ifstream inputfile;/in file streaminputfile.open(salaryfile); / inputfile>>noskipws;if(!inputfile) cout<<"no file"<<endl; string pp;while(!inputfile.eof() getline(inputfile,pp); istringstream istr(pp); string ppword; while(istr>>
24、;ppword)/ 根据空格分割字符串 split(ppword); /* int begin = 0;/ 去掉字符串的全部空格 begin = pp.find(",begin);/ 查找空格在 str 中第一次出现的位置 while(begin != -1)/ 表示字符串中存在空格pp.replace(begin, 1, "");/ 用空串替换str 中从begin 起先的1 个字符begin = pp.find(",begin);/ 查找空格在替换后的str 中第一次出现的位置 */ / cout<<"good"<
25、;<pp<<endl; / rowx+; rowy+;/ 换行 rowx=1;return 0; 七、试验总结通过本次试验使我不仅对词法分析器有了更深的了解,而且提高了编程实力,希望在以后的学习中可以解决词法分析更多的问题。验 试验 2LL(1) 分析法一、 试验目的 通过完成预料分析法的语法分析程序,了解预料分析法和递归子程序法的区 别和联系。使学生了解语法分析的功能,驾驭语法分析程序设计的原理和构造方 法,训练学生驾驭开发应用程序的基本方法。有利于提高学生的专业素养,为培 养适应社会多方面须要的实力。二、试验要求 1、编程时留意编程风格:空行的运用、注释的运用、缩进的运用
26、等。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三、试验内容 依据某一文法编制调试LL (1 )分析程序,以便对随意输入的符号串 进行分析。 构造预料分析表,并利用分析表和一个栈来实现对上述程序设计语言的分 析程序。 分析法的功能是利用 LL(1)限制程序依据显示栈栈顶内容、向前看符号 以及 LL
27、(1)分析表,对输入符号串自上而下的分析过程。四、试验步骤 1、依据流程图编写出各个模块的源程序代码上机调试。2、 编制好源程序后,设计若干用例对系统进行全面的上机测试,并通过所设计 的 LL(1)分析程序;直至能够得到完全满足的结果。3、书写试验报告 ;试验报告正文的内容: 写出 LL(1)分析法的思想及写出符合 LL(1)分析法的文法。 程序结构描述:函数调用格式、参数含义、返回值描述、函数功能;函数 之间的调用关系图。 具体的算法描述(程序执行流程图)。 给出软件的测试方法和测试结果。 试验总结 (设计的特点、不足、收获与体会)。 五、试验截图 六、 核心代码 #include<i
28、ostream> #include<string> using namespace std; string pp;/ 输出字符串 string hh="rn"/ 换行 const int max=50; int endfumax;/ 终止符序号表 int endfupointer=8; char endfurealmax=+,-,*,/,(,i,),#; int unendfumax; int unendfupointer=5; char unendfurealmax=E,G,T,S,F; string makemathmax="E->TG
29、","G->+TG","G->-TG","G->$","T->FS","S->*FS","S->/FS","S->$","F->(E)","F->i" /0 E->TG,1 G->+TG,2 G->-TG,3 G->$,4 T->FS,5 S->*FS,6 S->/FS,7 S->$,8 F->(E)
30、,9 F->i /$ 代表空串 string behaviormax=初始化","POP" int smarttablemaxmax;/ 分析表 int checkendfu(char fu)/ 查终结符序号 int x;for(x=0;x<endfupointer;x+) if(endfurealx=fu) break; if(x<endfupointer)return x;else return -1; ; int checkunendfu(char fu)/ 查非终结符序号 int x;for(x=0;x<unendfupointer
31、;x+) if(unendfurealx=fu)break;if(x<unendfupointer)return x;else return-1; ; string checkmakemath(int x)/ 查产生式表 return makemathx; ; int checksmarttable(int x,int y)/ 查分析表 return smarttablexy; ; class smartbox public:smartbox() box0=#; box1=E; boxpointer=1; void push(char fu) boxpointer+; boxboxpoi
32、nter=fu; char pop() char a=boxboxpointer; if(a!=#) /cout<<"pop: "<<boxpointer<<""<<a<<endl; /stringstream oss; /* pp=pp+"pop: " char buffermax; sprintf(buffer,"%d",boxpointer); string s=buffer; pp=pp+" pp=pp+s; pp=pp+hh; */ b
33、oxpointer-; return a; void check() if(checkendfu(boxboxpointer)!=-1) char a; /cout<<boxboxpointer<<checkendfu(boxboxpointer)<<" " /char buffermax; /sprintf(buffer /pp=pp+boxboxpointer;/ pp=pp+checkendfu(boxboxpointer); /pp=pp+" " a=pop();/ cout<<"out
34、"<<a<<endl; char boxmax; int boxpointer; int main() / TODO: Add extra validation here / pp=pp+步骤分析栈 剩余输入串所用产生式 动作"+hh; /*string s1="sdsfsrnsdfsds"string s3="aaaaaaaaaaaaa"s3=s3+s1;CString s2(s3.c_str(); / CString s2=CString(s1);SetDlgItemText(IDC_EDIT2,s2);/
35、 用 SetDlgItemText( 文本框 ID, 字符串), 将文本框的内容设置为字符串的内容.SetDlgItemText(IDC_EDIT2,s2); */ / MessageBox(str);string str; cin>>str;int x,y;for(x=0;x<max;x+)/ 初始化分析表 99 为错误代号 for(y=0;y<max;y+)smarttablexy=99; smarttable04=0;smarttable05=0;smarttable10=1;smarttable11=2;smarttable16=3;smarttable17=3
36、;smarttable24=4;smarttable25=4;smarttable30=7;smarttable31=7;smarttable32=5;smarttable33=5;smarttable36=7;smarttable37=7;smarttable44=8;smarttable45=9;smartbox mark;char fu;char enterfu;int endfunumber;int unendfunumber;string readyin;string enter; / cin>>enter;/enter="i+i*i#"enter=s
37、tr; /enter="(i)#"int count=0;/ 步骤 char buffer1max; sprintf(buffer1,"%d",count); string s1=buffer1;pp=pp+s1+" "/ 分析栈for(int qq1=0;qq1<=mark.boxpointer;qq1+) pp=pp+mark.boxqq1; for(qq1=0;qq1<10-mark.boxpointer;qq1+) pp=pp+"/ 剩余输入栈string jiequ1=enter.substr(0,en
38、ter.length();pp=pp+jiequ1; for(int t1=0;t1<20;t1+) pp=pp+" pp=pp+" 初始化"+hh;for(x=0;x<enter.length();) / 步骤 count+;char buffermax; sprintf(buffer,"%d",count); string s=buffer;pp=pp+s+" "/ 分析栈for(int qq=0;qq<=mark.boxpointer;qq+) pp=pp+mark.boxqq; for(qq=0;q
39、q<10-mark.boxpointer;qq+) pp=pp+"/ 剩余输入栈string jiequ=enter.substr(x,enter.length()-x);pp=pp+jiequ; for(int t=0;t<x+10;t+) pp=pp+"enterfu=enterx;/ cout<<"enterfu: "<<enterfu<<endl; mark.check(); fu=mark.pop(); /cout<<"fu: "<<fu<<
40、endl; if(fu=#)/&&enterfu=#) /cout<<"sucessed! over!"<<endl;pp=pp+"sucessed! over!"+hh;break; unendfunumber=checkunendfu(fu); endfunumber=checkendfu(enterfu);/ cout<<unendfunumber<<endl;/ cout<<endfunumber<<endl; if(smarttableunendfunumb
41、erendfunumber=99) pp=pp+"error!"break; readyin=makemathsmarttableunendfunumberendfunumber; pp=pp+readyin; for(int ddd=0;ddd<14-readyin.length();ddd+) pp=pp+" pp=pp+"POP,PUSH(" for(y=readyin.length()-1;y>2;y-) pp=pp+readyiny; pp=pp+")"+hh;/ cout<<"readyin:"<<rea