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

加入VIP,免费下载
 

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

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

下载须知

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

版权提示 | 免责声明

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

编译原理语法分析试验报告.docx

1、编译原理语法分析试验报告二、语法分析(一) 实验题目编写程序,实现对词法分析程序所提供的单词序列进行语法检查和 结构分析。(二)实验内容和要求1.要求程序至少能分析的语言的内容有:1) 变量说明语句2) 赋值语句3) 条件转移语句4) 表达式(算术表达式和逻辑表达式)5) 循环语句6) 过程调用语句2.此外要处理:包括依据文法对句子进行分析;出错处理;输出结果的 构造。3.输入输出的格式:输入:单词文件(词法分析的结果)输出:语法成分列表或语法树(都用文件表示),错误文件(对 于不合文法的句子)。4.实现方法:可以采用递归下降分析法,LL (1)分析法,算符优先法或 LR分析法的任何一种,也可

2、以针对不同的句子采用不同的分析方法。(三)实验分析与设计过程1.待分析的C语言子集的语法:该语法为一个缩减了的C语言文法,估计是整个C语言所有文 法的60% (各种关键字的定义都和词法分析中的一样),具体的 文法如下:语法:100: program - declaiationjist101: declarationjist - declarationjist declaration declaration102: declaiation - vai_declaiation|fijn_declaration103: vai.declaration - type_specifier ID;|tvp

3、e_specifier ID NUM;104: typ Jsp亡cifki - mt|void|float|chai-|long|double|105: fun_declaration - type_specifier ID (params)|compound_stmt106: paranis - params_list|void107: paramjist -paiam_list.paiam|paiam108: param - type-spectifier ED|type_specifier LD109: compound_stmt - locaLdeclaiations statemen

4、tjist110: locaLdeclarations - local_declarations var_declaration|empty111: statementjist - statementjist statement|emptv112: statement - epiesion_stmt|conipound_stmtselection.stmt iteration_stmt|retuin_stmt113: expressionstmt - expression;!;114: selection_stmt - ifexpressionjstatement if(expression)

5、statement else statement115: iteration_stmt - wliileexpression)statement116: return_stmt - return;|return expression;117: expression - var = expression|siinple-expression118: var - ID | ID expression119: suuple_expression -additive_expression relop additive_expression|additive_expression120: relop -

6、 =|=|= =|!=121: additive_expression - additive_expression addop term | term122: addop - + | -123: term - term mulop factor factor124: mulop - *|/125: factor - (expression)|var|call|NUM126: call - ID(aigs)127: args - aig_list|empty128: arg_list - arg_list,expression|expression该文法满足了实验的要求,而且多了很多的内容,相当

7、于一 个小型的文法说明:把文法标号从100到128是为了程序中便于找到原来的文法。2.实现方法的选择:因为时间的问题,我选择了递归下降的方法进行开发。3.消除左递归因为递归下降要求文法中不能出现有左递归的产生式,因 此必须把待分析的C语言子集的语法中带有左递归的都消除左 递归。其中产生式101、110、111、121、123、128均为左递归 文法。这些产生式消除左递归后的文法如下:1)101消除左递归后的产生式分别为:101: declaration_list - declaration declarationist_zdg135: declaration_list_zdg- declara

8、tion declaration_list_zdgempty2)110消除左递归后的产生式分别为:110: local_declarations - empty 1 o c a l_de c 1 ar a t i on s_z dg133: local_declarations_zdg-var_declarationlocal_declarations_zdgempty3)111消除左递归后的产生式分别为:111: statement_list- empty statement_1ist_zdg134: statement_list_zdg-statement statement_list_z

9、dg empty4)121消除左递归后的产生式分别为:121: additiv亡.expression - term additive_expression_zdg131: additive_expression_zdg- addop term addit ive_expression_zdgempty5)123消除左递归后的产生式分别为:123: term - factor term_zdg132: term_zdg- mulop factor term_zdg empy6)128消除左递归后的产生式分别为:128:arg_listexpress ion arg_list_zdg129:ar

10、g_list_zdg-r expression arg_list_zdg empty说明:empty代表可以为空。4.词法分析和语法分析的关系由于语法分析要用到词法分析的结果,在词法分析中,我逐 个得到单词,而语法分析的整个过程中都必须利用从词法分析中 得到的每一个单词,因此从语法分析的入口点开始就必须利用 token读取源C程序的第一个词,然后再语法分析的过程中,采取 相关的措施,在匹配当前单词后继续利用token读取下一个单词。5.递归下降的思想递归下降的思想在于“递归”二字,对于每一个消除了左 递归的产生式,通过为每一个产生式建立一个函数,函数名为相 应的产生式的左部,然后对产生式的每一

11、项进行展开,如果产生 式的右部碰到一个非终结符,则调用这个非终结符的函数(该非 终结符肯定是一个产生式的左部,为之建立一个函数),如果遇 到的是一个非终结符,则调用match ()方法(见下文),match 方法除了匹配当前的非终结符之外,还调用了词法分析的token 方法,读取下一个单词。这里举一个例子來说明:下面的产生式是一个关于变量定义 的产生式:vai_declaration - typespecifier ID:來说,编写的函数名为var_declaration的方法:简单的表达如下:public void var_declaration () typespecifiei ();ID

12、 ();match (SEMICOLON): / SENflCOLON表示分号其他的产生式的函数编写都跟这个vardeclaration函数类似。只 是,但是还有的产生式有比这复杂的地方,在后面继续说明。6.结果输出形式和错误处理1)结果的输出形式当碰到一个单词,我首先输出这个单词的类型,因为用 到的是递归函数,对于每个产生式,当展开到产生式的末尾 的时候,我就把反映该产生式的源代码(规约)都输出,当 最后到达产生是式pegiam(即分析出了是一个程序),便输出 整个程序,因此这种方法是一个反映了我语法分析过程的结 果输出。当遇到一个单词或者遇到了一个产生式的规约,便 输出结果,方法为:pub

13、lic void syiitaxPnnt(Strmg message, Strmg blk, mt n) 其中参数message为:当当前的输出为当前单词时,message 为当前的词类型,当当前的输出为一个产生式的规约时, message为当前用于规约的产生式。参数blk是为了方便结果 输出的时候,在程序中间加上必要的空格。参数11表示当前 用于规约的产生式的项的个数,当知道个数后,便与把保存 在栈顶的n个元素连接起來并且输出。2)错误处理因为语法分析的时候,源程序有很多的不符合语法的地 方,因此就需要处理,更重要的是需要进行错误恢复,以便 语法分析输出当前的错误后继续正确地进行分析。这里我

14、采 用了栈的形式來进行错误恢复(见数据结构设计与建立)7.数据结构(栈)这里用到了栈,栈的运用在这里主要就是用于结果的输出和 错误处理。当分析一个产生式的时候,如果发现当前的字符匹配,则把 当前的字符压入栈中,或者当前的不是一个字符,而是一个非终 结符(一个函数),则因为该函数也进行了相应的处理,当函数 结束的时候把一个字符串压在栈中,因此直接调用这个函数的时 候己经实现了压栈的动作,然后在输出该非终结符所表示的源程 序的时候,把在该非终结符的函数中压入栈中的内容合并成一个 字符串输出后再压回栈顶。实现了递归调用。如果在该非终结符的函数展开过程中,出现的错误,也即当 前的字符并不是产生式所需要

15、的,那么便往栈中压入一个空字 符,即做了错误恢复,从而继续进行分析。个人感觉利用栈让我很好地解决了分析结果的输出和错误 处理恢复。& 产生式函数的流程图这个问题是我在语法分析中遇到的比较棘手的儿个问题 之一,主要分成以下的几种情况。1)产生式的右部只有一种情况,如产生式102、126等 以 126: call - ED(args)为例,说明我处理这种情况的处理方法:因为产生式有右 部的F1攻集为ID (即标识符),的程序流程图,见下面的 流程图(3)流程图(3)2) 产生式的右部有两个或者两个以上的规约产生式,但是右部的这两个或者两个以上的产生式的Fust集并不 相同,如产生式112、113等

16、,其中还有复杂一点的情况, 因为有的产生式的右部的Fust有很多,或者是Fust集的寻 找比较困难,需要找到很多的产生式,这个属于Fust集的 寻找,在这里就不详细描述了。我以产生式112statement -expiession_stmt|compound_stmt|selection_stmt|iteiation_stmt|retum_stmt为例来说明处理这种情况的产生式的方法,其中 iteiation_stmt 的 Fiist集为WHILE, selection_stmt 的 Fust集为 if, retuin_stmt 的Fust 集为 RE TURN, compound_stmt

17、的 Fust 集为 LH, expression_stmt|的First集为LB、SEMICOLON和ID,详 细的流程图见下图流程图(4)流程图(4)3)产生式的右部有两个或者两个以上的规约产生式,但 是右部的这两个或者两个以上的产生式的Fust集的第 一个或者前几个都相同,如产生式103、108、116等, 则在这种情况下,就不像前两种情况那么简单了,因 为知道了当前的单词并不能知道到底使用哪个产生式 來进行规约,因此当当前字符相同的时候,需要读下 一个字符,如果下一个字符仍然相等,则继续往下读 取,一直到遇到的字符可以区分是使用哪个产生式为 止。在这种情况下,就需要在第一个字符的时候,记

18、 住当前的字符的位置,以便在判断知道是使用哪个产 生式的时候可以回退到函数刚开始的字符的位置,进 而用正确的产生式进行展开。下面以产生式116116: retum_stmt - return;|return expression;为例來说明这种情况的产生式的处理方法,因为产生式 右部的两个产生式的Fust集都为leUun,因此先记录当 前的状态,判断下一个词,如果为分号,则用左边的产 生式,如果为 ID、NUMBER 或 LB (expiession 的 Fust 集为LD、NUMBER或LB)则回退到当前字符为return 的状态,用产生式:retum_stmt -return expres

19、sion;详细的分 析见流程图(5)流程图(5)4)关于产生式中的empty的处理消除了左递归之后的那些产生式中都有empty的 现,empty代表可以为空。因此在这种情况下,就往 栈中压入一个空字符:tlus.mystack.push(H);5)其他的各种情况都在上述的几种情况之中,大同小异 因此这里不再赘述。9. 语法分析的流程图在把所有的产生式的函数都写好后,语法分析的过程就变得很 简单了,因为程序的入口点就是函数p】ognim(),只要用token为 其读取第一个单词即可进行以后的分析,以后的分析中在其他 的各个函数中实现了单词的读取和结果的输出以及错误的恢 复处理等。流程图见流程图(

20、6)o流程图(6)(四)实验编写代码和测试1.代码的编写,由于递归的实现就是为每个函数建立一个函数,对 不同的产生式类型用不同的方法进行编写,但由于逻辑的判断和 转换比较多,因此很容易出错和导致思维的混乱。由于用到的栈处理比较多,因此对栈的使用前先做了不少的测 试。2.程序的测试用例和结果输出,以及相应的错误恢复与错误显示。1)正确的测试用例以及结果测试用例:void niain(void)/* 主函数*7 int ss32;if(a = b)return a; else return b;wliile (a = b) a=b+a;结果显小: 分析结果显示 type_specifier voi

21、d void parains-void void type_specifier mt iiit vai_declaration typespecifier IDfNUNI; mt ss 32 ; locaLdeclaiations_zdg- var_declaration local_declaiations_zdg empty mt ss32;factor-vai- aterm - factor term_zdg aadditive_expression - term additive_expression_zdg a factor-vai- bterm - factor term_zdg

22、badditive_expression - term additive_expression_zdg b siinple_expression - additive_expression relop additiveexpression a = b expression -smiple_expiession a = bfactor-vai- aterm - factor term_zdg a additive_expression - term additive_expression_zdg a siinple_expression - additive_expression a expre

23、ssion -smiple_expression aretiiinstint - return expression; return a ; statement - return_stmt leturn a ;selection_stmt - if(expression)statement if(a = b )return a; statement - selection_stmt if(a= b)return a ;factor-vai- aterm - factor term_zdg a additive_expression - term additive_expression_zdg

24、a factor-vai- bterm - factor term_zdg badditive_expression - term additive_expression_zdg b siinple_expression - additive_expression relop additiveexpression a = b expression -smiple_expiession a = bfactor-vai- bterm - factor term_zdg baddop-+factor-vai- aterm - factor term_zdg aadditive_expression_

25、zdg- addop term additive_expression_zdg|empty +a additive_expression - term additive_expression_zdg b + a siinple_expression - additive_expression b + a expression -smiple_expression b + a expression - vai = expression a=b + aexpression_stint - expression; a=b + a ; statement - epresion_stmt a=b + a

26、 ;iteration_stmt - while(expression)statementwhile (a= b) a=b + a ; statement - iteration_stmt wliile (a= b) a=b + a;statement_list_zdg-statement statementjist_zdg|emptv while(a = b ) a=b + a ;statement_list_zdg-statement statement_list_zdg empty if(a=b)renin a; wliile ( a= b) a=b+ a ; statement_lis

27、t- statement_list_zdg if(a=b)return a; wliile(a= b) a=b+ a;compound_stint - local_declaiations statementjist iiit ss 32 ;if(a= b)ieturn a ; wliile ( a= b) a=b+ a ;declaration - fiin_declaration void niaiii (void) iiit ss 32 ; if(a = b)return a; wliile (a= b) a=b+ a; declarationjist -declarations dec

28、laration_list_zdg void main () ) mt ss 32 ; if(a= b)return a; wliile ( a= b) a=b + a;program - declaration_list void main ( void ) iiit ss 32 ; if(a = b)return a; wliile (a= b) a=b+ a; 2)测试用例中含有错误,错误显示 含错误的测试用例:int fiinction( param,int s)/* 参数没有定义 paiain=paiaiii*paianV * 失 分 号 */ int functioiiB(floa

29、t param,int sdd ss )/*数组参数中含有非法字符*/paiam=paiam*paiam;float functionC(float paranint s )/*数组参数 s 中缺少T*/paiam=paiam*paiam;void niam(void)int aa;if(aa=bb)dd=aa-bb;/*if 语句缺少丁 *7elsereturn /*return 语句缺少严/wliile(aa参数param没有定义类型或者缺失类型 声明!第3行有语法错误!:丢失!第4行有语法错误!数组参数s中卩中含有非法字符!第4行有语法错误!数组参数s中卩中含有太多的非法字符!第7行有语法错误!数组参数s中卩中含有非法字符!第7行有语法错误!数组参数s中缺失丁!第16行有语法错误!语句缺少丁!第18行有语法错误! return语句缺少:!第19行有语法错误! wlule语句缺少)说明:如果有的错误是出现在词法分析中的,就会导致语法分析 的错误不会太全面,或者会造成语法分析中的一些程序上的多次循 环,但是不管怎么样,被分析的程序只要出现错误范围是违背了我 的产生式的情况的,编译器都应该可以找出來的。

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

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