Exemple #1
0
        /// <summary>
        /// Creates an automaton that repeats the sub-automaton a number of times in the given range [min, max]
        /// </summary>
        /// <param name="sub">The sub-automaton</param>
        /// <param name="min">The minimum (included) number of time to repeat</param>
        /// <param name="max">The maximum (included) number of time to repeat</param>
        /// <returns>The new automaton</returns>
        // TODO: should get rid of static methods
        public static NFA NewRepeatRange(NFA sub, int min, int max)
        {
            NFA final = NewMinimal();

            NFAState last = final.StateEntry;

            for (int i = 0; i != min; i++)
            {
                NFA inner = sub.Clone();
                final.states.AddRange(inner.states);
                last.AddTransition(NFA.EPSILON, inner.StateEntry);
                last = inner.StateExit;
            }
            for (int i = min; i != max; i++)
            {
                NFA inner = NewOptional(sub, true);
                final.states.AddRange(inner.states);
                last.AddTransition(NFA.EPSILON, inner.StateEntry);
                last = inner.StateExit;
            }
            last.AddTransition(NFA.EPSILON, final.StateExit);

            if (min == 0)
            {
                final.StateEntry.AddTransition(NFA.EPSILON, final.StateExit);
            }
            return(final);
        }
Exemple #2
0
        /// <summary>
        /// Creates an automaton that repeats the sub-automaton one or more times
        /// </summary>
        /// <param name="sub">The sub-automaton</param>
        /// <param name="useClones">True to completely clone the sub-automaton</param>
        /// <returns>The new automaton</returns>
        // TODO: should get rid of static methods
        public static NFA NewRepeatOneOrMore(NFA sub, bool useClones)
        {
            NFA final = NewMinimal();

            if (useClones)
            {
                sub = sub.Clone();
            }
            final.states.AddRange(sub.states);
            final.StateEntry.AddTransition(NFA.EPSILON, sub.StateEntry);
            sub.StateExit.AddTransition(NFA.EPSILON, final.StateExit);
            final.StateExit.AddTransition(NFA.EPSILON, sub.StateEntry);
            return(final);
        }
Exemple #3
0
        /// <summary>
        /// Creates an automaton that concatenates the two sub-automaton
        /// </summary>
        /// <param name="left">The left automaton</param>
        /// <param name="right">The right automaton</param>
        /// <param name="useClones">True to completely clone the sub-automata</param>
        /// <returns>The new automaton</returns>
        // TODO: should get rid of static methods
        public static NFA NewConcatenation(NFA left, NFA right, bool useClones)
        {
            NFA final = new NFA();

            if (useClones)
            {
                left  = left.Clone(true);
                right = right.Clone(true);
            }
            final.states.AddRange(left.states);
            final.states.AddRange(right.states);
            final.StateEntry = left.StateEntry;
            final.StateExit  = right.StateExit;
            left.StateExit.AddTransition(NFA.EPSILON, right.StateEntry);
            return(final);
        }
Exemple #4
0
        /// <summary>
        /// Creates an automaton that is the union of the two sub-automaton
        /// </summary>
        /// <param name="left">The left automaton</param>
        /// <param name="right">The right automaton</param>
        /// <param name="useClones">True to completely clone the sub-automata</param>
        /// <returns>The new automaton</returns>
        // TODO: should get rid of static methods
        public static NFA NewUnion(NFA left, NFA right, bool useClones)
        {
            NFA final = NewMinimal();

            if (useClones)
            {
                left  = left.Clone(true);
                right = right.Clone(true);
            }
            final.states.AddRange(left.states);
            final.states.AddRange(right.states);
            final.StateEntry.AddTransition(NFA.EPSILON, left.StateEntry);
            final.StateEntry.AddTransition(NFA.EPSILON, right.StateEntry);
            left.StateExit.AddTransition(NFA.EPSILON, final.StateExit);
            right.StateExit.AddTransition(NFA.EPSILON, final.StateExit);
            return(final);
        }
Exemple #5
0
        /// <summary>
        /// Creates an automaton that is the difference between the left and right sub-automata
        /// </summary>
        /// <param name="left">The left automaton</param>
        /// <param name="right">The right automaton</param>
        /// <param name="useClones">True to completely clone the sub-automata</param>
        /// <returns>The new automaton</returns>
        // TODO: should get rid of static methods
        public static NFA NewDifference(NFA left, NFA right, bool useClones)
        {
            NFA      final         = NewMinimal();
            NFAState statePositive = final.AddNewState();
            NFAState stateNegative = final.AddNewState();

            statePositive.Mark = 1;
            stateNegative.Mark = -1;

            if (useClones)
            {
                left  = left.Clone(true);
                right = right.Clone(true);
            }
            final.states.AddRange(left.states);
            final.states.AddRange(right.states);
            final.StateEntry.AddTransition(NFA.EPSILON, left.StateEntry);
            final.StateEntry.AddTransition(NFA.EPSILON, right.StateEntry);
            left.StateExit.AddTransition(NFA.EPSILON, statePositive);
            right.StateExit.AddTransition(NFA.EPSILON, stateNegative);
            statePositive.AddTransition(NFA.EPSILON, final.StateExit);

            final.StateExit.AddItem(DummyItem.Instance);
            DFA equivalent = new DFA(final);

            equivalent.Prune();
            final           = new NFA(equivalent);
            final.StateExit = final.AddNewState();
            foreach (NFAState state in final.states)
            {
                if (state.Items.Contains(DummyItem.Instance))
                {
                    state.ClearItems();
                    state.AddTransition(NFA.EPSILON, final.StateExit);
                }
            }
            return(final);
        }