public Lexer(DFA dfa) { startStateNode = dfa.MinDFAStartStateNode; endStateNodes = dfa.MinDFAEndStateNodes; allStateNodes = dfa.MinDFAAllStateNodes; GenerateSourceCode(); }
/// <summary> /// 从当前包含多个NFA节点的DFA节点node出发,经路径route,所能到达的NFA节点集合 /// </summary> /// <param name="node"></param> /// <param name="route"></param> /// <returns></returns> private List <NFAStateNode> MoveTo(DFAStateNode node, char route) { List <NFAStateNode> destNodes = new List <NFAStateNode>(); foreach (NFAStateNode n in node.Content) { destNodes.AddRange(n.Pass(route)); } return(destNodes); }
/// <summary> /// 得到某一DFA状态节点所属的分组的索引 /// </summary> /// <param name="node"></param> /// <returns></returns> private int FindGroupIndex(List <List <DFAStateNode> > groups, DFAStateNode node) { for (int i = 0; i < groups.Count; i++) { if (groups.ElementAt(i).Contains(node)) { return(i); } } return(-1); }
/// <summary> /// 得到某一DFA状态节点所属的分组 /// </summary> /// <param name="node"></param> /// <returns></returns> private List <DFAStateNode> FindGroup(List <List <DFAStateNode> > groups, DFAStateNode node) { foreach (List <DFAStateNode> group in groups) { if (group.Contains(node)) { return(group); } } return(null); }
/// <summary> /// 用NFA构造DFA /// </summary> /// <param name="nfa"></param> private void CreateDFA(NFA nfa) { Stack <DFAStateNode> stack = new Stack <DFAStateNode>(); startStateNode = new DFAStateNode(); startStateNode.AddNFAStateNodeList(NullClosure(nfa.StartStateNode)); allStateNodes.Add(startStateNode); stack.Push(startStateNode); while (stack.Count != 0) { DFAStateNode curNode = stack.Pop(); foreach (char c in nfa.Alphabet) { List <NFAStateNode> destNodes = NullClosure(MoveTo(curNode, c)); // 是否需要产生新的DFA状态节点 bool needNew = true; foreach (DFAStateNode existedNode in allStateNodes) { if (existedNode.Contains(destNodes)) { curNode.Connect(existedNode, c); needNew = false; break; } } if (needNew && destNodes.Count != 0) { DFAStateNode newNode = new DFAStateNode(); newNode.AddNFAStateNodeList(destNodes); curNode.Connect(newNode, c); stack.Push(newNode); allStateNodes.Add(newNode); } } } FillEndStateNodes(); }
/// <summary> /// 生成"case"部分的代码块 /// </summary> /// <param name="stateNode"></param> private void GenerateCaseCode(DFAStateNode stateNode) { generatedSourceCode.Append("\t\t\tcase " + stateNode.Id + ":\r\n"); generatedSourceCode.Append("\t\t\t\tswitch(c)\r\n"); generatedSourceCode.Append("\t\t\t\t{ \r\n"); foreach (Edge <DFAStateNode> edge in stateNode.EdgeList) { generatedSourceCode.Append("\t\t\t\t\tcase '" + edge.Route + "':\r\n"); generatedSourceCode.Append("\t\t\t\t\t\tc = getchar();\r\n"); generatedSourceCode.Append("\t\t\t\t\t\tcurStateId = " + edge.EndStateNode.Id + ";\r\n"); generatedSourceCode.Append("\t\t\t\t\t\tbreak;\r\n\r\n"); } generatedSourceCode.Append("\t\t\t\t\tdefault:\r\n"); generatedSourceCode.Append("\t\t\t\t\t\tcurStateId = -1;\r\n"); generatedSourceCode.Append("\t\t\t\t} \r\n"); generatedSourceCode.Append("\t\t\t\tbreak; \r\n\r\n"); }
/// <summary> /// 根据产生的所有新分组构建最小化DFA /// </summary> /// <param name="groups"></param> private void CreateMinDFA(List <List <DFAStateNode> > groups) { if (groups != null && groups.Count > 0) { // 根据最小化的DFA的开始/结束状态节点,对各组节点重新组织、分类 List <List <DFAStateNode> > sortedGroups = new List <List <DFAStateNode> >(); // 最小化DFA的开始状态节点所属的组索引 int minDFAStartStateNodeGroupIndex = FindGroupIndex(groups, startStateNode); // 最小化DFA的所有结束状态节点所属的组索引 List <int> minDFAEndStateNodeGroupIndexes = new List <int>(); foreach (DFAStateNode node in endStateNodes) { int groupIndex = FindGroupIndex(groups, node); if (!minDFAEndStateNodeGroupIndexes.Contains(groupIndex)) { minDFAEndStateNodeGroupIndexes.Add(groupIndex); } } minDFAEndStateNodeGroupIndexes.Sort(); sortedGroups.Add(groups.ElementAt(minDFAStartStateNodeGroupIndex)); for (int i = 0; i < groups.Count; i++) { if (i != minDFAStartStateNodeGroupIndex && !minDFAEndStateNodeGroupIndexes.Contains(i)) { sortedGroups.Add(groups.ElementAt(i)); } } for (int i = 0; i < minDFAEndStateNodeGroupIndexes.Count; i++) { sortedGroups.Add(groups.ElementAt(minDFAEndStateNodeGroupIndexes.ElementAt(i))); } for (int i = 0; i < sortedGroups.Count; i++) { minDFAAllStateNodes.Add(new DFAStateNode()); } for (int i = 0; i < sortedGroups.Count; i++) { DFAStateNode node = sortedGroups.ElementAt(i).ElementAt(0); List <Edge <DFAStateNode> > edgeList = node.EdgeList; foreach (Edge <DFAStateNode> edge in edgeList) { minDFAAllStateNodes.ElementAt(i).Connect(minDFAAllStateNodes.ElementAt(FindGroupIndex(sortedGroups, edge.EndStateNode)), edge.Route); } } // 最小化DFA的开始状态节点 minDFAStartStateNode = minDFAAllStateNodes.ElementAt(FindGroupIndex(sortedGroups, startStateNode)); // 填充最小化DFA的结束状态节点集 for (int i = 0; i < minDFAAllStateNodes.Count; i++) { if (endStateNodes.Contains(sortedGroups.ElementAt(i).ElementAt(0))) { minDFAEndStateNodes.Add(minDFAAllStateNodes.ElementAt(i)); } } } }
/// <summary> /// DFA最小化 /// </summary> public void MiniMize() { DFAStateNode.counter = 1; // 所有分组(总分组) List <List <DFAStateNode> > allGroups = new List <List <DFAStateNode> >(); List <DFAStateNode> endStateNodeGroup = endStateNodes; List <DFAStateNode> nonEndStateNodeGroup = new List <DFAStateNode>(); foreach (DFAStateNode node in allStateNodes) { if (!endStateNodes.Contains(node)) { nonEndStateNodeGroup.Add(node); } } allGroups.Add(endStateNodeGroup); if (nonEndStateNodeGroup.Count > 0) { allGroups.Add(nonEndStateNodeGroup); } foreach (char eachRoute in GetAlphabet()) { // 所有分组在路径eachRoute下进行所有状态节点的比对时,产生的新分组 List <List <DFAStateNode> > allNewSmallGroups = new List <List <DFAStateNode> >(); // 对所有分组都遍历一遍 foreach (List <DFAStateNode> group in allGroups) { if (group.Count > 1) { // 保存当前分组中的所有状态节点经路径eachRoute后到达的目标节点所属的分组(属于allGroups中的哪个分组) List <List <DFAStateNode> > destNodeGroups = new List <List <DFAStateNode> >(); // 添加一个新的空分组,作为专门保存经路径eachRoute后到达的目标节点为null时,目标节点所属的分组 destNodeGroups.Add(new List <DFAStateNode>()); // 当前分组在路径eachRoute下进行所有状态节点的比对时,产生的新分组 List <List <DFAStateNode> > newSmallGroups = new List <List <DFAStateNode> >(); // 添加一个新的空分组,作为经路径eachRoute后到达的目标节点为null时,产生的新分组 newSmallGroups.Add(new List <DFAStateNode>()); DFAStateNode firstDestNode = group.ElementAt(0).Pass(eachRoute); // 该状况下,直接将当前的group作为当前的group中的状态节点经路径eachRoute后到达的目标节点为null时,所属的新分组 if (firstDestNode == null) { for (int i = group.Count - 1; i >= 1; i--) { DFAStateNode destNode = group.ElementAt(i).Pass(eachRoute); if (destNode != null) { List <DFAStateNode> destNodeGroup = FindGroup(allGroups, destNode); if (destNodeGroups.Contains(destNodeGroup)) { int location = destNodeGroups.IndexOf(destNodeGroup); newSmallGroups.ElementAt(location).Add(group.ElementAt(i)); group.RemoveAt(i); } else { destNodeGroups.Add(destNodeGroup); // 产生新分组 List <DFAStateNode> newSmallGroup = new List <DFAStateNode>(); newSmallGroup.Add(group.ElementAt(i)); newSmallGroups.Add(newSmallGroup); group.RemoveAt(i); } } } } else { // firstDestNode所属的分组 List <DFAStateNode> firstDestNodeGroup = FindGroup(allGroups, firstDestNode); for (int i = group.Count - 1; i >= 1; i--) { DFAStateNode destNode = group.ElementAt(i).Pass(eachRoute); if (destNode == null) { newSmallGroups.ElementAt(0).Add(group.ElementAt(i)); group.RemoveAt(i); } else { List <DFAStateNode> destNodeGroup = FindGroup(allGroups, destNode); if (destNodeGroup.Count != firstDestNodeGroup.Count || !destNodeGroup.All(firstDestNodeGroup.Contains)) { if (destNodeGroups.Contains(destNodeGroup)) { int location = destNodeGroups.IndexOf(destNodeGroup); newSmallGroups.ElementAt(location).Add(group.ElementAt(i)); group.RemoveAt(i); } else { destNodeGroups.Add(destNodeGroup); // 产生新分组 List <DFAStateNode> newSmallGroup = new List <DFAStateNode>(); newSmallGroup.Add(group.ElementAt(i)); newSmallGroups.Add(newSmallGroup); group.RemoveAt(i); } } } } } if (newSmallGroups.ElementAt(0).Count > 0) { allNewSmallGroups.AddRange(newSmallGroups); } else { newSmallGroups.RemoveAt(0); allNewSmallGroups.AddRange(newSmallGroups); } } } // 将新产生的分组加入到总分组中 allGroups.AddRange(allNewSmallGroups); } CreateMinDFA(allGroups); }