Exemple #1
0
        static void Main(string[] args)
        {
            String[] nomesParaNovasRegras = { "B",  "C",  "D",  "E",  "F",  "G",  "H",  "I",  "J",  "K",  "L",  "M",  "N",  "O",  "P",  "Q",  "R",  "S",  "T",  "U",  "V",  "X",  "W",  "Y",  "Z",
                                              "BA", "BB", "BC", "BD", "BE", "BF", "BG", "BH", "BI", "BJ", "BK", "BL", "BM", "BN", "BO", "BP", "BQ", "BR", "BS", "BT", "BU", "BV", "BX", "BW", "BY","BZ",
                                              "CA", "CB", "CC", "CD", "CE", "CF", "CG", "CH", "CI", "CJ", "CK", "CL", "CM", "CN", "CO", "CP", "CQ", "CR", "CS", "CT", "CU", "CV", "CX", "CW", "CY","CZ",
                                              "DA", "DB", "DC", "DD", "DE", "DF", "DG", "DH", "DI", "DJ", "DK", "DL", "DM", "DN", "DO", "DP", "DQ", "DR", "DS", "DT", "DU", "DV", "DX", "DW", "DY","DZ" };
            List <GramaticaRegular>   gramaticasRegulares = new List <GramaticaRegular>();
            List <String>             tokens              = new List <String>();
            List <Char>               alfabeto            = new List <Char>();
            List <String>             nomesEstados        = new List <String>();
            List <Regra>              regras              = new List <Regra>();
            List <ItemRegraAdicionar> transicoesAdicionar = new List <ItemRegraAdicionar>();
            List <ContadorTransicao>  contadorTransicoes  = new List <ContadorTransicao>();

            String estadoInicial = "S";

            //===== Leitura do arquivo

            string[] linhasArquivo = System.IO.File.ReadAllLines(@"Entrada.txt");

            //====== Define os tokens
            {
                foreach (String linha in linhasArquivo)
                {
                    if ((linha.Length > 0) && (!linha.Contains("::=")))
                    {
                        tokens.Add(linha);
                    }
                }
            }
            //====== Define os Estados
            {
                foreach (String linha in linhasArquivo)
                {
                    if (linha.Length > 0)
                    {
                        if ((linha.Contains("::=")))
                        {
                            GramaticaRegular gramaticaRegular = new GramaticaRegular();
                            gramaticaRegular.linhaInteira = linha;

                            String estado   = "";
                            int    read     = 0;
                            int    primeiro = 1;
                            foreach (char caractere in linha)
                            {
                                switch (caractere)
                                {
                                case '<':
                                    read   = 1;
                                    estado = "";
                                    break;

                                case '>':
                                    if (!nomesEstados.Contains(estado))
                                    {
                                        nomesEstados.Add(estado);
                                    }
                                    if (primeiro == 1)
                                    {
                                        gramaticaRegular.nomeEstado = estado;
                                    }
                                    primeiro = 0;
                                    read     = 0;
                                    break;

                                default:
                                    if (read == 1)
                                    {
                                        estado += caractere;
                                    }
                                    break;
                                }
                            }
                            gramaticasRegulares.Add(gramaticaRegular);
                        }
                    }
                }
                /// Definir Estado
            }
            //====== Define o alfabeto
            {
                foreach (String linha in linhasArquivo)
                {
                    if (linha.Length > 0)
                    {
                        if ((linha.Contains("::=")))
                        {
                            int read = 0;
                            foreach (char caractere in linha)
                            {
                                switch (caractere)
                                {
                                case '|':
                                    read = 1;
                                    break;

                                case '=':
                                    read = 1;
                                    break;

                                case '<':
                                    read = 0;
                                    break;

                                case ' ':
                                    break;

                                default:
                                    if ((read == 1) && (!alfabeto.Contains(caractere)))
                                    {
                                        alfabeto.Add(caractere);
                                    }
                                    break;
                                }
                            }
                        }
                    }
                }

                foreach (string token in tokens)
                {
                    foreach (char caractere in token)
                    {
                        if (!alfabeto.Contains(caractere))
                        {
                            alfabeto.Add(caractere);
                        }
                        ;
                    }
                }
            }
            //====== Debug Estados e Alfabeto
            {
                Console.WriteLine("Estados");
                foreach (string estado in nomesEstados)
                {
                    Console.WriteLine('*' + estado + '*');
                }

                Console.WriteLine("Alfabeto");
                foreach (char letra in alfabeto)
                {
                    Console.WriteLine(letra.ToString() + ' ');
                }
            }

            foreach (String estado in nomesEstados)
            {
                Regra regra = new Regra();
                regra.nomeRegra = estado;
                regras.Add(regra);
            }

            //====== Define as Regras pelas gramáticas informadas no arquivo
            {
                foreach (GramaticaRegular gramatica in gramaticasRegulares)
                {
                    int    read           = 0;
                    int    comecarLeitura = 0;
                    Char   simbolo        = ' ';
                    String transicao      = "";
                    foreach (char caractere in gramatica.linhaInteira)
                    {
                        /* READ = 1: Lendo terminal
                         * READ = 2: Lendo Não-terminal
                         * READ = 3: Adicionar a produção à regra
                         */

                        switch (caractere)
                        {
                        case '=':
                            read           = 1;
                            comecarLeitura = 1;
                            break;

                        case '|':
                            if (transicao.Length > 0 || !simbolo.Equals('\0'))
                            {
                                read = 3;
                            }
                            else
                            {
                                read = 1;
                            }

                            break;

                        case '<':
                            if (comecarLeitura == 1)
                            {
                                read = 2;
                            }
                            break;

                        case '>':
                            if (read == 2)
                            {
                                read = 3;
                            }
                            break;

                        default:
                            if ((read == 1) && !caractere.Equals(' '))
                            {
                                simbolo = caractere;
                            }
                            if ((read == 2) && !caractere.Equals(' '))
                            {
                                transicao += caractere;
                            }
                            if (read == 3)
                            {
                                ItemRegra itemRegra = new ItemRegra();
                                itemRegra.simbolo        = simbolo;
                                itemRegra.regraTransicao = transicao;

                                foreach (Regra regra in regras)
                                {
                                    if (regra.nomeRegra.Equals(gramatica.nomeEstado))
                                    {
                                        if (transicao == "")
                                        {
                                            regra.final = true;
                                        }

                                        try
                                        {
                                            regra.transicoes.Add(itemRegra);
                                        }
                                        catch
                                        {
                                            regra.transicoes.Insert(0, itemRegra);
                                        }
                                    }
                                }
                                read      = 1;
                                transicao = "";
                                simbolo   = '\0';
                            }
                            break;
                        }
                    }
                    // Tratar última produção quando ainda não tratada
                    if (read == 3)
                    {
                        ItemRegra itemRegra = new ItemRegra();
                        itemRegra.simbolo        = simbolo;
                        itemRegra.regraTransicao = transicao;

                        foreach (Regra regra in regras)
                        {
                            if (regra.nomeRegra.Equals(gramatica.nomeEstado))
                            {
                                try
                                {
                                    regra.transicoes.Add(itemRegra);
                                }
                                catch
                                {
                                    regra.transicoes.Insert(0, itemRegra);
                                }
                            }
                        }
                        read      = 0;
                        transicao = "";
                    }
                }
            }

            //====== Define as Regras pelos tokens
            {
                var estadoAtual = "S";
                var temRegra    = 0;
                foreach (var token in tokens)
                {
                    estadoAtual = "S";
                    foreach (var caractere in token)
                    {
                        var    adicionarRegra  = 0;
                        String novoNomeExterno = "";
                        foreach (var regra in regras)
                        {
                            if (regra.nomeRegra.Equals(estadoAtual))
                            {
                                foreach (var novoNome in nomesParaNovasRegras)
                                {
                                    temRegra = 0;
                                    foreach (var regraTeste in regras)
                                    {
                                        if (regraTeste.nomeRegra == novoNome)
                                        {
                                            temRegra = 1;
                                            continue;
                                        }
                                    }
                                    if (temRegra == 0)
                                    {
                                        adicionarRegra  = 1;
                                        novoNomeExterno = novoNome;
                                        estadoAtual     = novoNome;

                                        ItemRegra itemRegra = new ItemRegra();
                                        itemRegra.regraTransicao = novoNome;
                                        itemRegra.simbolo        = caractere;
                                        regra.transicoes.Add(itemRegra);

                                        break;
                                    }
                                }
                            }
                        }
                        if (adicionarRegra == 1)
                        {
                            if (!nomesEstados.Contains(novoNomeExterno))
                            {
                                nomesEstados.Add(novoNomeExterno);
                            }

                            Regra novaRegra = new Regra
                            {
                                transicoes = new List <ItemRegra>(),
                                nomeRegra  = novoNomeExterno
                            };
                            regras.Add(novaRegra);
                        }
                    }
                }
            }



            //====== Imprimir regras
            {
                ImprimirRegras(regras);
                ImprimirCSV(regras, alfabeto, nomesEstados, "AutomatoFinitoOriginal.csv");
            }

            //====== Identificar estados finais e epsilon transiçõess
            {
                //ItemRegra itemRegra = null;
                foreach (var regra in regras)
                {
                    if (regra.transicoes.Count == 0)
                    {
                        regra.final = true;

/*                        itemRegra = new ItemRegra();
 *                      itemRegra.simbolo = '&';
 *                      itemRegra.regraTransicao = "X";
 *                      regra.transicoes.Add(itemRegra);*/
                    }

                    /*foreach (var transicao in regra.transicoes)
                     * {
                     *  if (transicao.regraTransicao.Length == 0)
                     *  {
                     *      transicao.regraTransicao = "X";
                     *
                     *  }
                     *  if (transicao.simbolo.Equals('\0'))
                     *  {
                     *      if (!alfabeto.Contains('&'))
                     *      {
                     *          alfabeto.Add('&');
                     *      }
                     *      transicao.simbolo = '&';
                     *  }
                     *  if (transicao.simbolo.Equals('&')) regra.final = true;
                     * }*/
                }
            }
            //====== Remover Epsilon Transições
            {
                foreach (var regra in regras)
                {
                    foreach (var transicao in regra.transicoes)
                    {
                        if (transicao.simbolo.Equals('\0') || transicao.simbolo.Equals('&'))
                        {
                            var nomeRegraDestino = transicao.regraTransicao;
                            foreach (var regraDestino in regras)
                            {
                                if (regraDestino.nomeRegra == nomeRegraDestino)
                                {
                                    foreach (var transicaoRegraDestino in regraDestino.transicoes)
                                    {
                                        ItemRegraAdicionar transicaoAdicionar = new ItemRegraAdicionar
                                        {
                                            final          = regraDestino.final,
                                            nomeRegra      = regra.nomeRegra,
                                            regraTransicao = transicaoRegraDestino.regraTransicao,
                                            simbolo        = transicaoRegraDestino.simbolo
                                        };
                                        transicoesAdicionar.Add(transicaoAdicionar);
                                    }
                                }
                            }
                            transicao.valida = false;
                        }
                    }
                }
                foreach (var transicao in transicoesAdicionar)
                {
                    ItemRegra novaTransicao = new ItemRegra
                    {
                        regraTransicao = transicao.regraTransicao,
                        simbolo        = transicao.simbolo
                    };

                    Regra regra = BuscarRegra(regras, transicao.nomeRegra);
                    if (!VerificaExistenciaTransicaoRegra(regra, novaTransicao))
                    {
                        regra.transicoes.Add(novaTransicao);
                        if (transicao.final)
                        {
                            regra.final = true;
                        }
                    }
                }
                ImprimirRegras(regras);
                ImprimirCSV(regras, alfabeto, nomesEstados, "AutomatoFinitoSemEspilonTransicoes.csv");
            }
            //====== Determinização
            {
                Console.WriteLine("Determinização: ");


                bool alterou = true;


                while (alterou)
                {
                    contadorTransicoes.Clear();
                    alterou = false;
                    foreach (var regra in regras)
                    {
                        if (regra.valida)
                        {
                            foreach (var transicao in regra.transicoes)
                            {
                                if (transicao.valida)
                                {
                                    var achou = 0;
                                    foreach (var contador in contadorTransicoes)
                                    {
                                        if (transicao.simbolo.Equals(contador.simbolo) && regra.nomeRegra == contador.regraAssociada)
                                        {
                                            achou = 1;
                                            contador.quantidade++;
                                            contador.regras.Add(transicao.regraTransicao);
                                        }
                                    }
                                    if (achou == 0)
                                    {
                                        ContadorTransicao novoContador = new ContadorTransicao
                                        {
                                            regraAssociada = regra.nomeRegra,
                                            simbolo        = transicao.simbolo,
                                            quantidade     = 1
                                        };
                                        novoContador.regras.Insert(0, transicao.regraTransicao);
                                        contadorTransicoes.Add(novoContador);
                                    }
                                }
                            }
                        }
                    }


                    foreach (var contador in contadorTransicoes)
                    {
                        Console.WriteLine("Regra: " + contador.regraAssociada + " simbolo: " + contador.simbolo);
                        foreach (String regra in contador.regras)
                        {
                            Console.Write(" <" + regra + "> ");
                        }
                        Console.WriteLine("");
                    }

                    foreach (var contador in contadorTransicoes)
                    {
                        if (contador.quantidade > 1)
                        {
                            alterou = true;
                            String nomeNovaRegra = "";
                            foreach (String s in contador.regras)
                            {
                                nomeNovaRegra += s;
                            }
                            if (!nomesEstados.Contains(nomeNovaRegra))
                            {
                                nomesEstados.Add(nomeNovaRegra);


                                Regra novaRegra = new Regra();
                                novaRegra.nomeRegra = nomeNovaRegra;
                                foreach (String s in contador.regras)
                                {
                                    foreach (var regra in regras)
                                    {
                                        if (regra.nomeRegra == s)
                                        {
                                            if (regra.final)
                                            {
                                                novaRegra.final = true;
                                            }

                                            foreach (var transicao in regra.transicoes)
                                            {
                                                if (!VerificaExistenciaTransicaoRegra(novaRegra, transicao))
                                                {
                                                    ItemRegra novaTransicao = new ItemRegra()
                                                    {
                                                        simbolo        = transicao.simbolo,
                                                        valida         = transicao.valida,
                                                        regraTransicao = transicao.regraTransicao
                                                    };
                                                    novaRegra.transicoes.Add(novaTransicao);
                                                }
                                            }
                                        }
                                    }
                                }

                                regras.Add(novaRegra);
                            }
                            else
                            {
                                foreach (var regraExistente in regras)
                                {
                                    if (regraExistente.nomeRegra == nomeNovaRegra && regraExistente.valida)
                                    {
                                        foreach (String s in contador.regras)
                                        {
                                            foreach (var regra in regras)
                                            {
                                                if (regra.nomeRegra == s)
                                                {
                                                    if (regra.final)
                                                    {
                                                        regraExistente.final = true;
                                                    }

                                                    foreach (var transicao in regra.transicoes)
                                                    {
                                                        if (!VerificaExistenciaTransicaoRegra(regraExistente, transicao))
                                                        {
                                                            ItemRegra novaTransicao = new ItemRegra()
                                                            {
                                                                simbolo        = transicao.simbolo,
                                                                valida         = transicao.valida,
                                                                regraTransicao = transicao.regraTransicao
                                                            };
                                                            regraExistente.transicoes.Add(novaTransicao);
                                                        }
                                                    }
                                                    break;
                                                }
                                            }
                                        }
                                        break;
                                    }
                                }
                            }
                            //==== Adiciona o novo estado nas transicoes e invalida as transições que foram agrupadas.
                            foreach (var regra in regras)
                            {
                                if (contador.regraAssociada == regra.nomeRegra)
                                {
                                    ItemRegra novaTransicao = new ItemRegra();
                                    novaTransicao.regraTransicao = nomeNovaRegra;
                                    novaTransicao.simbolo        = contador.simbolo;
                                    if (!VerificaExistenciaTransicaoRegra(regra, novaTransicao))
                                    {
                                        regra.transicoes.Add(novaTransicao);
                                    }

                                    foreach (var transicao in regra.transicoes)
                                    {
                                        if (transicao.simbolo == contador.simbolo && transicao.regraTransicao != nomeNovaRegra)
                                        {
                                            transicao.valida = false;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }



                ImprimirRegras(regras);
                ImprimirCSV(regras, alfabeto, nomesEstados, "AutomatoFinitoDeterminizado.csv");
            }

            //====== Remover estados inalcançáveis
            {
                foreach (var regraChamada in regras)
                {
                    int chamada = 0;
                    foreach (var outraRegra in regras)
                    {
                        if (regraChamada.nomeRegra != outraRegra.nomeRegra)
                        {
                            if (outraRegra.valida)
                            {
                                foreach (var transicao in outraRegra.transicoes)
                                {
                                    if (transicao.regraTransicao == regraChamada.nomeRegra && transicao.valida)
                                    {
                                        chamada = 1;
                                    }
                                }
                            }
                        }
                    }
                    if (chamada == 0 && regraChamada.nomeRegra != estadoInicial)
                    {
                        regraChamada.valida = false;
                    }
                }
            }

            //====== Remover Estados Mortos
            {
                foreach (var estado in nomesEstados)
                {
                    foreach (var regra in regras)
                    {
                        if (regra.valida)
                        {
                            if (regra.nomeRegra == estado)
                            {
                                if (regra.final)
                                {
                                    continue;
                                }

                                regra.valida = PercorreRegra(estado, regra, regras);
                            }
                            if (!regra.valida)
                            {
                                foreach (var outrasRegras in regras)
                                {
                                    foreach (var transicao in outrasRegras.transicoes)
                                    {
                                        if (transicao.regraTransicao == regra.nomeRegra)
                                        {
                                            transicao.valida = false;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                ImprimirRegras(regras);
                ImprimirCSV(regras, alfabeto, nomesEstados, "AutomatoFinitoMinimizado.csv");
            }

            //====== Estado de erro
            {
                var deveCriarEstadoErro = 0;
                foreach (var letra in alfabeto)
                {
                    foreach (var regra in regras)
                    {
                        var achou = 0;
                        foreach (var transicao in regra.transicoes)
                        {
                            if (transicao.simbolo.Equals(letra) && transicao.valida)
                            {
                                achou = 1;
                                break;
                            }
                        }
                        if (achou == 0)
                        {
                            ItemRegra transacaoErro = new ItemRegra()
                            {
                                simbolo        = letra,
                                valida         = true,
                                regraTransicao = "!"
                            };
                            regra.transicoes.Add(transacaoErro);
                            deveCriarEstadoErro = 1;
                        }
                    }
                }
                if (deveCriarEstadoErro == 1)
                {
                    Regra regra = new Regra()
                    {
                        nomeRegra  = "!",
                        final      = true,
                        valida     = true,
                        transicoes = new List <ItemRegra>()
                    };

                    foreach (var letra in alfabeto)
                    {
                        ItemRegra transicaoErro = new ItemRegra()
                        {
                            regraTransicao = "!",
                            simbolo        = letra,
                            valida         = true
                        };
                        regra.transicoes.Add(transicaoErro);
                    }
                    regras.Add(regra);
                    nomesEstados.Add("!");
                }


                ImprimirRegras(regras);
                ImprimirCSV(regras, alfabeto, nomesEstados, "AutomatoFinitoEstadoErro.csv");
            }
        }
        static void Main(string[] args)
        {
            String[] nomesParaNovasRegras = { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "Y", "Z", "AA", "AB", "AC", "AD", "AE", "AF", "AG", "AH", "AI", "AJ", "AK", "AL", "AM", "AN", "AO", "AP", "AQ", "AR", "AS", "AT", "AU", "AV", "AX", "AW", "AY", "AZ" };
            List <GramaticaRegular>   gramaticasRegulares = new List <GramaticaRegular>();
            List <String>             tokens              = new List <String>();
            List <Char>               alfabeto            = new List <Char>();
            List <String>             nomesEstados        = new List <String>();
            List <Regra>              regras              = new List <Regra>();
            List <ItemRegraAdicionar> transicoesAdicionar = new List <ItemRegraAdicionar>();
            List <ContadorTransicao>  contadorTransicoes  = new List <ContadorTransicao>();

            String estadoInicial = "S";

            //===== Leitura do arquivo

            string[] linhasArquivo = System.IO.File.ReadAllLines(@"Entrada.txt");

            //====== Define os tokens
            {
                foreach (String linha in linhasArquivo)
                {
                    if ((linha.Length > 0) && (!linha.Contains("::=")))
                    {
                        tokens.Add(linha);
                    }
                }
            }
            //====== Define os Estados
            {
                foreach (String linha in linhasArquivo)
                {
                    if (linha.Length > 0)
                    {
                        if ((linha.Contains("::=")))
                        {
                            GramaticaRegular gramaticaRegular = new GramaticaRegular();
                            gramaticaRegular.linhaInteira = linha;

                            String estado   = "";
                            int    read     = 0;
                            int    primeiro = 1;
                            foreach (char caractere in linha)
                            {
                                switch (caractere)
                                {
                                case '<':
                                    read   = 1;
                                    estado = "";
                                    break;

                                case '>':
                                    if (!nomesEstados.Contains(estado))
                                    {
                                        nomesEstados.Add(estado);
                                    }
                                    if (primeiro == 1)
                                    {
                                        gramaticaRegular.nomeEstado = estado;
                                    }
                                    primeiro = 0;
                                    read     = 0;
                                    break;

                                default:
                                    if (read == 1)
                                    {
                                        estado += caractere;
                                    }
                                    break;
                                }
                            }
                            gramaticasRegulares.Add(gramaticaRegular);
                        }
                    }
                }
                /// Definir Estado
            }
            //====== Define o alfabeto
            {
                foreach (String linha in linhasArquivo)
                {
                    if (linha.Length > 0)
                    {
                        if ((linha.Contains("::=")))
                        {
                            int read = 0;
                            foreach (char caractere in linha)
                            {
                                switch (caractere)
                                {
                                case '|':
                                    read = 1;
                                    break;

                                case '=':
                                    read = 1;
                                    break;

                                case '<':
                                    read = 0;
                                    break;

                                case ' ':
                                    break;

                                default:
                                    if ((read == 1) && (!alfabeto.Contains(caractere)))
                                    {
                                        alfabeto.Add(caractere);
                                    }
                                    break;
                                }
                            }
                        }
                    }
                }

                foreach (string token in tokens)
                {
                    foreach (char caractere in token)
                    {
                        if (!alfabeto.Contains(caractere))
                        {
                            alfabeto.Add(caractere);
                        }
                        ;
                    }
                }
            }
            //====== Debug Estados e Alfabeto
            {
                Console.WriteLine("Estados");
                foreach (string estado in nomesEstados)
                {
                    Console.WriteLine('*' + estado + '*');
                }

                Console.WriteLine("Alfabeto");
                foreach (char letra in alfabeto)
                {
                    Console.WriteLine(letra.ToString() + ' ');
                }
            }
            //====== Define as Regras pelas gramáticas informadas no arquivo
            {
                foreach (String estado in nomesEstados)
                {
                    Regra regra = new Regra();
                    regra.nomeRegra = estado;
                    regras.Add(regra);
                }

                foreach (GramaticaRegular gramatica in gramaticasRegulares)
                {
                    int    read           = 0;
                    int    comecarLeitura = 0;
                    Char   simbolo        = ' ';
                    String transicao      = "";
                    foreach (char caractere in gramatica.linhaInteira)
                    {
                        /* READ = 1: Lendo terminal
                         * READ = 2: Lendo Não-terminal
                         * READ = 3: Adicionar a produção à regra
                         */

                        switch (caractere)
                        {
                        case '=':
                            read           = 1;
                            comecarLeitura = 1;
                            break;

                        case '|':
                            if (transicao.Length > 0 || !simbolo.Equals('\0'))
                            {
                                read = 3;
                            }
                            else
                            {
                                read = 1;
                            }

                            break;

                        case '<':
                            if (comecarLeitura == 1)
                            {
                                read = 2;
                            }
                            break;

                        case '>':
                            if (read == 2)
                            {
                                read = 3;
                            }
                            break;

                        default:
                            if ((read == 1) && !caractere.Equals(' '))
                            {
                                simbolo = caractere;
                            }
                            if ((read == 2) && !caractere.Equals(' '))
                            {
                                transicao += caractere;
                            }
                            if (read == 3)
                            {
                                ItemRegra itemRegra = new ItemRegra();
                                itemRegra.simbolo        = simbolo;
                                itemRegra.regraTransicao = transicao;

                                foreach (Regra regra in regras)
                                {
                                    if (regra.nomeRegra.Equals(gramatica.nomeEstado))
                                    {
                                        if (transicao == "")
                                        {
                                            regra.final = true;
                                        }

                                        try
                                        {
                                            regra.transicoes.Add(itemRegra);
                                        }
                                        catch
                                        {
                                            regra.transicoes.Insert(0, itemRegra);
                                        }
                                    }
                                }
                                read      = 1;
                                transicao = "";
                                simbolo   = '\0';
                            }
                            break;
                        }
                    }
                    // Tratar última produção quando ainda não tratada
                    if (read == 3)
                    {
                        ItemRegra itemRegra = new ItemRegra();
                        itemRegra.simbolo        = simbolo;
                        itemRegra.regraTransicao = transicao;

                        foreach (Regra regra in regras)
                        {
                            if (regra.nomeRegra.Equals(gramatica.nomeEstado))
                            {
                                try
                                {
                                    regra.transicoes.Add(itemRegra);
                                }
                                catch
                                {
                                    regra.transicoes.Insert(0, itemRegra);
                                }
                            }
                        }
                        read      = 0;
                        transicao = "";
                    }
                }
            }
            //====== Define as Regras pelos tokens
            {
                var estadoAtual = "S";
                var temRegra    = 0;
                foreach (var token in tokens)
                {
                    estadoAtual = "S";
                    foreach (var caractere in token)
                    {
                        var    adicionarRegra  = 0;
                        String novoNomeExterno = "";
                        foreach (var regra in regras)
                        {
                            if (regra.nomeRegra.Equals(estadoAtual))
                            {
                                foreach (var novoNome in nomesParaNovasRegras)
                                {
                                    temRegra = 0;
                                    foreach (var regraTeste in regras)
                                    {
                                        if (regraTeste.nomeRegra == novoNome)
                                        {
                                            temRegra = 1;
                                            continue;
                                        }
                                    }
                                    if (temRegra == 0)
                                    {
                                        adicionarRegra  = 1;
                                        novoNomeExterno = novoNome;
                                        estadoAtual     = novoNome;

                                        ItemRegra itemRegra = new ItemRegra();
                                        itemRegra.regraTransicao = novoNome;
                                        itemRegra.simbolo        = caractere;
                                        regra.transicoes.Add(itemRegra);

                                        break;
                                    }
                                }
                            }
                        }
                        if (adicionarRegra == 1)
                        {
                            if (!nomesEstados.Contains(novoNomeExterno))
                            {
                                nomesEstados.Add(novoNomeExterno);
                            }

                            Regra novaRegra = new Regra
                            {
                                transicoes = new List <ItemRegra>(),
                                nomeRegra  = novoNomeExterno
                            };
                            regras.Add(novaRegra);
                        }
                    }
                }
            }

            //==== Colocar epsilon transição nos tokens, para reconhecer variaveis
            foreach (string token in tokens)
            {
                string nomeRegra = "S";
                for (int i = 0; i < token.Length - 1; i++)
                {
                    int   achouToken = 0;
                    Regra regraAtual = null;
                    foreach (var regra in regras)
                    {
                        if (!regra.nomeRegra.Equals(nomeRegra))
                        {
                            continue;
                        }
                        foreach (var trans in regra.transicoes)
                        {
                            if (trans.simbolo == token[i])
                            {
                                achouToken = 1;
                                nomeRegra  = trans.regraTransicao;
                                regraAtual = regra;
                                break;
                            }
                        }
                    }

                    int addTransicao = 1;
                    foreach (var trans in regraAtual.transicoes)
                    {
                        if (trans.simbolo == token[i] && trans.regraTransicao.Equals(""))
                        {
                            addTransicao = 0;
                        }
                    }
                    if (addTransicao == 1)
                    {
                        //Adicionar producao com terminal para reconhecer variavel
                        ItemRegra itemRegra = new ItemRegra();
                        itemRegra.regraTransicao = "";
                        itemRegra.simbolo        = token[i];
                        regraAtual.transicoes.Add(itemRegra);
                        break;
                    }
                }
            }


            Console.WriteLine("\nDEBUG ATE ADICIONAR REGRAS E TRANSICOES\n");
            foreach (var m in regras)
            {
                if (m.valida)
                {
                    if (m.final)
                    {
                        Console.Write("*");
                    }
                    Console.Write("<" + m.nomeRegra + "> ::= ");
                    foreach (var trans in m.transicoes)
                    {
                        if (trans.valida)
                        {
                            Console.Write(trans.simbolo + "<" + trans.regraTransicao + "> | ");
                        }
                    }
                    Console.WriteLine("");
                }
            }

            //====== Identificar estados finais e epsilon transições
            {
                ItemRegra itemRegra = null;
                foreach (var regra in regras)
                {
                    if (regra.transicoes.Count == 0)
                    {
                        regra.final = true;

                        itemRegra                = new ItemRegra();
                        itemRegra.simbolo        = '&';
                        itemRegra.regraTransicao = "X";
                        regra.transicoes.Add(itemRegra);
                    }
                    foreach (var transicao in regra.transicoes)
                    {
                        if (transicao.regraTransicao.Length == 0)
                        {
                            transicao.regraTransicao = "X";
                        }
                        if (transicao.simbolo.Equals('\0'))
                        {
                            if (!alfabeto.Contains('&'))
                            {
                                alfabeto.Add('&');
                            }
                            transicao.simbolo = '&';
                        }
                        if (transicao.simbolo.Equals('&'))
                        {
                            regra.final = true;
                        }
                    }
                }
            }

            //====== Imprimir regras
            {
                ImprimirRegras(regras);
                ImprimirCSV(regras, alfabeto, nomesEstados, "AutomatoFinitoOriginal.csv");
            }

            Console.WriteLine("\nDEBUG DEPOIS DE IDENTIFICAR ESTADOS FINAIS E EPSILON TANSICOES\n");
            foreach (var m in regras)
            {
                if (m.valida)
                {
                    if (m.final)
                    {
                        Console.Write("*");
                    }
                    Console.Write("<" + m.nomeRegra + "> ::= ");
                    foreach (var trans in m.transicoes)
                    {
                        if (trans.valida)
                        {
                            Console.Write(trans.simbolo + "<" + trans.regraTransicao + "> | ");
                        }
                    }
                    Console.WriteLine("");
                }
            }

            //====== Remover Epsilon Transições
            {
                foreach (var regra in regras)
                {
                    foreach (var transicao in regra.transicoes)
                    {
                        if (transicao.simbolo.Equals('\0') || transicao.simbolo.Equals('&'))
                        {
                            var nomeRegraDestino = transicao.regraTransicao;
                            foreach (var regraDestino in regras)
                            {
                                if (regraDestino.nomeRegra == nomeRegraDestino)
                                {
                                    foreach (var transicaoRegraDestino in regraDestino.transicoes)
                                    {
                                        ItemRegraAdicionar transicaoAdicionar = new ItemRegraAdicionar
                                        {
                                            final          = regraDestino.final,
                                            nomeRegra      = regra.nomeRegra,
                                            regraTransicao = transicaoRegraDestino.regraTransicao,
                                            simbolo        = transicaoRegraDestino.simbolo
                                        };
                                        transicoesAdicionar.Add(transicaoAdicionar);
                                    }
                                }
                            }
                            transicao.valida = false;
                        }
                    }
                }
                foreach (var transicao in transicoesAdicionar)
                {
                    ItemRegra novaTransicao = new ItemRegra
                    {
                        regraTransicao = transicao.regraTransicao,
                        simbolo        = transicao.simbolo
                    };

                    Regra regra = BuscarRegra(regras, transicao.nomeRegra);
                    if (!VerificaExistenciaTransicaoRegra(regra, novaTransicao))
                    {
                        regra.transicoes.Add(novaTransicao);
                        if (transicao.final)
                        {
                            regra.final = true;
                        }
                    }
                }
                ImprimirRegras(regras);
                ImprimirCSV(regras, alfabeto, nomesEstados, "AutomatoFinitoSemEspilonTransicoes.csv");
            }

            Console.WriteLine("\nDEBUG DEPOIS DE REMOVER EPSILON TANSICOES\n");
            foreach (var m in regras)
            {
                if (m.valida)
                {
                    if (m.final)
                    {
                        Console.Write("*");
                    }
                    Console.Write("<" + m.nomeRegra + "> ::= ");
                    foreach (var trans in m.transicoes)
                    {
                        if (trans.valida)
                        {
                            Console.Write(trans.simbolo + "<" + trans.regraTransicao + "> | ");
                        }
                    }
                    Console.WriteLine("");
                }
            }

            //====== Determinização
            {
                Console.WriteLine("Determinização: ");


                bool alterou = true;


                while (alterou)
                {
                    contadorTransicoes.Clear();
                    alterou = false;
                    foreach (var regra in regras)
                    {
                        if (regra.valida)
                        {
                            foreach (var transicao in regra.transicoes)
                            {
                                if (transicao.valida)
                                {
                                    var achou = 0;
                                    foreach (var contador in contadorTransicoes)
                                    {
                                        if (transicao.simbolo.Equals(contador.simbolo) && regra.nomeRegra == contador.regraAssociada)
                                        {
                                            achou = 1;
                                            contador.quantidade++;
                                            contador.regras.Add(transicao.regraTransicao);
                                        }
                                    }
                                    if (achou == 0)
                                    {
                                        ContadorTransicao novoContador = new ContadorTransicao
                                        {
                                            regraAssociada = regra.nomeRegra,
                                            simbolo        = transicao.simbolo,
                                            quantidade     = 1
                                        };
                                        novoContador.regras.Insert(0, transicao.regraTransicao);
                                        contadorTransicoes.Add(novoContador);
                                    }
                                }
                            }
                        }
                    }

                    ImprimirRegras(regras);
                    ImprimirCSV(regras, alfabeto, nomesEstados, "AutomatoFinitoDeterminizado.csv");


                    foreach (var contador in contadorTransicoes)
                    {
                        Console.WriteLine("Regra: " + contador.regraAssociada + " simbolo: " + contador.simbolo);
                        foreach (String regra in contador.regras)
                        {
                            Console.Write(" <" + regra + "> ");
                        }
                        Console.WriteLine("");
                    }

                    foreach (var contador in contadorTransicoes)
                    {
                        if (contador.quantidade > 1)
                        {
                            alterou = true;
                            String nomeNovaRegra = "";
                            foreach (String s in contador.regras)
                            {
                                nomeNovaRegra += s;
                            }
                            if (!nomesEstados.Contains(nomeNovaRegra))
                            {
                                nomesEstados.Add(nomeNovaRegra);


                                Regra novaRegra = new Regra();
                                novaRegra.nomeRegra = nomeNovaRegra;
                                foreach (String s in contador.regras)
                                {
                                    foreach (var regra in regras)
                                    {
                                        if (regra.nomeRegra == s)
                                        {
                                            if (regra.final)
                                            {
                                                novaRegra.final = true;
                                            }

                                            foreach (var transicao in regra.transicoes)
                                            {
                                                if (!VerificaExistenciaTransicaoRegra(novaRegra, transicao))
                                                {
                                                    ItemRegra novaTransicao = new ItemRegra()
                                                    {
                                                        simbolo        = transicao.simbolo,
                                                        valida         = transicao.valida,
                                                        regraTransicao = transicao.regraTransicao
                                                    };
                                                    novaRegra.transicoes.Add(novaTransicao);
                                                }
                                            }
                                        }
                                    }
                                }

                                regras.Add(novaRegra);
                            }
                            else
                            {
                                foreach (var regraExistente in regras)
                                {
                                    if (regraExistente.nomeRegra == nomeNovaRegra && regraExistente.valida)
                                    {
                                        foreach (String s in contador.regras)
                                        {
                                            foreach (var regra in regras)
                                            {
                                                if (regra.nomeRegra == s)
                                                {
                                                    if (regra.final)
                                                    {
                                                        regraExistente.final = true;
                                                    }

                                                    foreach (var transicao in regra.transicoes)
                                                    {
                                                        if (!VerificaExistenciaTransicaoRegra(regraExistente, transicao))
                                                        {
                                                            ItemRegra novaTransicao = new ItemRegra()
                                                            {
                                                                simbolo        = transicao.simbolo,
                                                                valida         = transicao.valida,
                                                                regraTransicao = transicao.regraTransicao
                                                            };
                                                            regraExistente.transicoes.Add(novaTransicao);
                                                        }
                                                    }
                                                    break;
                                                }
                                            }
                                        }
                                        break;
                                    }
                                }
                            }
                            //==== Adiciona o novo estado nas transicoes e invalida as transições que foram agrupadas.
                            foreach (var regra in regras)
                            {
                                if (contador.regraAssociada == regra.nomeRegra)
                                {
                                    ItemRegra novaTransicao = new ItemRegra();
                                    novaTransicao.regraTransicao = nomeNovaRegra;
                                    novaTransicao.simbolo        = contador.simbolo;
                                    if (!VerificaExistenciaTransicaoRegra(regra, novaTransicao))
                                    {
                                        regra.transicoes.Add(novaTransicao);
                                    }

                                    foreach (var transicao in regra.transicoes)
                                    {
                                        if (transicao.simbolo == contador.simbolo && transicao.regraTransicao != nomeNovaRegra)
                                        {
                                            transicao.valida = false;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }



                ImprimirRegras(regras);
                ImprimirCSV(regras, alfabeto, nomesEstados, "AutomatoFinitoDeterminizado.csv");
            }

            //====== Remover estados inalcançáveis
            {
                foreach (var regraChamada in regras)
                {
                    int chamada = 0;
                    foreach (var outraRegra in regras)
                    {
                        if (regraChamada.nomeRegra != outraRegra.nomeRegra)
                        {
                            if (outraRegra.valida)
                            {
                                foreach (var transicao in outraRegra.transicoes)
                                {
                                    if (transicao.regraTransicao == regraChamada.nomeRegra && transicao.valida)
                                    {
                                        chamada = 1;
                                    }
                                }
                            }
                        }
                    }
                    if (chamada == 0 && regraChamada.nomeRegra != estadoInicial)
                    {
                        regraChamada.valida = false;
                    }
                }
            }

            //====== Remover Estados Mortos
            {
                foreach (var estado in nomesEstados)
                {
                    foreach (var regra in regras)
                    {
                        if (regra.valida)
                        {
                            if (regra.nomeRegra == estado)
                            {
                                if (regra.final)
                                {
                                    continue;
                                }

                                regra.valida = PercorreRegra(estado, regra, regras);
                            }
                            if (!regra.valida)
                            {
                                foreach (var outrasRegras in regras)
                                {
                                    foreach (var transicao in outrasRegras.transicoes)
                                    {
                                        if (transicao.regraTransicao == regra.nomeRegra)
                                        {
                                            transicao.valida = false;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                ImprimirRegras(regras);
                ImprimirCSV(regras, alfabeto, nomesEstados, "AutomatoFinitoMinimizado.csv");
            }

            //====== Estado de erro
            {
                var deveCriarEstadoErro = 0;
                foreach (var letra in alfabeto)
                {
                    foreach (var regra in regras)
                    {
                        var achou = 0;
                        foreach (var transicao in regra.transicoes)
                        {
                            if (transicao.simbolo.Equals(letra) && transicao.valida)
                            {
                                achou = 1;
                                break;
                            }
                        }
                        if (achou == 0)
                        {
                            ItemRegra transacaoErro = new ItemRegra()
                            {
                                simbolo        = letra,
                                valida         = true,
                                regraTransicao = "!"
                            };
                            regra.transicoes.Add(transacaoErro);
                            deveCriarEstadoErro = 1;
                        }
                    }
                }
                if (deveCriarEstadoErro == 1)
                {
                    Regra regra = new Regra()
                    {
                        nomeRegra  = "!",
                        final      = true,
                        valida     = true,
                        transicoes = new List <ItemRegra>()
                    };

                    foreach (var letra in alfabeto)
                    {
                        ItemRegra transicaoErro = new ItemRegra()
                        {
                            regraTransicao = "!",
                            simbolo        = letra,
                            valida         = true
                        };
                        regra.transicoes.Add(transicaoErro);
                    }
                    regras.Add(regra);
                    nomesEstados.Add("!");
                }


                ImprimirRegras(regras);
                ImprimirCSV(regras, alfabeto, nomesEstados, "AutomatoFinitoEstadoErro.csv");
            }
        }