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;
        }
Пример #2
0
        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);
        }
Пример #3
0
        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());
        }
Пример #4
0
        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);
        }
Пример #5
0
        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);
        }
Пример #6
0
        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);
        }