ImageVerifierCode 换一换
格式:DOCX , 页数:25 ,大小:124.90KB ,
资源ID:10408349      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/10408349.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(编译原理实验手册15版.docx)为本站会员(b****7)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

编译原理实验手册15版.docx

1、编译原理实验手册15版兰州大学计算机科学与技术专业编译原理实验手册(V1.5)第一节 概述 2一、实验目的 2二、实验内容 2三、PASCAL语言子集的文法 3四、实验要求: 6第二节 词法分析 7一、目的与要求 7二、设计步骤 7三、扩充 8第三节 语法分析 9一、目的与要求 9二、设计步骤 9三、程序流程示例: 10四、扩充 12第四节 语义分析和翻译 13一、目的与要求 13二、设计步骤 13三、算法示例 14四、建议生成的四元式统一采用如下的形式: 15五、扩充 16附录一 算符优先分析算法示例 17附录二 递归下降分析算法示例 18附录三 Pascal程序示例 20第一节 概述一、实

2、验目的编译原理是一门实践性很强的课程,但由于课时所限,只能在课堂上讲授一些通用的原理和方法。而为了真正学好这门课程,必须自己动手构造出一个编译器,才能对书里讲到的原理、方法和技术有较全面的体会,才能对学生以后的程序设计和解决实际问题的能力有所帮助。实际的编译程序是十分复杂的,有时由多达十几万条指令组成。为此,编译原理的实践教学,采用简化编译过程的办法,选择最关键的三个环节词法分析、语法分析、语义分析和中间代码产生,每个环节作为一个实践课题,逐步深入,扩展功能,直至得到一个简单实用的编译器。本实验不涉及到优化。二、实验内容任何一个实用的高级语言,其语法都比较复杂,如选其作为源语言,很难实践全过程

3、。故本试验将定义一个简化的语言PASCAL语言的一个子集作为源语言,分三个课题、一步步地构造出它的编译程序。所有试验项目前后贯穿这一条主线进行。本实验共进行6周,每周3学时,共18学时。本实验主要包括以下三个课题: 词法分析:以源程序为输入,输出单词符号流; 语法分析:以源语言的文法为依据,调用词法分析器,使用递归下降分析法或算符优先分析法或SLR(1)分析法,构造能识别源语言各种语法结构的语法分析器; 语义分析和中间代码产生:使用语法制导翻译技术,对源语言程序进行简单的翻译,输出四元式序列。在本节的第三部分给出了两个PASCAL语言的子集的文法,对这些文法稍加变换,即可获得用于语法分析的LL

4、(1)文法或SLR(1)文法。学生可以直接选择一个作为编译器的源语言,也可以对这些文法进行改造,以获得能力更为强大的源语言。学生也可以自己设计源语言,来完成这些题目;唯一的要求是源语言必须包含三种基本的程序设计结构(顺序、选择、循环)和至少两种不同的数据类型。本实验要求: 所有的输入输出均采用文件形式。 独立完成。 语言不限,开发工具不限;但必须有可运行的程序和规范的注释。三、PASCAL语言子集的文法由于Pascal语言结构严谨,层次清晰,语法与C语言接近,也便于理解,因此本实验抽取Pascal语言的一个子集,稍加改造,作为源语言,姑且命名为LittleP。一个LittleP程序由一系列全局

5、数据声明和一个主程序体组成。所有数据采用静态存储分配,没有I/O,只支持一种基本数据类型:无符号整数。1. LittleP的文法:程序程序首部程序体程序首部 program程序名; 程序体变量声明复合语句变量声明 var变量定义列表|空 变量定义列表 ;变量定义|变量定义 变量定义变量名列表: 变量名列表,变量名|变量名 integer 复合语句 begin 语句块 end 语句块语句语句块 ;语句语句赋值语句|条件语句|循环语句|复合语句|空赋值语句左部:= 右部 左部变量名右部算术表达式条件语句 if(关系表达式)then语句else语句循环语句 while(关系表达式)do语句 算术表达

6、式关系运算符算术表达式 项| 算术表达式加运算符项 因子| 项乘运算符因子因子变量名(算术表达式) 整数程序名标识符变量名标识符标识符字母标识符字母标识符数字整数数字整数数字关系运算符 | | = | | 加运算符 + | - 乘运算符 * | / 字母 a|b|x|y|z 数字 1|2|3|4|5|6|7|8|9|02.在此基础上加以扩充,可得功能较强的一个 LittleP 语言的超集:LittleP+。该语言引入了布尔型、一维数组和过程、函数的定义,参数传递采用传值方式。另外,加入了I/O支持,编译器提供两个系统函数:read()和write()。程序程序首部程序体程序首部 program

7、程序名; 程序体变量声明复合语句变量声明 var变量定义列表|空 变量定义列表 ;变量定义|变量定义变量定义变量名列表: 变量名列表,变量名|变量名 | integer | boolean array 下界.上界 of 分程序分程序声明|空分程序 分程序首部变量声明复合语句分程序首部 procedure过程名( );| function 函数名( ) : ; 形参定义 ,形参列表|形参定义|空形参定义变量名: 复合语句 begin语句块end 语句块语句语句块 ;语句语句赋值语句|条件语句|循环语句|过程调用语句|复合语句|读写语句|空赋值语句左部:= 右部左部变量名变量名 算术表达式 右部算

8、术表达式条件语句 if (逻辑表达式) then语句else语句循环语句 while (逻辑表达式) do语句过程调用语句过程名( ) |函数名( ) 算术表达式| 算术表达式 ,实参列表|空读写语句 read ( ) | write ( ) 逻辑项| 逻辑项逻辑运算符逻辑项 and | or |变量名| not true | false 算术表达式关系运算符算术表达式 项| 算术表达式加运算符项 因子| 项乘运算符因子因子变量名(算术表达式)函数名() 变量名 算术表达式 整数 程序名标识符变量名标识符过程名标识符函数名标识符标识符字母标识符字母标识符数字整数数字整数数字关系运算符 | |

9、= | | 加运算符 + | - 乘运算符 * | / 字母 a|b|x|y|z数字 1|2|3|4|5|6|7|8|9|03.对源程序语法的其他说明: 出现在 里的所有字符作为注释跳过。 各单词符号之间的空格可有可无,但关键字和标识符必须分隔开来。 分号作为语句之间的分割符;逗号作为语句内的分割符;一个完整的程序以点号作为结束符号。 过程没有返回值,只能出现在过程调用语句中;函数有且只有1个返回值,只能出现在算术表达式中或作为赋值语句的右部。函数返回值通过函数名带回,因此在函数体内必须给函数名赋值。 标识符的长度不得超过8个字符。 关键字保留,不得用做标识符。 read和write以缺省库函

10、数的形式实现,对stdin和stdout进行读写。 四、实验要求:每个课题完成后写出实验报告。实验报告应该包括: 程序设计时考虑的算法和主要的数据结构; 可执行的程序 至少2个测试用例,包括: 至少1个合法的源程序及其运行结果; 至少1个非法的源程序及其错误报告。第二节 词法分析一、目的与要求.目的通过设计、调试词法分析程序,实现从源程序中分离出各种单词的方法;加深对课堂教学的理解,尤其是对正规式、有穷自动机的原理和用途的理解;为以后软件开发过程中设计高效率的扫描器打下基础。.要求 应有适当的预处理。 输入源程序,输出定长单词符号流,均采用文件形式。 针对选定的源语言,构造识别其合法单词符号的

11、词法分析器。 应考虑到后续阶段的需要,合理设计词法分析器的结构。 本实验应在一周内完成。二、设计步骤1. 问题分析: 分析源语言的文法,找出各种词法单位的构词规则。 工作流程:构词规则正规式NFADFA状态转换图程序 ; 构词规则状态转换图程序 。 预处理:有哪些预处理工作要做。2. 总体设计: 输入输出缓冲区,输出格式(等长二元式序列); 表格设计(设计几张表,每张表登记什么信息): 关键字表 算符、分隔符表 变量表:简单变量、数组、过程与函数 出错处理。3. 程序流程设计:明确程序所使用的主要算法,一般以伪代码或程序流程图表示。图1给出了一个程序流程图的例子,作为参考。4. 编码与测试:编

12、写程序并调试通过,然后自己设计至少3个测试用例。测试用例包括两部分:输入(源程序代码)和预期结果(运行结果或错误信息)。5. 编写实验报告。图1 词法分析程序流程图 三、扩充有余力的同学,可适当扩大分析对象。譬如:1. 加入更多的数据类型,如:字符型和字符串型的常量、变量。2. 加入一元算术运算符,如:取负运算或自增自减运算 。第三节 语法分析一、目的与要求1. 目的通过设计、编写、调试一个典型的语法分析程序,实现对词法分析程序所提供的单词序列进行语法分析和检查,进一步掌握常用的语法分析方法的实现技术。2. 要求 调用词法分析器,分析源程序的语法结构(识别出各种语法结构),指出源程序中是否含有

13、语法错误。 推荐使用算符优先分析算术表达式,用递归子程序法分析其他各种语法结构,例如各种语句等。也可以使用LR分析法完成这些工作。 输入文本文件形式的源程序;输出分析结果(正确与错误)到文件。 本课题应在两周内完成。因时间紧张,建议采用增量开发模式:从简单到复杂、能力逐渐增强。 二、设计步骤1. 问题分析: 使用哪种语法分析方法?单独使用递归下降分析法可以完成任务吗? 从文法中提炼出主要的语法结构,如:程序、变量声明、分程序声明、复合语句、IF语句、算术表达式等,认真分析他们的语法结构。 如何利用前面构造的词法分析器和相关表格? 考虑错误处理的方法。2. 总体设计: 对文法进行必要的等价变换,

14、使之符合所选语法分析方法的要求。 若有必要,对上次实验后得到的词法分析器及相关符号表进行调整。 针对产生算术表达式(关系表达式)的文法,构造算符优先关系表,在此基础上,编写一小段程序,分析这类语法结构。(算法示例见附录一) 针对各种语法结构,逐一产生其递归下降分析的状态转换图,再一一翻译为程序段。(算法示例见附录二) 设计输出的形式。 将前面的工作组合起来,形成一个完整的语法分析器。3. 程序流程设计。4. 编码和测试:编写代码,调试通过,并设计测试用例。5. 编写实验报告。 三、程序流程示例:题目:递归下降法分析表达式(此题目仅供参考,而且不完全准确)1. 分析对象的BNF定义如下:算术表达

15、式项|算术表达式项|算术表达式项项因式|项因式|项因式因式变量(算术表达式)变量字母字母A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z 用递归下降法分析上述算术表达式的框图,如图2所示。(a)(b) (c)(d) (e) (f)图2 递归下降法分析表达式之框图(a) ZC 过程;(b) E 过程;(c) T 过程;(d) F 过程;(e) 函数过程 SYM ;(f) 过程 ADVANCE这里,ZC过程为总控程序,主要完成: 通知外界键入算术表达式; 控制过程分析算术表达式; 根据分析结果之正误,分别通知外界不同的信息。ZC过程被设计成可以

16、分析无穷多个算术表达式。E、T和F三个过程分别对应算术表达式、项和因式三个产生式的处理。它们用到两个公共过程。一个是函数过程SYM,它负责从输入字符串ST中取出下一个字符,并存入SYM中等待分析。另一个过程ADVANCE负责剔除ST中的首字符。四、扩充有余力的同学,可适当扩大分析对象。譬如:1. 加入 for 循环语句: for i:=1 to 5 do begin dosomething() end ;2. 引入二义性文法: stmt if cond then stmt else stmt | if cond then stmt 3. 加强语法检查,尽量 多 和 确切 地指出各种错误。第四节

17、 语义分析和翻译一、目的与要求1. 目的通过上机实习,加深对语法制导翻译和运行时存储空间分配的理解,掌握将语法分析所识别的语法范畴变换为某种中间表示的语义翻译方法。2. 要求 采用语法制导翻译方法。 实现简单的静态语义检查。 将通过检查的源程序翻译成中间表示。 中间表示可以选用:三元式、四元式或抽象语法树。 以两周内完成为宜。二、设计步骤1. 问题分析: 要做哪些静态语义检查工作,可以从以下几点来考虑:i. 标识符必须先说明,再使用;ii. 同一作用域内不得重复定义(不能重名);iii. 操作数与操作符的类型匹配a) 定义在integer上的运算:+ - * / 和关系运算符;b) 定义在bo

18、olean上的运算:not or and ;c) 赋值运算符:=两端的类型应该相同。iv. 还可以考虑数组下标越界和函数的形、实参匹配的问题;v. 对于不满足上述规则的,应给出错误提示;vi. 检查工作可以安排成单独一遍:在语法分析之后,翻译之前;也可以“语法、检查、翻译”三项工作一遍完成,把语义检查和翻译的代码插入语法分析过程之中。 如何把语法分析和语义分析结合起来(把语义子程序加入语法分析中); 如何设计语义子程序来产生中间表示: 声明语句:只操作符号表,不翻译代码; 数组元素:地址计算; 算术表达式及赋值:直接翻译; 条件语句: 先求值(同算术表达式)再判断;按照短路法则判断; 否定判断

19、:源代码中的条件是否不成立? 跳转目标:拉链返填 循环语句:同上; 子程序结构:先传参,再转移; 读写语句:特殊处理,可参照C语言的库函数方式。2. 总体设计: 对文法进行必要的等价变换,并为每条产生式添加语义规则。 将语义规则转换成语义子程序,生成中间表示; 分析各种语法结构,把语义子程序加入到语法分析代码的合适位置; 把四元式列表输出到文件。3. 程序流程设计:核心是语义子程序的设计。4. 编码与测试。5. 编写实验报告。三、算法示例 题目:在对简化的算术表达式进行语法分析的同时生成四元式(仅作参考)。 四元式生成程序的核心部分(指表达式、项和因式的处理)的算法,可描述如下: PROCED

20、URE E; BEGIN E1PLACE:=T; WHILE SYM=+ OR - DO BEGIN ADVANCE; E2PLACE:=T; T1:=NEWTEMP; GEN(,E1PLACE,E2PLACE,T1); E1PLACE:=T1 END; RETURN(E1PLACE) END; PROCEDURE T; BEGIN T1PLACE:=F; WHILE SYM=* OR / DO BEGIN ADVANCE: T2PLACE:=F; T1:=NEWTEMP; GEN(*/,T1PLACE,T2PLACE, T1); T1PLACE:=T1 END; RETURN(T1PLACE

21、) END; PROCEDURE F: BEGIN IF SYM= 标识符 THEN BEGIN ADVANCE; RETURN(ENTRY(i) END ELSE IF SYM=( THEN BEGIN ADVANCE; PLACE:=E; IF SYM=) THEN BEGIN ADVANCE; RETURN(PLACE) END ELSE ERROR END ELSE ERROR END.这里:E表达式;T项;F因子;ADVANCE将输入串指针调整至指向下一个输入字符;NEWTEMP分配一个新的工作单元;GEN将一个四元式填入四元式表;ENTRY查找变量名表,并获得名字所在位置值。四、建

22、议生成的四元式统一采用如下的形式: 赋值: 形如 x:=y 的赋值语句,x,y 采用内存直接寻址。 形如 x := yi 和 yi := x 的赋值语句。y是基址,i是偏移量。 控制流程转移: 无条件跳转 goto L , L是接下来要执行的四元式的编号。 条件跳转 jump x L ,若x为真,则跳转至L所指的四元式;否则顺序执行。x 指向内存中某个boolean型的值。 过程调用:先传参,后转子。 传参数 param x ,有n个参数就生成n条传参数四元式; 过程调用call p, n ,其中:p是过程或函数名,n 表示参数的个数; 返回值 return y 。五、扩充1. 在C语言中数组

23、名是一个常量,代表数组的首地址;而Pascal语言中数组名代表一个数组变量,因而可以用以下用法:定义 a ,b : array-7.16 of boolean; 引用 a := true; b := a;考虑实现这种用法。(深层次考虑,每种工具中一些东西的实现方法,找出各种工具的优势)2. 熟悉汇编的同学,也可以考虑一步到位,直接从源代码翻译成某种汇编。附录一 算符优先分析算法示例Tree term2Rest( Tree t , int minprec) / minprec is the lowest precedence of all binary operators. Tree odSta

24、ck = newOdStack(); /stack of operands; int opStack = newOpStack(); /stack of operators. int top = 0; /top pointer of stack. odStack0 = t ; int startPos = S.pos ; / S is a scanner. It returns a token and its position everytime . /topOp is always the top element of opStack. Its initial value is error.

25、int topOp = ERROR; while ( prec( S.token) = minprec) /移进opStacktop = topOp; top+; topOp = S.token; int pos = S.pos ; S.nextToken(); odStacktop = term(); / term() 分析表达式中的“项” /规约 while ( top0 & prec(topOp) = prec( S.token ) ) / You can do something here, such as creating a syntax tree or calculating t

26、he value. odStacktop-1 = makeop( pos, topOp, odStacktop-1, odStacktop ) ; top- ; topOp = opStacktop; . .#附录二 递归下降分析算法示例SyntaxTree* Parser:Statement() SyntaxTree *tree = NULL; switch(currentToken.type) . case ID: this-nextToken(); tree = Assign(); if(tree != NULL) tree-addLeft(ID); break; case WHILE: this-nextToken(); tree = While(); break; case BEGIN: this-nextToken(); tree = Block(); if(currentToken.type != END) tree = NULL; this-printError(ERROR! begin without end); this-currentToken.type = SEMI; break; case IF:

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1