已阅读5页,还剩15页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
课 程 设 计 课程名称_ 编译原理 _题目名称 PL/0语言的扩充 学生学院_ 计算机学院_专业班级_ 软件工程07级4班_学 号 学生姓名 指导教师_ 李小妹_ 2008 年 1 月 5 日19课程设计实验报告一、概述:源语言: PL/0目标语言: 目标代码(生成的文件后缀为*.COD)实验工具: Borland C+Builder 6运行平台: WindowsXP目的:在分析理解一个教学型编译程序(如PL/0)的基础上,对其词法分析程序、语法分析程序和语义处理程序进行部分修改扩充。达到进一步了解程序编译过程的基本原理和基本实现方法的目的。要求:对PL/0作以下修改扩充:基本内容(1)扩充赋值运算:+= 和 -=(2)扩充语句(Pascal的FOR语句):FOR := TO DO FOR := DOWNTO DO 其中,语句的循环变量的步长为1,语句的循环变量的步长为-1。选做内容 (1)增加运算:+ 和 -。(2)增加类型: 字符类型; 实数类型。(3)扩充函数: 有返回值和返回语句; 有参数函数。(4)增加一维数组类型(可增加指令)。(5)其他典型语言设施。二、结构设计说明:各功能模块描述Error()出错处理,打印出错位置和错误编码GetCh()漏掉空格,读取一个字符GetSym() 词法分析,读取一个单词 GEN()目标代码生成过程,本过程用于把生成的目标代码写入目标代码数组,供后面的解释器解释执行TEST() 测试当前单词是否合法过程testENTER() 登陆符号表过程enterPOSITION() 在符号表中查找指定符号所在位置的函数position VARDECLARATION()变量声明处理LISTCODE()输出目标代码清单;FACTOR() 因子处理过程factorTERM() 项处理过程term; EXPRESSION() 表达式处理过程CONDITION() 条件处理过程STATEMENT() 语句处理过程BLOCK() 编译程序主体,语法分析过程 BASE()通过静态链求出数据区基地址的函数,INTERPRET ()对目标代码解释运行过程Pl0编译程序的结构词法分析程序语法语义分析程序代码生成程序表格管理程序出错处理程序PL0源程序目标程序编译程序的总体流程图 词法分析状态转换图. 表示状态,对应每个状态编一段程序,每个状态调用取字符程序,根据当前字符转到不同的状态,并做相应操作。 表示终态,已识别出一个单词语法调用关系图 程序 pl0分程序 block语句 statement条件 condition表达式expression项 term主要成分描述1.符号表在编译程序中符号表用来存放语言程序中出现的有关标识符的属性信息,符号表中所登记的信息在编译的不同阶段都要用到。在语义分析中,符号表所登记的内容将用于语义检查(如检查一个名字的使用和原先的说明是否一致)和产生中间代码。在目标代码生成阶段,当对符号名进行地址分配时,符号表是地址分配的依据。对一个多遍扫描的编译程序,不同遍所用的符号表也往往各有不同。因为每遍所关心的信息各有差异。一张符号表的每一项(或称入口才包含两大栏(或称区段、字域),即名字栏(NAME) 信息栏(INFORMATION) 信息栏包含许多子栏和标志位,用来记录相应名字和种种不同属性,由于查填符号表一般是通过匹配名字来寮现的,因此,名字栏也称主栏。主栏的内容称为关键字(key word)。 2.运行时存储组织和管理由于编译时目标程序运行的数据空间大小已经规定,所以存储组织属于静态存储。源程序的标识符存放在TABLE表中,目标代码存放在CODE中,S是由解释程序定义的一维整型数组,是程序运行时的数据存储空间。3.语法分析方法自顶向下的语法分析: . VAR ; A BEGIN END READ ( ) A4.中间代码表示对PL/0编译程序的目标代码的指令格式描述如下: f l a其中f代表功能码,l表示层次差,a的含意对不同的指令有所区别,见下面对每条指令的解释说明:lit 0 a将常数值取到栈顶,a为常数值Lod l a将变量值取到栈顶,a为偏移量,l为层差Sto l a将栈顶内容送入某变量单元中,a为偏移量,l为层差Cal l a调用过程,a为过程地址,l为层差Int 0 a在运行栈中为被调用的过程开辟a个单元的数据区jmp 0 a无条件跳转至a地址Jpc 0 a条件跳转,当栈顶布尔值非真则跳转至a地址,否则顺序执行opr 0 0过程调用结束后,返回调用点并退栈opr 0 1栈顶元素取反opr 0 2次栈顶与栈顶相加,退两个栈元素,结果值进栈opr 0 3次栈顶减去栈顶,退两个栈元素,结果值进栈opr 0 4次栈顶乘以栈顶,退两个栈元素,结果值进栈opr 0 5次栈顶除以栈顶,退两个栈元素,结果值进栈opr 0 6栈顶元素的奇偶判断,结果值在栈顶opr 0 7opr 0 8次栈顶与栈顶是否相等,退两个栈元素,结果值进栈opr 0 9次栈顶与栈顶是否不等,退两个栈元素,结果值进栈opr 0 10次栈顶是否小于栈顶,退两个栈元素,结果值进栈opr 0 11次栈顶是否大于等于栈顶,退两个栈元素,结果值进栈opr 0 12次栈顶是否大于栈顶,退两个栈元素,结果值进栈opr 0 13次栈顶是否小于等于栈顶,退两个栈元素,结果值进栈opr 0 14栈顶值输出至屏幕opr 0 15屏幕输出换行opr 0 16从命令行读入一个输入置于栈顶三、程序代码:扩充后修改的部分代码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, PROGSYM, PLUSBK, MINUSBK, SQLPAREN,SQRPAREN, INC, DEC, ELSESYM, FORSYM, TOSYM, DOWNTOSYM, RETURNSYM SYMBOL;/添加SQLPAREN,SQRPAREN,INC,DEC,ELSESYM,FORSYM,TOSYM,DOWNTOSYM ,RETURNSYM char *SYMOUT = 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, PROGSYM, PLUSBK, MINUSBK, SQLPAREN,SQRPAREN, INC, DEC,ELSESYM, FORSYM, TOSYM, DOWNTOSYM, RETURNSYM ; /添加INC,DEC,ELSESYM,FORSYM,TOSYM,DOWNTOSYM /设置保留字名字 strcpy(KWORD 1,BEGIN); strcpy(KWORD 2,CALL); strcpy(KWORD 3,CONST); strcpy(KWORD 4,DO); strcpy(KWORD 5,DOWNTO); /downto strcpy(KWORD 6,ELSE); /else strcpy(KWORD 7,END); strcpy(KWORD 8,FOR); /for strcpy(KWORD 9,IF); strcpy(KWORD10,ODD); strcpy(KWORD11,PROCEDURE); strcpy(KWORD12,PROGRAM); strcpy(KWORD13,READ); strcpy(KWORD14,RETURN); /return strcpy(KWORD15,THEN); strcpy(KWORD16,TO); /to strcpy(KWORD17,VAR); strcpy(KWORD18,WHILE); strcpy(KWORD19,WRITE); /设置保留字符号 WSYM 1=BEGINSYM; WSYM 2=CALLSYM; WSYM 3=CONSTSYM; WSYM 4=DOSYM; WSYM 5=DOWNTOSYM; /downto WSYM 6=ELSESYM; /else WSYM 7=ENDSYM; WSYM 8=FORSYM; /for WSYM 9=IFSYM; WSYM10=ODDSYM; WSYM11=PROCSYM; WSYM12=PROGSYM; WSYM13=READSYM; WSYM14=RETURNSYM; /return WSYM15=THENSYM; WSYM16=TOSYM; /to WSYM17=VARSYM; WSYM18=WHILESYM; WSYM19=WRITESYM;词法分析,获取一个符号void GetSym() long i,J,K; ALFA A; while (CH=A & CH=Z) /*ID OR RESERVED WORD*/ K=0;do if (K=A & CH=0 & CH=9);AK=0;strcpy(ID,A); i=1; J=NORW;do K=(i+J) / 2; if (strcmp(ID,KWORDK)=0) i=K+1;while(i J) SYM=WSYMK; /if(SYM=ELSESYM) else SYM=IDENT; else if (CH=0 & CH=0 & CHNMAX) Error(30); else if (CH=:) GetCh();if (CH=) SYM=BECOMES; GetCh(); else SYM=NUL; else /* THE FOLLOWING TWO CHECK WERE ADDED BECAUSE ASCII DOES NOT HAVE A SINGLE CHARACTER FOR = */ if (CH=) SYM=NEQ; GetCh(); /3 修改不等号 else SYM=LSS;else if (CH=) GetCh();if (CH=) SYM=GEQ; GetCh(); else SYM=GTR; else /4添加+=,-=,+,- if(CH=+) GetCh(); if(CH=) SYM=PLUSBK; GetCh(); else if(CH=+) SYM=INC; GetCh(); else SYM=PLUS; else if(CH=-) GetCh(); if(CH=) SYM=MINUSBK; GetCh(); else if(CH=-) SYM=DEC; GetCh(); else SYM=MINUS; else if(CH=/) char c=LINECC; if(c=/) CC=LL;/for(int i=0;iprintls(JJJ,55); SYM=SLASH; GetCh(); else SYM=SSYMCH; GetCh(); /语句处理void STATEMENT(SYMSET FSYS,int LEV,int &TX) /*STATEMENT*/ int i,CX1,CX2,CX3,tm=0,jk=0; FCT STOMode3=STO,STOARR,STOVAR; FCT LODMode3=LOD,LODARR,LODVAR; SYMBOL Temp; switch (SYM) case IDENT:i=POSITION(ID,TX);if (i=0) Error(11);else if (TABLEi.KIND!=VARIABLE) /*ASSIGNMENT TO NON-VARIABLE*/Error(12); i=0; GetSym(); switch(SYM) /添加INC,DEC,PLUSBK,MINUSBK case BECOMES: GetSym(); EXPRESSION(FSYS,LEV,TX); if(i!=0) GEN(STO,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); break; case INC: /+运算 GetSym(); GEN(LODModejk,LEV-TABLEi.vp.LEVEL+tm,TABLEi.vp.ADR); GEN(LIT,0,1); GEN(OPR,0,2); GEN(STOModejk,LEV-TABLEi.vp.LEVEL+tm,TABLEi.vp.ADR); break; case DEC: /-运算 GetSym(); GEN(LODModejk,LEV-TABLEi.vp.LEVEL+tm,TABLEi.vp.ADR); GEN(LIT,0,1); GEN(OPR,0,3); GEN(STOModejk,LEV-TABLEi.vp.LEVEL+tm,TABLEi.vp.ADR); break; case PLUSBK: case MINUSBK: int flag=SYM; /flag是一个局部整型变量 GetSym(); GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); EXPRESSION(FSYS,LEV,TX); if(flag=PLUSBK) GEN(OPR,0,2); else GEN(OPR,0,3); GEN(STO,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); break; / default: Error(13); GetSym(); break;case READSYM:GetSym();if (SYM!=LPAREN) Error(34);else do GetSym();if (SYM=IDENT) i=POSITION(ID,TX);else i=0;if (i=0) Error(35);else GEN(OPR,0,16); GEN(STO,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR);GetSym(); while(SYM=COMMA);if (SYM!=RPAREN) Error(33); while (!SymIn(SYM,FSYS) GetSym();else GetSym();break; /* READSYM */case WRITESYM:GetSym();if (SYM=LPAREN) do GetSym();EXPRESSION(SymSetUnion(SymSetNew(RPAREN,COMMA),FSYS),LEV,TX);GEN(OPR,0,14); while(SYM=COMMA); if (SYM!=RPAREN) Error(33); else GetSym();GEN(OPR,0,15);break; /*WRITESYM*/ case CALLSYM:GetSym();if (SYM!=IDENT) Error(14); else i=POSITION(ID,TX); if (i=0) Error(11); GetSym(); if(SYM=LPAREN) GetSym(); int k=0; EXPRESSION(SymSetUnion(SymSetNew(RPAREN,COMMA),FSYS),LEV,TX); GEN(PUSH,0,k); k+; while(SYM=COMMA) GetSym(); EXPRESSION(SymSetUnion(SymSetNew(RPAREN,COMMA),FSYS),LEV,TX); GEN(PUSH,0,k); k+; if(SYM=RPAREN) GetSym(); else Form1-printls(错误CALL,400); /String s=IntToStr(i); /Form1-printls(s.c_str(),700); GEN(CAL,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); else if (TABLEi.KIND=PROCEDUR) GEN(CAL,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR);else Error(15); break;case IFSYM:GetSym();CONDITION(SymSetUnion(SymSetNew(THENSYM,DOSYM,ELSESYM),FSYS),LEV,TX);if (SYM=THENSYM) GetSym();else Error(16);CX1=CX; GEN(JPC,0,0);STATEMENT(SymSetUnion(SymSetNew(IDENT,ELSESYM,SEMICOLON),FSYS),LEV,TX); if(SYM!=SEMICOLON) Form1-printls(错误IF,300); else GetSym(); if(SYM!=ELSESYM) b=1; CODECX1.A=CX; return; else /6 添加else GetSym(); CX2=CX; GEN(JMP,0,0); STATEMENT(FSYS,LEV,TX); CODECX1.A=CX2+1; CODECX2.A=CX; break;case BEGINSYM:GetSym();STATEMENT(SymSetUnion(SymSetNew(SEMICOLON,ENDSYM),FSYS),LEV,TX);while (SYM=IDENT|SymIn(SYM, SymSetAdd(SEMICOLON,STATBEGSYS) if (SYM=SEMICOLON|b) if(b) b=0; else GetSym(); else Error(10); STATEMENT(SymSetUnion(SymSetNew(SEMICOLON,ENDSYM),FSYS),LEV,TX);if (SYM=ENDSYM) GetSym();else Error(17);break;case WHILESYM:CX1=CX; GetSym(); CONDITION(SymSetAdd(DOSYM,FSYS),LEV,TX);CX2=CX; GEN(JPC,0,0);if (SYM=DOSYM) GetSym();else Error(18);STATEMENT(FSYS,LEV,TX);GEN(JMP,0,CX1);CODECX2.A=CX;break; case FORSYM: /7 添加for GetSym(); /PASCAL语法 FOR := TO|DOWNTO DO if(SYM=IDENT) i=POSITION(ID,TX);if(i=0) Error(11);else /变量为常数或过程都出错if(TABLEi.KIND=CONSTANT|TABLEi.KIND=PROCEDUR)Error(12);i=0;if(TABLEi.KIND=ARR)ARRGetSub(FSYS,LEV,TX); jk=0; if(TABLEi.IsVAR) /处理变量是否为按地址传递的参数 GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); jk=2; /else if(i=0)GetSym();if(SYM=BECOMES) /变量赋初始值 GetSym(); /第一个运算表达式EXPRESSION(SymSetUnion(SymSetNew(TOSYM,DOWNTOSYM),FSYS),LEV,TX); if(SYM=TOSYM) /如果为TOCX1=CX; /CX1记录当前代码段作为开始循环位置 GEN(STOModejk,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); /把数存进变量中 GEN(LODModejk,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); /读取此变量的数,放入栈顶 GetSym(); EXPRESSION(SymSetUnion(SymSetNew(DOSYM),FSYS),LEV,TX); /计算第二个运算表达式,放入栈顶 GEN(OPR,0,13); /判断运算是否大于 CX2=CX; GEN(JPC,0,0); /CX2记录当前代码段,用于JPC的跳转地址回填 Temp=TOSYM;else if(SYM=DOWNTOSYM) /DOWNTO 类似 TO,不同处为判断预算选是否小于CX1=CX; GEN(STOModejk,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); GEN(LODModejk,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); GetSym(); EXPRESSION(SymSetUnion(SymSetNew(DOSYM),FSYS),LEV,TX); GEN(OPR,0,11);CX2=CX; GEN(JPC,0,0); Temp=DOWNTOSYM;else Error(19);if(SYM=DOSYM) GetSym(); /做DO后面的else Error(18);STATEMENT(FSYS,LEV,TX); GEN(LODModejk,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); /读取变量的值,放入栈顶 GEN(LIT,0,1); /步长为1 switch(Temp) case DOWNTOSYM: GEN(OPR,0,3); break; /DOWNTOSYM 就减 1 case TOSYM: GEN(OPR,0,2); break; /TOSYM 就加 1 GEN(JMP,0,CX1); /无条件跳转到CX1记录的地址段CODECX2.A=CX; /回填JPC的跳转地址 / if(SYM)else Error(97); break; TEST(FSYS,SymSetNULL(),19);四、测试用例:1. E1.plo测试+& PROGRAM E1;VAR A;BEGIN READ(A); A+; WRITE(A); A-; WRITE(A);END.运行0 JMP 0 1 1 INI 0 4 2 OPR 0 16 3 STO 0 3 4 LOD 0 3 5 LIT 0 1 6 OPR 0 2 7 STO 0 3 8 LOD 0 3 9 OPR 0 14 10 OPR 0 15 11 LOD 0 3 12 LIT 0 1 13 OPR 0 3 14 STO 0 3 15 LOD 0 3 16 OPR 0 14 17 OPR 0 15 18 OPR 0 0 RUN PL0 ? 565 END PL0 2. E2.plo测试不等号 PROGRAM E2;VAR A,B;BEGIN A:=50; READ(B); IF AB THEN WRITE(A); ELSE WRITE(B);END.运行0 JMP 0 1 1 INI 0 5 2 LIT 0 50 3 STO 0 3 4 OPR 0 16 5 STO 0 4 6 LOD 0 3 7 LOD 0 4 8 OPR 0 9 9 JPC 0 14 10 LOD 0 3 11 OPR 0 14 12 OPR 0 15 13 JMP 0 17 14 LOD 0 4 15 OPR 0 14 16 OPR 0 15 17 OPR 0 0 RUN PL0 ? 750 END PL0 3. E3.plo测试+=& PROGRAM E3;VAR A;BEGIN READ(A); A+=3; WRITE(A); A-=1; WRITE(A);END.运行0 JMP 0 1 1 INI 0 4 2 OPR 0 16 3 STO 0 3 4 LOD 0 3 5 LIT 0 3 6 OPR 0 2 7 STO 0 3 8 LOD 0 3 9 OPR 0 14 10 OPR 0 15 11 LOD 0 3 12 LIT 0 1 13 OPR 0 3 14 STO 0 3 15 LOD 0 3 16 OPR 0 14 17 OPR 0 15 18 OPR 0 0 RUN PL0 ? 81110 END PL0 4. E4.plo测试for PROGRAM E4
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- FPGAVerilog试题西安电子科技大学
- 保险经纪人资格考试冲刺押题试卷及答案解析
- 2025高级经济师真题及答案
- 3月《证券投资基金》考试试题
- 会计实务财税知识竞赛试题及答案
- 四川省专升本计算机基础模拟题21
- 2025年临床医学检验技术师考试真题卷历年真题
- 2025考研中山大学管理学院真题解析卷
- 中级银行从业资格之中级个人理财基础试题库和答案要点
- 2025年复旦大学自主招生试题解析
- 2025年社区工作者考试题库(各地真题)附答案
- 【《研发管理的定义和理论基础概述》2800字】
- 地下室防水工程质量监理细则
- 2025亚洲五国纺织制造业市场需求和供给分析及发展策略规划分析研究报告
- 2026年黑龙江交通职业技术学院单招职业倾向性测试题库及答案1套
- 2026年lng加气站建设项目可行性研究报告
- 2025河南省农业信贷担保有限责任公司秋季专场招聘28人考试笔试参考题库附答案解析
- 电机轴的生产流程
- 湖南省长沙市一中教育集团2025-2026学年上学期八年级期中考试数学试卷
- 十二指肠溃疡科普
- 2025年10月北京门头沟区龙泉镇流动人口协管员招聘2人笔试考试参考试题及答案解析
评论
0/150
提交评论