Example #1
0
File: NFA.cs Project: sebgod/hime
        /// <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);
        }
Example #2
0
File: NFA.cs Project: sebgod/hime
        /// <summary>
        /// Clones this automaton
        /// </summary>
        /// <param name="keepFinals">Whether to keep the marks for the final states</param>
        /// <returns>The cloned automaton</returns>
        public NFA Clone(bool keepFinals)
        {
            NFA copy = new NFA();

            // Create new states for copy, add marks and copy finals if required
            for (int i = 0; i != states.Count; i++)
            {
                NFAState state = new NFAState();
                state.Mark = states[i].Mark;
                if (keepFinals)
                {
                    state.AddItems(states[i].Items);
                }
                copy.states.Add(state);
            }
            // Make linkage
            for (int i = 0; i != states.Count; i++)
            {
                foreach (NFATransition transition in states[i].Transitions)
                {
                    copy.states[i].AddTransition(transition.Span, copy.states[states.IndexOf(transition.Next)]);
                }
            }
            if (StateEntry != null)
            {
                copy.StateEntry = copy.states[states.IndexOf(StateEntry)];
            }
            if (StateExit != null)
            {
                copy.StateExit = copy.states[states.IndexOf(StateExit)];
            }
            return(copy);
        }
Example #3
0
File: NFA.cs Project: sebgod/hime
        /// <summary>
        /// Creates and initializes a minimal automaton with an entry state and a separate exit state
        /// </summary>
        /// <returns>The created automaton</returns>
        public static NFA NewMinimal()
        {
            NFA result = new NFA();

            result.StateEntry = result.AddNewState();
            result.StateExit  = result.AddNewState();
            return(result);
        }
Example #4
0
File: DFA.cs Project: sebgod/hime
        /// <summary>
        /// Initializes this dfa as equivalent to the given nfa
        /// </summary>
        /// <param name="nfa">A nfa</param>
        public DFA(NFA nfa)
        {
            states = new List <DFAState>();

            List <NFAStateSet> nfaStateSets = new List <NFAStateSet>();
            // Create the first NFA set, add the entry and close it
            NFAStateSet nfaInit = new NFAStateSet();

            nfaStateSets.Add(nfaInit);
            nfaInit.Add(nfa.StateEntry);
            nfaInit.Close();
            // Create the initial state for the DFA
            DFAState dfaInit = new DFAState(0);

            states.Add(dfaInit);

            // For each set in the list of the NFA states
            for (int i = 0; i != nfaStateSets.Count; i++)
            {
                // Normalize transitions
                nfaStateSets[i].Normalize();

                // Get the transitions for the set
                Dictionary <CharSpan, NFAStateSet> transitions = nfaStateSets[i].GetTransitions();
                // For each transition
                foreach (CharSpan value in transitions.Keys)
                {
                    // The child by the transition
                    NFAStateSet next = transitions[value];
                    // Search for the child in the existing sets
                    bool found = false;
                    for (int j = 0; j != nfaStateSets.Count; j++)
                    {
                        // An existing equivalent set is already present
                        if (nfaStateSets[j].Equals(next))
                        {
                            states[i].AddTransition(value, states[j]);
                            found = true;
                            break;
                        }
                    }
                    // The child is not already present
                    if (!found)
                    {
                        // Add to the sets list
                        nfaStateSets.Add(next);
                        // Create the corresponding DFA state
                        DFAState newState = new DFAState(states.Count);
                        states.Add(newState);
                        // Setup transition
                        states[i].AddTransition(value, newState);
                    }
                }
                // Add finals
                states[i].AddItems(nfaStateSets[i].GetFinals());
            }
        }
Example #5
0
File: NFA.cs Project: sebgod/hime
        /// <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);
        }
Example #6
0
File: NFA.cs Project: sebgod/hime
        /// <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);
        }
Example #7
0
File: NFA.cs Project: sebgod/hime
        /// <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);
        }
Example #8
0
File: NFA.cs Project: sebgod/hime
        /// <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);
        }
Example #9
0
File: NFA.cs Project: sebgod/hime
 /// <summary>
 /// Inserts all the states of the given automaton into this one
 /// This does not make a copy of the states, this directly includes them
 /// </summary>
 /// <param name="sub">Sub-automaton to include in this one</param>
 public void InsertSubNFA(NFA sub)
 {
     states.AddRange(sub.states);
 }