当前位置:文档之家› (重庆理工大学计算机学院)编译原理课程设计报告

(重庆理工大学计算机学院)编译原理课程设计报告

编译原理课程设计报告实验名称编译原理课程设计班级学号姓名指导教师实验成绩2013 年06月一、实验目的➢通过设计、编写和调试,将正规式转换为不确定的有穷自动机,再将不确定的有穷自动机转换为与之等价的确定的有穷自动机,最后再将确定有穷自动机进行简化。

➢通过设计、编写和调试构造LR(0)项目集规范簇和LR分析表、对给定的符号串进行LR分析的程序,了解构造LR(0)分析表的步骤,对文法的要求,能够从文法G出发生成LR(0)分析表,并对给定的符号串进行分析。

二、实验内容➢正规式——>NFA——>DFA——>MFA1.正规式转化为不确定的有穷自动机(1)目的与要求通过设计、编写和调试将正规式转换为不确定的有穷自动机的程序,使学生了解Thompson算法,掌握转换过程中的相关概念和方法,NFA的表现形式可以是表格或图形。

(2)问题描述任意给定一个正规式r(包括连接、或、闭包运算),根据Thompson算法设计一个程序,生成与该正规式等价的NFA N。

(3)算法描述对于Σ上的每个正规式R,可以构造一个Σ上的NFA M,使得L(M)=L(R)。

步骤1:首先构造基本符号的有穷自动机。

步骤2:其次构造连接、或和闭包运算的有穷自动机。

(4)基本要求算法实现的基本要求是:(1) 输入一个正规式r;(2) 输出与正规式r等价的NFA。

(5)测试数据输入正规式:(a|b)*(aa|bb)(a|b)*得到与之等价的NFA N(6)输出结果2.不确定的有穷自动机的确定化(1)目的与要求通过设计、编写和调试将不确定的有穷自动机转换为与之等价的确定的有穷自动机的程序,使学生了解子集法,掌握转换过程中的相关概念和方法。

DFA的表现形式可以是表格或图形。

(2)问题描述任意给定一个不确定的有穷自动机N,根据算法设计一个程序,将该NFA N变换为与之等价的DFA D。

(3)算法描述用子集法将NFA转换成接受同样语言的DFA。

步骤一:对状态图进行改造(1) 增加状态X,Y,使之成为新的唯一的初态和终态。

从X引ε弧到原初态结点, 从原终态结点引ε弧到Y结点。

(2) 对状态图进一步进行如下形式的改变步骤2:对NFA 进行确定化,构造状态转换表。

(1)初始时,ε_closure(s0)是Dstates中唯一的状态且未被标记;while Dstates中存在一个未标记的状态T do begin标记T;for每个输入符号a do beginU:= ε_closure(move(T,a));if U没在Dstates中then将U作为一个未标记的状态添加到Dstates中;end;end;(2) ε_closure的计算,计算ε_closure(T)的简单算法是用栈来保存其弧还没有完成ε转换检查的状态。

将T中所有的状态压入栈stack中:将ε_closure(T)初始化为T;while栈stack不空do begin将栈顶元素t弹出栈;for每个这样的状态u:从t到u有一条标记为ε的边doif u不在ε_closure(T)中do begin将u添加到ε_closure(T);将u压入栈stack中;end;end;(4)基本要求算法实现的基本要求是:(1) 输入一个NFA N;(2) 输出与之等价的DFA。

(5)测试数据给定不确定的有穷自动机:得到与之等价的确定的有穷自动机:(6)输出效果输出状态转换表表示的确定的有穷自动机如下:3.确定的有穷自动机的化简(1)目的与要求通过设计、编写和调试将确定的有穷自动机的状态数变为最少的程序,使学生掌握化简有穷自动机的过程中的相关概念和方法。

DFA的表现形式可以是表格或图形。

(2)问题描述每一个正规集都可以由一个状态数最少的DFA所识别,这个DFA是唯一的(因状态名不同的同构情况除外)。

任意给定一个确定的有穷自动机,根据算法设计一个程序,将该DFA化简为与之等价的最简DFA。

(3)算法描述1.构造具有两个组的状态集合的初始划分Π:接受状态组F,非接受状态组S-F。

2.对Π采用下面所述的过程来构造新的划分Πnew。

forΠ中每个组G dobegin当且仅当对任意输入符号a,状态s和t读入a后转换到Π的同一组中;/*最坏情况下,一个状态就可能成为一个组*/用所有新形成的小组集代替Πnew中的G;end3.如果Πnew=Π,令Πfinal=Π,再执行步骤4;否则,令Π:=Πnew,重复步骤2。

4.在划分Πfinal的每个状态组中选一个状态作为该组的代表。

这些代表构成了简化后的DFA M'的状态。

另s是一个代表状态,而且假设:在DFA M中,在输入a上有从s到t的转换。

令t所在组的代表是r(r可能就是t),那么在M'中有一个从s到r的a上的转换。

令包含s0的状态组的代表是M'的开始状态,并令M'的接受状态是那些属于F的状态所在组的代表。

注意,Πfinal的每个组或者仅含F中的状态,或者不含F中的状态。

5.如果M'含有死状态(即一个对所有输入符号都有到自身的转换的非接受状态d),则从M'中去掉它;删除从开始状态不可到达的状态;取消从任何其他状态到死状态的转换。

(4)基本要求算法实现的基本要求是:(1) 输入一个DFA D;(2) 输出与之等价的最小化的DFA M。

(5)测试数据给定确定的有穷自动机:得到最小化的确定的有穷自动机:(6)输出效果➢LR(0)算法分析1.构造LR(0)项目集规范簇(1)问题描述给定一个LR(0)文法,求出其项目集规范簇,结果以图形或表格的形式输出。

(2)算法描述设有LR(0)文法G,首先求出其所有的项目,然后根据项目求出其LR(0)项目集规范簇,求项目PROCEDURE itemsets(G');BEGINC := { CLOSURE( {S' ·S} ) };REPEATfor C中的每个项目集I和每个文法符号X doif GO(I,X)非空且不属于C THEN把GO(I,X) 加入C中UNTIL C 不再增大;END;(3)测试数据输入如下所示的文法:E →aA|bBA →cA|dB →cB|d项目集合为:1. S' →·E2. S' →E ·3. E →.aA4. E →a·A5. E →aA·6. A →· cA7. A →c · A8. A →cA ·9. A →·d 10. A → d·11. E →.bB 12. E → b·B 13. E → bB·14. B →.cB 15. B →c·B 16. B →cB ·17. B →.d 18. B → d·(4)结果输出根据算法得到的项目集规范簇如下图所示:结果也可以用表格的形式表示如下:状态项目集后继符号后继状态S0{ S' →·EE→·aAE→·bB }EabS1S2S3S1{ S' →E · }#接受态2.构造LR(0)分析表(1)问题描述给定一个LR(0)文法,利用6.1得到的项目集规范簇,求出其LR(0)分析表,并以表格的形式输出。

(2)算法描述LR(0)(3)基本要求动态模拟算法的基本功能是:(1)输入LR分析文法,要求可以直接输入,也可以读入文件;(2)输出项目集规范簇(可选);(3)输出LR(0)分析表;(4)测试数据输入文法:E →aA|bBA →cA|dB →cB|d输出LR分析表如下:3.LR分析过程的实现(1)问题描述给定一个LR(0)文法,利用6.2求出其LR(0)分析表;或者给定某个LR分析表(可能不是LR(0)分析表,其分析过程类似),输入一个符号串,依据LR分析表输出与句子对应的语法树,能对语法树生成过程进行模拟。

(2)算法描述在分析过程中设置一个堆栈和一个分析表,根据分析表和输入符号串对堆栈进行操作,分析器的下一步动作是由栈顶状态Sm和当前面临的输入符号ai唯一确定的。

根据栈顶状态Sm和输入符号ai查action表, 根据表中的内容不同完成不同的动作,若action[Sm, ai]为:•移进:当前输入符号ai进符号栈,下一输入符号变成当前输入符号,将action表中指出的状态S进状态栈。

三元式变为:(S0S1…SmS, # X1X2…Xmai, ai+1…an#)•归约:按某个产生式A→β进行归约,若产生式的右端长度为r,则两个栈顶的r个元素同时出栈。

将归约后的符号A进符号栈; 根据新栈顶状态Sm-r和归约符号A查GOTO表,S=goto[Sm-r, A]进状态栈。

三元式变为:(S0S1 … Sm-r S, # X1X2…Xm-rA, aiai+1…an #)•接受:分析成功,终止分析。

三元式不再变化。

•出错:报告出错信息。

三元式的变化过程终止。

(3)基本要求动态模拟算法的基本功能是:(1). 输入LR分析表和一个句子;(2). 输出LR总控程序;(3). 输出依据句子构对应的语法树的过程;(4)测试数据输入句子:i*i+i输入文法:(1) E →E+T(2) E →T(3) T →T*F(4) T →F(5) F→(F)(6) F →i和如下所示的LR分析表:得到如下图所示的LR分析过程:三、实验方案设计➢正规式——>NFA——>DFA——>MFA1.优先符关系表的定义//行分别表示:'.','|','(',')','*','#'//列分别表示:'.','|','(',')','*','#'char[,] relation = {{'>','>','<','>','<','>'},{'<','>','<','>','<','>'},{'<','<','<','=','<','E'},{'>','>','E','>','>','>'},{'>','>','E','>','>','>'},{'<','<','<','E','<','='}};2.栈定义///<summary>/// NFA状态栈///</summary>struct StatusStack{public int start;public int end;}StatusStack[] stack_ZT = new StatusStack[100];///<summary>/// DFA化简状态集合结构///</summary>struct Tstates{public int[] data;//NFA的状态集public int length;//个数从零开始统计public bool mark;public int status;//计数状态public int accept;//标记开始状态(-1)或结尾状态(1) }Tstates[] Tstateslt = new Tstates[100];///<summary>/// MFA状态集///</summary>struct Mstates{public int[] data;public int length;public int status;//计数状态}Mstates[] Mstateslt = new Mstates[100];➢LR(0)算法分析1.构造LR(0)项目集规范簇(1)定义变量string nonterminal = ""; //保存非终结符string terminal = ""; //保存终结符string[] grammer = null; //保存文法List<itemsetsNode> itemsets = null; //项目集规范簇struct itemsetsNode//项目集{public string no;public List<ItemNode> itemsetsNodeValue;}class ItemNode{string item; //活前缀string nextSymbol; //后继符号string nextStatus; //后继状态}(2)函数实现char[] separator = { '\r', '\n' };grammer = this.txtgrammer.Text.Split(separator, StringSplitOptions.RemoveEmptyEntries); //分割文法符号串foreach (string tempStr2 in grammer){if (nonterminal.Contains(tempStr2[0]) == false)nonterminal += tempStr2[0];}itemsets = new List<itemsetsNode>(); //实例化存放项目集节点的链表itemsetsNode tempItemSetNode = new itemsetsNode();tempItemSetNode.no = "0";string tempStr = grammer[0];tempStr = tempStr.Insert(tempStr.IndexOf('>') + 1, "."); tempItemSetNode.itemsetsNodeValue = Item_Closure(tempStr); itemsets.Add(tempItemSetNode);int k = 0;while (k < itemsets.Count){foreach(ItemNode tempItemNode in itemsets[k].itemsetsNodeValue){//对每个项目进行处理List<ItemNode> tempItemsetsNode = null;//若不是是接受态或可规约项,使str中的.向后移一位string str = tempItemNode.Item;int index = str.IndexOf('.');if (index == str.Length - 1) //是接受态或可规约项{tempItemNode.NextSymbol = "#";if (str[0] == nonterminal[0])tempItemNode.NextStatus = "接受态";elsetempItemNode.NextStatus = "规约";continue;}str = str.Remove(index, 1);tempItemNode.NextSymbol = str[index].ToString();if(nonterminal.Contains(tempItemNode.NextSymbol)== false) //不是非终结符{if(terminal.Contains(tempItemNode.NextSymbol) == false)terminal += tempItemNode.NextSymbol;}str = str.Insert(index + 1, ".");tempItemsetsNode = Item_Closure(str); //求项目item 的Closureint row = Find(itemsets, tempItemsetsNode); //查找是否已存在该项目集if (row == -1) //不存在该项目集{tempItemSetNode = new itemsetsNode();tempItemNode.NextStatus = tempItemSetNode.no = itemsets.Count.ToString();tempItemSetNode.itemsetsNodeValue = tempItemsetsNode;itemsets.Add(tempItemSetNode);}else{tempItemNode.NextStatus = row.ToString();}}k++;}display(); //将结果显示在listview中2.构造LR(0)分析表(1)定义变量List<ActionNode> actionList = null; //存放action表的内容List<GotoNode> gotoList = null; //存放goto表的内容(2)函数实现actionList = new List<ActionNode>();gotoList = new List<GotoNode>();erminal += "#";//遍历项目集规范簇foreach (itemsetsNode tempItemSetsNode in itemsets){foreach (ItemNode tempItemNode intempItemSetsNode.itemsetsNodeValue){if (tempItemNode.NextSymbol != "#" &&nonterminal.Contains(tempItemNode.NextSymbol) == true){//后继符号是非终结符号,则想goto表添加内容GotoNode goTo = new GotoNode();goTo.Num = int.Parse(tempItemSetsNode.no);goTo.GoToSymbol = tempItemNode.NextSymbol;goTo.Value = int.Parse(tempItemNode.NextStatus);gotoList.Add(goTo);}else{//后继符号是终结符号,则想antion表添加内容if (tempItemNode.NextSymbol == "#"){if (tempItemNode.Item[0].ToString() == nonterminal[0].ToString()) //表示产生式左边是开始符号{ActionNode action = new ActionNode();action.Num = int.Parse(tempItemSetsNode.no);action.Symbol = tempItemNode.NextSymbol; action.Value = "acc";actionList.Add(action);}else{int k;for (k = 0; k < grammer.Length; k++){string str = tempItemNode.Item;str = str.Remove(tempItemNode.Item.Length - 1);if (grammer[k].Equals(str) == true) {k++;break;}}foreach (char ch in terminal){ActionNode action = new ActionNode(); action.Num = int.Parse(tempItemSetsNode.no);action.Symbol = ch.ToString();action.Value = "r" + k.ToString(); actionList.Add(action);}}}else{ActionNode action = new ActionNode();action.Num = int.Parse(tempItemSetsNode.no);action.Symbol = tempItemNode.NextSymbol;action.Value = "s" + tempItemNode.NextStatus;actionList.Add(action);}}}}DisplayLrTable(this.listView2);3.LR分析过程的实现(1)变量定义int stepCount = 0;Stack<int> statusStack = null; //状态栈Stack<string> symbolStack = null; //符号栈四、实验测试➢正规式——>NFA——>DFA——>MFA(1)输入一个表达式,将表达式转换为NFA(2)将NFA转换为DFA(3)将生成的DFA进行确定化,生成MFA➢LR(0)算法分析(1)从文件读入LR(0)文法后构造LR(0)项目集规范簇(2)构造LR(0)分析表(3)输入分析串,进行LR分析五、程序的使用手册➢正规式——>NFA——>DFA——>MFA现在文本框中输入一个表达式,点击“确定”,之后依次点击“NFA”按钮将表达式转换为NFA;点击“DFA”按钮,将生成的NFA转换为DFA;点击“MFA”按钮,将生成的DFA进行简化。

相关主题