public FSA(string name, IEnumerable <FSATransition <TValue> > transitions, IEnumerable <int> q0, IEnumerable <int> f) { Name = name.ThrowIfEmpty(); Q0 = q0.ToHashSet(); F = f.ToHashSet(); #region Speedup foreach (var t in transitions) { OrderedSet <FSATransition <TValue> > predics; if (!_lookup.TryGetValue(t.BeginState, out predics)) { predics = new OrderedSet <FSATransition <TValue> >(); _lookup[t.BeginState] = predics; } predics.Add(t); if (!PredicateEdgeBase <TValue> .IsEpsilon(t.Condition)) { _sigma.Add(t.Condition); } } StateCount = Q.Count(); #endregion }
private void AddTransition(FSATransition <TValue> trans) { if (trans == null) { throw new ArgumentNullException(nameof(trans)); } #region Speedup OrderedSet <FSATransition <TValue> > predics; if (!_lookup.TryGetValue(trans.BeginState, out predics)) { predics = new OrderedSet <FSATransition <TValue> >(); _lookup[trans.BeginState] = predics; } predics.Add(trans); if (!PredicateEdgeBase <TValue> .IsEpsilon(trans.Condition)) { _sigma.Add(trans.Condition); } #endregion }
/// <summary> /// Builds the Epsilon closure of states for the given NFA /// </summary> /// <param name="nfa"></param> /// <param name="states"></param> /// <returns></returns> private static Set <int> EpsilonClosure(FSA <TValue> nfa, Set <int> states) { // Push all states onto a stack Stack <int> uncheckedStack = new Stack <int>(states); // Initialize EpsilonClosure(states) to states Set <int> epsilonClosure = states; while (uncheckedStack.Count != 0) { // Pop state t, the top element, off the stack var t = uncheckedStack.Pop(); // For each state u with an edge from t to u labeled Epsilon IEnumerable <FSATransition <TValue> > transitions; if (nfa.TryGetTransitionsFrom(t, out transitions)) { foreach (var input in transitions) { if (PredicateEdgeBase <TValue> .IsEpsilon(input.Condition)) { int u = input.EndState; // If u is not already in epsilonClosure, add it and push it onto stack if (!epsilonClosure.Contains(u)) { epsilonClosure.Add(u); uncheckedStack.Push(u); } } } } } return(epsilonClosure); }
public bool TryRun(SequenceHandler <TValue> values, int startIndex, OCaptureTable <TValue> table, out Range range) { range = default(Range); var piStack = _piStack; piStack.Clear(); var stack = _instanceStack; stack.Clear(); bool hasSubCaptures = false; FSAState state = CreateState(_startState, startIndex); stack.Push(state); var pi = 0; piStack.Push(pi); while (stack.Count > 0) { state = stack.Peek(); pi = piStack.Peek(); bool retrieved = false; var transitions = _transitionMatrix[state.StateId]; if (transitions != null && transitions.Length > 0) { for (int i = pi; i < transitions.Length; i++) { var trans = transitions[i]; piStack.Push(piStack.Pop() + 1); var isMatch = trans.Condition.IsMatch(values, state.CurrentIndex); if (isMatch) { var isEps = PredicateEdgeBase <TValue> .IsEpsilon(trans.Condition); hasSubCaptures |= trans.Condition.IsSystemPredicate && ((SystemPredicateEdge <TValue>)trans.Condition).IsCapture; stack.Push(CreateState(trans.EndState, state.CurrentIndex + (isEps ? 0 : 1))); piStack.Push(0); retrieved = true; break; } } } if (!retrieved) { if (_finalsLookup[state.StateId]) { break; } stack.Pop(); piStack.Pop(); } } if (stack.Count != 0 && _finalsLookup[state.StateId]) { if (hasSubCaptures && table != null) { ManageSubCaptures(table, values, stack, piStack); } range = new Range(startIndex, state.CurrentIndex - startIndex); return(true); } return(false); }