public FSA <TValue> CreateRawFsa(AstRootNode root, ORegexOptions options) { var result = new FSA <TValue>(root.CaptureGroupNames[0]) { CaptureNames = root.CaptureGroupNames }; var start = result.NewState(); var end = result.NewState(); Evaluate(start, end, result, root, options); result.AddFinal(end); result.AddStart(start); return(result); }
/// <summary> /// Subset machine that employs the powerset construction or subset construction algorithm. /// It creates a DFA that recognizes the same language as the given NFA. /// </summary> private static FSA <TValue> ToDfa(FSA <TValue> fsa) { FSA <TValue> dfa = new FSA <TValue>(fsa.Name) { ExactBegin = fsa.ExactBegin, ExactEnd = fsa.ExactEnd, CaptureNames = fsa.CaptureNames, }; // Sets of NFA states which is represented by some DFA state var markedStates = new HashSet <Set <int> >(); var unmarkedStates = new HashSet <Set <int> >(); // Gives a number to each state in the DFA var dfaStateNum = new Dictionary <Set <int>, int>(); var nfaInitial = fsa.Q0.ToSet(); // Initially, EpsilonClosure(nfa.initial) is the only state in the DFAs states // and it's unmarked. var first = EpsilonClosure(fsa, nfaInitial); unmarkedStates.Add(first); // The initial dfa state int dfaInitial = dfa.NewState(); dfaStateNum[first] = dfaInitial; dfa.AddStart(dfaInitial); while (unmarkedStates.Count != 0) { // Takes out one unmarked state and posteriorly mark it. var aState = unmarkedStates.First(); // Removes from the unmarked set. unmarkedStates.Remove(aState); // Inserts into the marked set. markedStates.Add(aState); // If this state contains the NFA's final state, add it to the DFA's set of // final states. if (fsa.F.Any(x => aState.Contains(x))) { dfa.AddFinal(dfaStateNum[aState]); } // For each input symbol the NFA knows... foreach (var current in fsa.Sigma) { // Next state var next = EpsilonClosure(fsa, fsa.Move(aState, current)); if (next.Count > 0) { // If we haven't examined this state before, add it to the unmarkedStates, // and make up a new number for it. if (!unmarkedStates.Contains(next) && !markedStates.Contains(next)) { unmarkedStates.Add(next); dfaStateNum.Add(next, dfa.NewState()); } var from = dfaStateNum[aState]; var to = dfaStateNum[next]; var condition = current; dfa.AddTransition(from, condition, to); } } } return(dfa); }
private int CreateNewState(FSA <TValue> fsa) { return(fsa.NewState()); }