欢迎来到淘文阁 - 分享文档赚钱的网站! | 帮助中心 好文档才是您的得力助手!
淘文阁 - 分享文档赚钱的网站
全部分类
  • 研究报告>
  • 管理文献>
  • 标准材料>
  • 技术资料>
  • 教育专区>
  • 应用文书>
  • 生活休闲>
  • 考试试题>
  • pptx模板>
  • 工商注册>
  • 期刊短文>
  • 图片设计>
  • ImageVerifierCode 换一换

    PL0编译原理课程设计(3109006080何路生)(共25页).doc

    • 资源ID:14156624       资源大小:1.12MB        全文页数:25页
    • 资源格式: DOC        下载积分:20金币
    快捷下载 游客一键下载
    会员登录下载
    微信登录下载
    三方登录下载: 微信开放平台登录   QQ登录  
    二维码
    微信扫一扫登录
    下载资源需要20金币
    邮箱/手机:
    温馨提示:
    快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。
    如填写123,账号就是123,密码也是123。
    支付方式: 支付宝    微信支付   
    验证码:   换一换

     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    PL0编译原理课程设计(3109006080何路生)(共25页).doc

    精选优质文档-倾情为你奉上课 程 设 计 课程名称_ 编译原理_ _题目名称_编译原理课程设计_ _学生学院_ 计算机学院_专业班级_ 09级计科5班 _学 号 学生姓名_ 何路生_指导教师_张巍_2011 年 12 月29 日一 课程设计目的在分析理解一个教学型编译程序(如PL/0)的基础上,对其词法分析程序、语法分析程序和语义处理程序进行部分修改扩充。达到进一步了解程序编译过程的基本原理和基本实现方法的目的。二 课程设计要求课内实验:对PL/0作以下修改扩充:(1)增加单词:保留字 ELSE,FOR,STEP,UNTIL,RETURN运算符 +=,-=,+,-,(2)修改单词:不等号# 改为 <>(3)增加条件语句的ELSE子句,要求:写出相关文法,语法图,语义规则。课程设计:基本内容(成绩范围:“中”、“及格”或“不及格”)(1)扩充赋值运算:+= 和 -=(2)扩充语句(Pascal的FOR语句):FOR <变量>:=<表达式> STEP <表达式>UNTIL <表达式> DO <语句>(3)增加运算:+ 和 -。选做内容(成绩评定范围扩大到:“优”和“良”)(1)增加类型: 字符类型; 实数类型。(2)扩充函数: 有返回值和返回语句; 有参数函数。(3)增加一维数组类型(可增加指令)。(4)其他典型语言设施。三 课程设计环境与工具(1)计算机及操作系统:PC机,Windows7(2)实现工具:C+Builder6(3)教学型编译程序:PL/0 四 结构设计说明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(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):实数说明处理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) :语句部分处理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) 词法分析词法分析是编译的第一个阶段,它的主要任务是从左向右逐个字符地对源程序进行扫描,产生一个个单词序列用于语法分析。PL/0词法分析程序GETSYM的功能是为语法分析提供单词用的,是语法分析的基础,把输入的字符串形式的源程序分割成一个个单词符号。经过词法分析程序分析出来的单词,对语言固有的单词只给出类别存放在全程变量SYM中,而对用户定义的单词(标识符或常数)既给出类别又给值,其类别放在SYM中,值放在全程变量ID或全程变量NUM中,全部单词种类由编译程序定义的纯量类型SYMBOL给出,称为语法词汇表。词法分析程序GETSYM将完成下列任务:(1)滤空格 (2)识别保留字 (3)识别标识符(4)拼数 (5)拼复合词 (6)输出源程序e) 语法分析PL/0编译程序的语法分析采用了自顶向下的递归的子程序法。语法分析同时也根据程序的语义生成相应三元代码,并提供了出错处理的机制。语法分析主要由分程序分析过程(BLOCK)、常量定义分析过程(ConstDeclaration)、变量定义分析过程(Vardeclaration)、语句分析过程(Statement)、表达式处理过程(Expression)、项处理过程(Term)、因子处理过程(Factor)和条件处理过程(Condition)构成。这些过程在结构上构成一个嵌套的层次结构。f) 语义分析PL/0 的语义分析主要进行以下检查:(1) 是否存在标识符先引用未声明的情况;(2) 是否存在己声明的标识符的错误引用;(3) 是否存在一般标识符的多重声明。g) 中间代码生成h) 语法错误处理PL/0编译程序对语法错误的处理采用两种办法:(1)对于一些易于校正的错误,如丢了逗号、分号等,指出出错的位置,加以校正,继续进行分析。 (2)对于难于校正的错误,给出错误的位置与性质,跳过后面一些单词,直到下一个可以进行正常语法分析的语法单位。错误类型如下0 过程开始部分说明不正确1 常数说明中"="写成":="2 常数说明中"="后应为整数或实数或字符3 常数说明中的标识符后应是"="4 const, var, procedure后应为标识符5 漏掉了","或""6 过程说明后的符号不正确(应该是语句开始符,或过程定义符)7 应是语句开始符8 程序体内语句部分的后跟符不正确9 程序结尾丢了句号"."10 语句间漏了""11 标识符未说明12 赋值语句中,赋值号左部标识符属性应是变量13 变量后不能是此符号14 call后应为标识符15 call后标识符属性应为过程16 条件语句中丢了"then"17 丢了"end"或""18 while型循环语句丢了"do"19 语句后的符号不正确20 应为关系运算符21 表达式内标识符属性不能是过程22 表达式中漏掉右括号"("23 因子后的非法符号24 表达式的开始符不能是此符号31 数越界五 设计过程(一) 课内实验内容(1)增加单词:保留字 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, BECOMES, 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 = "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" , "ELSESYM","FORSYM","STEPSYM","UNTILSYM","RETURNSYM", "ANDSYM","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");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 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=BEGINSYM; 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=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'<'=LESSTHAN; SSYM'>'=MORETHAN;SSYM'&'=ANDSYM; SSYM'|'=ORSYM;SSYM'!'=NOTSYM;(二) 课程设计内容1. 增加运算符+=,-=,+,-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 = MINUSEQUALSYM; GetCh(); else if(CH = '-') /增加- SYM = DECSYM; GetCh(); else SYM = MINUS; else SYM=SSYMCH; GetCh(); b) 后+ +和后- -的实现根据以上语法图,我们只要对语句处理程序和因子处理程序进行修改添加,即可实现增加 后INC 和 后DEC 操作,首先对语句处理程序STATEMENT进行如下修改:根据以上语法图,我们只要对语句处理程序和因子处理程序进行修改添加,即可实现增加 后INC 和 后DEC 操作,首先对语句处理程序STATEMENT进行如下修改:根据以上语法图,我们只要对语句处理程序和因子处理程序进行修改添加,即可实现增加 后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,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,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.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-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: /前+ 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 Error(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,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-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); 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,TABLEi.vp.ADR); /将栈顶送入变量单元 GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); /将变量送入栈顶 GetSym (); else Error(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.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 != IDENT) 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); /把栈顶的值送到变量 / 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) 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); / G

    注意事项

    本文(PL0编译原理课程设计(3109006080何路生)(共25页).doc)为本站会员(飞****2)主动上传,淘文阁 - 分享文档赚钱的网站仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知淘文阁 - 分享文档赚钱的网站(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    关于淘文阁 - 版权申诉 - 用户使用规则 - 积分规则 - 联系我们

    本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

    工信部备案号:黑ICP备15003705号 © 2020-2023 www.taowenge.com 淘文阁 

    收起
    展开