编译原理PL课程设计报告_第1页
编译原理PL课程设计报告_第2页
编译原理PL课程设计报告_第3页
编译原理PL课程设计报告_第4页
编译原理PL课程设计报告_第5页
已阅读5页,还剩15页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、课程设计班级:21301学号:姓名:马瑞泽百度一. 课程设计目的在分析理解一个教学型编译程序(如PL/0)的基础上,对其词法分析程序、 语法分析程序和语义处理程序进行部分修改扩充。达到进一步了解程序编译过 程的基本原理和基本实现方法的目的。二. 课程设计要求1. 基本内容(1) 扩充赋值运算:+=和-=(2) 扩充语句(Pascal的FOF语句): FOR变量:= 表达式TO表达式DO语句 FOR变量:= 表达式DOWNT表达式DO语句 其中,语句的循环变量的步长为 2,语句的循环变量的步长为-2。2. 选做内容(1) 增加运算:+和 -。(2) 增加类型:字符类型;实数类型。(3) 扩充函数

2、:有返回值和返回语句;有参数函数。(4) 增加一维数组类型(可增加指令)。(5) 其他典型语言设施。3. 本人在课程设计中已实现的功能(1)增加单词:保留字 ELSE FOR TQ DOWNTO,REPEAT,UNTIL,RETURN 运算符 +=, -= , +,-(2) 修改单词:不等号#改为(3) 增加条件语句的ELSE子句(4) 扩充赋值运算:+=和 -=(5) 扩充语句FOR变量:= 表达式T0表达式D0语句FOR变量 :=表达式DOWNT表达式D0语句(6) 增加运算:+和-(包括前后+、-运算)(7) 增加一维数组类型(8) 其他典型语言设施:REPEATS句UNTIL语句三.

3、课程设计环境与工具(1) 计算机及操作系统:PC机,Win7(2) 实现工具:VC+,C语言(3) 教学型编译程序:PL/0四. 结构设计说明1) PL/0编译程序的结构图2) PL/0编译程序的过程或函数的功能表过程或函数名简要功能说明pio主程序error出错处理,打印出错位置和错误编码getsym词法分析,读取一个单词getch漏掉空格,读取一个字符gen生成目标代码,并送入目标程序区test测试当前单词符号是否合法block分程序分析处理过程en ter登录名字表positi on(函数)查找标识符在名字表中的位置con stdeclarati on常量定义处理vardeclarati

4、 on变量说明处理listode列出目标代码清单stateme nt语句处理expressi on表达式处理term项处理factor因子处理con diti on条件处理in terpret对目标代码的解释执行程序base(函数)通过静态链求出数据区的基地址3) PL/0编译程序的总体流程图启动置初值4)词法分析词法分析是编译的第一个阶段,它的主要任务是从左向右逐个字符地对源程 序进行扫描,产生一个个单词序列用于语法分析。PL/O词法分析程序GETSY的 功能是为语法分析提供单词用的,是语法分析的基础,把输入的字符串形式的源 程序分割成一个个单词符号。经过词法分析程序分析出来的单词, 对语言

5、固有的 单词只给出类别存放在全程变量 SY附,而对用户定义的单词(标识符或常数) 既给出类别又给值,其类别放在SYM中,值放在全程变量ID或全程变量NUM中, 全部单词种类由编译程序定义的纯量类型 SYMBO给出,称为语法词汇表。词法分析器的分析过程:调用 GETSY时,它通过GETC过程从源程序中获得一个字符。如果这个字符是字母,则继续获取字符或数字,最终可以拼成一个单词,查保留字表,如果查到为保留字,则把SYM变量赋成相应的保留字类型值; 如果没有查到,则这个单词应是一个用户自定义的标识符 (可能是变量名、常量 名或是过程的名字),把 SYM置为IDENT,把这个单词存入ID变量。查保留字

6、 表时使用了二分法查找以提高效率。如果释Gefch获得的字符是数字,则继续用 并把它们标拼成标个整数或实数,然后把 NUM变量。如果识别出其它合法的符号、小于等于号等),则把 Sym则成相应的类型。如果遇到不合法的字符,把Getch获取数字, 把拼成的数值放入SYMS为 INTEGER 并 号(比如:赋值号、大于SYM置成NUL词法分析程序GETSYI将完成下列任务:(1)滤空格(2)识别保留字(3)识别标识符(4)拼数(5)拼复合词(6)输出源程序5)语法分析PL/O编译程序的语法分析采用了自顶向下的递归的子程 序法。语法分析同时也根据程序的语义生成相应三元代码, 并提供了出错处理的机制。语

7、法分析主要由分程序分析过程(BLOCK、常量定义分析过程(ConstDeclaration )、变量 定义分析过程(Vardeclaration )、语句分析过程(Statement)、表达式处理过程(Expression )、项处理过 程(Term)、因子处理过程(Factor )和条件处理过程(Condition )构成。这些过程在结构上构成一个嵌套的层次 结构。除此之外,还有出错报告过程(Error )、代码生成过 程(Ger)、测试单词合法性及出错恢复过程(Test)、登录 名字表过程(Enter)、查询名字表函数(Position )以及列 出类PCOD代码过程(Listcode )

8、作过语法分析的辅助过程。由PL/0的语法图可知:一个完整的 PL/0程序是由分程 序和句号构成的。因此,本编译程序在运行的时候,通过主 程序中调用分程序处理过程block来分析分程序部分(分程 序分析过程中还可能会递归调用block过程),然后,判断最后读入的符号是否为句号。如果是句号且分程序分析中未 出错,则是一个合法的PL/0程序,可以运行生成的代码,否 则就说明源PL/0程序是不合法的,输出出错提示即可。PL/0语法调用关系图6)语义分析PL/O的语义分析主要进行以下检查:(1)是否存在标识符先引用未声明的情况;(2)是否存在己声明的标识符的错误引用;(3)是否存在一般标识符的多重声明。

9、7) 中间代码生成目标代码类自己添加覆盖了pcode 是一种假想栈式计算机的汇编语言OPRO14栈顶值输出至屏幕(字符型)OPRO15栈顶值输出至屏幕(整数型)OPRO16栈顶值输出至屏幕(实数型)OPRO17屏幕输出换行OPRO18从命令行读入一个字符输入置于栈顶OPRO19从命令行读入一个整数输入置于栈顶OPRO2O从命令行读入一个实数输入置于栈顶8) 语法错误处理PL/O 编译程序对语法错误的处理采用两种办法:(1)对于一些易于校正的错误,如丢了逗号、分号等,指出出错的位置, 加以校正,继续进行分析。(2)对于难于校正的错误,给出错误的位置与性质,跳过后面一些单词, 直到下一个可以进行正

10、常语法分析的语法单位。错误类型如下O 过程开始部分说明不正确1 常数说明中 "=" 写成 ":="2 常数说明中 "=" 后应为整数或实数或字符3 常数说明中的标识符后应是 "="4const,var,procedure 后应为标识符5 漏掉了 "," 或 ""6过程说明后的符号不正确 (应该是语句开始符 ,或过程定义符 )7 应是语句开始符8 程序体内语句部分的后跟符不正确9 程序结尾丢了句号 "."10 语句间漏了 ""11 标识符

11、未说明12赋值语句中 ,赋值号左部标识符属性应是变量13 变量后不能是此符号14call 后应为标识符15call 后标识符属性应为过程16 条件语句中丢了 "then"17 丢了 "end"或""18while 型循环语句丢了 "do"19 语句后的符号不正确20 应为关系运算符21 表达式内标识符属性不能是过程22 表达式中漏掉右括号 "("23因子后的非法符号24表达式的开始符不能是此符号31数越界 补充说明了:32read 或 write33read 或 write34read 或 wr

12、ite35read 或 write语句括号中的标识符不是变量语句缺少右括号")"语句缺少左括号"("括号里应为变量自己增加了:45+或-后面应为变量46repeat 缺少 until47for语句错误48for语句缺少do49类型值不匹配50类型无法转换51只有整数能+或 -52类型不正确五. 设计过程(一)实验内容1.增加单词:保留字 ELSE , FOR,TO,DOWNTO,REPEAT , UNTIL , RETURN运算符 +=(PLUSBK),-=(MINUSBK),+(INC),-(DEC)首先要扩展 SYMBOL ,在此基础上再进行其它细节

13、的修改。要添加的 SYMBOL 为:typedefenumNUL,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, ELSESYM, FORSYM,TOSYM,DOWNTOSYM,REPEATSYM,UNTILS

14、YM,RETURNSYM,PLUSBK,MINUSBK,INC,DEC SYMBOL;char*SYMOUT="NUL","IDENT","NUMBER","PLUS","MINUS","TIMES", "SLASH","ODDSYM","EQL","NEQ","LSS","LEQ","GTR","GEQ", &quo

15、t;LPAREN","RPAREN","COMMA","SEMICOLON","PERIOD", "BECOMES","BEGINSYM","ENDSYM","IFSYM","THENSYM", "WHILESYM","WRITESYM","READSYM","DOSYM","CALLSYM", "

16、CONSTSYM","VARSYM","PROCSYM","PROGSYM", "ELSE","FOR", "TO","DOWNTO","REPEAT","UNTIL","RETU RN","PLUSBK","MINUSBK","INC ” "DEC" ; 其中黑斜体为新加入的 SYMBOL 。NEQ再将 "

17、ELSE","FOR" ,"TO" ,"DOWNTO" , "REPEAT","UNTIL","RETURN","PLUSBK","MINUSBK","INC", "DEC" 关键字加到 KWORD 和将相应的 SYM 加到 WSYM ,按字母顺序排列。以及修改 后如下 void_fastcallTForm1:ButtonRunClick(TObject*Sender)for(CH=&q

18、uot;CH<='A'CH+)SSYMCH=NUL; strcpy(KWORD1,"BEGIN");strcpy(KWORD2,"CALL"); strcpy(KWORD3,"CONST");strcpy(KWORD4,"DEC"); strcpy(KWORD5,"DO");strcpy(KWORD6,"DOWHILE"); strcpy(KWORD7,"DOWNTO");strcpy(KWORD8,"ELSE")

19、;strcpy(KWORD9,"END");strcpy(KWORD10,"FOR"); strcpy(KWORD11,"IF");strcpy(KWORD12,"INC"); strcpy(KWORD13,"MINUSBK");strcpy(KWORD14,"ODD"); strcpy(KWORD15,"PLUSBK");strcpy(KWORD16,"PROCEDURE"); strcpy(KWORD17,"PROGRAM

20、");strcpy(KWORD18,"READ"); strcpy(KWORD19,"REPEAT");strcpy(KWORD20,"RETURN"); strcpy(KWORD21,"THEN");strcpy(KWORD22,"TO"); strcpy(KWORD23,"VAR");strcpy(KWORD24,"UNTIL");strcpy(KWORD25,"WHILE");strcpy(KWORD26,"W

21、RITE"); WSYM1=BEGINSYM;WSYM2=CALLSYM;WSYM3=CONSTSYM;WSYM4=DEC; WSYM5=DOSYM;WSYM6=DOWHILESYM;WSYM7=DOWNTOSYMs;WSYM8=ELSESYM;WSYM9=ENDSYM;WSYM10=FORSYM; WSYM11=IFSYM;WSYM12=INCSYM; WSYM13=MINUSBK;WSYM14=ODDSYM; WSYM15=PLUSBK;WSYM16=PROCSYM;WSYM17=PROGSYM;WSYM18=READSYM;WSYM19=REPEATSYM;WSYM20=RET

22、URNSYM;WSYM21=THENSYM;WSYM22=TOSYM;WSYM23=VARSYM;WSYM24=UNTILSYM;WSYM25=WHILESYM;WSYM26=WRITESYM;SSYM'+'=PLUS;SSYM'-'=MINUS;SSYM'*'=TIMES;SSYM'/'=SLASH;SSYM'('=LPAREN;SSYM')'=RPAREN;SSYM'='=EQL;SSYM','=COMMA;SSYM'.'=PERIOD;SSYM&

23、#39;'=SEMICOLON;因为关键字增加到了26个,所以令constNORW=26;SYMBO由原来的33个值扩展为目前的44个值,SYMOU也由原来的33个元素扩展为目前的 44个元素.我用个SYMMA来记录SYMBO值的个数,所以,除了Error函数中可能岀现的作为参数的“3 3”不被替换为“4 4”外,其余的“3 3”均用“ SYMMA”来替换。SYMBOL扩展完毕。2修改单词:不等号#改为<>只要修改GetSym ()函数。当编译器检测到当前字符为“”时,接着检测下一个字符,如果是“”,则使 SYM=NEQ代码修改如下:if(CH='v')Ge

24、tCh();if(CH='=')SYM=LEQ;GetCh();elseif(CH='>')SYM=NEQ;GetCh();加条件语句的 ELSE 子句该条件语法描述图如下:语句只要在STATEMENT修改如下代码:caseIFSYM:GetSym();CONDITION(SymSetUnion(SymSetNew (T HENSYM,DOSYM),FSYS) ,L EV,TX); if(SYM=THENSYM)GetSym();elseError(16);CX1=CX;GEN(JPC,0,0);STATEMENT(SymSetUnion(SymSetNe

25、w(ELSESYM),FSYS),LEV,TX);if(SYM!=ELSESYM)CODECX1.A=CX;=CX;=CX; 加运算符 += ,-+a) 词法分析1) 在GetSym ()中完成INC ( + + )、 PLUSBK ( + =)的词法分析,代码修改如下: elseif(CH='+')GetCh();if(CH='=')IND!=VARIABLE)/*ASSIGNMENTTONON-VARIABLE*/Error(12);i=0;GetSym();if(SYM=BECOMES)GetSym();EXPRESSION(FSYS,LEV,TX); i

26、f(i!=0)GEN(STO,LEV-TABLEi.,TABLEi.; elseif(SYM=INC)TABLEi.; GEN(LIT,0,1);GEN(OPR,0,2);if(i!=0)GEN(STO,LEV-TABLEi.,TABLEi.; GetSym(); elseif(SYM=DEC)TABLEi.; GEN(LIT,0,1);GEN(OPR,0,3);if(i!=0)GEN(STO,LEV-TABLEi.,TABLEi.; GetSym();在接受到 SYM=IDENT 后,如果 SYM 为 I N C ,则主要执行这四条指令:GEN(LOD,LEV-TABLEi.,TABLEi.

27、 将 IDENT 的值放到栈顶, GEN(LIT,0,1); 将常数 1 放到栈顶,GEN(OPR,0,2) 次栈顶加栈顶,+运GEN(STO,LEV-TABLEi.,TABLEi.; 将栈顶内容保存到 IDENT 中。这样就完成了语句中的 如果 SYM 为 DEC ,则主要执行这四条指令:GEN(LOD,LEV-TABLEi.,TABLEi. 将 IDENT 的值放到栈顶, GEN(LIT,0,1); 将常数 1 放到栈顶,GEN(OPR,0,3) 次栈顶减栈顶,-运GEN(STO,LEV-TABLEi.,TABLEi.; 将栈顶内容保存到 IDENT 中。这样就完成了语句中的 算。其次,再

28、对因子处理程序 FACTOR 修改如下:if(SYM=IDENT)i=POSITION(ID,TX);if(i=0)Error(11);elseswitch(TABLEi.KIND) caseCONSTANT:GEN(LIT,0,TABLEi.VAL);GetSym();break; caseVARIABLE:GEN(LOD,LEV-TABLEi.,TABLEi.;GetSym();if(SYM=INC|SYM=DEC)TABLEi.;TABLEi.;语句IND!=VARIABLE)/*ASSIGNMENTTONON-VARIABLE*/Error(12);i=0;if(i!=0)GEN(LO

29、D,LEV-TABLEi.,TABLEi.;GEN(LIT,0,1);GEN(OPR,0,2);if(i!=0)GEN(STO,LEV-TABLEi.,TABLEi.;GetSym();elseError(45);break;>if(SYM=IDENT)i=POSITION(ID,TX);if(i=0)Error(11);elseif(TABLEi.KIND!=VARIABLE)/*ASSIGNMENTTONON-VARIABLE*/Error(12);i=0;if(i!=0)GEN(LOD,LEV-TABLEi.,TABLEi.;GEN(LIT,0,1);GEN(OPR,0,3);if

30、(i!=0)GEN(STO,LEV-TABLEi.,TABLEi.;GetSym();elseError(45);break;再次,再对因子处理程序FACTOR修改如下:因子elseif(SYM=INC)IND!=VARIABLE)/*ASSIGNMENTTONON-VARIABLE*/Error(12);i=0;if(i!=0)GEN(LOD,LEV-TABLEi.,TABLEi.;GEN(LIT,0,1);GEN(OPR,0,2);if(i!=0)GEN(STO,LEV-TABLEi.,TABLEi.;TABLEi.;IND!=VARIABLE)/*ASSIGNMENTTONON-VARI

31、ABLE*/Error(12);i=0;if(i!=0)GEN(LOD,LEV-TABLEi.,TABLEi.;GEN(LIT,0,1);GEN(OPR,0,3);if(i!=0)GEN(STO,LEV-TABLEi.,TABLEi.;TABLEi.;TABLEi.;GetSym();EXPRESSION(FSYS ,L EV,TX);GEN(OPR,0,2);if(i!=0)GEN(STO,LEV-TABLEi.,TABLEi.;elseif(SYM=MINUSBK)TABLEi.;GetSym();EXPRESSION(FSYS ,L EV,TX);GEN(OPR,0,3);if(i!=0

32、)GEN(STO,LEV-TABLEi.,TABLEi.;这样就完成了对+二运算和二运算的添加。2.增加Pascal的FOR语句:a)格式如下:FOR变量 >:=< 常数>TO(或 DOWNTO常数 >DO <语句>b)添加语句 for 语句的语句语法图如下: 首先 ,词法分析部分增加关键字在 SYMBO里增加 FORSYM,TOSYM,DOWNTQSYM应 SYMMAX=44;NORW=25;初始化中strcpy(KWORD10,"FOR");WSYM10=IFSYM;strcpy(KWORD22,"TO");WSY

33、M22=TOSYM;strcpy(KW0RD7,"D0WNT0"); WSYM7=D0WNT0SYM;其次 ,修改 STATEMENT ,代码如下:if(SYM!=IDENT)Error(47);elsei=POSITION(ID,TX);if(i=0)Error(11); elseif(TABLEi.KIND!=VARIABLE)/*ASSIGNMENTTONON-VARIABLE*/Error(12);i=0;GetSym();if(SYM=BECOMES)GetSym();elseError(13);EXPRESSION(SymSetUnion(SymSetNew(T

34、OSYM,DOWNTOSYM),FSYS),LEV,TX); if(i!=0)GEN(STO,LEV-TABLEi.,TABLEi.;if(SYM=TOSYM)TABLEi.;TABLEi.;GEN(LIT,0,1);GEN(OPR,0,2);GEN(STO,LEV-TABLEi.,TABLEi.;=CX;elseif(SYM=DOWNTOSYM)TABLEi.;GetSym();EXPRESSION(SymSetUnion(SymSetNew(DOSYM),FSYS),LEV,TX);GEN(OPR,0,11);TABLEi.;GEN(LIT,0,1);GEN(OPR,0,3);GEN(ST

35、O,LEV-TABLEi.,TABLEi.;=CX;elseError(47);break; 加一维数组类型首先设置一维数组的左右括号:ssym''=lepa;ind)caseconstant:printf("%dconst%s",i,);printf("val=%dn",tablei.val);fprintf(fas,"%dconst%s",i,);fprintf(fas,"val=%dn",tablei.val);break;casevariable:

36、printf("%dvar%s",i,);printf("lev=%daddr=%dn",tablei.level,tablei.adr);fprintf(fas,"%dvar%s",i,);fprintf(fas,"lev=%daddr=%dn",tablei.level,tablei.adr);break;caseprocedur:printf("%dproc%s",i,); printf("lev=%daddr=%

37、dsize=%dn",tablei.level,tablei.adr,tablei.size); fprintf(fas,"%dproc%s",i,);fprintf(fas,"lev=%dadr=%dsize=%dn",tablei.level,tablei.adr,tablei.size);break;caseprintf("%dvar-array%s",i,);printf("lev=%daddr=%dsize=%dn",tablei.level,tablei.adr,tablei.siz

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论