2022年编译原理实验报告-LL文法构造 .pdf
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_05.gif)
《2022年编译原理实验报告-LL文法构造 .pdf》由会员分享,可在线阅读,更多相关《2022年编译原理实验报告-LL文法构造 .pdf(18页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、实验 3 LL (1)文法构造一、实验目的熟悉 LL (1)文法的分析条件,了解LL (1)文法的构造方法。二、实验内容1、编制一个能够将一个非LL ( 1)文法转换为LL (1)文法;2、消除左递归;3、消除回溯。三、实验要求1、 将一个可转换非LL (1)文法转换为LL (1)文法,要经过两个阶段,1)消除文法左递归, 2)提取左因子,消除回溯。2、 提取文法左因子算法:1)对文法G的所有非终结符进行排序2)按上述顺序对每一个非终结符Pi 依次执行 : for( j=1; j Pi| ,其中 不以 Pi 开头,则修改产生式为:Pi Pi Pi Pi| 3)化简上述所得文法。3、 提取左因子
2、的算法: A 1| 2| | n| 1| 2| | m ( 其中 , 每个 不以开头 ) 那么 , 可以把这些产生式改写成 A A| 1| 2| m A 1| 2| | n4、 利用上述算法,实现构造一个LL (1)文法:1) 从文本文件g.txt 中读入文法,利用实验1 的结果,存入实验1 设计的数据结名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 1 页,共 18 页 - - - - - - - - - 构;2) 设计函数remove_left_recursion ()和 rem
3、ove_left_gene()实现消除左递归和提取左因子算法,分别对文法进行操作,消除文法中的左递归和提出左因子;3) 整理得到的新文法;4) 在一个新的文本文件newg.txt 输出文法,文法输出按照一个非终结符号一行,开始符号引出的产生式写在第一行,同一个非终结符号的候选式用“|”分隔的方式输出。四、实验环境PC 微机DOS 操作系统或Windows 操作系统Turbo C 程序集成环境或Visual C+ 程序集成环境五、实验步骤1、学习 LL (1)文法的分析条件;2、学习构造LL (1)文法的算法;3、结合实验1 给出的数据结构,编程实现构造LL (1)文法的算法;4、结合实验1 编
4、程和调试实现对一个具体文法运用上述算法,构造它的LL (1)文法形式;5、 把实验结果写入一个新建立的文本文件。六、测试数据输入数据:编辑一个文本文文件g.txt,在文件中输入如下内容:正确结果:本实验的输出结果是不唯一的,根据消除左递归是选择非终结符号的顺序不同,或选择新的非终结符号的不同,可能会得到不同的结果,下面只是可能的一个结果:七、实验报告要求实验报告应包括以下几个部分:1、 满足 LL (1)文法的分析条件;转换前要求文法中不含回路(经过推导有形如P-P 之类的),也不含以 为右部的产生式。一个文法要能进行LL (1)分析,那么这个文法应该满足:无二义性,无左递归,S-Qc|c|c
5、ab; Q-Rb|b; R-Sa|a; S-Qc|cT; T-|ab; /由于无法输出 ,用 代替Q-Rb|b; R-bcaU|caU|cabaU|aU; U-bcaU|; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 2 页,共 18 页 - - - - - - - - - 无左公因子。首先需要定义一些规则:1.在程序运行前文法就必须输入进文本文件中,输入的文法只包含其中的所有产生式,并且默认其为可转换的非LL (1)文法,即通过消除左递归和反复提取公共左因子,就转换成了LL (
6、1)文法。2.输入的产生式为原实验1 的结果,即一个非终结符只有一条产生式,候选之间用“ |”隔开。3.产生式与产生式之间只能以换行符或分号隔开。4.开始符号对应的产生式必须第一个输入,即默认输入的第一个产生式的左部的大写字母是开始符号。5.输入与输出都会保存在文本文件中文件名分别是g.txt 和 newg.txt,本实验测试数据时,将两个文本放在了桌面。6.用 代替,输入与输出都使用 。7.新产生的非终结符统一使用没有在非终结符集合中出现的大写字母。8.规定产生式最多只有20 个。2、 构造 LL (1)文法的算法;算法:1)从文本文件g.txt 中读入文法,存入结构体中。将第一个读到的大写
7、字母记为开始符号S,将读到的包括开始符号在内的所有大写字母判定为非终结符,并将第一次出现的存入文法的非终结符集合中,终结符小写字母也一样。将以换行符或分号隔开的字符串判断为一条产生式存入文法中。实现函数是scanP()。2)对文法中的产生式消除左递归。实现函数是remove_left_recursion() 。3)对文法中的产生式反复提取公共左因子。实现函数是remove_left_gene ()。4)向 newg.txt 中输出文法的所有产生式。3、 消除左递归文法和提取左因子算法实现方法;消除左递归文法(包括其中用到其它的子函数):/*字符串分割函数,将产生式右部的候选返回,识别| ,从p
8、os位开始分割 */string strsplit(string strTok, int pos ) string str; size_t position; position = strTok.find( |,pos); if (position != string:npos) /找到了 | str = strTok.substr(pos,position - pos); else /没找到名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 3 页,共 18 页 - - - - - -
9、 - - - str = strTok.substr(pos, strTok.size() - pos); return str; /*获得一个文法中尚未定义的非终结符,即特定的大写字母*/char GetWord(char *p) char ch,word = 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 ; int w,x; for (w = 0; w 26; w+) ch = wordw; for (x = 0; x m; x+) if (ch = px) break; if (x
10、 = m) break; return ch; /*判断非终结符是否已存在*/bool checkWord(char ch, string Vn) int i; bool flag = true; for (i = 0; i Vn0); /初始化设置开始符号bool flag20; flag0 = false; /标记哪个产生式需要删除char ch; int i,j,k,l,o; for (i = 0; i str.size(); i+) for (j = 3; j PsVni.size(); j+) 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - -
11、- - - - - - 名师精心整理 - - - - - - - 第 4 页,共 18 页 - - - - - - - - - for (k = 0; k PsVnij PsVnij Z) break; /不是非终结符无需判断if (gp-PsVnij = gp-Vnk) /判断从开始符号可以到达的非终结符在 Vn的哪个位置flagk = false; if (checkWord(gp-Vnk, str) /将在str中没有的有用非终结符插入 strint e = str.size(); sVne = k; str.insert(str.size(), 1, gp-Vnk); break; f
12、or (l = 0; l Vnl = ; for (o = l + 1; o Vno - 1; gp-Vno - 1 = gp-Vno; gp-Vno = ch; gp-Po - 1.clear(); gp-Po - 1.swap(gp-Po); m-; void remove_left_recursion(struct grammar *gp) /子函数,消除文法左递归int i, j,num_i,num_j,ipos,jpos; char ch_i, ch_j; for (i = 1; i Vni - 1; /获取当前要被处理的非终结符,即Pi /分割产生式,得到右部的所有候选名师资料总结
13、 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 5 页,共 18 页 - - - - - - - - - while (ipos != gp-Pi - 1.size() + 1) str_inum_i = strsplit(gp-Pi - 1, ipos); restr_inum_i = str_inum_i; ipos = ipos + str_inum_i.size() + 1; num_i+; for (j = 1; j Vni - 1; /重新获取当前要被处理的非终结符,即 Pi /分割
14、产生式,得到右部的所有候选while (ipos != gp-Pi - 1.size() + 1) str_inum_i = strsplit(gp-Pi - 1, ipos); restr_inum_i = str_inum_i; ipos = ipos + str_inum_i.size() + 1; num_i+; repeat = true; string str_j20; int l; jpos = 3; num_j = 0; ch_j = gp-Vnj - 1; /获取当前要替换的非终结符,即Pj/分割产生式,得到右部的所有候选while (jpos != gp-Pj - 1.si
15、ze() + 1) str_jnum_j = strsplit(gp-Pj - 1, jpos); jpos = jpos + str_jnum_j.size() + 1; num_j+; for (l = 0; l ; stri.insert(0,1,ch_i); int index = 0; while (1) /将替换后的 Pi的所有候选进行重组并存进文法中if (index = num_i) break; if (index = num_i - 1) stri = stri + str_iindex; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - -
16、 - - - - - - - 名师精心整理 - - - - - - - 第 7 页,共 18 页 - - - - - - - - - else stri = stri + str_iindex + |; index+; gp-Pi - 1 = stri; /消除直接左递归string splitstr30, resplitstr30; int s = 0,ps = 3,h = 0; while (1) /分割替换后的产生式splitstrs = strsplit(gp-Pi - 1, ps); resplitstrs = splitstrs; ps = ps + splitstrs.size(
17、) + 1; if (ps = gp-Pi - 1.size() + 1) break; s+; string Pi = -,Pichange = - ; Pi = ch_i + Pi; int link = 0,flag = -1; bool flagpos30; char newWord; for (; link Vn); /获取一个新的非终结符gp-Vnm = newWord; Pichange = newWord + Pichange; m+; splitstrlink = splitstrlink.substr(1) + newWord; flagposlink = false; g
18、p-Pm - 1 = Pichange + splitstrlink + |; if (flag 0) splitstrlink = splitstrlink.substr(1) + newWord; flagposlink = false; gp-Pm - 1 = gp-Pm - 1 + splitstrlink + |; /对消除了直接左递归的候选进行重组成为产生式并存入文法if (flag -1) gp-Pi - 1 = - ; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第
19、8 页,共 18 页 - - - - - - - - - gp-Pi - 1.insert(0, 1, ch_i); for (; h Pi - 1 = gp-Pi - 1 + splitstrh + |; gp-Pm - 1 += ; gp-Pi - 1.erase(gp-Pi - 1.size() - 1, 1); simplify(gp); /化简无用的产生式 提取左因子(包括辅助函数):/对字符串数组排序void str_sort(string *str, int num) int i, j; for (i = 0; i num; i+) for (j = i + 1; j strj)
20、 stri.swap(strj); /*子函数,提取左因子 */void remove_left_gene(struct grammar *gp) int rule_a, i, j, k, l, matchnum,oldmatchnum, resize,size; char ch, newWord; for (rule_a = 0; rule_a Prule_a.size() + 1) /分割替换后的产生式strnum = strsplit(gp-Prule_a, ps); restrnum = strnum; ps = ps + strnum.size() + 1; num+; str_so
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 2022年编译原理实验报告-LL文法构造 2022 编译 原理 实验 报告 LL 文法 构造
![提示](https://www.taowenge.com/images/bang_tan.gif)
限制150内