コード例 #1
0
ファイル: NFA.cs プロジェクト: wyb314/RegexEngine
        /////////////////////////////////////////////////////////////////
        //
        // NFA building functions
        //
        // Using Thompson Construction, build NFAs from basic inputs or
        // compositions of other NFAs.
        //

        /// <summary>
        /// Builds a basic, single input NFA
        /// </summary>
        /// <param name="in"></param>
        /// <returns></returns>
        public static NFA BuildNFABasic(input @in)
        {
            NFA basic = new NFA(2, 0, 1);

            basic.AddTrans(0, 1, @in);

            return(basic);
        }
コード例 #2
0
ファイル: NFA.cs プロジェクト: wyb314/RegexEngine
 public NFA(NFA nfa)
 {
     initial    = nfa.initial;
     final      = nfa.final;
     size       = nfa.size;
     inputs     = nfa.inputs;
     transTable = nfa.transTable;
 }
コード例 #3
0
ファイル: NFA.cs プロジェクト: wyb314/RegexEngine
        /// <summary>
        /// Fills states 0 up to other.size with other's states.
        /// </summary>
        /// <param name="other"></param>
        public void FillStates(NFA other)
        {
            for (state i = 0; i < other.size; ++i)
            {
                for (state j = 0; j < other.size; ++j)
                {
                    transTable[i][j] = other.transTable[i][j];
                }
            }

            SCG.IEnumerator <input> cE = other.inputs.GetEnumerator();

            while (cE.MoveNext())
            {
                inputs.Add(cE.Current);
            }
        }
コード例 #4
0
ファイル: NFA old.cs プロジェクト: wyb314/RegexEngine
        public void FillStates(NFA other)
        {
            for (state i = 0; i < other.size; ++i)
            {
                for (state j = 0; j < other.size; ++j)
                {
                    transTable[i][j] = other.transTable[i][j];
                }
            }

            for (int i = 0; i < other.inputs.Count; i++)
            {
                if (!inputs.Contains(other.inputs[i]))
                {
                    inputs.Add(other.inputs[i]);
                }
            }
        }
コード例 #5
0
ファイル: RegexParser.cs プロジェクト: wyb314/RegexEngine
        /// <summary>
        /// The main entry point of the Console Application
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            if (args.Length != 3)
            {
                Console.WriteLine("Call with the regex as an argument.");

                Environment.Exit(1);
            }

            RegexParser myRegexParser = new RegexParser();

            // Passing the regex to be preprocessed.
            myRegexParser.Init(args[1]);

            // Creating a parse tree with the preprocessed regex
            ParseTree parseTree = myRegexParser.Expr();

            // Checking for a string termination character after
            // parsing the regex
            if (myRegexParser.Peek() != '\0')
            {
                Console.WriteLine("Parse error: unexpected char, got {0} at #{1}",

                                  myRegexParser.Peek(), myRegexParser.GetPos());

                Environment.Exit(1);
            }

            PrintTree(parseTree, 1);

            NFA nfa = NFA.TreeToNFA(parseTree);

            nfa.Show();

            DFA dfa = SubsetMachine.SubsetConstruct(nfa);

            dfa.Show();

            Console.Write("\n\n");

            Console.Write("Result: {0}", dfa.Simulate(args[2]));

            Console.ReadKey();
        }
コード例 #6
0
ファイル: NFA.cs プロジェクト: wyb314/RegexEngine
        /// <summary>
        /// Builds a star (kleene closure) of nfa (nfa*)
        /// How this is done: First will come the new initial state, then NFA, then the
        /// new final state
        /// </summary>
        /// <param name="nfa"></param>
        /// <returns></returns>
        public static NFA BuildNFAStar(NFA nfa)
        {
            // Makes room for the new initial state
            nfa.ShiftStates(1);

            // Makes room for the new final state
            nfa.AppendEmptyState();

            // Adds new transitions
            nfa.AddTrans(nfa.final, nfa.initial, (char)Constants.Epsilon);
            nfa.AddTrans(0, nfa.initial, (char)Constants.Epsilon);
            nfa.AddTrans(nfa.final, nfa.size - 1, (char)Constants.Epsilon);
            nfa.AddTrans(0, nfa.size - 1, (char)Constants.Epsilon);

            nfa.initial = 0;
            nfa.final   = nfa.size - 1;

            return(nfa);
        }
コード例 #7
0
ファイル: NFA.cs プロジェクト: wyb314/RegexEngine
        /// <summary>
        /// Builds an alternation of nfa1 and nfa2 (nfa1|nfa2)
        /// </summary>
        /// <param name="nfa1"></param>
        /// <param name="nfa2"></param>
        /// <returns></returns>
        public static NFA BuildNFAConcat(NFA nfa1, NFA nfa2)
        {
            // How this is done: First will come nfa1, then nfa2 (its initial state replaced
            // with nfa1's final state)
            nfa2.ShiftStates(nfa1.size - 1);

            // Creates a new NFA and initialize it with (the shifted) nfa2
            NFA newNFA = new NFA(nfa2);

            // nfa1's states take their places in newNFA
            // note: nfa1's final state overwrites nfa2's initial state,
            // thus we get the desired merge automagically (the transition
            // from nfa2's initial state now transits from nfa1's final state)
            newNFA.FillStates(nfa1);

            // Sets the new initial state (the final state stays nfa2's final state,
            // and was already copied)
            newNFA.initial = nfa1.initial;

            return(newNFA);
        }
コード例 #8
0
ファイル: NFA.cs プロジェクト: wyb314/RegexEngine
        /// <summary>
        /// Builds an alternation of nfa1 and nfa2 (nfa1|nfa2)
        /// </summary>
        /// <param name="nfa1"></param>
        /// <param name="nfa2"></param>
        /// <returns></returns>
        public static NFA BuildNFAAlter(NFA nfa1, NFA nfa2)
        {
            // How this is done: the new nfa must contain all the states in
            // nfa1 and nfa2, plus a new initial and final states.
            // First will come the new initial state, then nfa1's states, then
            // nfa2's states, then the new final state

            // make room for the new initial state
            nfa1.ShiftStates(1);

            // make room for nfa1
            nfa2.ShiftStates(nfa1.size);

            // create a new nfa and initialize it with (the shifted) nfa2
            NFA newNFA = new NFA(nfa2);

            // nfa1's states take their places in new_nfa
            newNFA.FillStates(nfa1);

            // Set new initial state and the transitions from it
            newNFA.AddTrans(0, nfa1.initial, (char)Constants.Epsilon);
            newNFA.AddTrans(0, nfa2.initial, (char)Constants.Epsilon);

            newNFA.initial = 0;

            // Make up space for the new final state
            newNFA.AppendEmptyState();

            // Set new final state
            newNFA.final = newNFA.size - 1;

            newNFA.AddTrans(nfa1.final, newNFA.final, (char)Constants.Epsilon);
            newNFA.AddTrans(nfa2.final, newNFA.final, (char)Constants.Epsilon);

            return(newNFA);
        }
コード例 #9
0
        /// <summary>
        /// Builds the Epsilon closure of states for the given NFA
        /// </summary>
        /// <param name="nfa"></param>
        /// <param name="states"></param>
        /// <returns></returns>
        static Set <state> EpsilonClosure(NFA nfa, Set <state> states)
        {
            // Push all states onto a stack
            SCG.Stack <state> uncheckedStack = new SCG.Stack <state>(states);

            // Initialize EpsilonClosure(states) to states
            Set <state> epsilonClosure = states;

            while (uncheckedStack.Count != 0)
            {
                // Pop state t, the top element, off the stack
                state t = uncheckedStack.Pop();

                int i = 0;

                // For each state u with an edge from t to u labeled Epsilon
                foreach (input input in nfa.transTable[t])
                {
                    if (input == (char)NFA.Constants.Epsilon)
                    {
                        state u = Array.IndexOf(nfa.transTable[t], input, i);

                        // If u is not already in epsilonClosure, add it and push it onto stack
                        if (!epsilonClosure.Contains(u))
                        {
                            epsilonClosure.Add(u);
                            uncheckedStack.Push(u);
                        }
                    }

                    i = i + 1;
                }
            }

            return(epsilonClosure);
        }
コード例 #10
0
        /// <summary>
        /// Subset machine that employs the powerset construction or subset construction algorithm.
        /// It creates a DFA that recognizes the same language as the given NFA.
        /// </summary>
        public static DFA SubsetConstruct(NFA nfa)
        {
            DFA dfa = new DFA();

            // Sets of NFA states which is represented by some DFA state
            Set <Set <state> > markedStates   = new Set <Set <state> >();
            Set <Set <state> > unmarkedStates = new Set <Set <state> >();

            // Gives a number to each state in the DFA
            HashDictionary <Set <state>, state> dfaStateNum = new HashDictionary <Set <state>, state>();

            Set <state> nfaInitial = new Set <state>();

            nfaInitial.Add(nfa.initial);

            // Initially, EpsilonClosure(nfa.initial) is the only state in the DFAs states
            // and it's unmarked.
            Set <state> first = EpsilonClosure(nfa, nfaInitial);

            unmarkedStates.Add(first);

            // The initial dfa state
            state dfaInitial = GenNewState();

            dfaStateNum[first] = dfaInitial;
            dfa.start          = dfaInitial;

            while (unmarkedStates.Count != 0)
            {
                // Takes out one unmarked state and posteriorly mark it.
                Set <state> aState = unmarkedStates.Choose();

                // Removes from the unmarked set.
                unmarkedStates.Remove(aState);

                // Inserts into the marked set.
                markedStates.Add(aState);

                // If this state contains the NFA's final state, add it to the DFA's set of
                // final states.
                if (aState.Contains(nfa.final))
                {
                    dfa.final.Add(dfaStateNum[aState]);
                }

                SCG.IEnumerator <input> iE = nfa.inputs.GetEnumerator();

                // For each input symbol the NFA knows...
                while (iE.MoveNext())
                {
                    // Next state
                    Set <state> next = EpsilonClosure(nfa, nfa.Move(aState, iE.Current));

                    // If we haven't examined this state before, add it to the unmarkedStates,
                    // and make up a new number for it.
                    if (!unmarkedStates.Contains(next) && !markedStates.Contains(next))
                    {
                        unmarkedStates.Add(next);
                        dfaStateNum.Add(next, GenNewState());
                    }

                    KeyValuePair <state, input> transition = new KeyValuePair <state, input>();
                    transition.Key   = dfaStateNum[aState];
                    transition.Value = iE.Current;

                    dfa.transTable[transition] = dfaStateNum[next];
                }
            }

            return(dfa);
        }