예제 #1
0
        internal Nfa.Nfa BuildNfa()
        {
            // build a chain (not connected here) of the minimal repetitions
            Nfa.Nfa[] min_coll = Enumerable.Range(0, Math.Max(1, repetition.Min)).Select(it => RegexAtomTraits.BuildNfa(atom)).ToArray();
            var       nfa      = Nfa.Nfa.Concat(min_coll).ClearAccepting(min_coll.Last().Accepting());

            if (!repetition.Max.HasValue)
            {
                min_coll.Last().StartNode.ConnectFrom(min_coll.Last().Accepting(), NfaEdge.CreateEmpty());
            }
            else
            {
                IEnumerable <Nfa.Nfa> max_coll = Enumerable.Range(0, repetition.Max.Value - min_coll.Length).Select(it => RegexAtomTraits.BuildNfa(atom)).ToList();
                if (max_coll.Any())
                {
                    var max_nfa = Nfa.Nfa.Concat(max_coll);
                    max_nfa.StartNode.ConnectFrom(min_coll.Last().Accepting(), NfaEdge.CreateEmpty());
                }
            }

            // put it as last step, otherwise we could get connection right from the start node
            if (repetition.Min == 0)
            {
                nfa.Accepting().ForEach(it => nfa.StartNode.ConnectTo(it, NfaEdge.CreateEmpty()));
            }

            return(nfa);
        }
예제 #2
0
 internal Nfa.Nfa BuildNfa()
 {
     Nfa.Nfa[] alt_nfa = chains.Select(it => RegexChainTraits.BuildNfa(it)).ToArray();
     if (alt_nfa.Length == 1)
     {
         return(alt_nfa.Single());
     }
     else
     {
         var nfa = new Nfa.Nfa();
         alt_nfa.ForEach(it => nfa.StartNode.ConnectTo(it.StartNode, NfaEdge.CreateEmpty()));
         // accepting nodes have no outgoing edges
         mergeNodes(alt_nfa.Select(it => it.Accepting()).Flatten().Where(it => !it.ConnectedTo.Any()).ToArray());
         return(nfa);
     }
 }