private void EvaluateConcat(int start, int end, FSA <TValue> fsa, AstConcatNode node, ORegexOptions options) { var group = node as AstGroupNode; if (group != null) { if (group.Quantifier != null) { // ReSharper disable once CanBeReplacedWithTryCastAndCheckForNull if (group.Quantifier is CaptureQuantifier) { var captureQ = (CaptureQuantifier)group.Quantifier; var sys = new SystemPredicateEdge <TValue>("#capture") { IsCapture = true, CaptureName = captureQ.CaptureName, CaptureId = captureQ.CaptureId }; var startTmp = CreateNewState(fsa); fsa.AddTransition(start, sys, startTmp); start = startTmp; var endTmp = CreateNewState(fsa); fsa.AddTransition(endTmp, sys, end); end = endTmp; } else if (group.Quantifier is LookAheadQuantifier) { var lookQ = (LookAheadQuantifier)group.Quantifier; EvaluateLook(start, end, fsa, lookQ, group, options); return; } } } var prev = start; int next; var children = node.GetChildren().ToArray(); for (int i = 0; i < children.Length - 1; i++) { next = CreateNewState(fsa); Evaluate(prev, next, fsa, children[i], options); prev = next; } next = end; Evaluate(prev, next, fsa, children[children.Length - 1], options); }
/// <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 void EvaluateCondition(int start, int end, FSA <TValue> fsa, PredicateEdgeBase <TValue> condition) { fsa.AddTransition(start, condition, end); }