PL0编译原理课程设计(3109006080何路生_第1页
PL0编译原理课程设计(3109006080何路生_第2页
PL0编译原理课程设计(3109006080何路生_第3页
PL0编译原理课程设计(3109006080何路生_第4页
PL0编译原理课程设计(3109006080何路生_第5页
已阅读5页,还剩20页未读 继续免费阅读

下载本文档

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

文档简介

1、课 程 设 计 课程名称_ 编译原理_ _题目名称_编译原理课程设计_ _学生学院_ 计算机学院_专业班级_ 09级计科5班 _学 号 学生姓名_ 何路生_指导教师_张巍_2011 年 12 月29 日1 课程设计目的在分析理解一个教学型编译程序(如PL/0)的基础上,对其词法分析程序、语法分析程序和语义处理程序进行部分修改扩充。达到进一步了解程序编译过程的基本原理和基本实现方法的目的。2 课程设计要求课内实验:对PL/0作以下修改扩充:(1)增加单词:保留字 ELSE,FOR,STEP,UNTIL,RETURN运算符 +=,-=,+,-,(2)修改单词:不等号# 改为 (3)增加条件语句的E

2、LSE子句,要求:写出相关文法,语法图,语义规则。课程设计:基本内容(成绩范围:“中”、“及格”或“不及格”)(1)扩充赋值运算:+= 和 -=(2)扩充语句(Pascal的FOR语句):FOR := STEP UNTIL DO (3)增加运算:+ 和 -。选做内容(成绩评定范围扩大到:“优”和“良”)(1)增加类型: 字符类型; 实数类型。(2)扩充函数: 有返回值和返回语句; 有参数函数。(3)增加一维数组类型(可增加指令)。(4)其他典型语言设施。3 课程设计环境与工具(1)计算机及操作系统:PC机,Windows7(2)实现工具:C+Builder6(3)教学型编译程序:PL/0 4

3、结构设计说明a) PL/0编译程序的结构图Pl0 源 程 序词法分析程序语法分析程序代码生产程序目 标 程 序表 格 管 理 程 序出 错 处 理 程 序b) PL/0编译程序的过程或函数的功能表1、void Error(int n) :错误处理,打印出错位置和错误编码2、void GetCh():漏掉空格,读取一个字符3、void GetSym():词法分析,读取一个单词4、void GEN(FCT X, int Y, int Z):生成目标代码,并送入目标程序区5、void TEST(SYMSET S1, SYMSET S2, int N):测试当前单词符号是否合法6、void ENTER

4、(OBJECTS K, int LEV, int &TX, int &DX):登录名字表7、int POSITION(ALFA ID, int TX):查找标识符在名字表中的位置8、void ConstDeclaration(int LEV,int &TX,int &DX):常量说明处理9、void VarDeclaration(int LEV,int &TX,int &DX):变量说明处理10、void CharDeclaration(int LEV,int &TX,int &DX):字符说明处理11、void RealDeclaration(int LEV,int &TX,int &DX)

5、:实数说明处理12、void ListCode(int CX0):列出目标代码清单13、void FACTOR(SYMSET FSYS, int LEV, int &TX) :因子处理14、void TERM(SYMSET FSYS, int LEV, int &TX) :项处理15、void EXPRESSION(SYMSET FSYS, int LEV, int &TX):表达式处理16、void CONDITION(SYMSET FSYS,int LEV,int &TX) :条件处理17、void STATEMENT(SYMSET FSYS,int LEV,int &TX) :语句部分处

6、理18、void Block(int LEV, int TX, SYMSET FSYS) :分程序分析处理过程19、int BASE(int L,int B,int S):通过静态链求出数据区的基地址20、void Interpret() :对目标代码的解释执行程序21、void _fastcall TForm1:ButtonRunClick(TObject *Sender):进行编译,RUNc) PL/0编译程序的总体流程图启动置初值调用getsym取单词调用block过程是否为源程序结束符源程序是否有错误调用解释过程interpret解释执行目标执行目标程序结束出错打印错误NNYYd) 词

7、法分析词法分析是编译的第一个阶段,它的主要任务是从左向右逐个字符地对源程序进行扫描,产生一个个单词序列用于语法分析。PL/0词法分析程序GETSYM的功能是为语法分析提供单词用的,是语法分析的基础,把输入的字符串形式的源程序分割成一个个单词符号。经过词法分析程序分析出来的单词,对语言固有的单词只给出类别存放在全程变量SYM中,而对用户定义的单词(标识符或常数)既给出类别又给值,其类别放在SYM中,值放在全程变量ID或全程变量NUM中,全部单词种类由编译程序定义的纯量类型SYMBOL给出,称为语法词汇表。词法分析程序GETSYM将完成下列任务:(1)滤空格 (2)识别保留字 (3)识别标识符(4

8、)拼数 (5)拼复合词 (6)输出源程序e) 语法分析PL/0编译程序的语法分析采用了自顶向下的递归的子程序法。语法分析同时也根据程序的语义生成相应三元代码,并提供了出错处理的机制。语法分析主要由分程序分析过程(BLOCK)、常量定义分析过程(ConstDeclaration)、变量定义分析过程(Vardeclaration)、语句分析过程(Statement)、表达式处理过程(Expression)、项处理过程(Term)、因子处理过程(Factor)和条件处理过程(Condition)构成。这些过程在结构上构成一个嵌套的层次结构。f) 语义分析PL/0 的语义分析主要进行以下检查:(1)

9、是否存在标识符先引用未声明的情况;(2) 是否存在己声明的标识符的错误引用;(3) 是否存在一般标识符的多重声明。g) 中间代码生成h) 语法错误处理PL/0编译程序对语法错误的处理采用两种办法:(1)对于一些易于校正的错误,如丢了逗号、分号等,指出出错的位置,加以校正,继续进行分析。 (2)对于难于校正的错误,给出错误的位置与性质,跳过后面一些单词,直到下一个可以进行正常语法分析的语法单位。错误类型如下0 过程开始部分说明不正确1 常数说明中=写成:=2 常数说明中=后应为整数或实数或字符3 常数说明中的标识符后应是=4 const, var, procedure后应为标识符5 漏掉了,或;

10、6 过程说明后的符号不正确(应该是语句开始符,或过程定义符)7 应是语句开始符8 程序体内语句部分的后跟符不正确9 程序结尾丢了句号.10 语句间漏了;11 标识符未说明12 赋值语句中,赋值号左部标识符属性应是变量13 变量后不能是此符号14 call后应为标识符15 call后标识符属性应为过程16 条件语句中丢了then17 丢了end或;18 while型循环语句丢了do19 语句后的符号不正确20 应为关系运算符21 表达式内标识符属性不能是过程22 表达式中漏掉右括号(23 因子后的非法符号24 表达式的开始符不能是此符号31 数越界5 设计过程(一) 课内实验内容(1)增加单词:

11、保留字 ELSE(ELSESYM),FOR(FORSYM),STEP(STEPSYM),UNTIL(UNTILSYM),RETURN(SYM)运算符 +=(ADDEQUALSYM),-=(MINUSEQUALSYM),+(INCSYM),-(DECSYM),(ANDSYM),(ORSYM),(NOTSYM)typedef enum NUL, IDENT, NUMBER, PLUS, MINUS, TIMES, SLASH, ODDSYM, EQL, NEQ, LSS, LEQ, GTR, GEQ, LPAREN, RPAREN, COMMA, SEMICOLON, PERIOD, BECOME

12、S, BEGINSYM, ENDSYM, IFSYM, THENSYM, WHILESYM, WRITESYM, READSYM, DOSYM, CALLSYM, CONSTSYM, VARSYM, PROCSYM, PROGSYM , ELSESYM , FORSYM,STEPSYM,UNTILSYM,RETURNSYM , ANDSYM,ORSYM,NOTSYM,LESSTHAN,MORETHAN, ADDEQUALSYM,MINUSEQUALSYM,INCSYM,DECSYM,CHARSYM,INTSYM,REALSYM,OFSYM SYMBOL; /51char *SYMOUT = N

13、UL, 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,STEPSYM,UNTILSYM,RETURNSYM, ANDSYM

14、,ORSYM,NOTSYM,LESSTHAN,MORETHAN ADDEQUAL,MINUSEQUAL,INC,DEC,CHARSYM,INTSYM,REALSYM,OFSYM;其中黑斜体为新加入的SYMBOL。再将上述黑斜体关键字加到KWORD和将相应的SYM加到WSYM,按字母顺序排列void _fastcall TForm1:ButtonRunClick(TObject *Sender) for (CH= ; CH=; CH+) SSYMCH=NUL; strcpy(KWORD 1,ADDEQUAL);strcpy(KWORD 2,BEGIN); strcpy(KWORD 3,CALL)

15、;strcpy(KWORD4,CHAR); strcpy(KWORD5,CONST);strcpy(KWORD6,DEC); strcpy(KWORD 7,DO); strcpy(KWORD 8,ELSE); strcpy(KWORD 9,END);strcpy(KWORD 10,FOR); strcpy(KWORD 11,IF);strcpy(KWORD 12,INC); strcpy(KWORD13,INT);strcpy(KWORD 14,MINUSEQUAL); strcpy(KWORD 15,ODD); strcpy(KWORD 16,PROCEDURE); strcpy(KWORD

16、 17,PROGRAM); strcpy(KWORD18,READ); strcpy(KWORD19,REAL);strcpy(KWORD 20,RETURN); strcpy(KWORD 21,STEP);strcpy(KWORD22,THEN); strcpy(KWORD23,UNTIL);strcpy(KWORD24,VAR); strcpy(KWORD25,WHILE);strcpy(KWORD26,WRITE); /添加了 保留字 ELSE,FOR,STEP,UNTIL,RETURN ,CHAR ,INT , REAL WSYM 1=ADDEQUALSYM;WSYM 2=BEGINS

17、YM; WSYM 3=CALLSYM;WSYM 4=CHARSYM;WSYM 5=CONSTSYM; WSYM 6=DECSYM;WSYM 7=DOSYM; WSYM 8=ELSESYM; WSYM 9=ENDSYM; WSYM 10=FORSYM; WSYM11=IFSYM; WSYM 12=INCSYM;WSYM 13=INTSYM;WSYM 14=MINUSEQUALSYM; WSYM 15=ODDSYM; WSYM 16=PROCSYM; WSYM 17=PROGSYM; WSYM18=READSYM;WSYM19=REALSYM; WSYM 20=RETURNSYM; WSYM21=

18、STEPSYM; WSYM22=THENSYM; WSYM 23=UNTILSYM; WSYM24=VARSYM; WSYM25=WHILESYM; WSYM26=WRITESYM; SSYM+=PLUS; SSYM-=MINUS; SSYM*=TIMES; SSYM/=SLASH; SSYM(=LPAREN; SSYM)=RPAREN; SSYM=EQL; SSYM,=COMMA; SSYM.=PERIOD; SSYM#=NEQ; SSYM;=SEMICOLON; SSYM=MORETHAN;SSYM&=ANDSYM; SSYM|=ORSYM;SSYM!=NOTSYM;(二) 课程设计内容1

19、. 增加运算符+=,-=,+,-a) 词法分析 在GetSym()中完成INC(+ +)、DEC(- -)、ADDEQUAL(=)、MINUSEQUAL(- =)的词法分析,代码修改如下:/-GetSym()增加功能- else if(CH = +) GetCh(); if(CH = =) /增加+= SYM = ADDEQUALSYM; GetCh(); else if(CH = +) /增加+ SYM = INCSYM; GetCh(); else SYM = PLUS; else if(CH = -) GetCh(); if(CH = =) /增加-= SYM = MINUSEQUALS

20、YM; GetCh(); else if(CH = -) /增加- SYM = DECSYM; GetCh(); else SYM = MINUS; else SYM=SSYMCH; GetCh(); b) 后+ +和后- -的实现根据以上语法图,我们只要对语句处理程序和因子处理程序进行修改添加,即可实现增加 后INC 和 后DEC 操作,首先对语句处理程序STATEMENT进行如下修改:根据以上语法图,我们只要对语句处理程序和因子处理程序进行修改添加,即可实现增加 后INC 和 后DEC 操作,首先对语句处理程序STATEMENT进行如下修改:根据以上语法图,我们只要对语句处理程序和因子处理

21、程序进行修改添加,即可实现增加 后INC 和 后DEC 操作,首先对语句处理程序STATEMENT进行如下修改:/-后的+ -case IDENT:. else if (SYM=INCSYM) /语句中的+运算 if (i!=0) GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); GEN(LIT,0,1); GEN(OPR,0,2); if (i!=0) GEN(STO,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); GetSym(); else if (SYM=DECSYM) /语句中的-运算 if (i!=0) GEN(LOD,

22、LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); GEN (LIT,0,1); GEN (OPR,0,3); if (i!=0) GEN(STO,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); GetSym (); break;在接受到SYM=IDENT后,如果SYM为INC,则主要执行这四条指令:GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR) 将IDENT的值放到栈顶,GEN(LIT,0,1); 将常数1放到栈顶,GEN(OPR,0,2) 次栈顶加栈顶,GEN(STO,LEV-TABLEi.vp.LEVEL,

23、TABLEi.vp.ADR);将栈顶内容保存到IDENT中。这样就完成了语句中的+运算。如果SYM为DEC,则主要执行这四条指令:GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR) 将IDENT的值放到栈顶,GEN(LIT,0,1); 将常数1放到栈顶,GEN(OPR,0,3) 次栈顶减栈顶,GEN(STO,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR);将栈顶内容保存到IDENT中。这样就完成了语句中的-运算。其次,再对因子处理程序FACTOR修改如下:if(SYM=INCSYM|SYM=DECSYM) /因子中的+和-运算 count

24、.length+; count.idcount.length=i; GEN(LIT,0,1); if(SYM=INCSYM) GEN(OPR,0,2);count.icount.length=1; GEN(STO,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR);/将栈顶送入变量单元 GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); /将变量送入栈顶 GEN(LIT,0,-1); GEN(OPR,0,2); /如果为INC,则加1 else GEN(OPR,0,3);count.icount.length=-1; GEN(STO,LEV

25、-TABLEi.vp.LEVEL,TABLEi.vp.ADR);/将栈顶送入变量单元 GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); /将变量送入栈顶 GEN(LIT,0,1);GEN(OPR,0,2); /否则减一对后+和后的处理思想是,在表达式中不进行自加/自减操作,但在送往变量的时候进行c) 前+和前-的实现语法树:语句+indentindent根据以上语法图,我们只要对语句处理程序和因子处理程序进行修改添加,即可实现增加 前INC 和 前DEC 操作,首先对语句处理程序STATEMENT进行如下修改:/- 前的+- case INCSYM: /前

26、+ GetSym(); if (SYM = IDENT) i=POSITION(ID,TX); if (i=0) Error(11); else if (TABLEi.KIND!=VARIABLE) /*ASSIGNMENT TO NON-VARIABLE*/ Error(12); i=0; if (i!=0) GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); GEN(LIT,0,1); GEN(OPR,0,2); if (i!=0) GEN(STO,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); GetSym(); else Er

27、ror(45); break; case DECSYM: /前- GetSym(); if (SYM = IDENT) i=POSITION(ID,TX); if (i=0) Error(11); else if (TABLEi.KIND!=VARIABLE) /*ASSIGNMENT TO NON-VARIABLE*/ Error(12); i=0; if (i!=0) GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); GEN (LIT,0,1); GEN (OPR,0,3); if (i!=0) GEN(STO,LEV-TABLEi.vp.LEVEL,

28、TABLEi.vp.ADR); GetSym (); else Error(45); break;再对因子处理,对于前+、前-,只在EXPRESSION中处理,因子部分只处理后+、后操作因子+indentindentelse if(SYM = INCSYM) /前+ GetSym(); if (SYM = IDENT) i=POSITION(ID,TX); if (i=0) Error(11); else if (TABLEi.KIND!=VARIABLE) /*ASSIGNMENT TO NON-VARIABLE*/ Error(12); i=0; if (i!=0) GEN(LOD,LEV

29、-TABLEi.vp.LEVEL,TABLEi.vp.ADR); GEN(LIT,0,1); GEN(OPR,0,2); if (i!=0) GEN(STO,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); /将栈顶送入变量单元 GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); /将变量送入栈顶 GetSym(); else Error(45); else if(SYM = DECSYM) /前- GetSym(); if (SYM = IDENT) i=POSITION(ID,TX); if (i=0) Error(11); els

30、e if (TABLEi.KIND!=VARIABLE) /*ASSIGNMENT TO NON-VARIABLE*/ Error(12); i=0; if (i!=0) GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); GEN (LIT,0,1); GEN (OPR,0,3); if (i!=0) GEN(STO,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); /将栈顶送入变量单元 GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); /将变量送入栈顶 GetSym (); else Error(

31、45); d) 扩充+=和-=操作语法树:根据图3,在语句处理STATEMENT中,在已经处理INC和DEC的基础上,添加对ADDEQUAL(+=)运算和MINUSEQUAL(-=)运算的扩充,相关代码添加如下:case IDENT:else if (SYM=ADDEQUALSYM) /增加运算符+= if (i!=0) GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); GetSym(); EXPRESSION(FSYS,LEV,TX); GEN(OPR,0,2); if (i!=0) GEN(STO,LEV-TABLEi.vp.LEVEL,TABLEi.

32、vp.ADR); else if (SYM=MINUSEQUALSYM) /增加运算符-= if (i!=0) GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); GetSym(); EXPRESSION(FSYS,LEV,TX); GEN(OPR,0,3); if (i!=0) GEN(STO,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); break;2. 增加Pascal的FOR语句:表达式UNTIL表达式STEPE表达式:=ident/-添加FOR功能 case FORSYM: GetSym(); if(SYM != IDEN

33、T) Error(47); else i=POSITION(ID,TX);if(i = 0) Error(11);else if (TABLEi.KIND!=VARIABLE) /*ASSIGNMENT TO NON-VARIABLE*/Error(12); i=0; GetSym(); if(SYM = BECOMES) GetSym();else Error(13); EXPRESSION(SymSetUnion(SymSetNew(STEPSYM),FSYS),LEV,TX);if(i != 0) GEN(STO,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); /

34、把栈顶的值送到变量 / GetSym(); if(SYM=STEPSYM) GetSym(); else Error(46); CX1=CX;GEN(JMP,0,0); CX3=CX; EXPRESSION(SymSetUnion(SymSetNew(UNTILSYM),FSYS),LEV,TX); GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); /将变量送回栈顶 GEN(OPR,0,2); GEN(STO,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR);/把栈顶的值送到变量 / GetSym(); if(SYM=UNTILSYM)

35、 GetSym(); else Error(47); CODECX1.A=CX; EXPRESSION(SymSetUnion(SymSetNew(DOSYM),FSYS),LEV,TX); /终止条件 GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); /将变量送回栈顶 GEN(OPR,0,11); CX2=CX;GEN(JPC,0,0); / GetSym(); if(SYM=DOSYM) GetSym(); else Error(48); STATEMENT(FSYS,LEV,TX); GEN(JMP,0,CX3); CODECX2.A=CX;FOR语

36、句扩充完毕。3.增加类型:字符类型 和 实数类型typedef enum CHARCON, INTCON, REALCON, NOTYP TYPES; /类型TYPES TY; /记录类型struct ALFA NAME; OBJECTS KIND; TYPES TYPE; /增加类型 union float VAL; /*CONSTANT*/ /统一用浮点型记录 struct int LEVEL,ADR,SIZE; vp; /*VARIABLE,PROCEDUR: 层次、地址、存储空间*/ ; TABLETXMAX;在SYMBOL中加入REALSYM, INTSYM, CHARSYM, OF

37、SYM对应的SYMMAX=52;NORW=26;增加实数和字符词法分析else /-加入浮点数读入 if (CH=0 & CH=0 & CH=0 & CHNMAX) Error(30); else/-加入字符类型 只接受 a 里面的一个字母 if(int)CH=39) SYM = CONSTSYM; GetCh(); if(CH=A & CH=a & CHprintcs(char)ST); fprintf(FOUT,%cn,(char)ST); T-; break; case 15: /整数输出 Form1-printls(,ST); fprintf(FOUT,%dn,(int)ST); T-; break; case 16: /实数输出 Form1-printrs(,ST); fprintf(FOUT,%.4fn,ST); T-; break; case 17: break; case 18: /输入字符 T+; ST=InputBox(输入,请输入一个字符:, 0).ToDoubl

温馨提示

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

评论

0/150

提交评论