コード例 #1
0
        public Dfa.DfaTable BuildDfa()
        {
            Nfa.Nfa nfa = nfaWorker.Compile();

            // -- from here build DFA out of NFA
            List <DfaNode> done   = new List <DfaNode>();
            List <Link>    to_add = (new[] { new Link(null, 0, new DfaNode(nfa.StartNode)) }).ToList();

            while (to_add.Any())
            {
                // build closures for incoming nodes
                to_add.Select(it => it.Target).ForEach(it => it.BuildClosure());

                List <Link> new_links = new List <Link>();

                foreach (Link link in to_add)
                {
                    // check if we already have that DFA node
                    DfaNode existing = done.SingleOrDefault(it => it.SameNfaCore(link.Target));

                    if (existing == null)
                    {
                        done.Add(link.Target);

                        if (link.Source != null)
                        {
                            link.Source.ConnectTo(link.Edge, link.Target);
                        }
                        new_links.AddRange(link.Target.ComputeLinks());
                    }
                    else
                    {
                        link.Source.ConnectTo(link.Edge, existing);
                    }
                }

                to_add = new_links;
            }

            done.ZipWithIndex().ForEach(it => it.Item1.Index = it.Item2);

            var dfa = new Dfa.DfaTable(done.Count);

            foreach (DfaNode node in done)
            {
                dfa.SetAccepting(node.Index, node.AcceptingValues);
                node.CreateTransitions(dfa);
            }

            return(dfa);
        }