4. CONCLUSÃO
4.1. TRABALHOS FUTUROS
Durante todo o desenvolvimento e o experimento da ferramenta projetada, foram percebidas possíveis implementações para estender as possibilidades da meta-linguagem e do editor. Dessas implementações destacam-se:
• Aceitar uma gramática mais recente do Java nos blocos de código. A gramática do Java implementada não aceita a especificação de tipo na utilização de classes genéricas, por exemplo.
Essa não é apenas uma limitação da implementação da meta-linguagem, mas também do próprio JavaCC e do JastAdd.
• Permitir que os atributos de um não-terminal sejam inicializados de modo que não precisem ser inicializados em um bloco dentro da própria produção.
• Permitir disposição de terminais definidos repetidas vezes, diferenciando-os de modo equivalente aos não-terminais.
• Permitir a definição de produções abstratas apenas com identificador e, opcionalmente, com atributos. Assim, não seria necessário utilizar a expansão para especificar os não-terminais que podem assumir a forma, utilizando apenas a definição de "herança" para definir alternativas de expansão, como é feito no arquivo com extensão ast.
• Realizar a declaração de atributos utilizando o arquivo com extensão jrag. Essa implementação exigiria uma análise adicional sobre a manipulação dos atributos dos não-terminais.
Complementar a essa implementação, a meta-linguagem precisaria permitir que o usuário optasse entre utilizar gramáticas de atributos ou apenas o tratamento do contexto pelo blocos de código Java.
• Desenvolver a geração de um compilador em apenas uma passagem para quando o usuário não pretender utilizar visitantes e as ações semânticas especificadas puderem ser executadas sem necessidade de avaliação pela ausência de dependências da expansão de outros não-terminais.
• Sugerir ao usuário as palavras reservadas da meta-linguagem e da linguagem Java, bem como os terminais e não-terminais já declarados, de modo a auto-completar enquanto o usuário os digita, agilizando a especificação da linguagem.
• Implementar a indentação automática da meta-linguagem e dos blocos de código no editor. A coloração é importante, mas não é o único recurso que pode facilitar a compreensão do conteúdo de um arquivo estruturado.
• Unificar a implementação da coloração do editor com o analisador léxico da meta-linguagem e da linguagem Java, suprimindo a necessidade de alterações no editor sempre que há uma modificação na especificação da meta-linguagem ou da linguagem Java.
• Permitir que a gramática da meta-linguagem reconheça a especificação de tokens que devem ser ignorados durante a análise léxica, como é o caso dos comentários de linha e de bloco e espaços em brancos.
AHO, Alfred V.; SETHI, Ravi; ULLMAN, Jeffrey D. Compiladores: princípios, técnicas e ferramentas. Rio de Janeiro: Editora Guanabara Koogan S/A, 1995.
AHO, Alfred V. et al. Compiladores: princípios, técnicas e ferramentas. 2ª. ed. São Paulo: Pearson Addison-Wesley, 2008.
DAMAS, Luís. Linguagem C. 10ª. ed. Rio de Janeiro: LTC, 2007.
DEITEL, Harvey M; DEITEL, Paul J. Java: como programar. 8ª. ed. São Paulo: Pearson Education do Brasil, 2010.
DELAMARO, Márcio Eduardo. Como construir um compilador utilizando ferramentas Java. São Paulo: Novatec, 2004.
GRUNE, Dick et al. Projeto moderno de compiladores: implementação e aplicações. Rio de Janeiro:
Campus, 2001.
JAVA.NET. Código-fonte do JavaCC. Disponível em: <https://java.net/projects/javacc/sources/svn/
content/trunk>. Acesso em: 10 maio 2013.
LAKATOS, Eva Maria; MARCONI, Marina de Andrade. Metodologia científico. 3ª. ed. São Paulo:
Atlas, 2011.
LOUDEN, Kenneth C. Compiladores: princípios e práticas. São Paulo: Pioneira Thomson Learning, 2004.
MENEZES, Paulo Fernando Blauth. Linguagens formais e autômatos. 3ª. ed. Porto Alegre: Sagra, 2000.
PRESSMAN, Roger S. Engenharia de Software. 6ª. ed. São Paulo: McGraw-Hill Interamericana do Brasil, 2006.
PRICE, Ana Maria de Alencar; TOSCANI, Simão Sirineo. Implementação de linguagens de programação: compiladores. 3ª. ed. Porto Alegre: Sagra, 2005.
RAMOS, Marcus Vinícius Midena; JOSÉ NETO, João; VEGA, Ítalo Santiago. Linguagens formais: teoria, modelagem e implementação. Porto Alegre: Bookman, 2009.
SEBESTA, Robert W. Conceitos de linguagens de programação. 5ª. ed. Porto Alegre: Bookman, 2003.
APÊNDICE I - Teclas de atalhos do editor
Tabela com as teclas de atalho do editor.
Ícone Windows e Linux OS X Ação
ctrl + O command + O Permite abrir um arquivo esquema de tradução ctrl + N command + N Abre uma nova aba com o editor em branco
ctrl + S command + S Salva o conteúdo do editor da aba selecionada no arquivo correspondente
ctrl + shift + S command + shift + S Salva o conteúdo do editor da aba selecionada em um novo arquivo
ctrl + alt + S command + alt + S Salva o conteúdo do editor de todas as abas em seus arquivos correspondentes
ctrl + W command + W Fecha a aba/arquivo selecionado
ctrl + Z command + Z Desfaz a última alteração feita no conteúdo do editor da aba selecionada
ctrl + Y command + Y Refaz a última alteração desfeita no conteúdo do editor da aba selecionada
ctrl + X command + X Move o conteúdo selecionado no editor para área de transferência
ctrl + C command + C Copia o conteúdo selecionada no editor para área de transferência
ctrl + V command + V Colar o conteúdo da área de transferência a partir da posição do cursor no editor da aba selecionada
ctrl + G command + G Posiciona o cursor na linha especificada ctrl + A command + A Seleciona todo o conteúdo do editor
ctrl + E command + E Compila o conteúdo do editor (ou arquivo) da aba selecionada
F1 F1 Abre o arquivo com o conteúdo da Ajuda
shift + F1 Abre as informações sobre a aplicação
APÊNDICE II - Classes utilizadas na implementação de uma linguagem
public enum TipoEnum { LOGICO, INTEIRO, REAL, LITERAL, INDETERMINADO }
public class Simbolo {
! private Integer ponteiro;
! private String identificador;
! private TipoEnum tipo;
!
! public Simbolo(Integer ponteiro, String identificador, TipoEnum tipo) {
! ! this.ponteiro = ponteiro;
! ! this.identificador = identificador;
! ! this.tipo = tipo;
! }
!
! public Integer getPonteiro(){
! ! return this.ponteiro;
! }
!
! public String getIdentificador(){
! ! return this.identificador;
! }
!
! public TipoEnum getTipo(){
! ! return this.tipo;
! }
}
public class ReportadorDeErros {
! private List<Excecao> errosReportados;
!
! private static ReportadorDeErros instancia = null;
!
! public static ReportadorDeErros getInstancia(){
! ! if(instancia == null)
! ! ! instancia = new ReportadorDeErros();
! ! return instancia;
! }
!
! protected ReportadorDeErros(){
! ! this.errosReportados = new LinkedList<Excecao>();
! }
! public static void reportaErroSemantico(Excecao excecao){
! ! getInstancia().errosReportados.add(excecao);
! }
!
! public final List<Excecao> getErrosReportados(){
! ! return errosReportados;
! }
}
public class TabelaDeSimbolos {
! private HashMap<String, Simbolo> simbolosRegistrados;
! private static TabelaDeSimbolos instancia = null;
!
! public static TabelaDeSimbolos getInstancia(){
! ! if(instancia == null)
! ! ! instancia = new TabelaDeSimbolos();
! ! return instancia;
! }
!
! protected TabelaDeSimbolos(){
! ! this.simbolosRegistrados = new HashMap<String,Simbolo>();
! }
!
! public static void registraSimbolo(int ponteiro, String identificador,
! ! ! TipoEnum tipo) throws IdentifcadorJaDeclaradoExcecao {
! ! if(exiteSimbolo(identificador))! {
! ! ! throw new IdentifcadorJaDeclaradoExcecao(identificador);
! ! }
! ! Simbolo simbolo = new Simbolo(ponteiro, identificador, tipo);
! ! getInstancia().simbolosRegistrados.put(identificador, simbolo);
! }
!
! public static boolean exiteSimbolo(String identificador){
! ! return getInstancia().simbolosRegistrados.containsKey(identificador);
! }
!
! public static Simbolo recuperaSimbolo(String identificador)
! ! ! throws IdentifcadorNaoDeclaradoExcecao {
! ! if(!exiteSimbolo(identificador))! {
! ! ! throw new IdentifcadorNaoDeclaradoExcecao(identificador);
! ! }
! ! return getInstancia().simbolosRegistrados.get(identificador);
! }
}
public class VariaveisSemanticas {
! private String contexto;
! private TipoEnum tipoAtual;
! private static VariaveisSemanticas instancia = null;
!
! public static VariaveisSemanticas getInstancia(){
! ! if(instancia == null)
! ! ! instancia = new VariaveisSemanticas();
! ! return instancia;
! }
! protected VariaveisSemanticas(){
! ! this.contexto = "";
! ! this.tipoAtual = null;
! }
!
! public static void registraContexto(String contexto){
! ! getInstancia().contexto = contexto;
! }
! public final static String recuperaContexto(){
! ! return getInstancia().contexto;
! }
!
! public static void registraTipoAtual(TipoEnum tipo){
! ! getInstancia().tipoAtual = tipo;
! }
! public final static TipoEnum recuperaTipoAtual(){
! ! return getInstancia().tipoAtual;
! }
}
public class FilaDeInstrucoes {
! public List<Instrucao> instrucoesGeradas;
! private static FilaDeInstrucoes instancia = null;
!
! public static FilaDeInstrucoes getInstancia(){
! ! if(instancia == null)
! ! ! instancia = new FilaDeInstrucoes();
! ! return instancia;
! }
! protected FilaDeInstrucoes(){
! ! this.instrucoesGeradas = new LinkedList<Instrucao>();
! }
!
! public final List<Instrucao> getInstrucoesGeradas(){
! ! return this.instrucoesGeradas;
! }
!
! public static void getInstrucaoImprimeConstantes(String constante, TipoEnum tipo){
! ! Instrucao instrucao = null;
! ! instrucao = InstrucaoFabrica.geraAdicionaConstanteAoTopo(constante, tipo);
! ! instrucao = InstrucaoFabrica.geraImprime(tipo);
! ! getInstancia().instrucoesGeradas.add(instrucao);
! }
!
! public static void getInstrucaoImprimeVariavel(Integer ponteiro, TipoEnum tipo){
! ! Instrucao instrucao = null;
! ! instrucao = InstrucaoFabrica.geraRecuperaVariavel(ponteiro, tipo);
! ! getInstancia().instrucoesGeradas.add(instrucao);
! ! instrucao = InstrucaoFabrica.geraImprime(tipo);
! ! getInstancia().instrucoesGeradas.add(instrucao);
! }
public static InstrucaoDesvio
geraInstrucaoDeDesvioQuandoFalsoSemEndereco(Integer ponteiro){
InstrucaoDesvio instrucao = null;
instrucao = InstrucaoFabrica.geraDesvioQuandoFalsoSemEndereco(ponteiro);
getInstancia().instrucoesGeradas.add(instrucao);
return instrucao;
}
public static void geraInstrucaoDeDesvioQuandoVerdadeiro(Integer ponteiro, Integer endereco){
InstrucaoDesvio instrucao = null;
instrucao = InstrucaoFabrica.geraDesvioQuandoVerdadeiro(ponteiro, endereco);
getInstancia().instrucoesGeradas.add(instrucao);
}
public static void geraInstrucaoDeDesvioIncondicional(Integer ponteiro, Integer endereco){
InstrucaoDesvio instrucao = null;
instrucao = InstrucaoFabrica.geraDesvioIncondicional(ponteiro, endereco);
getInstancia().instrucoesGeradas.add(instrucao);
} }
public class AvaliadorDeTipos {
private static boolean tipoIndeterminado(TipoEnum tipo0, TipoEnum tipo1){
if(tipo0 == TipoEnum.INDETERMINADO || tipo1 == TipoEnum.INDETERMINADO) return true;
return false;
}
public static TipoEnum avaliaTipoExpressaoRelacional(TipoEnum tipo0, TipoEnum tipo1)
throws ExpressaoComTipoIndeterminado { if(tipoIndeterminado(tipo0,tipo1))
throw new ExpressaoComTipoIndeterminado();
return TipoEnum.LOGICO;
}
public static TipoEnum avaliaTipoExpressaoLogica(TipoEnum tipo0, TipoEnum tipo1)
throws ExpressaoComTipoIndeterminado, ExpressaoLogicaComTipoNaoLogico { if(tipoIndeterminado(tipo0,tipo1))
throw new ExpressaoComTipoIndeterminado();
if(tipo0 != TipoEnum.LOGICO || tipo1 != TipoEnum.LOGICO) throw new ExpressaoLogicaComTipoNaoLogico();
return TipoEnum.LOGICO;
}
public static TipoEnum avaliaTipoExpressaoAritmetica(TipoEnum tipo0, TipoEnum tipo1) throws ExpressaoComTipoIndeterminado, ExpressaoAritmeticaComTipoLogico, ExpressaoAritmeticaComTipoLiteral {
if(tipoIndeterminado(tipo0,tipo1))
throw new ExpressaoComTipoIndeterminado();
if(tipo0 == TipoEnum.LOGICO || tipo1 == TipoEnum.LOGICO)
throw new ExpressaoAritmeticaComTipoLogico();
if(tipo0 == TipoEnum.LITERAL || tipo1 == TipoEnum.LITERAL) throw new ExpressaoAritmeticaComTipoLiteral();
if(tipo0.ordinal()>=tipo1.ordinal()) return TipoEnum.tipo0;
return TipoEnum.tipo1;
} }