예제 #1
0
        public void Concat(NFA second)
        {
            Finish.Translations.Add(new Translation(second.Initial, Translation.Eps)); // Соединяем первый финиш и второе начало по ε
            Finish = second.Finish;                                                    // Сохраняем новый финиш

            Size = UpdateStates();                                                     // Обновляем номера состояний
        }
예제 #2
0
        public void Alter(NFA second)
        {
            State newFinish = new State(1, new List <Translation>());                    // Создаем новый финиш

            Finish.Translations.Add(new Translation(newFinish, Translation.Eps));        // Добавляем старому финишу первого автомата переход в новый
            second.Finish.Translations.Add(new Translation(newFinish, Translation.Eps)); // Добавляем старому финишу второго автомата переход в новый
            Finish = newFinish;                                                          // Сохраняем новый финиш на место старого
            State oldInit = Initial;                                                     // Сохраняем старое начало

            Initial = new State(0, new List <Translation>()
            {
                new Translation(oldInit, Translation.Eps),
                new Translation(second.Initial, Translation.Eps)
            });                     // Создаем новое начало с двумя ε переходами в данные автоматы

            Size = UpdateStates();  // Обновляем номера состояний
        }
예제 #3
0
        public static NFA ToNFA(string postfix)
        {
            Stack <NFA> nfas = new Stack <NFA>();

            CharEnumerator c = postfix.GetEnumerator();

            while (c.MoveNext())
            {
                if (char.IsLetterOrDigit(c.Current))
                {
                    nfas.Push(new NFA(c.Current));
                }
                else if (c.Current == '.')
                {
                    NFA b = nfas.Pop();
                    NFA a = nfas.Pop();
                    a.Concat(b);

                    nfas.Push(a);
                }
                else if (c.Current == '|')
                {
                    NFA b = nfas.Pop();
                    NFA a = nfas.Pop();
                    a.Alter(b);

                    nfas.Push(a);
                }
                else if (c.Current == '*')
                {
                    nfas.Peek().Star();
                }
                else if (c.Current == '+')
                {
                    nfas.Peek().Plus();
                }
            }

            return(nfas.Pop());
        }
예제 #4
0
        public static void Main(string[] args)
        {
            //List<char> alphabet = Enumerable.Range('a', 'z' - 'a' + 1).Select(i => (Char) i).ToList();
            List <char> alphabet = Enumerable.Range('a', 'b' - 'a' + 1).Select(i => (Char)i).ToList();
            //alphabet = alphabet.Concat(Enumerable.Range('0', '9' - '0' + 1).Select(i => (Char) i)).ToList();
            List <char> epsAlphabet = alphabet.Concat(new char[] { 'ε' }.ToList()).ToList();

            GraphVizBuilder graphViz = new GraphVizBuilder();

            // Read valid regexp
            Console.WriteLine("Enter RegExp to build FA:");
            string regexp = Console.ReadLine();

            // Preprocess regexp (adding dots where concatenating)
            string processedRegexp = Preprocess(regexp);

            // Process regexp to postfix
            string postfixRegexp = ToPostfix(processedRegexp);

            // Building NFA in graph from postfix regexp
            NFA nfa      = ToNFA(postfixRegexp);
            var nfaTable = nfa.BuildTable(epsAlphabet);  // Building NFA in table from graph


            // Draw NFA
            string graphNFA = graphViz.BuildString(epsAlphabet, nfaTable, nfa.Initial.S, new List <int>()
            {
                nfa.Finish.S
            });

            graphViz.CreateGraph(graphNFA, "nfa.png");

            // Building DFA from NFA
            DFA dfa = new DFA(nfaTable, alphabet, epsAlphabet.IndexOf(Translation.Eps), nfa.Initial.S, nfa.Finish.S);



            string graphDFA = graphViz.BuildString(alphabet, dfa.DFATable, dfa.Initial, dfa.Finish);

            graphViz.CreateGraph(graphDFA, "dfa.png");

            //R

            dfa.Reverse();
            string graphDFAr = graphViz.BuildString(dfa.Alphabet, dfa.DFATable, dfa.Initial, dfa.Finish);

            graphViz.CreateGraph(graphDFAr, "dfa_r.png");

            //RD
            dfa.MakeDfa();

            string graphDFArd = graphViz.BuildString(dfa.Alphabet, dfa.DFATable, dfa.Initial, dfa.Finish);

            graphViz.CreateGraph(graphDFArd, "dfa_rd.png");

            //RDR

            dfa.Reverse();
            string graphDFArdr = graphViz.BuildString(dfa.Alphabet, dfa.DFATable, dfa.Initial, dfa.Finish);

            graphViz.CreateGraph(graphDFArdr, "dfa_rdr.png");

            //RDRD
            dfa.MakeDfa();
            string graphDFArdrd = graphViz.BuildString(dfa.Alphabet, dfa.DFATable, dfa.Initial, dfa.Finish);

            graphViz.CreateGraph(graphDFArdrd, "dfa_rdrd.png");

            while (true)
            {
                Console.WriteLine("Enter word to check allowness:");
                string word = Console.ReadLine();
                if (word == "`")
                {
                    break;
                }

                // Model FA for given word
                bool res = dfa.Model(word, alphabet);
                Console.WriteLine($"Result: {res}\n");
            }
        }