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; } }
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(); }
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); } } } } }