private void ExecuteOperation(char operation)
        {
            switch (operation)
            {
            case '*':
            {
                Automate automate = automats.Pop();
                automate = op.Interation(automate);
                index++;
                automats.Push(automate);
            }
            break;

            case '|':
            {
                Automate automat1 = automats.Pop();
                Automate automat2 = automats.Pop();
                automat1 = op.Union(automat1, automat2);
                automats.Push(automat1);
            }
            break;

            case '$':
            {
                Automate automat2 = automats.Pop();
                Automate automat1 = automats.Pop();
                automat1 = op.Concat(automat1, automat2);
                automats.Push(automat1);
            }
            break;
            }
        }
        public Automate Concat(Automate automat1, Automate automat2)
        {
            if (automat1.alphabet != null)
            {
                Automate newAutomate = new Automate();
                newAutomate.name     = automat1.name;
                newAutomate.priority = automat1.priority;
                automat1.alphabet.UnionWith(automat2.alphabet);
                newAutomate.alphabet     = automat1.alphabet;
                newAutomate.startStates  = automat1.startStates;
                newAutomate.finishStates = automat2.finishStates;
                newAutomate.setStates    = automat1.setStates;
                newAutomate.setStates.UnionWith(automat2.setStates);
                newAutomate.Table = automat1.Table;
                foreach (var i in automat2.Table.Keys)
                {
                    newAutomate.Table.Add(i, automat2.Table[i]);
                }
                foreach (var i in automat1.finishStates)
                {
                    foreach (var j in automat2.startStates)
                    {
                        foreach (var pair in automat2.Table[j])
                        {
                            if (newAutomate.Table[i].ContainsKey(pair.Key))
                            {
                                HashSet <int> values = new HashSet <int>();
                                foreach (var vl in newAutomate.Table[i][pair.Key])
                                {
                                    values.Add(vl);
                                }
                                foreach (var value in pair.Value)
                                {
                                    values.Add(value);
                                }
                                newAutomate.Table[i][pair.Key] = values;
                            }
                            else
                            {
                                newAutomate.Table[i].Add(pair.Key, pair.Value);
                            }
                        }
                    }
                }

                if (automat2.finishStates.Intersect(automat2.startStates).Count() != 0)
                {
                    //если хотя бы одно из начачальное состоние было заключительным, то объявляем заключительными все заключ. сост 1го автомата
                    newAutomate.finishStates.UnionWith(automat1.finishStates);
                }
                return(newAutomate);
            }
            else
            {
                return(automat2);
            }
        }
 public Automate(Automate automat)
 {
     name         = automat.name;
     priority     = automat.priority;
     alphabet     = new HashSet <string>(automat.alphabet);
     setStates    = new HashSet <int>(automat.setStates);
     startStates  = new HashSet <int>(automat.startStates);
     finishStates = new HashSet <int>(automat.finishStates);
     Table        = automat.Table;
 }
        public Result MaxString(Automate automate, string str, int k)
        {
            HashSet <int> currentSet = new HashSet <int>(automate.startStates);
            Result        result     = new Result(false, 0, "");

            if (automate.finishStates.Intersect(currentSet).Count() != 0)
            {
                result.res = true;
            }
            HashSet <int> temp;

            for (int i = k; i < str.Length; i++)
            {
                temp = new HashSet <int>();
                if (automate.alphabet.Contains(str[i].ToString()))
                {
                    foreach (var currentState in currentSet)
                    {
                        foreach (var pair in automate.Table[currentState])
                        {
                            if (pair.Key == str[i].ToString())
                            {
                                foreach (var p in pair.Value)
                                {
                                    if (p != -1)
                                    {
                                        temp.Add(p);
                                    }
                                }
                            }
                        }
                        if (automate.finishStates.Intersect(temp).Count() != 0)
                        {
                            result.res       = true;
                            result.m         = i - k + 1;
                            result.substring = str.Substring(k, result.m);
                            break;
                        }
                    }
                    if (temp.Count == 0)
                    {
                        return(result);
                    }
                    temp.Remove(-1);
                    currentSet = temp;
                }
                else
                {
                    break;
                }
            }
            return(result);
        }
        public Automate Interation(Automate automate)
        {
            //Из всех заключительных состояний организуем переходы туда же, куда есть переходы из нач состояний
            Automate newAutomate = new Automate(automate);

            foreach (var i in automate.finishStates)
            {
                foreach (var j in newAutomate.startStates)
                {
                    foreach (var pair in newAutomate.Table[j])
                    {
                        if (newAutomate.Table[i].ContainsKey(pair.Key))
                        {
                            //newAutomat.Table[i][pair.Key] = pair.Value;
                            HashSet <int> values = new HashSet <int>();
                            foreach (var vl in newAutomate.Table[i][pair.Key])
                            {
                                values.Add(vl);
                            }
                            foreach (var value in pair.Value)
                            {
                                values.Add(value);
                            }
                            newAutomate.Table[i][pair.Key] = values;
                        }
                        else
                        {
                            newAutomate.Table[i].Add(pair.Key, pair.Value);
                        }
                    }
                }
            }
            //Добавляем новое состояние и делаем его заключительным и начальным
            int index = automate.Table.Keys.Max();

            index++;
            newAutomate.startStates.Add(index);
            newAutomate.finishStates.Add(index);
            newAutomate.setStates.Add(index);

            Dictionary <string, HashSet <int> > dictionary = new Dictionary <string, HashSet <int> >();

            foreach (var item in automate.alphabet)
            {
                dictionary.Add(item, new HashSet <int> {
                    -1
                });
            }
            newAutomate.Table.Add(index, dictionary);
            return(newAutomate);
        }
        public Automate CreateSimpleAutomat(string name, int priority, HashSet <string> alphabet, HashSet <string> newChar, ref int index)
        {
            Automate automate = new Automate();

            //автомат для 1 символа
            automate.name         = name;
            automate.priority     = priority;
            automate.startStates  = new HashSet <int>();
            automate.setStates    = new HashSet <int>();
            automate.finishStates = new HashSet <int>();
            automate.alphabet     = new HashSet <string>(alphabet);
            automate.Table        = new Dictionary <int, Dictionary <string, HashSet <int> > >();

            automate.startStates.Add(index);
            automate.setStates.UnionWith(automate.startStates);
            index++;
            automate.finishStates.Add(index);
            index++;
            automate.setStates.UnionWith(automate.finishStates);

            Dictionary <string, HashSet <int> > list    = new Dictionary <string, HashSet <int> >();
            Dictionary <string, HashSet <int> > listEnd = new Dictionary <string, HashSet <int> >();

            for (int j = 0; j < automate.alphabet.Count; j++)
            {
                list.Add(automate.alphabet.ElementAt(j), new HashSet <int> {
                    -1
                });
                listEnd.Add(automate.alphabet.ElementAt(j), new HashSet <int> {
                    -1
                });
            }
            Dictionary <string, HashSet <int> > listCopy = new Dictionary <string, HashSet <int> >(list);

            for (int j = 0; j < newChar.Count; j++)
            {
                foreach (var pair in list)
                {
                    if (newChar.ElementAt(j).Contains(pair.Key))
                    {
                        listCopy[pair.Key] = new HashSet <int>(automate.finishStates);
                    }
                }
            }
            automate.Table.Add(automate.startStates.ElementAt(0), listCopy);
            automate.Table.Add(automate.finishStates.ElementAt(0), listEnd);

            return(automate);
        }
Пример #7
0
        static void Main(string[] args)
        {
            List <Lexeme>   lexemes   = ReadLexemes();
            List <Automate> automates = new List <Automate>();
            CreateAutomate  ca        = new CreateAutomate();

            for (int i = 0; i < lexemes.Count; i++) //внешний цикл по все лексемам
            {
                Console.WriteLine(lexemes[i].regex);
                Automate automat = new Automate(lexemes[i].name, lexemes[i].priority, lexemes[i].regex);
                automat = ca.Create(automat);
                automates.Add(automat);
            }
            SearchSubstring        task       = new SearchSubstring();
            List <MaxStringResult> listTokens = task.Start(automates);
            RecursiveDescentParser rDP        = new RecursiveDescentParser();
            int        k           = 0;
            List <int> regulations = rDP.RecursiveDescentParserMethod(ref k, listTokens);

            WriteIntoFile("outputRegulations.txt", regulations);
        }
        public Automate Union(Automate automat1, Automate automat2)
        {
            Automate newAutomate = new Automate();

            newAutomate.name     = automat1.name;
            newAutomate.priority = automat1.priority;
            automat1.setStates.UnionWith(automat2.setStates);
            newAutomate.setStates = automat1.setStates;
            automat1.alphabet.UnionWith(automat2.alphabet);
            newAutomate.alphabet = automat1.alphabet;
            automat1.startStates.UnionWith(automat2.startStates);
            newAutomate.startStates = automat1.startStates;
            automat1.finishStates.UnionWith(automat2.finishStates);
            newAutomate.finishStates = automat1.finishStates;
            newAutomate.Table        = automat1.Table;
            foreach (var i in automat2.Table.Keys)
            {
                newAutomate.Table.Add(i, automat2.Table[i]);
            }
            return(newAutomate);
        }
        public Automate Create(Automate automate)
        {
            HashSet <string> alph = new HashSet <string> {
                "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "a", "s", "d", "f", "g", "h", "j", "k", "l", "z", "x", "c", "v", "b", "n", "m"
            };
            HashSet <string> digits = new HashSet <string> {
                "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"
            };
            HashSet <string> allSymbols = new HashSet <string> {
                "!", "@", "\"", "#", "№", "$", ";", ":", "%", "^", "&", "?", "*", "(", ")", "-", "+", "=", ",", ".", "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "a", "s", "d", "f", "g", "h", "j", "k", "l", "z", "x", "c", "v", "b", "n", "m", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"
            };

            automats  = new Stack <Automate>();
            operators = new Stack <char>();
            index     = 0;
            StringBuilder regex = automate.regex;

            for (int i = 0; i < regex.Length; i++)
            {
                switch (regex[i])
                {
                case '(':
                    operators.Push('(');
                    break;

                case ')':
                    while (operators.Peek() != '(')
                    {
                        ExecuteOperation(operators.Pop());
                    }
                    operators.Pop();
                    break;

                case '*':
                case '|':
                case '$':
                    char currentOperator = regex[i];
                    while (operators.Count != 0 && automats.Count != 0 && GetPriorityOperation(operators.Peek()) >= GetPriorityOperation(currentOperator))
                    {
                        ExecuteOperation(operators.Pop());
                    }
                    operators.Push(currentOperator);
                    break;

                case '\\':
                    i++;
                    switch (regex[i])
                    {
                    case ('w'):
                        automate.alphabet.UnionWith(alph);
                        automats.Push(CreateSimpleAutomat(automate.name, automate.priority, automate.alphabet, alph, ref index));
                        break;

                    case ('d'):
                        automate.alphabet.UnionWith(digits);
                        automats.Push(CreateSimpleAutomat(automate.name, automate.priority, automate.alphabet, digits, ref index));
                        break;

                    case ('s'):
                        automate.alphabet.UnionWith(new HashSet <string> {
                            "\\s"
                        });
                        automats.Push(CreateSimpleAutomat(automate.name, automate.priority, automate.alphabet, new HashSet <string> {
                            "\\s"
                        }, ref index));
                        break;

                    case (' '):
                        automate.alphabet.UnionWith(new HashSet <string> {
                            "\\s"
                        });
                        automats.Push(CreateSimpleAutomat(automate.name, automate.priority, automate.alphabet, new HashSet <string> {
                            "\\s"
                        }, ref index));
                        break;

                    case ('t'):
                        automate.alphabet.UnionWith(new HashSet <string> {
                            "\t"
                        });
                        automats.Push(CreateSimpleAutomat(automate.name, automate.priority, automate.alphabet, new HashSet <string> {
                            "\t"
                        }, ref index));
                        break;

                    case ('r'):
                        automate.alphabet.UnionWith(new HashSet <string> {
                            "\r"
                        });
                        automats.Push(CreateSimpleAutomat(automate.name, automate.priority, automate.alphabet, new HashSet <string> {
                            "\r"
                        }, ref index));
                        break;

                    case ('n'):
                        automate.alphabet.UnionWith(new HashSet <string> {
                            "\n"
                        });
                        automats.Push(CreateSimpleAutomat(automate.name, automate.priority, automate.alphabet, new HashSet <string> {
                            "\n"
                        }, ref index));
                        break;

                    case ('@'):
                        automate.alphabet.UnionWith(new HashSet <string> {
                            ""
                        });
                        automats.Push(CreateSimpleAutomat(automate.name, automate.priority, automate.alphabet, new HashSet <string> {
                            ""
                        }, ref index));
                        break;

                    case ('.'):
                        automate.alphabet.UnionWith(allSymbols);
                        automats.Push(CreateSimpleAutomat(automate.name, automate.priority, automate.alphabet, allSymbols, ref index));
                        break;

                    default:
                        automate.alphabet.UnionWith(new HashSet <string> {
                            regex[i].ToString()
                        });
                        automats.Push(CreateSimpleAutomat(automate.name, automate.priority, automate.alphabet, new HashSet <string> {
                            regex[i].ToString()
                        }, ref index));
                        break;
                    }
                    break;

                default:
                    automate.alphabet.UnionWith(new HashSet <string> {
                        regex[i].ToString()
                    });
                    automats.Push(CreateSimpleAutomat(automate.name, automate.priority, automate.alphabet, new HashSet <string> {
                        regex[i].ToString()
                    }, ref index));
                    break;
                }
            }
            while (operators.Count() != 0)
            {
                ExecuteOperation(operators.Pop());
            }
            if (automats.Count() == 1)
            {
                return(automats.Pop());
            }
            return(null);
        }