public IDfaState Transform(INfa nfa) { var processOnceQueue = new ProcessOnceQueue<NfaClosure>(); var set = SharedPools.Default<HashSet<INfaState>>().AllocateAndClear(); foreach (var state in nfa.Start.Closure()) set.Add(state); var start = new NfaClosure(set, nfa.Start.Equals(nfa.End)); processOnceQueue.Enqueue(start); while (processOnceQueue.Count > 0) { var nfaClosure = processOnceQueue.Dequeue(); var transitions = SharedPools .Default<Dictionary<ITerminal, HashSet<INfaState>>>() .AllocateAndClear(); foreach (var state in nfaClosure.Closure) { for (var t = 0; t < state.Transitions.Count; t++) { var transition = state.Transitions[t]; switch (transition.TransitionType) { case NfaTransitionType.Terminal: var terminalTransition = transition as TerminalNfaTransition; var terminal = terminalTransition.Terminal; if (!transitions.ContainsKey(terminalTransition.Terminal)) transitions[terminal] = SharedPools.Default<HashSet<INfaState>>().AllocateAndClear(); transitions[terminal].Add(transition.Target); break; } } } foreach (var terminal in transitions.Keys) { var targetStates = transitions[terminal]; var closure = Closure(targetStates, nfa.End); closure = processOnceQueue.EnqueueOrGetExisting(closure); nfaClosure.State.AddTransition( new DfaTransition(terminal, closure.State)); SharedPools.Default<HashSet<INfaState>>().Free(targetStates); } SharedPools .Default<HashSet<INfaState>>() .Free(nfaClosure.Closure); SharedPools .Default<Dictionary<ITerminal, HashSet<INfaState>>>() .ClearAndFree(transitions); } return start.State; }
public override DfaState Transform(Nfa nfa) { var processOnceQueue = new ProcessOnceQueue <NfaClosure>(); var set = ObjectPoolExtensions.Allocate(SharedPools.Default <HashSet <NfaState> >()); foreach (var state in nfa.Start.Closure()) { set.Add(state); } var start = new NfaClosure(set, nfa.Start.Equals(nfa.End)); processOnceQueue.Enqueue(start); while (processOnceQueue.Count > 0) { var nfaClosure = processOnceQueue.Dequeue(); var transitions = ObjectPoolExtensions.Allocate(SharedPools.Default <Dictionary <AtomTerminal, HashSet <NfaState> > >()); foreach (var state in nfaClosure.Set) { foreach (var transition in state.Transitions) { if (transition is TerminalNfaTransition terminalTransition) { var terminal = terminalTransition.Terminal; if (!transitions.ContainsKey(terminal)) { transitions[terminal] = ObjectPoolExtensions.Allocate(SharedPools.Default <HashSet <NfaState> >()); } transitions[terminal].Add(transition.Target); } } } foreach (var terminal in transitions.Keys) { var targetStates = transitions[terminal]; var closure = Closure(targetStates, nfa.End); closure = processOnceQueue.EnqueueOrGetExisting(closure); nfaClosure.State.AddTransition(terminal, closure.State); SharedPools.Default <HashSet <NfaState> >().ClearAndFree(targetStates); } SharedPools .Default <HashSet <NfaState> >() .ClearAndFree(nfaClosure.Set); SharedPools .Default <Dictionary <AtomTerminal, HashSet <NfaState> > >() .ClearAndFree(transitions); } return(start.State); }
public void NfaClosuresFromSameSetShouldBeEqual() { var state1 = new NfaState(); var state2 = new NfaState(); var sut1 = new NfaClosure(new[] { state1, state2 }, state1); var sut2 = new NfaClosure(new[] { state2, state1 }, state1); Assert.IsTrue(sut1.Equals(sut2)); Assert.AreEqual(sut1.GetHashCode(), sut1.GetHashCode()); }
public void NfaClosureShouldNewWithEmptyStates() { var state = new NfaState(); var sut = new NfaClosure(Enumerable.Empty <NfaState>(), state); Assert.IsNotNull(sut); Assert.IsNotNull(sut.Set); Assert.AreEqual(0, sut.Set.Count); Assert.IsNotNull(sut.State); Assert.AreEqual(false, sut.State.IsFinal); }
public void NfaClosureShouldNewWithOneState() { var state = new NfaState(); var sut = new NfaClosure(Enumerable.Repeat(state, 1), state); Assert.IsNotNull(sut); Assert.IsNotNull(sut.Set); Assert.AreEqual(1, sut.Set.Count); Assert.IsNotNull(sut.State); Assert.AreEqual(true, sut.State.IsFinal); }
public void NfaClosureShouldNewWithTwoStates() { var state1 = new NfaState(); var state2 = new NfaState(); var sut = new NfaClosure(new [] { state1, state2 }, state1); Assert.IsNotNull(sut); Assert.IsNotNull(sut.Set); Assert.AreEqual(2, sut.Set.Count); Assert.IsNotNull(sut.State); Assert.AreEqual(true, sut.State.IsFinal); }
public IDfaState Transform(INfa nfa) { var processOnceQueue = new ProcessOnceQueue <NfaClosure>(); var set = SharedPools.Default <SortedSet <INfaState> >().AllocateAndClear(); foreach (var state in nfa.Start.Closure()) { set.Add(state); } var start = new NfaClosure(set, nfa.Start.Equals(nfa.End)); processOnceQueue.Enqueue(start); while (processOnceQueue.Count > 0) { var nfaClosure = processOnceQueue.Dequeue(); var transitions = SharedPools .Default <Dictionary <ITerminal, SortedSet <INfaState> > >() .AllocateAndClear(); for (int i = 0; i < nfaClosure.Closure.Length; i++) { var state = nfaClosure.Closure[i]; for (var t = 0; t < state.Transitions.Count; t++) { var transition = state.Transitions[t]; switch (transition.TransitionType) { case NfaTransitionType.Edge: var terminalTransition = transition as TerminalNfaTransition; var terminal = terminalTransition.Terminal; if (!transitions.ContainsKey(terminalTransition.Terminal)) { transitions[terminal] = SharedPools.Default <SortedSet <INfaState> >().AllocateAndClear(); } transitions[terminal].Add(transition.Target); break; } } } foreach (var terminal in transitions.Keys) { var targetStates = transitions[terminal]; var closure = Closure(targetStates, nfa.End); closure = processOnceQueue.EnqueueOrGetExisting(closure); nfaClosure.State.AddTransition( new DfaTransition(terminal, closure.State)); SharedPools.Default <SortedSet <INfaState> >().ClearAndFree(targetStates); } SharedPools .Default <SortedSet <INfaState> >() .ClearAndFree(nfaClosure.Set); SharedPools .Default <Dictionary <ITerminal, SortedSet <INfaState> > >() .ClearAndFree(transitions); } return(start.State); }