Ejemplo n.º 1
0
 public Lexer(DFA dfa)
 {
     startStateNode = dfa.MinDFAStartStateNode;
     endStateNodes  = dfa.MinDFAEndStateNodes;
     allStateNodes  = dfa.MinDFAAllStateNodes;
     GenerateSourceCode();
 }
Ejemplo n.º 2
0
        /// <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);
        }
Ejemplo n.º 3
0
        /// <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);
        }
Ejemplo n.º 4
0
        /// <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);
        }
Ejemplo n.º 5
0
        /// <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();
        }
Ejemplo n.º 6
0
        /// <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");
        }
Ejemplo n.º 7
0
        /// <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));
                    }
                }
            }
        }
Ejemplo n.º 8
0
        /// <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);
        }