public void Concat(NFA second) { Finish.Translations.Add(new Translation(second.Initial, Translation.Eps)); // Соединяем первый финиш и второе начало по ε Finish = second.Finish; // Сохраняем новый финиш Size = UpdateStates(); // Обновляем номера состояний }
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(); // Обновляем номера состояний }
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()); }
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"); } }