版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
编译原理实验三:语义分析PAGEPAGE1编译原理实验三语义分析实验报告学院:数学与计算机科学技术学院专业:计算机科学与技术班级:级计算机班小组组员:姓名:学号:姓名:学号:姓名:学号:姓名:学号:实验题目一、实验目的要求学生用与实验2相同的语言,编制语义分析程序。二、实验准备微机CPU主频以上,128M内存,安装好C语言,PASCAL语言,或C++。三、实验时间13学时四、实验内容要求学生用与实验2相同的语言,编制语义分析程序。定义该语言的语义成分,将语义分析程序编制成子程序,在实验2分析出各语法单位后,分析其含义,并将可执行语句或表达式翻译为四元式输出,并将错误信息输出。实验报告必须包括设计的思路,以及测试报告(输入测试例子,输出结果)。五、上交文档1.实验报告(书面);2.程序文件(通过网络提交)。<program>::=<block>.<block>::=<const-decl><var-decl><proc-decl><statement><const-decl>::=const<const-assignment-list>;|ε<const-assignment-list>::=<ident>=<number>|<const-assignment-list>,<ident>=<number><var-decl>::=var<ident-list>;|ε<ident-list>::=<ident>|<ident-list>,<ident><proc-decl>::=<proc-decl>procedure<ident>;<block>;|ε<statement>::=<ident>:=<expression>|call<ident>|begin<statement-list>end|if<condition>then<statement>|while<condition>do<statement>|ε<statement-list>::=<statement>|<statement-list>;<statement><condition>::=odd<expression>|<expression><relation><expression><relation>::==|<>|<|>|<=|>=<expression>::=<term>|<adding-operator><term>|<expression><adding-operator><term><adding-operator>::=+|-<term>::=<factor>|<term><multiplying-operator><factor><multiplying-operator>::=*|/<factor>::=<ident>|<number>|(<expression>)注意:(1)"ε"表示空串。.(2)<ident>和<number>分别表示标识符和数。。实验报告一.【需求分析】1.PL/M机器的机器指令LODa栈指针增1。装入a的值到栈顶。STOa存栈顶到a。栈指针减1。LITn栈指针增1。装入数n到栈顶。ADD栈顶两个元素相加。弹出这两个元素。存结果在栈顶。MUL栈顶两个元素相乘。弹出这两个元素。存结果在栈顶。这些指令以源码形式由解释程序执行。2.PL/M程序文本及修改原文本:P→S;P|S;!S→id=EE→E+T|TT→T×F|FF→(E)|id|digitid→a|b|……|zdigit→0|1|……|9添上必要的语义动作print()产生中间代码,及相应修改某些产生式修改后的文本:P1→S;P2P→S;!{print(END)}S→id=E{print(STOid)}E→T+E{print(ADD)}E→TT→F×T{print(MUL)}T→FF→(E)F→id{print(LODid)}F→digit{print(LITn)}id→a|b|……|zdigit→0|1|……|9(摘至附录)二.【概要设计】参考附录:有关编译程序/解释程序设计的简单说明存储区采用数组形式,变量按照说明的先后顺序分配存储单元。解释程序利用运行栈进行,所有运算都在栈顶(和次栈顶)进行。编译程序从源程序生成目标代码。解释程序基于前面描述的存储管理方法执行目标代码。变量说明arrayx:保存用户程序arraym:储存用户定义的变量arraystack:运行栈arraycode:存储目标代码arrayadr:用作操作数。如果操作数是变量,存的是地址。如果操作数是数,存的是数值。函数说明Error():出错处理程序init():初始读入用户程序到数组x。id()给出变量的地址getsym()读入下一符号到变量current.S()处理语句。在处理完赋值号左边后,如果下一符号是“=”,读入下一符号,然后处理表达式。E()处理表达式。在处理好一个项(term)后,当下一符号是“+”,读入下一符号,然后处理项。T()处理项。在处理好一个因子(factor)后,当下一符号是“×”,读入下一符号,然后处理因子。F()处理因子。(1)如果当前符号是“(“,读入下一符号,处理表达式。此后,如果当前符号是“)”,读入下一符号,退出。(2)如果当前符号是变量,读入下个符号,退出。(3)如果都不是,出错error().Interpret()执行用户的目标代码。变量“i”作为指令计数器。就是执行code[i]fori=1,...,j-1.三.【详细的算法描述及源程序清单】主程序main()的流程图init()init()p()对读入的源码进行编译对编译得到的源码进行解释,并输出结果开始读入成功?编译成功?结束失败成功失败成功代码清单及注释分析/*头文件*/#include<stdio.h>#include<fstream.h>#include<stdlib.h>//与exit()相关#include<ctype.h>//与isdigit()和islower()相关/*输入输出文件流*/ifstreamfin("source.txt");//source.txt中存放的是要编译的源码,ofstreamfout("result.txt");/*数据结构*///常量定义,限定数组的长度#definecodemaxlength512#definexmaxlength512#definesmaxdepth512intcode_line;//写code[]的时作计数器intx_line;//读入文件时作计数器intn_error;//错误处理时作计数器charcurrent;//当前处理的字符intforward;//当前处理的字符在数组x[]中的下标intsp;//栈顶指针intsourcelength;//源码的长度enumoperation//定义机器指令类型为枚举operation{LOD,STO,LIT,ADD,MUL,END};structnode//数组code[]的元素结构,包含机器指令类型,{enumoperationop;//包含机器指令类型,chary;//及其操作数};structnodecode[codemaxlength];//存储目标代码charx[xmaxlength];//保存用户程序intstack[smaxdepth];//运行栈intm[26][2];//变量标,即符号表intadr[2];//用作操作数/*getsym()*///读入下一符号到变量currentchargetsym(){forward++;if(forward>sourcelength) exit(1);else returnx[forward];}/*error()*///出错处理程序voiderror(char*str,inta){n_error++;//处理读文件到x[]时出现的错误if(a==0)printf("(%d)读入文件错误(第%d条语句):%s\n",n_error,x_line,str);//处理编译目标代码时出现的错误else{printf("(%d)编译错误(第%d语句):%c%s\n",n_error,x_line,current,str);current=getsym();}}/*初始化init()*///初始化,并读入用户的源码到数组x[]中boolinit(){x_line=1;n_error=0;//初始符号表for(inti=0;i<26;i++)m[i][0]=0;/*读入文件source.txt中的源码到x[]数组*/charc;printf("读入文件中……\n");fin>>c;i=0;while(!fin.eof()){if(c=='\0'||c=='\n')//去空白符fin>>c;else { x[i]=c; if(c=='!') { fin>>c; if(fin.eof())//读入文件成功 { sourcelength=i; return1; } else//出现了类似如下的代码:"a=1;b=3;!;c=5;!", //即代码中间出现了!的错误 { error("程序中间出现'!'/n",0); fin>>c; } } elseif(c==';')x_line++;//对源码行的计数 fin>>c; i++; if(i==xmaxlength)//x[]数组溢出检查 { error("源码太长,数组x溢出",0); exit(1);}}}if(i==0)error("source.txt为空文件!请输入源码!",0);//空文件elseerror("程序并未以'!'结尾",0);//读入文件失败return0;}/*id()*///给出变量的地址intid(charc){ returnc-97;}/*writecode()*///写入代码到code数组voidwritecode(enumoperationa,charb)//写带操作数的指令{code[code_line].op=a;code[code_line].y=b;code_line++;if(code_line==codemaxlength) //溢出检查{printf("生成的目标代码太长,code数组溢出!");exit(1);}}voidwritecode(enumoperationa) //写不带操作数的指令{code[code_line].op=a;code_line++;if(code_line==codemaxlength) //溢出检查{printf("生成的目标代码太长,code数组溢出!");exit(1);}}/*处理因子--F()*/intE();intF(){//处理F->(E)if(current=='('){ current=getsym();E();if(current==')') {current=getsym();return1; }else { error("括号不匹配",1);//类似a=1;b=2+(a*4;!错误current=x[--forward]; return0; }}//处理F->idelseif(islower(current)){if(m[id(current)][0]==0){error("变量未定义",1);//赋值语句右值中出现未定义的id,例a=b+1;!中的breturn0;}else{writecode(LOD,current); current=getsym(); return1; }}//处理F->digitelseif(isdigit(current)){writecode(LIT,current);current=getsym();return1;}//a=!情况和a=;!情况elseif(current=='!'||current==';') {error("右值出错!",1);current=x[--forward];return0;}//非法变量else{error("非法变量",1);return0;}}/*处理项T()*///处理T->F或T->F*TintT(){F();if(current=='*')//处理T->F*T{current=getsym();T();writecode(MUL);//语义动作}return1;}/*处理表达式-E()*///处理E->T或E->T*EintE(){T();if(current=='+'){current=getsym();E();writecode(ADD);//语义动作}return1;}/*处理语句S()*///S→id=Eints(){charc;if(islower(current)){if(m[id(current)][0]==0)//判断id是否已定义m[id(current)][0]=1;c=current;current=getsym();if(current=='='){current=getsym(); E(); writecode(STO,c);//语义动作 return1;}else{error("缺少'='",1);//a=1;b1;!情况 current=x[--forward]; E(); return0;}}elseif(current=='='){error("缺少左值",1);//a=1;=2;!情况E();return0;;}elseif(current==';'){error("空语句",1);//a=1;;b=2;!情况current=x[--forward];return1;}else{error("非法左值",1);//a=1;A=3;!if(current=='='){current=getsym(); E(); return1;}else{error("缺少'='",1);//a=1;A3;! current=x[--forward]; E(); return0;}}}/*编译主程序P()*///处理P→S;P|S;!intp(){s();if(current==';'){x_line++;current=getsym();if(current=='!'){writecode(END);return1;}else{p();return1;}}else//a=1;b=2c=a+b;!{error("语句缺少';'",1);current=x[--forward];p();return0;}}/*show()*///输出执行栈中数据及将要执行的目标指令intshow(enumoperationoper,charc){inti;for(i=0;i<=sp;i++)//输出栈fout<<stack[i]<<"";fout<<'\t'<<'\t'<<'\t';switch(oper)//输出指令{caseLOD:fout<<"LOD"<<c<<endl;break;caseSTO:fout<<"STO"<<c<<endl;break;caseLIT:fout<<"LIT"<<c<<endl;break;caseADD:fout<<"ADD"<<endl;break;caseMUL:fout<<"MUL"<<endl;break;}return0;}/*interpret()*///解释程序,执行用户的目标代码intinterpret(){code_line=0;sp=0;//用0表示栈底,即实际上栈是从stack[1]开始,这样方便阅读charc;enumoperationoper;while(1)//开始执行{oper=code[code_line].op;c=code[code_line].y;show(oper,c);switch(oper){caseLOD:stack[++sp]=m[id(c)][1]; break;caseSTO:m[id(c)][1]=stack[sp--]; break;caseLIT:stack[++sp]=int(c)-48; break;caseADD:adr[0]=stack[sp--]; adr[1]=stack[sp]; stack[sp]=adr[0]+adr[1]; break;caseMUL:adr[0]=stack[sp--]; adr[1]=stack[sp]; stack[sp]=adr[0]*adr[1]; break;caseEND:return0;}if(oper==END)break;//执行结束code_line++;}return0;}/*主程序*/intmain(){fout.open("code.txt");//建立文件,用来存目标代码fout.close();fout.open("result.txt");//建立文件,用来显示目标代码的执行过程fout.close();inti=0;charc;//////////////读入源码init();if(n_error){printf("初始读入文本文件source.txt失败!\n请修改源码并重新读入\n"); return0;}elseprintf("读入文本文件source.txt成功!\n\n");/////////////编译源码,产生目标指令while(1){printf("是否进行编译(按回车确定)");c=getchar();if(c=='\n')break;}printf("编译中……\n");n_error=0;x_line=1;forward=-1;current=getsym();p();//编译if(n_error){ printf("编译失败!请修改源码并重新读入文件!\n"); return0;}else{……\n\n"); enumoperationoper; fout.open("code.txt");//输出目标代码到code.txt文本中 while(1) { oper=code[i].op; c=code[i].y; switch(oper) { caseLOD: fout<<i<<":LOD"<<c<<endl;break; caseSTO: fout<<i<<":STO
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025版城市物流配送承包合同3篇
- 电子产品制造安全用品规定
- 2025个人租房合同范本标准版
- 食品安全厨师聘用合同模板
- 乙供物资供应商质量管理体系
- 2025版商铺转租与新能源技术应用合同范本3篇
- 2025版风电项目用地租赁合同3篇
- 2025版虫草保健品原料供应合同2篇
- 2025版冷链物流快递业务承包管理合同3篇
- 2024年货物买卖合同标的及权益说明
- 《建筑工程设计文件编制深度规定》(2022年版)
- 七年级体育《排球》教案
- 2024-2030年中国工控机行业需求状况及发展趋势分析研究报告
- 癫痫发作急救与护理
- 中医医案学习方法:医案的分类
- 小学《象棋》校本课程教案
- 公司会议室设备管理制度
- 2024年版的企业绩效评价标准
- 风险保证金协议书
- 宝玉石鉴定指南智慧树知到期末考试答案章节答案2024年四川文化产业职业学院
- 《埋地塑料排水管道工程技术规程》CJJ143-2010
评论
0/150
提交评论