private Simbolo PreencheAtributos(Simbolo s, int cod_erro)
        {
            if (cod_erro >= 0) //Caso ocorra um erro, as seguintes informações são solicitadas
            {
                string _descricaoERRO = "";
                TiposErros.TryGetValue(cod_erro, out _descricaoERRO);
                s.DescricaoERRO = _descricaoERRO;
            }

            s.Coluna = _coluna;
            s.Linha  = _linha;

            return(s);
        }
        private Simbolo CriaErro(int codErro)
        {
            //Informações necessárias para a criação de um erro
            Simbolo s = new Simbolo();

            string _descricaoERRO = "";

            s.Linha  = ++_linha;
            s.Coluna = _coluna;
            TiposErros.TryGetValue(codErro, out _descricaoERRO);
            s.DescricaoERRO = _descricaoERRO;

            return(s);
        }
        public Simbolo AnaliseLexica(string codigoFonte) // Percorre ocodigo fonte do Mgol
        {
            _proxEstado      = "q0";                     // a cada inicialização ele deve começar do estado incial
            _estadoAnterior  = "q0";
            _lexema          = "";                       // lexema vazio
            _linhaDoEstado   = 0;
            _colunaDaEntrada = 0;
            _tipo_de_erro    = -1;

            while (_ponteiro != codigoFonte.Length) // percorre o ponteiro enquanto ele não chegar no final do codigo fonte
            {
                //_ponteiro -> do codigo fonte
                _caracterAtual = codigoFonte[_ponteiro];

                ModificaLinhaColuna();                                       // Contador que atualiza o valor da linha e da coluna

                if (!SimbolosValidos.ContainsKey(_caracterAtual.ToString())) //verifica se o caractere atual é valido
                {                                                            // se não for caractere válido retorna o erro
                    _tipo_de_erro = 0;
                    _proxEstado   = "ERRO";
                }

                _estadoAnterior = _proxEstado;  //armazena o estado anterior para o proximo estado ser modificado

                TodosEstados.TryGetValue(_proxEstado, out _linhaDoEstado);

                SimbolosValidos.TryGetValue(_caracterAtual.ToString(), out _colunaDaEntrada); //Modifica o valor da coluna de acordo com o caractere

                if (_estadoAnterior == "num" && (_caracterAtual == 'E' || _caracterAtual == 'e'))
                {
                    _colunaDaEntrada = 9;
                }

                _proxEstado = Convert.ToString(TabelaDeTransicao[_linhaDoEstado][_colunaDaEntrada]);

                if (EstadosFinais.ContainsKey(_estadoAnterior) && _proxEstado == "")
                {
                    if (_estadoAnterior == "qG")
                    {
                        _estadoAnterior = "opr";
                    }

                    //VERIFICA SE TEM ESSE LEXEMA NA LISTA DE SIMBOLOS
                    Simbolo s = TabelaDeSimbolos.Find(o => o.Lexema == _lexema);

                    if (s == null) // s-> simbolo do codigo fonte
                    {
                        s = new Simbolo()
                        {
                            Lexema = _lexema, Token = _estadoAnterior, Tipo = null
                        };

                        if (_estadoAnterior.Equals("id"))
                        {
                            TabelaDeSimbolos.Add(s);             // lista de identificadores
                        }
                        s = PreencheAtributos(s, _tipo_de_erro); //Verifica se ocorreu algum erro de caracter inválido durante a leitura

                        return(s);
                    }
                    else
                    {
                        s = PreencheAtributos(s, _tipo_de_erro);//Verifica se ocorreu algum erro de caracter inválido durante a leitura

                        return(s);
                    }
                }

                if (!char.IsWhiteSpace(_caracterAtual) || _proxEstado == "qA") // Verifica se o caractere atual é espaço em  branco ou se o proximo estado é qA
                {
                    if (_caracterAtual == '\r')                                //Converte o \r para ' '
                    {
                        _caracterAtual = ' ';
                    }

                    _lexema += _caracterAtual;
                }

                _ponteiro++;

                continue; // Continua o laço de análise
            }

            Simbolo simb = TabelaDeSimbolos.Find(o => o.Lexema == _lexema); // verifica se o lexema formado está na tabela de simbolo

            if (simb == null)                                               // verifica se chegou no final da leitura do arquivo
            {
                simb = new Simbolo {
                    Token = "$"
                };
                _linha++;
                PreencheAtributos(simb, _tipo_de_erro);
            }

            //if (_contador_de_Erros != 0)
            //{
            //    foreach (Simbolo s in _listaDeErros)
            //        Console.WriteLine($@"Token: {s.Token} Descrição: {s.DescricaoERRO} Linha: {s.Linha} Coluna: {s.Coluna}");
            //}

            return(simb);
        }
        private static Dictionary <string, Simbolo> Palavras_Chave()
        {
            Dictionary <string, Simbolo> TabelaDeSimbolos = new Dictionary <string, Simbolo>();

            //palavras chave da linguagem MGOL
            var inicio = new Simbolo()
            {
                Lexema = "inicio",
                Token  = "inicio",
                Tipo   = null
            };

            var varinicio = new Simbolo()
            {
                Lexema = "varinicio",
                Token  = "varinicio",
                Tipo   = null
            };

            var varfim = new Simbolo()
            {
                Lexema = "varfim",
                Token  = "varfim",
                Tipo   = null
            };

            var escreva = new Simbolo()
            {
                Lexema = "escreva",
                Token  = "escreva",
                Tipo   = null
            };

            var leia = new Simbolo()
            {
                Lexema = "leia",
                Token  = "leia",
                Tipo   = null
            };

            var se = new Simbolo()
            {
                Lexema = "se",
                Token  = "se",
                Tipo   = null
            };

            var entao = new Simbolo()
            {
                Lexema = "entao",
                Token  = "entao",
                Tipo   = null
            };

            var fimse = new Simbolo()
            {
                Lexema = "fimse",
                Token  = "fimse",
                Tipo   = null
            };

            var fim = new Simbolo()
            {
                Lexema = "fim",
                Token  = "fim",
                Tipo   = null
            };

            var inteiro = new Simbolo()
            {
                Lexema = "inteiro",
                Token  = "inteiro",
                Tipo   = "inteiro"
            };

            var lit = new Simbolo()
            {
                Lexema = "lit",
                Token  = "lit",
                Tipo   = "lit"
            };

            var real = new Simbolo()
            {
                Lexema = "real",
                Token  = "real",
                Tipo   = "real"
            };

            TabelaDeSimbolos.Add(inicio.Lexema, inicio);
            TabelaDeSimbolos.Add(varinicio.Lexema, varinicio);
            TabelaDeSimbolos.Add(varfim.Lexema, varfim);
            TabelaDeSimbolos.Add(escreva.Lexema, escreva);
            TabelaDeSimbolos.Add(leia.Lexema, leia);
            TabelaDeSimbolos.Add(se.Lexema, se);
            TabelaDeSimbolos.Add(entao.Lexema, entao);
            TabelaDeSimbolos.Add(fimse.Lexema, fimse);
            TabelaDeSimbolos.Add(fim.Lexema, fim);
            TabelaDeSimbolos.Add(inteiro.Lexema, inteiro);
            TabelaDeSimbolos.Add(lit.Lexema, lit);
            TabelaDeSimbolos.Add(real.Lexema, real);

            return(TabelaDeSimbolos);
        }