




已阅读5页,还剩24页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
南昌航空大学实验报告二0一0 年 十一 月十七日课程名称: 编译原理 实验名称: 扩充的PL0程序 班级: 08061130 姓名: 胡作堃 同组人: 指导教师评定: 签名: 一、 实验目的进一步熟悉编译程序的整体框架,给出整个编译程序的流程结构,用C或vc+语言编写程序;并将编制的编译程序进行调试、实现PL/0编译程序。二、 实验要求(1)根据所选的程序设计语言,修改并调试。(2)举出例子程序,在程序中进行编译。(3)用此编译程序对有关语句进行编译,并输出目标指令。(4)书写出合格的实验报告。三、 实验步骤1.输入文件中变量的声明形如:var a,b,c; 以var保留字开始,不同变量以”,”分隔,最后以”;”结束。2.read语句格式为read(a)或者read(a,b);3.write语句格式为write(a),括号里面没有字符串常量,注意与书后的形如write(a=,a)是不相同的。4.的声明形如:”procedure proname;”不含参数表。5.一维数组形如:变量类型array 数组名数组下标。6条件语句形如:if then ;else,语句7扩充的记录型数据类型形如:for 循环语句及带参数的过程。四、 参考源代码#include #include #include #include #include #include #ifndef WIRTH_ZYC_#define WIRTH_ZYC_using namespace std;const int norw = 16; / no. of reserved words 保留字的个数const int txmax = 100; / length of identifier table 标示符表的长度(容量)const int al = 10; / length of identifiers 标示符的最大长度const int nmax = 14; / max. no. of digits in numbers 数字的最大长度const int amax = 2047; / maximum address 寻址空间const int levmax = 3; / maximum depth of block nesting 最大允许的块嵌套层数const int cxmax = 200; / size of code array 类PCODE目标代码数组长度(可容纳代码行数)const int lineLength = 82; / 行缓冲区长度typedef enum NUL,IDENT,NUMBER,PLUS,MINUS,TIMES,SLASH,ODDSYM,EQL,NEQ,LSS,LEQ,GTR,GEQ,LPAREN,RPAREN,COMMA,SEMICOLON,PERIOD,BECOMES,BEGINSYM,ENDSYM,IFSYM,THENSYM,WHILESYM,WRITESYM,READSYM,DOSYM,CALLSYM,CONSTSYM,VARSYM,PROCSYM,ELSESYM,REPEATSYM,UNTILSYM symbol; / symobl类型标识了不同类型的词汇typedef char alfaal+1; / alfa类型用于标识符typedef enum CONSTANT,VARIABLE,PROCEDURE,ARRAY obj0; / 三种标识符的类型typedef enum LIT,OPR,LOD,STO,CAL,INT,JMP,JPC fct; / functionstypedef set symset;struct instructionfct f; / function codeint l; / level,cannt big than levmax int a; / displacement address,cannt big than amax; / 类PCODE指令类型,包含三个字段:指令f、层差l和另一个操作数a/*lit 0,a: load constant a *opr 0,a: execute operation a *lod l,a: load variable l,a *sto l,a: store variable l,a *cal l,a: call procedure a at level l *int 0,a: increment t-register by a *jmp 0,a: jump to a *jpc 0,a: jump conditional to a */typedef structalfa name;obj0 kind;union structint level,adr,size;inOther;int val;other; Table;class PL0 protected:bool listswitch,sourceEnd;char ch; / last character readsymbol sym; / last symbol readalfa id; / last identifier readint num; / last number readint cc; / character countint ll; / line lengthint kk,err;int cx; / code allocation indexint codeNo; / code line no.static string errStr; / error string char linelineLength; / code linevector errorString; / error arrayalfa a; / 词法分析器中用于临时存放正在分析的词instruction codecxmax+1; / destination code arrayalfa wordnorw+1; / 保留字表symbol wsymnorw+1; / 保留字表中每一个保留字对应的symbol类型 symbol ssym100; / 一些符号对应的symbol类型表char mnemonic86; / 类PCODE指令助记符表 symset declbegsys,statbegsys,facbegsys; / 声明开始、表达式开始和项开始符号集合Table tabletxmax+1; / 符号表FILE* fin,*fout;public:PL0(char* source,char*destination); / 构造函数PL0()fclose(fin),fclose(fout); / 析构函数 void error(int n); / 出错处理,打印出错位置和出错代码void getsym(); / 词法分析,读取一个单词 void getch(); / 漏掉空格,读取一个字符void gen(fct x,int y,int z); / 生成目标代码,并送入目标程序区void test(symset s1,symset s2,int n); / 测试当前单词符号是否合法 void block(int lev,int tx,symset fsys); / 分程序分析处理过程 void enter(obj0 k,int &tx,int &dx,int lev); / 登入名字表int position(alfa id,int tx); / 查找标示符在名字表中的位置 void constdeclaration(int&tx,int&dx,int lev); / 常量定义处理void vardeclaration(int&tx,int&dx,int lev); / 变量说明处理void listcode(int cx0); / 列出目标代码清单void statement(symset fsys,int tx,int lev); / 语句部分处理 void expression(symset fsys,int tx,int lev); / 表达式处理 void term(symset fsys,int tx,int lev); / 项处理 void factor(symset fsys,int tx,int lev); / 因子处理void condition(symset fsys,int tx,int lev); / 条件处理void arraydeclaration(int& tx,int& dx,int lev); / 数组说明处理void interpret(); / 对目标代码的解释执行程序 int base(int l,int b,int s); / 通过静态链求出数据区的基地址 void SaveCode(); / 保存代码 ;string PL0:errStr= ,error 0001: 常数说明中“=”写成“:=”,error 0002: 常数说明中的“=”后应为数字,error 0003: 常数说明中的标识符后应是“=”,error 0004: const,var,procedure后应为标识符,error 0005: 漏掉了,或;,error 0006: 过程说明后的符号不正确(应是语句开始符或过程开始符),error 0007: 应是语句开始符,error 0008: 过程体内语句部分的后跟符不正确,error 0009: 程序皆为丢了句号.,error 0010: 语句之间漏了;,error 0011: 标识符没说明,error 0012: 赋值语句中,赋值号左部标识符属性应是变量,error 0013: 赋值语句左部标识符应是赋值号:=,error 0014: call后应为标识符,error 0015: call后标识符属性应为过程,error 0016: 条件语句中丢了then,error 0017: 丢了end或;,error 0018: while型循环语句中丢了do,error 0019: 语句后的标识符不正确,error 0020: 应为关系运算符,error 0021: 表达式内标识符属性不能是过程,error 0022: 表达式中漏掉了右括号),error 0023: 因子后的非法符号,error 0024: 表达式开始符不能是此符号,error 0025: 文件在不该结束的地方结束了,error 0026: 结束符出现在不该结束的地方,error 0027: ,error 0028: ,error 0029: ,error 0030: ,error 0031: 数越界,error 0032: read语句括号中标识符不是变量,error 0033: else附近错误 ,error 0034: repeat附近错误; / PL0构造函数PL0:PL0(char* source,char*destination)listswitch=true,sourceEnd=false;strcpy(word1,begin); / 初始化存储保留字strcpy(word2,call);strcpy(word3,const); strcpy(word4,do);strcpy(word5,else);strcpy(word6,end);strcpy(word7,if);strcpy(word8,odd);strcpy(word9,procedure);strcpy(word10,read);strcpy(word11,repeat);strcpy(word12,then);strcpy(word13,until);strcpy(word14,var);strcpy(word15,while);strcpy(word16,write);wsym1= BEGINSYM; wsym2= CALLSYM; / 初始化保留字表中每一个保留字对应的symbol类型 wsym3= CONSTSYM; wsym4= DOSYM;wsym5= ELSESYM; wsym6= ENDSYM;wsym7= IFSYM; wsym8= ODDSYM;wsym9= PROCSYM; wsym10= READSYM; wsym11= REPEATSYM; wsym12= THENSYM;wsym13= UNTILSYM; wsym14= VARSYM; wsym15= WHILESYM; wsym16= WRITESYM; memset(code,0,sizeof(code);memset(ssym,0,100*sizeof(symbol);memset(table,0,sizeof(table);memset(line,0,sizeof(line);ssym+= PLUS; / 初始化一些符号对应的symbol类型表ssym-= MINUS;ssym*= TIMES;ssym/= SLASH;ssym(= LPAREN;ssym)= RPAREN;ssym= EQL;ssym,= COMMA;ssym.= PERIOD;ssym#= NEQ;ssym= GTR;ssym;= SEMICOLON;strcpy(mnemonicLIT, lit ); / 初始化类PCODE指令助记符表 strcpy(mnemonicOPR, opr );strcpy(mnemonicLOD, lod );strcpy(mnemonicSTO, sto );strcpy(mnemonicCAL, cal );strcpy(mnemonicINT, int );strcpy(mnemonicJMP, jmp );strcpy(mnemonicJPC, jpc );declbegsys.insert(CONSTSYM),declbegsys.insert(VARSYM),declbegsys.insert(PROCSYM); / 初始化声明开始符号集合 statbegsys.insert(BEGINSYM),statbegsys.insert(CALLSYM),statbegsys.insert(IFSYM),statbegsys.insert(WHILESYM); / 初始化表达式开始符号集合facbegsys.insert(IDENT),facbegsys.insert(NUMBER),facbegsys.insert(LPAREN); / 初始化项开始符号集合err= 0;cc= 0; / 行缓冲区指针cx= 0; / 代码分配指针,代码生成模块总在cx所指位置生成新的代码 ll= 0; / 行缓冲区长度ch= ; / last character read kk= al; / 引入此变量是出于程序性能考虑codeNo=0; / code line no.fin=fopen(source,r);fout=fopen(destination,w);/ 出错处理,打印出错位置和出错代码void PL0:error(int n)char s10;sprintf(s,第 %d 行:,codeNo);/errorString.push_back(s+errStrn);err= err+1;/error count/error end/ 词法分析,读取一个单词 void PL0:getsym()if(sourceEnd)return;int i,j,k;while (ch = |ch=9)getch(); / cls space and tabif(isalpha(ch) / id or reserved wordk=0;memset(a,0,al+1);/ 检测一个单词长度doif (k = kk)kk = k;elsedoakk= ;kk= kk-1;while(kk k);strcpy(id,a);i= 1;j= norw;/ 判断是否是关键字(二分搜索)dok= (i+j) / 2;if(strcmp(id, wordk)=0)i= k+1;while(i j)sym= wsymk;elsesym= IDENT;else if(isdigit(ch) / numberk= 0;num= 0;sym= NUMBER;donum= 10 * num + ch - 0;k= k+1;getch();while(isdigit(ch);if(k nmax)error(30);else if (ch = :)getch();if( ch = =)sym= BECOMES;getch();elsesym= NUL;else if(ch = ) / extra stuff added to support )getch();if( ch = =)sym= GEQ;getch();elsesym= GTR;else / end of extra stuffsym= ssymch; / 其它符号的赋值getch();/ 漏掉空格,读取一个字符void PL0:getch()if(cc = ll)if(feof(fin)if(sym!=PERIOD)error(25);sourceEnd=true;return;cc= 0;fgets(line,lineLength,fin);codeNo+;ll=strlen(line);if(linell-1=10) ll-;ch= linecc;cc= cc+1;/ 生成目标代码,并送入目标程序区void PL0:gen(fct x,int y,int z)if (cx cxmax)coutlevmax)error(32);do if( sym = CONSTSYM) / 处理常量声明getsym();doconstdeclaration(tx,dx,lev); / 调用常量处理while (sym = COMMA) / 如果是逗号getsym(); / 读取下一个单词constdeclaration(tx,dx,lev); / 调用常量处理if (sym =SEMICOLON) / 如果是分号getsym(); / 读取下一个单词else / 否则报错,缺少;或,error(5); while(sym=IDENT); / 如果有效的字符if( sym = VARSYM) / 处理变量声明getsym();dovardeclaration(tx,dx,lev);while( sym = COMMA)getsym();vardeclaration(tx,dx,lev);if( sym =SEMICOLON)getsym();elseerror(5);while(sym=IDENT);while( sym =PROCSYM) / 处理过程的声明getsym();if (sym =IDENT)enter(PROCEDURE,tx,dx,lev);getsym();elseerror(4);if( sym =SEMICOLON)getsym();elseerror(5);symset tmp = fsys;tmp.insert(SEMICOLON);block(lev+1,tx,tmp);if (sym = SEMICOLON)getsym();symset tmp = statbegsys;for(int i= IDENT;i=PROCSYM;i+)tmp.insert(symbol)i);test(tmp,fsys,6);elseerror(5);symset tmp=statbegsys;tmp.insert(IDENT);test(tmp,declbegsys,7);while(declbegsys.find(sym)!=declbegsys.end();codetabletx0.other.inOther.adr.a= cx;tabletx0.other.inOther.adr= cx; / start adr of codetabletx0.other.inOther.size=dx;cx0= cx;gen(INT,0,dx);symset tmp=statbegsys;for(int i=SEMICOLON;i amax)error(31);num=0;tabletx.other.val=num;break;case VARIABLE:tabletx.other.inOther.level=lev;tabletx.other.inOther.adr=dx;dx+;break;case PROCEDURE:tabletx.other.inOther.level=lev;break;case ARRAY:tabletx.other.inOther.size = lev;break;/enter end/ 查找标示符在名字表中的位置 int PL0:position(alfa id,int tx)/find identifier id in tableint i;strcpy(, id);i= tx;while (strcmp(,id)!=0)i-;return i;/position end/ 常量定义处理void PL0:constdeclaration(int&tx,int&dx,int lev)if(sym = IDENT) getsym(); if(sym=EQL&sym=BECOMES) if( sym =BECOMES) error(1);getsym();if( sym = NUMBER)enter(CONSTANT,tx,dx,lev);getsym();else error(2); elseerror(3);else error(4);/ constdeclaration end/ 变量说明处理void PL0:vardeclaration(int&tx,int&dx,int lev)if( sym = IDENT)enter(VARIABLE,tx,dx,lev);getsym();elseerror(4);/vardeclaration end/ 数组说明处理void PL0:arraydeclaration(int&tx,int&dx,int lev) int upscript=0,downscript=0;getsym();if(sym = NUMBER | sym = CONSTSYM)if(num = 0)upscript = num;getsym();else error(32);if(sym = COMMA)getsym();elseerror(32);if(sym = NUMBER | sym = CONSTSYM)downscript = num;getsym();if(sym != RPAREN)error(32);elseenter(ARRAY,tx,dx,downscript+1);getsym();/ 列出目标代码清单void PL0:listcode(int cx0)/list code generated for this blockint i;if(listswitch)for (i= cx0;icx;i+) cout i mnemoniccodei.f codei.l codei.aendl;/ listcode end/ 语句部分处理 void PL0:statement(symset fsys,int tx,int lev)if(sourceEnd)return;int i,cx1,cx2;if(sym =IDENT)i= position(id,tx);if (i = 0)error(11);else if (tablei.kind!=VARIABLE)error(12);i= 0;getsym();if(sym =BECOMES)getsym();elseerror(13);expression(fsys,tx,lev);if(sym != SEMICOLON)error(10);if( i!= 0)gen(STO,lev-tablei.other.inOther.level,tablei.other.inOther.adr);else if( sym = READSYM)getsym();if( sym!=LPAREN)error(34);elsedogetsym();if (sym=IDENT)i=position(id,tx);elsei=0;if( i=0 )error(35);elsegen(OPR,0,16);gen(STO,lev-tablei.other.inOther.level,tablei.other.inOther.adr);getsym();while(sym = COMMA);if (sym != RPAREN)error(33);while (fsys.find(sym)!=fsys.end() getsym();else getsym();else if( sym = WRITESYM )getsym();if (sym=LPAREN)dogetsym();symset tmp=fsys;for(int t=RPAREN;t=COMMA;t+)tmp.insert(symbol)t);expression(tmp,tx,lev);gen(OPR,0,14);while(sym=COMMA);if (sym!=RPAREN)error(33);elsegetsym();gen(OPR,0,15);else if( sym =CALLSYM)getsym();if( sym!=IDENT)error(14);elsei= position(id,tx);if (i = 0)error(11);else if (tablei.kind = PROCEDURE)gen(CAL,lev-tablei.other.inOther.level,tablei.other.inOther.adr);elseerror(15);getsym();else if( sym =IFSYM)getsym();symset tmp=fsys;int j = 0;for(j= THENSYM;j= DOSYM;j+)tmp.insert(symbol)j);condition(tmp,tx,lev);if( sym = THENSYM)getsym();elseerror(16);cx1= cx;gen(JPC,0,0);tmp.insert(ELSESYM);statement(tmp,tx,lev);getsym();codecx1.a= cx;if(sym = ELSESYM) getsym(); cx2=cx; gen(JMP,0,0); codecx1.a=cx; statement(fsys,tx,lev); codecx2.a=cx;else if( sym =BEGINSYM)getsym();symset tmp=fsys;int k =0;for(k=SEMICOLON;k=ENDSYM;k+)tmp.insert(symbol)k);statement(tmp,tx,lev);tmp=statbegsys;tmp.insert(SEMICOLON);while( tmp.find(sym)!=tmp.end()if(sourceEnd)return;if (sym =SEMICOLON|sym =ENDSYM)getsym();else if(sym=PERIOD)error(26);getsym();elseerror(10);tmp=fsys;int m = 0;for(m=SEMICOLON;m=ENDSYM;m+)tmp.insert(symbol)m);if(sour
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 工作中的有效沟通与合作能力培养
- 工作中的时间管理艺术与实践经验分享
- 工作场所心理健康关怀
- 工业领域中的热管理新材料探索
- 工程制造中的精确测量与数学计算
- 工作流程优化中的设备管理关键点
- 工厂教育培训提升员工技能的新途径
- 工程机械的远程监控和故障诊断技术应用
- 工厂电气节能改造的案例分析
- 工程机械的保养与维修技巧
- 淋球菌基因表达调控-深度研究
- 冠心病二级预防ABCDE原则
- 《车库门的PLC控制》课件
- 恪守职业道德课件
- 新能源汽车全解析
- 2024年秋期国家开放大学《11809企业战略管理(统设课)》期末考试题库
- 卫氏并殖吸虫病
- 医务人员职业安全管理制度(4篇)
- 土木工程CAD-终结性考核-国开(SC)-参考资料
- 确认收货单-模板
- 金融行业安全生产责任管理
评论
0/150
提交评论