




已阅读5页,还剩14页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
编译原理实验报告课 程 名 称: 编译原理课程设计 考试形式: 实验报告 授课院 (系): 软件学院 交作业日期: 2013 年 7 月 26 日 共 19 页班级: 学号: 姓 名: 联系方式:电子邮件: 手机号码: 上机检查出勤实验报告(二)实验报告(三)总分标准分7010155100得 分一、 上机实验检查(总计70分):(1)分离解释和编译器(10分):将解释器从已有代码中分离出来,形成一个独立的解释器,对于中间代码文件,可以执行并输出相应的结果。(2)注释处理(10): 增加对注释的支持,注释由 (* 和 *)包含,不允许嵌套。(3)布尔数据处理(10分): 增加对于布尔类型的支持,其产生式见编译原理实践教程。(4)布尔表达式的短路处理(10分): 在上面工作的基础上,对 and 和 or 采取短路计算。(5)for 语句处理(10分):参照语言,增加对于 for 语句处理。(6)编译器界面实现(10分):增加界面实现,以可视化方法展示编译器运行过程。(7) 编译器界面动画实现(10分):增加界面动画实现,以动态可视化方法展示编译器运行过程。二、 完成情况(15分):一、 完成情况(15分):1. 修改后的PL/0词法(正规式)下面是本设计用到的正规式,bool 类型的常量与变量都是通过保留字来体现的, number 只是用于识别整型变量与常量。 空白 w- ; /空格 n-n; /回车 t-Tab; /制表 blank - (w | n | t)+; 保留字 begin -begin; /保留字 end - end; if - if; then - then; while - while; do - do; call-call; const - const; var - var; procedure - procedure; boolean -boolean; bool -true|false;/布尔常量数字以及 ID digit - 0|1|2|3|4|5|6|7|8|9;number - digit(digit)*; letter - a-zA-Z; id - letter (digit|letter)*; 特殊符号 becomes-:=; leq- =; res - ;relation - = | = | | +; minus- -; times - *; slash - /; odd - odd; equ -=; lparen -(; rparen - ); comma - ,; semicolon - ; period - .; and - &; or - |; not - !; 详情如下表:空白w 空格nn回车ttTabblank(w|n|t)+关键字beganbeganendendififthenthenwhilewhiledodocallcallconstconstvarvarprocedureprocedurebooleanbooleanboolfalse|true数字|IDdigit1|2|3|4|5|6|7|8|9|0numberdigit(digit)*lettera-zA-Zidletter(letter|digit)*特殊符号becomes:=leq=les=resrelation=|=| Block .Block - Const_decl | Var_option | Procedures |Statement| Block|Procedure_decl - procedure identifier; Block;Procedures - Procedure_decl Procedures |Const_decl - const Const_menber |Const_menber - ident=number, Const_menber | ident=number;Var_option - var Var_decl_list |Var_decl_list - Var_decl | Var_decl_list Var_declVar_decl - Ident_list : TypeIdent_list - ident,Ident_list | identifierType - integer | boolStatement - ident:=Condition;Statement - call identifier;Statement - begin Statements endStatements - Statement Statements |Statement - for ident:= Expression to Expression do StatementStatement - if Condition then StatementStatement - while Condition do StatementCondition - odd Expression| ExpressionCondition -Expression Compare Expression_1 | ExpressionCompare - = | | = | | Expression or Expression_1 | Expression_1Expression_1 - Expression_1 and Expression_2 | Expression_2 Expression_2 - Expression_2+ Symbol Term | Expression_2 - Symbol Term |Symbol TermSymbol - + | - |Term - Term * Factor | Term / Factor | FactorFactor - not Factor | number | ident | (Expression)1. 各任务的实现伪代码或者主要思想实验一:分离解释和编译器实验分析:Pl0含一个主函数,2个后端处理函数和16个前端处理函数,这两个前段处理函数是base()和interpret()。其中各函数的作用是:Base():通过静态连找到数据区的基地址;Interpret():执行目标代码;Block():分析程序处理过程;Statement():语句部分处理;Constdeclaration():常数定义处理;Vardeclaration():整型定义处理;Expression():表达式部分处理;Term():项部分处理;Factor():因子部分处理;Condition():条件部分处理;Gen():生成目标代码,并写入code;Enter():填入声明的名字,包括常数、整型、函数名;Test():测试当前单词是否合理;Error():出错处理;Getch():获取下一个字符;Getsym():词法分析,获取下一个标识符;Listcode():输出目标代码;Position():查找名字的位置;基本思路:分离解释器的主要思想是不需要前段处理,直接用后端处理函数处理生成的中间代码,然后输出结果。实验输出结果:实验二:增加注释处理功能实验分析:当读入特定的字符时忽略之后读入的内容,当再次读入某些特定的字符时恢复读入字符。基本思路:当读入“(*”时忽略之后读入的所有内容直至再次独到“*)”。代码实现:在getch()函数确认读入文件后加入如下代码: if(ch=()ch=getc(infile);if(ch=*)while(!feof(infile)ch=getc(infile);if(ch=* & (ch=getc(infile)=)break;continue;elseprintf();printf(%c,ch);实验输出结果:实验三:增加布尔变量处理和布尔短路处理实验分析:需要增加一种变量类型涉及到增加与之对应的关键字、指令、标示符等诸多与之对应的操作和声明,在每个函数和最开始的头文件中都要有增加。基本思路:在头文件和函数中做相关操作,增加bool变量处理功能。代码实现:头文件声明部分:在原有基础上,在oprcode中添加了JPD和JPE两种指令,JPE是遇到0就跳转,但是会保留栈顶的计算结果,JPD是遇到1就会跳转,同样保留栈顶的结果。在symtype枚举类型中添加了SYM_FALSE,SYM_TRUE,SYM_AND,SYM_OR,SYM_NOT,SYM_COLON,SYM_INTEGER,SYM_BOOLEN,同时把它们到wsym中,在table类型中添加了type,用于标明该名字是布尔型还是整型,同时在mark中也添加type。主程序部分:变量声明部分,只是在变量中区别了是整型还是布尔型,将变量的定义形式改为var a,b:bool(int);逻辑运算部分,按照以下优先级调用函数:赋值运算符 关系运算符 + or * / and not statement()=condition()=expression()(过程中调用l_or()=term()(过程中调用l_and())=factor()(过程中调用l_not();每个函数包括两个参数,fsys和tp。fsys是sym的集合,tp是名字的类型(bool和int)。在布尔设计过程中,遵循以下规则:不可以在逻辑运算表达式中算数表达式。在布尔短路设计中,在l_or()和l_and()函数中分别添加JPE和JPD跳转指令,由于要回填跳转位置,故采用递归。具体实现过程:Block()函数将变量声明部分作如下变化:if (sym = SYM_VAR) / variable declarationsgetsym();dovardeclaration();if (sym = SYM_SEMICOLON)getsym();elseerror(5); while (sym = SYM_IDENTIFIER);block_dx = dx; 若是sym=SYM_VAR,那么所有的处理都在vardeclaration()中进行,Vardeclaration()函数如下:void vardeclaration(void)char ID100MAXIDLEN + 1; /作为临时的变量,用于存储idint i = 0;int k;if (sym = SYM_IDENTIFIER) /每读到一个id,先将其存到ID中,然后判断 sym是否为,若是,重复以上操作;若否, 检查是否位:,若是读入类型,若否,出错。strcpy(IDi+,id);getsym();while (sym = SYM_COMMA)getsym();if (sym = SYM_IDENTIFIER)strcpy(IDi+,id);getsym();if (sym = SYM_COLON)getsym();if (sym = SYM_INTEGER | sym = SYM_BOOLEN)/在获取类型后,再将ID中的内容依次复制给id,同时与类型同作为参数,传递给enter(id,sym),填入table.k=i;i=0;while (i k)strcpy(id,IDi);enter(ID_VARIABLE,sym);i+;getsym();elseerror(35);/缺少参数elseerror(34);/缺少冒号elseerror(4);/在var后面一定要有一个名字 / vardeclaration在变量声明结束以后,进行语句处理。Statement()语句处理时,若是sym=SYM_IDENTIFIER,那么在确认id有效的同时,获取type,即添加了tp = tablei.type;按照优先级关系,在此调用condition()。对condition()做一定的修改,使其可以满足除关系运算以外的其他运算。Condition()获取一个id或者是num以后,若是sym不是关系运算符,直接返回。在此,先调用expression(),然后若是if (! inset(sym, relset),表明不是关系运算,直接return。对expression()作如下修改:(1) 在set中添加SYM_OR,即set = uniteset(fsys, createset(SYM_PLUS, SYM_MINUS, SYM_OR, SYM_NULL);(2) 对于代码生成部分,修改为:while (sym = SYM_PLUS | sym = SYM_MINUS | sym = SYM_OR)if (sym = SYM_PLUS | sym = SYM_MINUS)if (tp != SYM_INTEGER)error(38);/在做算术运算时,操作数一定要是整型addop = sym;getsym();term(set, tp);if (addop = SYM_PLUS)gen(OPR, 0, OPR_ADD);else if (addop = SYM_MINUS)gen(OPR, 0, OPR_MIN);else if (sym = SYM_OR)l_or(set, tp); / while在此调用的l_or()为:void l_or(symset fsys, int tp)if (sym = SYM_OR)int addop, cx1;getsym();term(fsys, tp);gen(OPR, 0, OPR_OR);/以下部分是实现短路设计用的。在每遇到一个or时,其后都添加一条遇1跳转指令,由于要回填,故而先记录指令的位置,在读完最后一个操作数之后再填入,用递归实现。因为term()处理的操作的优先级都高于l_or(),所以每次递归结束后都能获得一个操作数,实现了按优先级操作。cx1 = cx;gen(JPD, 0, 0);l_or(fsys, tp);codecx1.a = cx;对于term()作同样修改,修改后为:(1) set=uniteset(fsys,createset(SYM_PLUS,SYM_MINUS,SYM_AND,SYM_NULL);(2) 代码生成部分:while (sym = SYM_TIMES | sym = SYM_SLASH | sym = SYM_AND)if (sym = SYM_TIMES | sym = SYM_SLASH)if (tp != SYM_INTEGER)error(38);mulop = sym;getsym();factor(set, tp);if (mulop = SYM_TIMES)gen(OPR, 0, OPR_MUL);else if (mulop = SYM_SLASH)gen(OPR, 0, OPR_DIV);else if (sym = SYM_AND)l_and(set, tp); / while调用的l_and()为:void l_and(symset fsys, int tp)if (sym = SYM_AND)int addop, cx1;addop = sym;getsym();factor(fsys, tp);gen(OPR, 0, OPR_AND);cx1 = cx;gen(JPE, 0, 0);l_and(fsys, tp);codecx1.a = cx;对于被调用的处理因子的factor(),添加对常量false和true的处理,同时添加对not运算的处理。添加的部分为:else if (sym = SYM_FALSE)if (tp != SYM_BOOLEN)error(38);gen(LIT, 0, 0);getsym();else if (sym = SYM_TRUE)if (tp != SYM_BOOLEN)error(38);gen(LIT, 0, 1);getsym();else if (sym = SYM_NOT)l_not(fsys, tp);L_not()函数为:void l_not(symset fsys, int tp)int addop;void factor();symset set;getsym();set = uniteset(fsys, createset( SYM_NOT, SYM_NULL);factor(set, tp); gen(OPR, 0, OPR_NOT);destroyset(set);以上就是添加了bool类型后做的修改。修改后的图示内容如下:程序程序体语句条件表达式项因子实验输出结果: 短路:实验五:for语句处理实验分析:C语言风格的for处理,要求程序按照左括号、声明、分号、逻辑运算、分号、计算、右括号的顺序进行分析操作,这样就可以编写代码对此功能进行实现。基本思路:按照for语句的语法要求进行匹配,若不匹配报错。代码实现:出去再生命中加入SYM_FOR之外还在statement()加入如下代码else if(sym=SYM_FOR)int tag;int sym1;tag=0; getsym();if(sym=SYM_LPAREN) cx1 = cx; / printf(%dn,cx); getsym(); sym1=sym; set1 = createset(SYM_IDENTIFIER,SYM_SEMICOLON,SYM_NULL); set = uniteset(set1, fsys); statement(set); destroyset(set1); destroyset(set); cx4=cx;elseprintf(缺少左括号,退出n);exit(0);if(sym=SYM_SEMICOLON) / printf(%dn,cx); getsym(); sym1=sym; cx4=cx; if(sym1=SYM_IDENTIFIER) set1 = createset(SYM_IDENTIFIER,SYM_SEMICOLON,SYM_NULL); set = uniteset(set1, fsys); condition(set); destroyset(set1); destroyset(set); cx3 = cx; gen(JPC, 0,0); else cx3=cx; / statement(fsys);else error(10); if(sym=SYM_SEMICOLON) cx2 =cx3; getsym(); set1 = createset(SYM_IDENTIFIER,SYM_RPAREN,SYM_NULL); set = uniteset(set1, fsys); statement(set); destroyset(set1); destroyset(set);elseerror(10);if(sym=SYM_RPAREN) getsym();if(sym=SYM_ZUO) getsym(); set1 = createset(SYM_YOU,SYM_SEMICOLON,SYM_BREAK,SYM_END,SYM_NULL); set = uniteset(set1, fsys); statement(set); while (sym = SYM_SEMICOLON | inset(sym, statbegsys) / printf(%dn,cx6); if (sym = SYM_SEMICOLON) getsym(); else error(10); statement(set); / while destroyset(set1); destroyset(set); if(sym=SYM_BREAK)tag=1; cx6=cx; getsym(); /printf(%dn,sym); getsym(); gen(JMP, 0, cx);codecx6.a=cx;/printf(%dn,cx6); if (sym = SYM_YOU)if(tag=1)codecx6-1.a=cx; getsym(); set1 = createset(SYM_END,SYM_NULL); set = uniteset(set1, fsys); statement(set); destroyset(set1); destroyset(set); gen(JMP, 0, cx4); / if(sym1=SYM_IDENTIFIER) codecx2.a = cx4; codecx3.a=cx;if(tag=1)codecx6.a=cx; codecx6.a=cx; else printf(缺少右大括号,退出n); exit(0);else if(sym=SYM_SEMICOLON)getsym();set1 = createset(SYM_YOU,SYM_SEMICOLON,SYM_END,SYM_NULL); set = uniteset(set1, fsys); statement(set);destroyset(set1); destroyset(set); gen(JMP, 0, cx4);codecx2.a = cx4; codecx3.a=cx; else printf(缺少左大括号,退出n); exit(0); else printf(缺少右括号,退出n); exit(0); /* gen(JMP, 0, cx4);codecx2.a = cx4;codecx3.a=cx;*/ /printf(cx=%d,cx2=%d,cx3=%d,cx4=%d,cx,cx2,cx3,cx4); elsetest(fsys, phi, 19);(修改后的statement)验结果输出:(6) (7)编译器界面实现编译器界面动画实现首先对于MFC的认识及相应的代码程序核心代码中涉及到的函数说明:(在Pl0Doc.cpp中)/词法分析用函数char GetChar(int n=1); /得到一个字符CString OutputKeyWord();/输出关键词int SearchKeyWord(CString str);/寻找关键词/语法分析用函数void Advance(int i=1); /读入下一个单词bool test(CString n, int lev,int tx);/检查语法错误,即是否是合法的单词,并负责跳到下一个正确的语法单元继续分析bool test(CString n,int lev,int tx,KIND k); /重载的test函数bool enter(CString n,KIND k,int lev,int val,int r,int c); /登录符号表 void error(int a); /当语法分析中查到错误时,报告出错信息void factor(int lev, int tx);/因子处理函数,用来处理源程序中的“因子”部分void expression(int lev, int tx); /表达式处理函数,用来处理源程序(文本)中的“表达式”部分void term(int lev, int tx); /项处理函数,用来处理源程序(文本)中的“项”void condition(int lev,int tx); / 条件处理函数,用来处理 “条件”部分void statement(int lev,int tx); /语句处理函数,用来处理“语句”void block(int lev,int tx); /分程序的处理函数,用来处理“分程序”void program(); / 程序处理函数,用来处理“程序” /语义分析用的函数(生成中间代码)void Constdeclaration(int & dep); /常量声明的语义分析void Vardeclaration(int & dep); /变量声明的语义分析void Advanced(int i=1); /从单词表中读入下一个单词int Position(CString idname); /查找标识符在符号表中的登录信息,并检查是否在符号表中void Factor(int lev,int tx); /因子的语义分析void Term(int lev,int tx,int i=1); /项的语义分析void Expression(int lev,int tx); /表达式的语义分析void Condition(int lev,int tx); /条件的语义分析void Statement(int lev,int tx); /语句的语义分析void Block(int lev,int tx); / 分程序的语义分析bool Generate(Functions func,int lev,int amount); /生成一条中间代码/解释执行中用到的函数int Base(int lev); /查找当前被调用的变量、常量、过程在虚拟内存中的地址或数值信息void Interpret(bool & interrupt,int count); /负责动态的分配内存空间和对中间代码进行的解释执行与可视化界面有关的一些函数的说明(在Pl0Doc.h中) afx_msg void OnFileSaveAs(); /保存文档 afx_msg bool OnSyntaxAnalyze() /语法分析 OnWordAnalyze(); /现调用词法分析 total_err=0; TX=1; Advance(0); program(); afx_msg void OnWordAnalyze(); /词法分析,具体内容见CPL0Doc.cppafx_msg void OnWordAnalyzeFile(); afx_msg void OnWordAnalyzeSee(); /查看词法分析的结果afx_msg bool OnCodesAnalyze() /中间代码生成 bool flag=false; if(OnSyntaxAnalyze()=true)/语法分析已经完成,并且正确 if(twoelement.head!=NULL) /若源程序为空,不生成代码 Advanced(0); TXCode = 0; CIndex = 0; Block(0,0);/调用分程序处理模块,初始时程序为第零层 flag=true; /代码生成完成 return flag; /返回参数,表示代码生成成功与否 afx_msg void OnCodesview(); /查看生成的中间代码,结果显示在次窗口中afx_msg void OnExecute() /程序的执行 if(OnCodesAnalyze()Interpret(Interrupt,Count); / 调用解释执行程序 afx_msg void OnSynHelp(); / 弹出一个窗口,显示语法定义规则Afx_msg需要在.h文件声明消息的相应函数,然后在相应的.cpp文件中建立map对应关系BEGIN_MESSAGE_MAP(CPL0Doc, CDocument)/AFX_MSG_MAP(CPL0Doc) 将.h文件与.cpp文件对应的映射起来,再往下问文件.cpp的实现ON_COMMAND(ID_FILE_SAVE_AS, OnFileSaveAs)ON_COMMAND(ID_SYNTAX_ANALYZE
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 安徽省宣城市郎溪县2023-2024学年高一上学期期末考试历史题目及答案
- 幽默三国读后感550字(9篇)
- 售后服务流程标准化服务脚本
- 城市绿化养护项目管理合同
- 营销方案撰写指南
- 可爱的小仓鼠爱的作文(15篇)
- 时间变化的声音课件
- 通稿2003读后感9篇范文
- 诗歌修辞手法与意境构建:八年级古诗鉴赏教案
- 记一件令我感动的事感动作文(10篇)
- 水泵设备单机试运转记录
- 完整版医院体检报告范本
- 速成意大利语(上)
- 彭静山针灸秘验
- Q∕SY 1535-2012 海底管道混凝土配重层技术规范
- 生育服务证办理承诺书空白模板
- 壳寡糖功能课件
- 腰椎间盘突出症的护理查房课件(PPT 27页)
- 项目评审检查清单(质量阀)
- 篮球战术传切配合“一传一切”课时教学计划
- 新建搅拌站策划方案样本21
评论
0/150
提交评论