PL0扩充课程设计报告_第1页
PL0扩充课程设计报告_第2页
PL0扩充课程设计报告_第3页
PL0扩充课程设计报告_第4页
PL0扩充课程设计报告_第5页
已阅读5页,还剩15页未读 继续免费阅读

下载本文档

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

文档简介

课课 程程 设设 计计 课程名称 编译原理 题目名称 PL 0 扩充 学 院 专 业 班 级 学 号 姓 名 指导教师 2011 年 1 月 8 日 一 一 课程设计目的与要求课程设计目的与要求 1 课程设计目的 课程设计目的 在分析理解一个教学型编译程序 如 PL 0 的基础上 对其词法分析 程序 语法分析程序和语义处理程序进行部分修改扩充 达到进一步了解 程序编译过程的基本原理和基本实现方法的目的 2 2 课程设计要求 课程设计要求 基本内容 成绩范围 中 及格 或 不及格 1 扩充赋值运算 和 2 扩充语句 Pascal 的 FOR 语句 FOR TO DO FOR DOWNTO DO 其中 语句 的循环变量的步长为 1 语句 的循环变量的步长为 1 选做内容 成绩评定范围扩大到 优 和 良 1 增加运算 和 2 增加类型 字符类型 实数类型 3 扩充函数 有返回值和返回语句 有参数函数 4 增加一维数组类型 可增加指令 5 其他典型语言设施 二 实验环境与工具二 实验环境与工具 1 计算机及操作系统 PC 机 WindowsXP 2 程序设计语言 VC 6 0 C C 语言 3 教学型编译程序 PL 0 三三 结构设计方案结构设计方案 1 结构设计说明 结构设计说明 PL 0 的编译程序以语法分析程序为核心 词法分析程序和代码生成程 序都作为一个独立的过程 当语法分析需要读单词时就用词法分析程序 而 当语法分析正确需生成相应的目标代码时 则调用代码生成程序 此外 用 表格管理程序建立变量 常量和过程标识符的说明与引用之间的信息联系 用出错处理程序对词法和语法分析遇到的错误给出在源程序中出错的位置和 错误性质 2 各功能模块图示 各功能模块图示 3 各功能模块作用表 各功能模块作用表 1PL0 主程序 2Error 出错处理 打印出错位置和错误编码 3GetCh 漏掉空格 读取一个字符 4GetSym 词法分析 读取一个单词 5Gen 生成目标代码 并送入目标程序区 6TEST 测试当前单词符号是否合法 7ENTER 登录名字表 8POSITION 查找标识符在名字表中的位置 9ConstDeclaration 常量定义处理 10VarDeclaration 变量说明处理 11ListCode 列出目标代码清单 12FACTOR 因子处理 13TERM 项处理 14EXPRESSION 表达式处理 15CONDITION 条件处理 16STATEMENT 语句部分处理 17Block 分程序分析处理过程 18BASE 通过静态链求出数据区的基地址 19Interpret 对目标代码的解释执行程序 3 符号名字表结构 符号名字表结构 struct tablestruct char name al 名字名字 enum object kind 类型 类型 constconst varvar arrayarray oror procedure procedure int val 数值 仅数值 仅 constconst 使用使用 int level 所处层 仅所处层 仅 constconst 不使用不使用 int adr 地址 仅地址 仅 constconst 不使用不使用 int size 需要分配的数据区空间 仅需要分配的数据区空间 仅 procedureprocedure 使用使用 4 保留关键字枚举结构 保留关键字枚举结构 enum symbol 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 elsesym forsym tosym downtosym returnsym pluseql minuseql plusplus minusminus 5 5 名字表中标识符枚举类型 名字表中标识符枚举类型 enum object constant 常量常量 variable 变量变量 procedur 过程过程 6 6 虚拟机虚拟机 enum fct 虚拟机代码虚拟机代码 lit opr lod sto cal inte jmp jpc struct instruction 虚拟机代码结构虚拟机代码结构 enum fct f 虚拟机代码指令虚拟机代码指令 int l 引用层与声明层的层次表引用层与声明层的层次表 int a 根据根据 f f 的不同而不同的不同而不同 7 扩充部分语法描述图 扩充部分语法描述图 Ident If 条件 Then 语句语句 Else Ident 语句 表达式 For 语句 To Downto 表达式 To 语句 因子 Number Ident Ident 表达式 表达式 Then Then Then 8 8 运行时存储组织和管理运行时存储组织和管理 对于源程序的每一个过程 包括主程序 在被调用时 首先在数据段中 开辟三个空间 存放静态链SL 动态链DL和返回地址RA 静态链记录了定义 该过程的直接外过程 或主程序 运行时最新数据段的基地址 动态链记录调 用该过程前正在运行的过程的数据段基址 返回地址记录了调用该过程时程序 运行的断点位置 对于主程序来说 SL DL和RA的值均置为0 静态链的功能 是在一个子过程要引用它的直接或间接父过程 这里的父过程是按定义过程时 的嵌套情况来定的 而不是按执行时的调用顺序定的 的变量时 可以通过静 态链 跳过个数为层差的数据段 找到包含要引用的变量所在的数据段基址 然后通过偏移地址访问它 在过程返回时 解释程序通过返回地址恢复指令指针的值到调用前的地址 通过当前段基址恢复数据段分配指针 通过动态链恢复局部段基址指针 实现 子过程的返回 对于主程序来说 解释程序会遇到返回地址为0的情况 这时就 认为程序运行结束 解释程序过程中的base函数的功能 就是用于沿着静态链 向前查找相差 指定层数的局部数据段基址 这在使用sto lod stoArr lodArr等访问局部变 量的指令中会经常用到 类PCODE代码解释执行的部分通过循环和简单的case判断不同的指令 做 出相应的动作 当遇到主程序中的返回指令时 指令指针会指到0位置 把这样 一个条件作为终至循环的条件 保证程序运行可以正常的结束 9 9 扩充赋值运算 扩充赋值运算 和和 设计 设计 对于 和 赋值运算符 在程序中出现的情况只有如下一种 文 法的 EBNF 表示为 赋值语句 1 扩充的语法描述见结构设计中的 PL 0 分程序和主要语句的语法描述 中的描述图 2 分析区别赋值运算符采用 读标识符后再读一个字符 后根据读到的 字符转去不同的赋值语句执行 3 中间代码生成情况 运算符 其他赋值运算符架构是一样的 只 是执行加法改为相应的算数运算 表达式 else if sym pluseql 检测到 符号 i position id ptx 把类x 3的x的地址取出来 gendo lod lev table i level table i adr 找到变量地址并将其值入栈 getsymdo if sym semicolon getsymdo memcpy nxtlev fsys sizeof bool symnum expressiondo nxtlev ptx lev gendo opr 0 2 if i 0 gendo sto lev table i level table i adr else if sym minuseql 检测到 符号 i position id ptx 把类x 3的x的地址取出来 gendo lod lev table i level table i adr 找到变量地址并将其值入栈 getsymdo 读到 运算符单词 求 运算符后的表达式 expressiondo nxtlev ptx lev 取 左部的标识符的值到栈顶 gendo lod lev table i level table i adr 执行加法 gendo opr lev table i level 2 保存赋值后的结果 gendo sto lev table i level table i adr if sym semicolon getsymdo memcpy nxtlev fsys sizeof bool symnum expressiondo nxtlev ptx lev gendo opr 0 3 if i 0 gendo sto lev table i level table i adr 10 10 扩充语句 扩充语句 Pascal 的的 FOR 语句 语句 FOR TO DO FOR DOWNTO DO 其中 语句其中 语句 的循环变量的步长为的循环变量的步长为 1 语语句句 的循环变量的步长为的循环变量的步长为 1 For i E1 to E2 do S1 循环语句 ALGOL 等价于 i E1 goto OVER AGAIN i i 1 OVER if i E2 then Begin S1 goto again end 注意程序中基础用到循环控制变量 i 因此 entry i 必须被保存下来 而 Pascal 这样的语言中 循环变量在循环外也是可见的 本次扩充约定循环步长为 1 或者 1 具体需要在程序 staement 添加 for 的句法判断 else if sym forsym 检测到for语句 getsymdo if sym ident i position id ptx if i 0 error 11 else if table i kind variable 赋值语句中 赋值号左部标识符属性应是变量 error 12 i 0 else getsymdo if sym becomes error 13 赋值语句左部标识符后应是赋值号 else getsymdo memcpy nxtlev fsys sizeof bool symnum nxtlev tosym true 后跟符to和downto nxtlev downtosym true expressiondo nxtlev ptx lev 处理赋值语句右部的表达式E1 gendo sto lev table i level table i adr 保存初值 switch sym case tosym 步长为的向上增加 getsymdo cx1 cx 保存循环开始点 将循环判断变量取出放到栈顶 gendo lod lev table i level table i adr memcpy nxtlev fsys sizeof bool symnum 处理表达式E2 nxtlev dosym true 后跟符do expressiondo nxtlev ptx lev 判断循环变量条件 比如for i E1 to E2 do S中 判断i是否小 于E2 如小于等于 继续循环 大 于的话 跳出循环 gendo opr 0 13 生成比较指令 i是否小于等于E2的值 cx2 cx 保存循环结束点 生成条件跳转指令 跳出循环 跳出的地址未知 gendo jpc 0 0 if sym dosym 处理循环体S getsymdo statement fsys ptx lev 循环体处理 增加循环变量步长为 将循环变量取出放在栈顶 gendo lod lev table i level table i adr gendo lit 0 1 将步长取到栈顶 gendo opr 0 2 循环变量加步长 将栈顶的值存入循环变量 gendo sto lev table i level table i adr gendo jmp 0 cx1 无条件跳转到循环开始点 回填循环结束点的地址 cx为else后语句执行 完的位置 它正是前面未定的跳转地址 code cx2 a cx else error 29 for语句中少了do break case downtosym 步长为的向下减少 getsymdo cx1 cx 保存循环开始点 将循环判断变量取出放到栈顶 gendo lod lev table i level table i adr memcpy nxtlev fsys sizeof bool symnum 处理表达式E2 nxtlev dosym true 后跟符do expressiondo nxtlev ptx lev 判断循环变量条件 比如for i E1 downto E2 do S中 判断i是否大于等于E2 如大于等 于 继续循环 小于的话 跳出循环 gendo opr 0 11 生成比较指令 i是否大于等于E2的值 cx2 cx 保存循环结束点 生成条件跳转指令 跳出循环 跳出的地址未知 gendo jpc 0 0 if sym dosym 处理循环体S getsymdo statement fsys ptx lev 循环体处理 增加循环变量步长为 将循环变量取出放在栈顶 gendo lod lev table i level table i adr gendo lit 0 1 将步长取到栈顶 gendo opr 0 3 循环变量加步长 将栈顶的值存入循环变量 gendo sto lev table i level table i adr gendo jmp 0 cx1 无条件跳转到循环开始点 回填循环结束点的地址 cx为else后语句 执行完的位置 它正是前面未定的跳转地址 code cx2 a cx else error 29 for语句中少了do break else error 19 for语句后跟赋值语句 赋值语句左部是变量 缺少变量 11 11 增加运算 增加运算 和和 对于 和 运算符 扩充时要注意存在 有两个情况 1 作为语句的 时候 2 作为表达式中的因子的时候 1 作为语句的时候 有四种情况 A A A A 文法的 EBNF 表示形式为 2 作为因子的时候 有两种情况 a 和 a 作为因子 比如 b a a 语句 a 和 a 作为因子 比如 b a 2 a 语句 文法的 EBNF 表示形式为 其中的 表示前后都可以有其他的项或因子 1 作为语句 符号分为以下两种情况考虑 情况 1 对于自增自减符号置后的只需要在判断 后面添加句法分析即可 后置自增符号 a a 类型添加代码 else if sym plusplus 检测到后置 符号 gendo lit 0 1 gendo lod lev table i level table i adr 找到变量地址并将其值入栈 gendo opr 0 2 执行加操作 if i 0 gendo sto lev table i level table i adr getsymdo else if sym minusminus 检测到后置 符号 gendo lod lev table i level table i adr 找到变量地址并将其值入栈 gendo lit 0 1 gendo opr 0 3 执行减操作 if i 0 gendo sto lev table i level table i adr getsymdo 情况 2 对于 前置的需要添加因子开始符号 facbegsys plusplus true 增加符号 开始因子plusplus facbegsys minusminus true 增加符号 开始因子 minusminus 前置自增符号 a a 类型添加代码 if sym plusplus getsymdo if sym ident 后面跟的是变量 i position id ptx if i 0 error 11 else if table i kind variable 后没跟变量 出错 error 12 i 0 else 后跟变量 处理生成中间代 码 if table i kind variable gendo lod lev table i level table i adr 先取值到栈顶 gendo lit 0 1 将值为入栈 gendo opr 0 2 加法 即 1 栈顶加次栈 顶 gendo sto lev table i level table i adr 出栈取值到内存 getsymdo else if sym minusminus getsymdo if sym ident 后面跟的是变量 i position id ptx if i 0 error 11 else if table i kind variable 后没跟变量 出错 error 12 i 0 else 后跟变量 处理生成中间代 码 if table i kind variable 后跟变量 gendo lod lev table i level table i adr 先取值到栈顶 gendo lit 0 1 将值为入栈 gendo opr 0 3 加法 即 1 栈顶减次栈 顶 gendo sto lev table i level table i adr 出栈取值到内存 getsymdo 2 作为因子的时候也有两种情形考虑 添加 int factor bool fsys int ptx int lev 函数如下 如果因子可能出现b a 或b a 类型的处理 if sym plusplus gendo lit lev table i level 1 将值为入栈 gendo opr lev table i level 2 加法 即 1 栈顶加次栈顶 gendo sto lev table i level table i adr 出栈取值到内存 gendo lod lev table i level table i adr 取值到栈顶 gendo lit 0 1 gendo opr 0 3 栈顶值减 getsymdo else if sym minusminus gendo lit lev table i level 1 将值为入栈 gendo opr lev table i level 3 减法 即 1 栈顶减次栈顶 gendo sto lev table i level table i adr 出栈取值到内存 gendo lod lev table i level table i adr gendo lit 0 1 gendo opr 0 2 栈顶值加 getsymdo 如果因子是表达式的时候 则有可能是包含 a或者 a 如b a或b a else if sym plusplus getsymdo if sym ident getsymdo i position id ptx if i 0 error 11 else if table i kind variable 变量 先加后再用a gendo lod lev table i level table i adr 先取值到栈顶 gendo lit 0 1 将值为入栈 gendo opr 0 2 加法 即 1 栈顶加次栈顶 gendo sto lev table i level table i adr 出栈取值到内存 gendo lod lev table i level table i adr 取值到栈顶 else if sym minusminus getsymdo if sym ident getsymdo i position id ptx if i 0 error 11 else if table i kind variable 变量 先减后再用a gendo lod lev table i level table i adr 先取值到栈顶 gendo lit 0 1 将值为入栈 gendo opr 0 3 减法 即 1 栈顶减次栈 顶 gendo sto lev table i level table i adr 出栈取值到内存 gendo lod lev table i level table i adr 取值到栈顶 testdo fsys facbegsys 23 因子后有非法符号 结束 四四 程序测试程序测试 1 扩充赋值运算 扩充赋值运算 和和 测试文件 test3 pl 运行结果 结果分析 a 9 b 3 a b 结果为 12 正确 扩充成功 2 扩充语句 扩充语句 Pascal 的的 FOR 语句 语句 测试文件 test4 pl0

温馨提示

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

评论

0/150

提交评论