private bool BFS(AutomatoFinito automatoFinito, Estado estadoInicial)
        {
            // retorna true se encontra um estado final, senão false
            Queue <Estado> fila = new Queue <Estado>();
            List <Estado>  estadosAlcancados = new List <Estado>();

            fila.Enqueue(estadoInicial);
            while (fila.Count > 0)
            {
                Estado estadoDesempilhado = fila.Dequeue();
                foreach (Transicao transicao in estadoDesempilhado.transicoes)
                {
                    if (transicao.estadoDestino != null)
                    {
                        if (!estadosAlcancados.Contains(transicao.estadoDestino))
                        {
                            if (transicao.estadoDestino.final)
                            {
                                return(true);
                            }
                            fila.Enqueue(transicao.estadoDestino);
                            estadosAlcancados.Add(transicao.estadoDestino);
                        }
                    }
                }
            }
            return(false);
        }
 private void analisarTokens(List <string> tokens, AutomatoFinito automatoFinito)
 {
     if (automatoFinito.estados.Count == 0)                             // se não tem produções, só tokens
     {
         automatoFinito.estados.Add(new Estado((0).ToString(), false)); // primeiro estado: S
     }
     foreach (var token in tokens)
     {
         Estado estadoAtual = automatoFinito.estados[0]; // estado S
         foreach (var simbolo in token)
         {
             // cria um novo estado para transição
             int    idEstado   = automatoFinito.estados.Count();
             Estado estadoNovo = new Estado(idEstado.ToString(), false);
             automatoFinito.estados.Add(estadoNovo);
             // cria a transição para o novo estado
             estadoAtual.transicoes.Add(new Transicao(simbolo, estadoNovo));
             if (!automatoFinito.alfabeto.Contains(simbolo))
             {
                 automatoFinito.alfabeto.Add(simbolo);
             }
             estadoAtual = estadoNovo;
         }
         estadoAtual.final = true;
     }
 }
Beispiel #3
0
        private void threadProcessos()
        {
            System.IO.StreamWriter streamWriterSaida = new System.IO.StreamWriter(txtArquivoSaida.Text, false, Encoding.UTF8);

            ServicoGeracaoAutomatoFinito servicoGeracaoAF = new ServicoGeracaoAutomatoFinito();
            AutomatoFinito automatoFinito = servicoGeracaoAF.gerarAutomatoFinitoInicial(txtArquivoGramatica.Text);

            automatoFinito = servicoGeracaoAF.determinizarAutomato(automatoFinito);
            servicoGeracaoAF.removerMortos(automatoFinito);

            streamWriterSaida.WriteLine("Autômato finito gerado.");
            streamWriterSaida.WriteLine(automatoFinito.criaListaSaida());

            ServicoAnalisadorLexico servicoAnalisadorLexico = new ServicoAnalisadorLexico();
            List <TabelaSimbolos>   tokensLidos             = new List <TabelaSimbolos>();
            List <string>           erros = new List <string>();

            servicoAnalisadorLexico.analisar(txtArquivoCodigoFonte.Text, automatoFinito, ref tokensLidos, ref erros);

            streamWriterSaida.WriteLine("Tokens Lidos:\r\n" + String.Join(Environment.NewLine, tokensLidos.Select(token => String.Format("id: {0}, estado: {1}, rotulo: {2}, linha {3}", token.identificador, token.estadoReconhecedor.label, token.rotulo, token.linha))));

            streamWriterSaida.WriteLine("Erros:\r\n" + (erros == null || erros.Count == 0 ? "Nenhum." : String.Join(Environment.NewLine, erros)));

            streamWriterSaida.WriteLine("Análise léxica concluída...\n");

            streamWriterSaida.Close();
            streamWriterSaida.Dispose();
        }
Beispiel #4
0
        public void analisar(string arquivoEntrada, AutomatoFinito automatoFinito, ref List <TabelaSimbolos> tokensReconhecidos, ref List <string> erros)
        {
            lerArquivo(arquivoEntrada);
            string textoLinha;

            for (int numeroLinha = 0; numeroLinha < _listaEntrada.Count; numeroLinha++)
            {
                // passa cada linha
                textoLinha = _listaEntrada[numeroLinha];
                textoLinha = textoLinha.Replace(System.Environment.NewLine, " "); // remove quebra de linha e poe espaço
                List <string> matches = new List <string>();
                // insere espaço antes dos operadores para separar
                foreach (System.Text.RegularExpressions.Match m in Utilidades.expressaoOperadores.Matches(textoLinha))
                {
                    if (matches.Contains(m.Value))
                    {
                        continue;
                    }
                    matches.Insert(0, m.Value);
                    textoLinha = textoLinha.Replace(matches[0], " " + matches[0] + " ");
                }
                _listaEntrada[numeroLinha] = Utilidades.expressaoEspacosDuplos.Replace(textoLinha, " ").Trim(); // remove espaços duplos
                string[] tokens = _listaEntrada[numeroLinha].Split(' ');                                        // separa cada token pelo separador
                foreach (var token in tokens)
                {
                    // passa cada token da linha
                    Estado estadoAtual = automatoFinito.estados[0]; // estado inicial
                    for (int i = 0; i < token.Length; i++)
                    {
                        // passa cada caractere do token
                        // verifica se tem uma transição para esse caractere/simbolo
                        // como ta determinizado, só tem uma ou nenhuma trasição por esse caractere/simbolo
                        Transicao transicaoSimbolo = (estadoAtual.transicoes.Where(x => x.simbolo.Equals(token[i]))).FirstOrDefault();
                        if (transicaoSimbolo == null)
                        {
                            // não encontrou transição, leva o índice para a última posição
                            i = token.Length - 1;
                        }
                        else
                        {
                            estadoAtual = transicaoSimbolo.estadoDestino;
                        }

                        if (i == token.Length - 1)   // encontrou um separador
                        {
                            if (!estadoAtual.final || transicaoSimbolo == null)
                            {
                                // erro
                                erros.Add("Linha " + (numeroLinha + 1) + ": a sequência de símbolos " + token + " não é reconhecida como sentença...");
                            }
                            else
                            {
                                // token reconhecido
                                tokensReconhecidos.Add(new TabelaSimbolos(tokensReconhecidos.Count(), token, estadoAtual, numeroLinha + 1));
                            }
                        }
                    }
                }
            }
        }
        private void threadProcessos()
        {
            System.IO.StreamWriter streamWriterSaida = new System.IO.StreamWriter(txtArquivoSaida.Text, false, Encoding.UTF8);

            ServicoGeracaoAutomatoFinito servicoGeracaoAF = new ServicoGeracaoAutomatoFinito();
            AutomatoFinito automatoFinito = servicoGeracaoAF.gerarAutomatoFinitoInicial(txtArquivoGramatica.Text);

            automatoFinito = servicoGeracaoAF.determinizarAutomato(automatoFinito);
            servicoGeracaoAF.removerMortos(automatoFinito);

            streamWriterSaida.WriteLine("Autômato finito gerado.");
            streamWriterSaida.WriteLine(automatoFinito.criaListaSaida());

            ServicoAnalisadorLexico servicoAnalisadorLexico = new ServicoAnalisadorLexico();
            List <TabelaSimbolos>   tokensLidos             = new List <TabelaSimbolos>();
            List <string>           erros = new List <string>();

            servicoAnalisadorLexico.analisar(txtArquivoCodigoFonte.Text, automatoFinito, ref tokensLidos, ref erros);

            streamWriterSaida.WriteLine("Tokens Lidos:\r\n" + String.Join(Environment.NewLine, tokensLidos.Select(token => String.Format("id: {0}, estado: {1}, rotulo: {2}, linha {3}", token.identificador, token.estadoReconhecedor.label, token.rotulo, token.linha))));

            streamWriterSaida.WriteLine("Erros:\r\n" + (erros == null || erros.Count == 0 ? "Nenhum." : String.Join(Environment.NewLine, erros)));

            streamWriterSaida.WriteLine("Análise léxica concluída...\n");

            if (erros != null && erros.Count > 0)
            {
                MessageBox.Show("Foram encontrados erros na análise léxica. Verifique o log!");
                streamWriterSaida.Close();
                streamWriterSaida.Dispose();
                return;
            }

            ServicoAnalisadorSintatico servicoAnalisadorSintatico = new ServicoAnalisadorSintatico(txtArquivoGoldParser.Text);

            servicoAnalisadorSintatico.lerSimbolos();
            servicoAnalisadorSintatico.lerProducoes();
            servicoAnalisadorSintatico.lerTabelaLALR();

            List <string> resultadoAnaliseSintatica = servicoAnalisadorSintatico.analisar(tokensLidos);

            streamWriterSaida.WriteLine(String.Join(Environment.NewLine, resultadoAnaliseSintatica));

            streamWriterSaida.Close();
            streamWriterSaida.Dispose();

            if (resultadoAnaliseSintatica != null && resultadoAnaliseSintatica.Count > 0)
            {
                MessageBox.Show("Foram encontrados erros na análise sintática. Verifique o log!");
            }
            else
            {
                MessageBox.Show("Análise sintática concluída!");
            }
        }
 SaidaRotina Reset(Evento evento)
 {
     Acumulador      = new List <TokenLexico>();
     Cabecote        = new Cabecote(AutomatoFinito.EstadoInicial);
     Cabecote.Aceito = AutomatoFinito.ConfereEstadoFinal(Cabecote.EstadoAtual);
     return(new SaidaRotina(
                new List <Evento>(),
                new List <Evento>(),
                new List <Evento>()
                ));
 }
        public RecategorizadorLexico()
        {
            AutomatoFinito  = InstanciaAutomato();
            Acumulador      = new List <TokenLexico>();
            Cabecote        = new Cabecote(AutomatoFinito.EstadoInicial);
            Cabecote.Aceito = AutomatoFinito.ConfereEstadoFinal(Cabecote.EstadoAtual);

            Rotinas.Add(TipoEvento.TOKEN_LEXICO, new Func <Evento, SaidaRotina>(ReceberToken));
            Rotinas.Add(TipoEvento.RESET, new Func <Evento, SaidaRotina>(Reset));
            Rotinas.Add(TipoEvento.EOL, new Func <Evento, SaidaRotina>(Eol));
            Rotinas.Add(TipoEvento.EOF, new Func <Evento, SaidaRotina>(Eof));
        }
        public AutomatoFinito determinizarAutomato(AutomatoFinito automatoFinito)
        {
            AutomatoFinito   automatoFinitoDeterminizado = new AutomatoFinito();
            List <Estado>    estadosPendentes            = new List <Estado>();
            List <Estado>    estadosCombinados           = new List <Estado>();
            List <Transicao> transicoes = new List <Transicao>();

            automatoFinitoDeterminizado.alfabeto = automatoFinito.alfabeto;
            estadosPendentes.Add(automatoFinito.estados[0]);
            while (estadosPendentes.Count > 0)
            {
                List <string> labelsCombinados = estadosPendentes[0].label.Split(',').ToList();
                estadosCombinados = (from obj in automatoFinito.estados where labelsCombinados.Contains(obj.label) select obj).ToList();

                Estado novoEstado = (from obj in automatoFinitoDeterminizado.estados where obj.label.Equals(estadosPendentes[0].label) select obj).FirstOrDefault();
                if (novoEstado == null)
                {
                    novoEstado = new Estado(estadosPendentes[0].label, estadosCombinados.Exists(x => x.final));
                    automatoFinitoDeterminizado.estados.Add(novoEstado);
                }
                else
                {
                    novoEstado.final = estadosCombinados.Exists(x => x.final);
                }

                foreach (var estado in estadosCombinados)
                {
                    transicoes.AddRange(estado.transicoes);
                }

                List <char> simbolosDistintos = transicoes.Select(x => x.simbolo).Distinct().ToList();
                simbolosDistintos.Sort();
                foreach (var simbolo in simbolosDistintos)
                {
                    List <string> estadosAlcancadosPeloSimbolo = transicoes.Where(x => x.simbolo.Equals(simbolo)).Select(x => x.estadoDestino.label).Distinct().ToList();
                    estadosAlcancadosPeloSimbolo.Sort();
                    string labelEstadoDestino = string.Join(",", estadosAlcancadosPeloSimbolo);
                    Estado estadoDestino      = (from obj in automatoFinitoDeterminizado.estados where obj.label.Equals(labelEstadoDestino) select obj).FirstOrDefault();
                    if (estadoDestino == null)
                    {
                        estadoDestino = new Estado(labelEstadoDestino, false);
                        automatoFinitoDeterminizado.estados.Add(estadoDestino);
                        estadosPendentes.Add(estadoDestino);
                    }
                    novoEstado.transicoes.Add(new Transicao(simbolo, estadoDestino));
                }
                transicoes.Clear();
                estadosPendentes.RemoveAt(0);
            }
            return(automatoFinitoDeterminizado);
        }
        /// <summary>
        /// Recebe um Evento contendo um Token Lexico
        /// </summary>
        /// <param name="evento">Tipo: TOKEN_LEXICO, Conteudo: TokenLexico </param>
        /// <returns></returns>
        public SaidaRotina ReceberToken(Evento evento)
        {
            TokenLexico tokenLexico = (TokenLexico)evento.Conteudo;

            Transicao transicao = AutomatoFinito.BuscaTransicao(Cabecote.EstadoAtual, tokenLexico.Categoria);

            if (transicao != null)
            {
                Transicao(transicao);
                Acumulador.Add(tokenLexico);
                return(new SaidaRotina(
                           new List <Evento>(),
                           new List <Evento>(),
                           new List <Evento>()
                           ));
            }
            else
            {
                if (Cabecote.Aceito)
                {
                    return(new SaidaRotina(
                               new List <Evento>(),
                               new List <Evento>()
                    {
                        new Evento(evento.InstanteProgramado + 1, TipoEvento.RESET, evento.Tarefa, null), new Evento(evento.InstanteProgramado + 2, TipoEvento.TOKEN_LEXICO, evento.Tarefa, evento.Conteudo)
                    },
                               new List <Evento>()
                    {
                        new Evento(evento.InstanteProgramado + 1, TipoEvento.TOKEN_LEXICO, evento.Tarefa, GetTokenLexicoFromEstadoAtual())
                    }
                               ));
                }
                else
                {
                    List <Evento> eventosSaida = new List <Evento>();
                    eventosSaida.AddRange(Acumulador.Select(t => new Evento(evento.InstanteProgramado + 1, TipoEvento.TOKEN_LEXICO, evento.Tarefa, t)));
                    eventosSaida.Add(new Evento(evento.InstanteProgramado + 2, TipoEvento.TOKEN_LEXICO, evento.Tarefa, evento.Conteudo));

                    return(new SaidaRotina(
                               new List <Evento>(),
                               new List <Evento>()
                    {
                        new Evento(evento.InstanteProgramado + 1, TipoEvento.RESET, evento.Tarefa, null)
                    },
                               eventosSaida
                               ));
                }
            }
        }
        public AutomatoFinito gerarAutomatoFinitoInicial(string arquivoEntrada)
        {
            lerArquivo(arquivoEntrada);
            List <string> producoes, tokens;

            producoes = (from linha in _listaEntrada where linha.Contains(Utilidades.simboloAtribuicao) select linha.Replace(" ", string.Empty)).ToList();
            _listaEntrada.RemoveAll(x => producoes.Contains(x.Replace(" ", string.Empty)));
            tokens = (from linha in _listaEntrada select linha.Replace(" ", string.Empty)).ToList();

            AutomatoFinito automatoFinitoInicial = new AutomatoFinito();

            analisarProducoes(producoes, automatoFinitoInicial);
            analisarTokens(tokens, automatoFinitoInicial);

            return(automatoFinitoInicial);
        }
        /// <summary>
        /// Recebe um Evento contendo uma CaracterCaracterizado
        /// </summary>
        /// <param name="evento">Tipo: ASCII, Conteudo: CaracterClassificado </param>
        /// <returns></returns>
        //  Token possui Tipo (Identificador, Número, Especial) e Valor
        public SaidaRotina ReceberCaracter(Evento evento)
        {
            CaracterClassificado caracterClassificado = (CaracterClassificado)evento.Conteudo;

            Transicao transicao = AutomatoFinito.BuscaTransicao(Cabecote.EstadoAtual, caracterClassificado.Caracter);

            if (transicao != null)
            {
                Transicao(transicao);
                if (caracterClassificado.Funcao != FuncaoCaracter.DESCARTAVEL)
                {
                    Acumulador.Add(caracterClassificado);
                }
                return(new SaidaRotina(
                           new List <Evento>(),
                           new List <Evento>(),
                           new List <Evento>()
                           ));
            }
            else if (caracterClassificado.Tipo == TipoCaracter.DELIMITADOR || Cabecote.Aceito)
            {
                return(new SaidaRotina(
                           new List <Evento>(),
                           new List <Evento>()
                {
                    new Evento(evento.InstanteProgramado + 1, TipoEvento.RESET, evento.Tarefa, null), new Evento(evento.InstanteProgramado + 2, TipoEvento.ASCII, evento.Tarefa, evento.Conteudo)
                },
                           new List <Evento>()
                {
                    new Evento(evento.InstanteProgramado + 1, TipoEvento.TOKEN_LEXICO, evento.Tarefa, GetTokenLexicoFromEstadoAtual())
                }
                           ));
            }
            else
            {
                TransicaoNA();
                Acumulador.Add(caracterClassificado);
                return(new SaidaRotina(
                           new List <Evento>(),
                           new List <Evento>(),
                           new List <Evento>()
                           ));
            }
        }
        public void removerMortos(AutomatoFinito automatoFinito)
        {
            List <Estado> estadosRemover = new List <Estado>();

            foreach (Estado estado in automatoFinito.estados)
            {
                if (estado.final)
                {
                    continue;
                }
                bool vivo = BFS(automatoFinito, estado);
                if (!vivo)
                {
                    estadosRemover.Add(estado);
                }
            }
            automatoFinito.estados.RemoveAll(x => estadosRemover.Contains(x));
            foreach (Estado estado in automatoFinito.estados)
            {
                estado.transicoes = estado.transicoes.Where(x => automatoFinito.estados.Contains(x.estadoDestino)).ToList();
            }
        }
 void Transicao(Transicao transicao)
 {
     Cabecote.EstadoAtual = transicao.Destino;
     Cabecote.Aceito      = AutomatoFinito.ConfereEstadoFinal(Cabecote.EstadoAtual);
 }
        private void analisarProducoes(List <string> producoes, AutomatoFinito automatoFinito)
        {
            int indiceDoSeparador;

            string[] transicoes;
            char     simbolo;
            Estado   estadoAtual;
            Dictionary <string, string> mapeamentoEstados = new Dictionary <string, string>();

            automatoFinito.estados.Add(new Estado((0).ToString(), false)); // primeiro estado: S
            foreach (var producao in producoes)
            {
                indiceDoSeparador = producao.IndexOf(Utilidades.simboloAtribuicao);
                string labelEstado = producao.Substring(0, indiceDoSeparador).Replace("<", String.Empty).Replace(">", String.Empty);
                if (labelEstado.Equals("S"))   // indica que uma nova gramatica ta comecando
                {
                    mapeamentoEstados.Clear();
                    mapeamentoEstados.Add("S", (0).ToString());
                }
                if (mapeamentoEstados.ContainsKey(labelEstado))   // se o estado ja ta mapeado busca o estado
                {
                    string valor;
                    mapeamentoEstados.TryGetValue(labelEstado, out valor);
                    estadoAtual = (from obj in automatoFinito.estados where obj.label.Equals(valor) select obj).FirstOrDefault();
                }
                else     // senao mapeia e cria um estado novo
                {
                    int idEstado = automatoFinito.estados.Count();
                    mapeamentoEstados.Add(labelEstado, idEstado.ToString());
                    estadoAtual = new Estado(idEstado.ToString(), false);
                    automatoFinito.estados.Add(estadoAtual);
                }

                transicoes = producao.Substring(indiceDoSeparador + Utilidades.simboloAtribuicao.Length).Replace("<", String.Empty).Replace(">", String.Empty).Split('|');
                foreach (var transicao in transicoes)
                {
                    // transicao(0) é simbolo
                    // transicao(1), se tiver, é estado, se não tiver cria um final sem transição
                    // se o estado nao ta no mapeamento, cria um e poe no map
                    simbolo = transicao[0];
                    if (simbolo.Equals(Utilidades.epsolon))   // se o símbolo é o epsolon, o estado é final
                    {
                        estadoAtual.final = true;
                    }
                    else
                    {
                        Estado estadoDestino;
                        if (simbolo.ToString().Equals(transicao))   // se só tem um símbolo, sem transição, cria um novo estado final
                        {
                            int idEstado = automatoFinito.estados.Count();
                            //mapeamentoEstados.Add(labelEstado, idEstado); não mapeia pq não vai ter outra referencia para este estado
                            estadoDestino = new Estado(idEstado.ToString(), true);
                            automatoFinito.estados.Add(estadoDestino);
                        }
                        else
                        {
                            // se tem simbolo e transição para outro estado
                            // verifica se o estado existe, senao cria um e mapeia
                            string lblEstadoTransicao = transicao.Substring(1);
                            if (mapeamentoEstados.ContainsKey(lblEstadoTransicao))   // se o estado ja ta mapeado busca o estado
                            {
                                string valor;
                                mapeamentoEstados.TryGetValue(lblEstadoTransicao, out valor);
                                estadoDestino = (from obj in automatoFinito.estados where obj.label.Equals(valor) select obj).FirstOrDefault();
                            }
                            else     // senao mapeia e cria um estado novo
                            {
                                int idEstado = automatoFinito.estados.Count();
                                mapeamentoEstados.Add(lblEstadoTransicao, idEstado.ToString());
                                estadoDestino = new Estado(idEstado.ToString(), false);
                                automatoFinito.estados.Add(estadoDestino);
                            }
                        }
                        estadoAtual.transicoes.Add(new Transicao(simbolo, estadoDestino));
                        if (!automatoFinito.alfabeto.Contains(simbolo))
                        {
                            automatoFinito.alfabeto.Add(simbolo);
                        }
                    }
                }
            }
        }