Exemplo n.º 1
0
        public static Automata GrammarParser(string program)
        {
            Stack <char>       control = new Stack <char>();
            Stack <ENextSteps> steps   = new Stack <ENextSteps>();

            steps.Push(ENextSteps.NormalizeTransitions);
            steps.Push(ENextSteps.InitialStates);
            steps.Push(ENextSteps.ReadTransitions);
            steps.Push(ENextSteps.Alphabet);
            steps.Push(ENextSteps.States);

            Automata   automata    = new Automata();
            ENextSteps currentStep = ENextSteps.Undefined;
            string     processed   = "";

            for (int i = 0; i < program.Length; i++)
            {
                var c     = program[i];
                var cNext = '#';
                if (c == ';' || c == '(')
                {
                    if (steps.Count > 0)
                    {
                        currentStep = steps.Pop();
                        cNext       = program[i + 1];
                    }
                    else
                    {
                        currentStep = ENextSteps.Undefined;
                    }
                }
                else
                {
                    if (c != ')')
                    {
                        cNext = program[i + 1];
                    }
                }

                switch (currentStep)
                {
                case ENextSteps.Begin:
                {
                    break;
                }

                case ENextSteps.States:
                {
                    if (char.IsLetterOrDigit(c))
                    {
                        processed = processed + c;
                    }
                    if ((c == ',' || cNext == '}'))
                    {
                        automata.States.Add(processed);
                        processed = "";
                    }
                }
                break;

                case ENextSteps.Alphabet:
                {
                    if (char.IsLetterOrDigit(c))
                    {
                        processed = processed + c;
                    }
                    if (c == ',' || cNext == '}')
                    {
                        automata.Alphabet.Add(processed[0]);
                        processed = "";
                    }
                    break;
                }

                case ENextSteps.ReadTransitions:
                {
                    if ((char.IsLetterOrDigit(c) || c == '#') && (cNext == '-' || cNext == ',' || cNext == '}'))
                    {
                        processed = processed + c;
                    }
                    if (c == '>' & char.IsLetterOrDigit(cNext))
                    {
                        processed = processed + cNext + '|';
                    }
                    if (c == '-' && cNext == '>')
                    {
                        processed = processed + '|';
                    }
                    if (c == '#')
                    {
                        processed = processed + "|#";
                    }
                    if (processed.Split('|').Length == 3 && processed.Split('|')[2] != "")
                    {
                        var itens = processed.Split('|');
                        if (automata.States.Contains(itens[0]) && automata.States.Contains(itens[2]) || automata.Alphabet.Contains(itens[2][0]) || itens[2][0] == '#')
                        {
                            automata.Transitions.Add(new Tuple <string, char, string>(itens[0], itens[1].ToCharArray()[0], itens[2]));
                            processed = "";
                        }
                    }
                    break;
                }

                case ENextSteps.InitialStates:
                {
                    if (char.IsLetterOrDigit(c) && cNext != '-')
                    {
                        processed = processed + c;
                    }
                    if (automata.States.Contains(processed) && cNext == ')')
                    {
                        automata.InitialNode = new List <string>()
                        {
                            processed
                        };
                        processed = "";

                        currentStep = ENextSteps.NormalizeTransitions;
                    }
                    break;
                }

                case ENextSteps.NormalizeTransitions:
                {
                    var toNormalize = automata.Transitions.Where(x => automata.Alphabet.Contains(x.Item3[0]) || x.Item3[0] == '#');
                    if (toNormalize.Count() > 0)
                    {
                        var normalized = new List <Tuple <string, char, string> >();
                        automata.Transitions = automata.Transitions.Except(toNormalize).ToList();
                        FinalLambdaStates    = toNormalize.Where(x => x.Item2 == '#' && x.Item3 == "#").Select(x => { return(x.Item1.ToString()); }).ToList();
                        var generate = true;
                        var state    = GenerateState();

                        while (generate)
                        {
                            if (!automata.States.Contains(state.ToString()))
                            {
                                automata.States.Add(state.ToString());
                                normalized = toNormalize.Select(x => { return(new Tuple <string, char, string>(x.Item1, x.Item2, state.ToString())); }).ToList();
                                automata.FinalNodes.Add(state.ToString());
                                generate = false;
                            }
                            else
                            {
                                state = GenerateState();
                            }
                        }

                        automata.Transitions.AddRange(normalized);
                    }
                    break;
                }

                case ENextSteps.Undefined:
                    break;

                default:
                    break;
                }
            }
            return(automata);
        }
        public static Automata StringToAutomata(string program)
        {
            Stack <char>       control      = new Stack <char>();
            Stack <ENextSteps> sequenceStep = new Stack <ENextSteps>();

            sequenceStep.Push(ENextSteps.FinalStates);
            sequenceStep.Push(ENextSteps.InitialState);
            sequenceStep.Push(ENextSteps.BuildTransitions);
            sequenceStep.Push(ENextSteps.ReadTransitions);
            sequenceStep.Push(ENextSteps.Transitions);
            sequenceStep.Push(ENextSteps.States);
            sequenceStep.Push(ENextSteps.Begin);

            Automata   automata = new Automata();
            ENextSteps toDo     = ENextSteps.Undefined;
            string     toBuild  = "";
            Tuple <string, char, string> toBuilTuple = new Tuple <string, char, string>("", ' ', "");
            string nameBuilder = "";
            var    iterateName = program.GetEnumerator();

            iterateName.MoveNext();
            while (iterateName.Current != '{')
            {
                nameBuilder = nameBuilder + iterateName.Current;
                iterateName.MoveNext();
            }

            automata.Name = nameBuilder;

            for (int i = 0; i < program.Length; i++)
            {
                var c     = program[i];
                var cNext = '#';
                if (c == '{' || c == '}')
                {
                    if (sequenceStep.Count > 0)
                    {
                        toDo  = sequenceStep.Pop();
                        cNext = program[i + 1];
                    }
                    else
                    {
                        toDo = ENextSteps.Undefined;
                    }
                }
                else
                {
                    cNext = program[i + 1];
                }

                switch (toDo)
                {
                case ENextSteps.Begin:
                {
                    break;
                }

                case ENextSteps.States:
                {
                    if (char.IsLetterOrDigit(c))
                    {
                        toBuild = toBuild + c;
                    }
                    if (c == ',' || cNext == '}')
                    {
                        automata.States.Add(toBuild);
                        toBuild = "";
                    }
                }
                break;

                case ENextSteps.ReadTransitions:
                {
                    if (char.IsLetterOrDigit(c) && cNext != '-')
                    {
                        toBuild = toBuild + c;
                    }
                    if (c == ',' && cNext != '(' || c == '=')
                    {
                        toBuild = toBuild + '|';
                    }
                    if (toBuild.Split('|').Length == 3)
                    {
                        var itens = toBuild.Split('|');
                        if (automata.States.Contains(itens[0]) && automata.States.Contains(itens[2]))
                        {
                            automata.Transitions.Add(new Tuple <string, char, string>(itens[0], itens[1].ToCharArray()[0], itens[2]));
                            toBuild = "";
                        }
                    }
                    break;
                }

                case ENextSteps.BuildTransitions:
                {
                    toDo = ENextSteps.InitialState;
                    break;
                }

                case ENextSteps.InitialState:
                {
                    if (char.IsLetterOrDigit(c) && cNext != '-')
                    {
                        toBuild = toBuild + c;
                    }
                    if (automata.States.Contains(toBuild) && cNext == ';')
                    {
                        automata.InitialNode = toBuild;
                        toBuild = "";

                        toDo = ENextSteps.FinalStates;
                    }
                    break;
                }

                case ENextSteps.FinalStates:
                {
                    if (char.IsLetterOrDigit(c) && cNext != '-')
                    {
                        toBuild = toBuild + c;
                    }
                    if (c == ',' || cNext == '}')
                    {
                        automata.FinalNodes.Add(toBuild);
                        toBuild = "";
                    }
                    break;
                }

                case ENextSteps.Undefined:
                    break;

                default:
                    break;
                }
            }
            return(automata);
        }