编译原理课程设计-- PL0语言的扩充.doc_第1页
编译原理课程设计-- PL0语言的扩充.doc_第2页
编译原理课程设计-- PL0语言的扩充.doc_第3页
编译原理课程设计-- PL0语言的扩充.doc_第4页
编译原理课程设计-- PL0语言的扩充.doc_第5页
免费预览已结束,剩余24页可下载查看

下载本文档

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

文档简介

0 编译原理课程设计 项目名称 PL 0 语言的扩充语言的扩充 学 院 计算机学院 专业班级 学 号 姓 名 指导教师 2013 年 1 月 3 日 报告成绩 0 一 一 课程设计目的课程设计目的 0 二 二 课程设计要求课程设计要求 0 基本内容 基本内容 0 选做内容 选做内容 0 已实现的功能 已实现的功能 0 三 三 编译环境与工具编译环境与工具 0 四 四 结构设计说明结构设计说明 0 1 1 PL 0PL 0 编译程序的结构图编译程序的结构图 0 2 2 PL 0PL 0 编译程序的过程或函数的功能表编译程序的过程或函数的功能表 1 3 3 PL 0PL 0 编译程序的总体流程图编译程序的总体流程图 1 4 4 PL 0PL 0 编译程序的中间代码编译程序的中间代码 2 5 5 PL 0PL 0 的编译程序的过程和函数的功能的编译程序的过程和函数的功能 3 五 五 课程设计的设计与步骤课程设计的设计与步骤 3 1 扩充赋值运算 扩充赋值运算 和和 5 2 增加 增加 PASCAL的的 FOR 语句语句 15 3 一维数组 一维数组 17 六 六 调试测试调试测试 19 1 1 的测试的测试 19 2 FOR2 FOR 语句的测试语句的测试 21 3 3 数组的调试数组的调试 22 4 4 综合调试 综合调试 23 七 七 课程设计总结课程设计总结 25 参考文献参考文献 26 0 1 1 课程设计目的课程设计目的 在分析理解一个教学型编译程序 如 PL 0 的基础上 对其词法分析程序 语法分析 程序和语义处理程序进行部分修改扩充 达到进一步了解程序编译过程的基本原理和基本 实现方法的目的 2 2 课程设计要求课程设计要求 基本内容 基本内容 1 扩充赋值运算 和 2 扩充语句 Pascal 的 FOR 语句 FOR TO DO FOR DOWNTO DO 其中 语句 的循环变量的步长为 2 语句 的循环变量的步长为 2 3 增加运算 和 选做内容 选做内容 1 增加类型 字符类型 实数类型 2 扩充函数 有返回值和返回语句 有参数函数 3 增加一维数组类型 可增加指令 4 其他典型语言设施 已实现的功能 已实现的功能 1 扩充赋值运算 和 另外也扩充了 和 2 扩充语句 Pascal 的 FOR 语句 FOR TO DO FOR DOWNTO DO 3 增加运算 和 4 增加一维数组类型 可增加指令 3 3 编译环境与工具编译环境与工具 编译环境 编译环境 Microsoft Windows 7 64bit 编译工具 编译工具 Microsoft Visual C 6 0 4 4 结构设计说明结构设计说明 1 1 PL 0PL 0 编译程序的结构图编译程序的结构图 1 PL 0 源程序 词法分析程序 语法语义分析程序 代码生成 目标代码 表格 管理 程序 出错 管理 程序 2 2 PL 0PL 0 编译程序的过程或函数的功能表编译程序的过程或函数的功能表 过程或函数名简要功能说明 pl0 主程序 error 出错处理 打印出错位置和错误编码 getsym 词法分析 读取一个单词 getch 漏掉空格 读取一个字符 gen 生成目标代码 并送入目标程序区 test 测试当前单词符号是否合法 block 分程序分析处理过程 enter 登录名字表 position 函数 查找标识符在名字表中的位置 constdeclaration 常量定义处理 vardeclaration 变量说明处理 listode 列出目标代码清单 statement 语句处理 expression 表达式处理 term 项处理 factor 因子处理 condition 条件处理 interpret 对目标代码的解释执行程序 base 函数 通过静态链求出数据区的基地址 表 4 1 PL 0 编译程序的过程或函数的功能表 3 3 PL 0PL 0 编译程序的总体流程图编译程序的总体流程图 图 4 1 PL 0 编译程序的结构图 2 启启动动 置置初初值值 调调用用GETSYM取取单单词词 调调用用BLOCK过过程程 当当前前单单词词 是是否否为为源源程程序序结结束束符符 出出错错 源源程程序序中中 是是否否有有错错误误 调调用用解解释释过过程程INTERPRET 解解释释执执行行目目标标程程序序 打打印印错错误误 结结束束 N N Y Y Y Y N N 图 4 2 PL 0 编译程序的总体流程图 4 4 PL 0PL 0 编译程序的中间代码编译程序的中间代码 对 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 7 opr 0 8次栈顶与栈顶是否相等 退两个栈元素 结果值进栈 opr 0 9次栈顶与栈顶是否不等 退两个栈元素 结果值进栈 3 opr 0 10次栈顶是否小于栈顶 退两个栈元素 结果值进栈 opr 0 11次栈顶是否大于等于栈顶 退两个栈元素 结果值进栈 opr 0 12次栈顶是否大于栈顶 退两个栈元素 结果值进栈 opr 0 13次栈顶是否小于等于栈顶 退两个栈元素 结果值进栈 opr 0 14栈顶值输出至屏幕 opr 0 15屏幕输出换行 opr 0 16从命令行读入一个输入置于栈顶 表 4 2 PL 0 编译程序的目标指令 5 5 PL 0PL 0 的编译程序的过程和函数的功能的编译程序的过程和函数的功能 Pl0 主程序 Error 出错处理 打印出错位置和错误编码 Getsym 词法分析 读取一个单词 Getch 漏掉空格 读取一个字符 Gen 生成目标代码 并送入目标程序区 Test 测试当前单词符号是否合法 Block 分程序分析处理过程 Enter 登陆名字表 Position 查找标识符在名字表中的位置 Constdeclaration 常量定义处理 Vardeclaration 变量说明处理 Listcode 列出目标代码清单 Statement 语句部分处理 Expression 表达式处理 Term 项处理 Factor 因子处理 Condition 条件处理 Interpret 对目标代码的解释执行程序 Base 通过静态链求出数据区的基地址 5 5 课程设计的设计与步骤课程设计的设计与步骤 本次课程设计是在实验的基础上 在实验中 已经实现对 PL 0 作以下修改扩充 1 增加单词 保留字 ELSE FOR STEP UNTIL RETURN 运算符 2 修改单词 不等号 改为 3 增加条件语句的 ELSE 子句 在课程设计中 因为关键字增加到了 18 个 所以令 define norw 18 SYMBOL 扩展 为 48 个值 在 pl0 h 中做了如下更改 具体如下 粗体部分为课程设计更改部分 enum symbol nul ident number plus minus times slash oddsym eql neq lss leq gtr geq lparen rparen comma semicolon period becomes 4 beginsym endsym ifsym thensym whilesym writesym readsym dosym callsym constsym varsym procsym elsesym forsym stepsym untilsym returnsym plusbecomes dplus minusbecomes dminus and or not lepa ripa slashbecomes timesbecomes define symnum 48 符号和关键字扩展 粗体部分为课程设计更改部分 ssym plus ssym minus ssym times ssym slash ssym lparen ssym rparen ssym eql ssym comma ssym period ssym neq 去掉 改为 ssym semicolon ssym not 非 ssym lepa 一维数组的左括号 ssym ripa 一维数组的右括号 设置保留字名字 按照字母顺序 便于折半查找 strcpy strcpy strcpy strcpy strcpy strcpy strcpy strcpy strcpy strcpy strcpy strcpy strcpy strcpy strcpy strcpy strcpy strcpy 设置保留字符号 wsym 0 beginsym 5 wsym 1 callsym wsym 2 constsym wsym 3 dosym wsym 4 elsesym wsym 5 endsym wsym 6 forsym wsym 7 ifsym wsym 8 oddsym wsym 9 procsym wsym 10 readsym wsym 11 returnsym wsym 12 stepsym wsym 13 thensym wsym 14 untilsym wsym 15 varsym wsym 16 whilesym wsym 17 writesym 设置指令名称 粗体部分为课程设计更改部分 strcpy strcpy strcpy strcpy strcpy strcpy strcpy strcpy strcpy strcpy strcpy strcpy strcpy strcpy 1 扩充赋值运算 扩充赋值运算 和和 6 变量表达式 表达式 a 或者 a a 或者 a 图 5 1 扩充赋值运算 和 1 在 symbol 增加字符 Plusbecomes Minusbecomes Slashbecomes Timesbecomes 2 对取字符 getsym 函数进行扩充 具体如下 粗体部分为更改部分 int getsym 此处省略部分未修改过的代码 else if ch 读到加号 getchdo 再读一个字符 if ch 读到等号 则与 号构成加等 sym plusbecomes 7 getchdo else if ch 读到加号 则与加号构成 sym dplus getchdo else sym plus 那就是一个单独的加号 else if ch 读到减号 getchdo if ch 读到等号 则与减号构成减等 sym minusbecomes getchdo else if ch 读到减号 则与减号构成 sym dminus getchdo else sym minus 那就是一个单独的减号 else if ch getchdo if ch 读到乘号 则与减号构成乘等 sym timesbecomes getchdo else sym times 那就是一个单独的乘 else if ch 8 getchdo if ch 读到乘号 则与减号构成除等 sym slashbecomes getchdo else sym slash 那就是一个单独的除 此处省略部分未修改过的代码 3 对 statemen 函数进行扩展 int statement bool fsys int ptx int lev 此处省略部分未修改过的代码 if sym ident i position id ptx if i 0 error 11 else if table i kind variable i 0 else getsymdo if sym lepa 如果是数组 getsymdo 处理 里的表达式 memcpy nxtlev fsys sizeof bool symnum nxtlev ripa true expressiondo nxtlev ptx lev gendo tra 0 table i size 生成将数组下标范围入栈指令 gendo jud 0 0 判断下标合法性 9 if sym ripa error 26 getsymdo if sym becomes 赋值 getsymdo flag 1 else if sym plusbecomes 加赋值 getsymdo flag 2 else if sym minusbecomes 减赋值 getsymdo flag 3 else if sym dplus getsymdo flag 4 else if sym dminus getsymdo flag 5 else if sym timesbecomes getsymdo flag 6 else if sym slashbecomes getsymdo flag 7 else error 13 10 if i 0 if flag 1 memcpy nxtlev fsys sizeof bool symnum expressiondo nxtlev ptx lev else if flag 2 memcpy nxtlev fsys sizeof bool symnum expressiondo nxtlev ptx lev gendo lod lev table i level table i adr 先取值到栈顶 gendo opr lev table i level 2 执行加法 else if i 0 expressiondo nxtlev ptx lev gendo lod lev table i level table i adr 先取值到栈顶 gendo opr lev table i level 3 执行减法 gendo opr lev table i level 1 取反 else if i 0 先取值到栈顶 gendo lit lev table i level 1 将值为 1 入栈 gendo opr lev table i level 2 加法 即 加 1 if table i kind array gendo gar lev table i level table i adr gendo lit lev table i level 1 gendo opr lev table i level 2 11 else if i 0 先取值到栈顶 gendo lit lev table i level 1 将值为 1 入栈 gendo opr lev table i level 3 减法 即 1 if table i kind array gendo gar lev table i level table i adr gendo lit lev table i level 1 gendo opr lev table i level 3 else if i 0 expressiondo nxtlev ptx lev gendo lod lev table i level table i adr 先取值到栈顶 gendo opr lev table i level 4 乘法 else if i 0 gendo lod lev table i level table i adr 先取值到栈顶 memcpy nxtlev fsys sizeof bool symnum expressiondo nxtlev ptx lev gendo opr lev table i level 5 除法 if table i kind array 数组 根据偏移地址存入数组 gendo sar lev table i level table i adr gendo del 0 0 赋值语句需将存入数组后栈顶为偏移地 址出栈 else 变量 gendo sto lev table i level table i adr 12 根据变量地址存入变量 else if sym dplus 变量 getsymdo if sym ident 后面跟的是变量 i position id ptx if i 0 error 11 else if table i kind variablei 0 else 后跟变量 处理生成中间代码 if table i kind variable gendo lod lev table i level table i adr 先取 值到栈顶 gendo lit 0 1 将值为 1 入栈 gendo opr 0 2 加法 即 1 栈顶加次栈顶 gendo sto lev table i level table i adr 出栈 取值到内存 getsymdo else if table i kind array 后跟数组 getsymdo if sym lepa getsymdo memcpy nxtlev fsys sizeof bool symnum nxtlev ripa true expressiondo nxtlev ptx lev 13 gendo tra 0 table i size 生成将数组下标范围 入栈指令 gendo jud 0 0 判断下标合法性 if sym ripa error 26 缺少 else gendo gar lev table i level table i adr gendo lit 0 1 gendo opr 0 2 gendo sar lev table i level table i adr gendo del 0 0 getsymdo else error 27 缺少 else if sym dminus 变量 getsymdo if sym ident 后面跟的是变量 i position id ptx if i 0 error 11 else if table i kind variablei 0 14 else 后跟变量 处理生成中间代码 if table i kind variable 后跟变量 gendo lod lev table i level table i adr 先取 值到栈顶 gendo lit 0 1 将值为 1 入栈 gendo opr 0 3 加法 即 1 栈顶减次栈顶 gendo sto lev table i level table i adr 出栈 取值到内存 getsymdo else if table i kind array 后跟数组变量 getsymdo if sym lepa getsymdo memcpy nxtlev fsys sizeof bool symnum nxtlev ripa true expressiondo nxtlev ptx lev gendo tra 0 table i size 生成将数组下标范围入 栈指令 gendo jud 0 0 判断下标合法性 if sym ripa error 26 缺少 else gendo gar lev table i level table i adr gendo lit 0 1 gendo opr 0 3 gendo sar lev table i level table i adr gendo del 0 0 getsymdo else error 27 缺少 15 此处省略部分未修改过的代码 2 增加 增加 Pascal 的的 FOR 语句语句 本次课程设计中要求扩充的是 Pascal 的 FOR 语句 FOR TO DO FOR DOWNTO DO 流程图如下 for变量 表达式to downto 表达式do语句 图 5 2 增加 Pascal 的 FOR 语句 1 在 symbol 增加字符 FORSYM strcpy KWORD 10 for WSYM 10 forsym strcpy KWORD 22 to WSYM 22 tosym strcpy KWORD 7 downto WSYM 7 downtosym 2 对 statement 函数进行扩充 int statement bool fsys int ptx int lev 此处省略部分未修改过的代码 else if sym forsym getsymdo if sym ident ident 为变量的符号 i position id ptx if i 0 error 11 else if table i kind variable 赋值语句中 赋值号左部标识符属性应是 16 变量 error 12 i 0 else getsymdo if sym becomes error 13 else getsymdo memcpy nxtlev fsys sizeof bool symnum if nxtlev tosym true tosym else nxtlev downtosym true downtosym expressiondo nxtlev ptx lev 处理赋值语句右部的表达式 gendo sto lev table i level table i adr 保存初始值 getsymdo cx1 cx 保存循环开始点 memcpy nxtlev fsys sizeof bool symnum if sym dosym getsymdo statement fsys ptx lev 循环体处理 gendo lod lev table i level table i adr 将循环变 量取出放在栈顶 gendo opr 0 2 循环变量加长 gendo sto lev table i level table i adr 将栈顶的 值存入循环变量 gendo jmp 0 cx1 无条件跳转到循环开始点 code cx2 a cx 回填循环结束点的地址 else error 29 for 语句中少了 do else error 19 for 后面为赋值语句 赋值语句左部是变量 缺少变量 此处省略部分未修改过的代码 17 3 一维数组 一维数组 1 设置一维数组的左右括号 ssym lepa 一维数组的左括号 ssym ripa 一维数组的右括号 2 增加指令 strcpy strcpy strcpy strcpy strcpy strcpy enum fct lit opr lod sto cal inte jmp jpc gar sar shd del jud tra 由于指令有原来的 8 条拓展到了 14 条 故进行如下修改 define fctnum 14 增加的指令意义如下 gar 根据栈顶的偏移地址从数组中取值到新的栈顶 sar 根据次栈顶的偏移地址把栈顶的值存入数组 shd 将栈顶的值下移到次栈顶 栈顶出栈 即次栈顶成为栈顶 del 出栈顶 jud 判断数组下标合法性 tra 将数组的下标范围入栈 gendo tra 0 数组下标最大值 3 增加标识符类型属性 enum object constant variable procedur array 数组 4 在 block 函数中添加如下代码 for i tx0 1 i tx i switch table i kind case constant 常量名字 此处省略部分未修改过的代码 case variable 变量名字 此处省略部分未修改过的代码 case procedur 过程名字 此处省略部分未修改过的代码 18 case array 数组变量 printf d var array s i table i name printf lev d addr d size d n table i level table i adr table i size fprintf fas d var array s i table i name fprintf fas lev d addr d size d n table i level table i adr table i size 5 在 enter 函数添加如下代码 switch k case constant 常量名字 此处省略部分未修改过的代码 case variable 变量名字 此处省略部分未修改过的代码 case procedur 过程名字 此处省略部分未修改过的代码 case array 数组名字 table ptx level lev table ptx adr pdx arraysize table ptx size arraysize break 6 在 Vardeclaration 函数中添加数组的变量声明 代码如下 int vardeclaration int ptx int lev int pdx 此处省略部分未修改过的代码 case gar 根据栈顶的偏移地址从数组中取值到新的栈顶 s t s base i l s b i a s t 1 偏移地址为上一层过程的基址 当 前指令的层次 栈顶的偏移地址 t break case sar 根据次栈顶的偏移地址把栈顶的值存入数组 t s base i l s b i a s t 1 s t t break case shd 将栈顶的值保存到次栈顶 t s t 1 s t 19 break case del 将栈顶的值出栈 t break case jud 判断数组下标的合法性 t if s t 1 s t error 28 printf n 运行问题出错 程序退出 请输入任意数字退出 scanf d exit 1 break case tra 将数组的下标范围入栈 s t i a t break 此处省略部分未修改过的代码 6 6 调试测试调试测试 1 1 的测试的测试 20 图 6 1 测试文件 PL0 1 TXT 图 6 2 的测试结果 1 21 图 6 2 的测试结果 2 2 FOR2 FOR 语句的测试语句的测试 图 6 4 FOR 语句的测试文件 PL0 TXT 图 6 5 FOR 语句的测试结果 22 3 3 数组的调试数组的调试 图 6 6 数组的测试文件 PL0 3 TXT 图 6 6 数组的测试结果 1 图 6 6 数组的测试结果 2 23 4 4 综合调试 综合调试 综合测试是定语一个 1 维数组 数组每个元素的值等于它的位置 然后依次输出数组元 素 再次 对数组元素分别进行 运算 用 FOR 语句输出结果 最后用 FOR 语句对其进行求和 再次

温馨提示

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

评论

0/150

提交评论