logo资料库

编译原理 文法的化简与改造.doc

第1页 / 共20页
第2页 / 共20页
第3页 / 共20页
第4页 / 共20页
第5页 / 共20页
第6页 / 共20页
第7页 / 共20页
第8页 / 共20页
资料共20页,剩余部分请下载后查看
一.实验目的
二.实验环境
三.实验内容
深 圳 大 学 实 验 报 告 课程名称:编译原理 实验名称:文法的化简和改造 姓 名: 学 号: 班 级: 实验日期:
一.实验目的 1) 编写文法的化简和改造程序; 二.实验环境 1) 硬件环境:计算机; 2) 软件环境:C/C++编译器; 三.实验内容 1. 用 C/C++语言编写方法的化简和改造程序,实现以下功能之一(如实现两个功能,则满 分为 110 分;如实现三个功能,则满分为 120 分): (1) 无用符号和无用产生式的删除,参考课本中算法 2.1 和算法 2.2。 (2) ε-产生式的消除,参考课本中算法 2.3、2.4 和 2.5。 (3) 单产生式的消除,参考课本中算法 2.6。 从文件或终端中读入文法,并将化简和改造后的文法输出到另一文件或终端中。文法的表 示如下: S->aS S->W S->U U->a V->bV V->ac W->aW 用空字符表示ε 用大写的拉丁字母表示文法的非终结符号,用小写的拉丁字母表示文法的终结符号,每个 产生式占一行,第一个产生式的左部为开始符号。在下面写出代码,并用课本 2.4 节中相应 的例子进行验证,提供相应的截图(对窗口截图时先同时按 alt 和 prtscn 键,再按 ctrl+v 粘贴) 答:因为这一次的实验的代码量大概有 1300 行,所以没有在下面只写出书本中算法的主要 代码,其他的实验代码请老师看压缩包;因为我这一次的实验是以 txt 的格式输出结果,请 老师去看压缩包里的输出结果 删除单产生式.txt 、删除无用产生式.txt 、消除空产生
式.txt 等文件。实验代码通过课后的习题验证都没有问题,但在课本 2.4 节中相应的例子中 删除掉无用符号和无用产生式后的结果与课本中的结果不一样 课本中的结果为: S->aS S->U U->a 而在实验中输出结果为: S->aS S->a 下面是书本中算法的主要代码: //algorithm21, algorithm22 用于消除无用产生式 //算法 2.1 void algorithm21() { SymbolSet VN1; ProductionSet P1; struct Lnode *left = NULL; struct Rnode *right = NULL; int flag = 0, added = 1; VN1.next = NULL; P1.next = NULL; P1.num = 0; //第一步 left = Productions.next; while(left) { flag = 1; right = left->right; while(right) { if(strcmp(right->name, "") == 0)
break; if(IsInSet(&Terminators, right->name) == 0) { } flag = 0; break; right = right->next; } if(flag == 1) { } //如果原来不存在则添加 if(IsInSet(&VN1, left->name) == 0) AddSym(&VN1, left->name); left = left->next; } //第二步 added = 1; while(added) { added = 0; left = Productions.next; while(left) { flag = 1; right = left->right; while(right) { if(strcmp(right->name, "") == 0) break;
if((IsInSet(&Terminators, right->name) == 0) && ( IsInSet(&VN1, right->name) == 0)) { } flag = 0; break; right = right->next; } if(flag == 1) { } //如果原来不存在则添加 if(IsInSet(&VN1, left->name) == 0) { } AddSym(&VN1, left->name); added = 1; left = left->next; } } //第三步 left = Productions.next; while(left) { flag = 1; right = left->right; while(right) { if(strcmp(right->name, "") == 0) break;
if((IsInSet(&Terminators, right->name) == 0) &&( IsInSet(&VN1, right->name) == 0)) { } flag = 0; break; right = right->next; } if(flag == 1) AddPro(&P1, left); left = left->next; } //转移到系统链表集合 { } //删除原有的 ClearProductionSet(&Productions); DestroySymbolSet(&NonTerminators); //转移 Productions.num = P1.num; Productions.next = P1.next; NonTerminators.next = VN1.next; } //算法 2.2 void algorithm22() { SymbolSet VN1, VT1; ProductionSet P1; struct Lnode *left = NULL;
struct Rnode *right = NULL; int flag = 0, added = 1; VN1.next = NULL; VT1.next = NULL; P1.next = NULL; P1.num = 0; //开始符号放入 VN1 AddSym(&VN1, Start); //第一步 added = 1; while(added) { added = 0; left = Productions.next; while(left) { if(IsInSet(&VN1, left->name) == 1) { right = left->right; while(right) { if(IsInSet(&NonTerminators, right->name) == 1) added = AddSym(&VN1, right->name); else if(IsInSet(&Terminators, right->name) == 1 || strcmp(right->name, "") == 0) added = AddSym(&VT1, right->name); right = right->next; } }
left = left->next; } } //第二步 left = Productions.next; while(left) { flag = 1; if(IsInSet(&VN1, left->name) == 1) 0) { } right = left->right; while(right) { } if(IsInSet(&VN1, right->name) == 0 && IsInSet(&VT1, right->name) == { } flag = 0; break; right = right->next; if(flag == 1) AddPro(&P1, left); left = left->next; } //转移到系统链表集合 { //删除原有的
分享到:
收藏