Análise Semântica e Geração de Código
Por: thiagool93 • 10/7/2016 • Abstract • 770 Palavras (4 Páginas) • 227 Visualizações
Compiladores Relatório Final
Análise Semântica e Geração de Código
Alunos: Lucas Montesuma
Thiago de Oliveira Lima
1. Introdução
Para esta ultima parte do trabalho de compiladores, foram implementadas as funcionalidades de análise semântica e geração de código do compilador minijava. Foi usada a IDE Eclipse e sistema operacional Linux, assim como na primeira parte do trabalho (scanner e parser). Ao final da execução, o compilador minijava exibe as informações de verificação léxica e sintática, análise das regras semânticas e as tabelas geradas. A seguir explicarei o funcionamento da análise semântica, assim como a geração de código.
2. Análise semântica
O analisador semântico utiliza a árvore sintática determinada pelo analisador sintático para identificar operadores e operandos das expressões, reconhecer erros semânticos, fazer verificações de compatibilidade de tipos, analisar escopos das variáveis, etc. Para isso, é necessário a utilização da estrutura de dados chamada AST (Abstract Syntax Tree), que é uma representação abstrata simplificada da estrutura semântica de um código fonte.
O parseamento do código é realizado em duas etapas que correspondem as passagens pela AST. Na primeira etapa, a AST é percorrida para gerar uma tabela HASH contendo todos os elementos definidos no código e verificando se as variáveis foram declaradas, ou se houve dupla declaração de classes, métodos ou variáveis. Na segunda etapa, a AST é percorrida mais uma vez para a verificação de tipos, como também, verificar se o número de argumentos na chamada de um método corresponde com o número de argumentos que o método exige.
Abaixo todas as checagens semânticas implementadas listadas:
- Declaração de classes, métodos e variáveis já existentes;
- Operador "+" somente aplicado a inteiros;
- Operador "-" somente aplicado a inteiros;
- Operador "*" somente aplicado a inteiros;
- Operador "<" somente aplicado a inteiros;
- Operador "&&" somente aplicado a booleano;
- Operador "!" somente aplicado a booleanos;
- Expressão no "if" somente booleano;
- Expressão no "while" somente booleano;
- Tipo de retorno de Método igual ao tipo do método;
- Chamada de Métodos com o número correto de parâmetros;
- Chamada de Métodos com os tipos dos parâmetros corretos;
- Variável utilizada é declarada anteriormente;
- Variável usada, onde a declaração é em uma classe base;
- Herda de classe inexistente;
- Atribuições: variáveis simples(int = int e boolean = boolean);
- Atribuições: vetor1 = vetor2;
- Atribuição de vetor[exp1] = exp2 tem o mesmo tipo;
- Atribuições: variável simples(int ou boolean) recebe o retorno de um método;
- Atribuições: Objeto recebe outro Objeto;
- Atribuições: Objeto recebe retorno de um método;
- Expressões em System.out.println(EXP) somente tipo inteiro;
- Expressão EXP.length somente aplicado ao tipo int[];
- Expressão em new int [EXP] somente tipo inteiro;
- Expressão (index) em vetor [EXP] somente tipo inteiro;
- Declaração de objeto de uma classe inexistente;
- Declaração de tipo inexistente;
- Métodos sobrepostos (overriding) têm mesma lista de argumentos e mesmo retorno;
- Verificar se argumentos e variáveis de um método não são iguais;
- Chamada de método inexistente;
- Atribuições: Objeto recebe um Objeto de uma classe base (Herança);
- Atribuições: Verificar se vetor2 (vetor1 = vetor2) é do tipo intArrayType;
3. Geração de código
A fase final do processo de compilação é a geração de código assembly. Se trata de uma fase importante, pois traduz a estrutura intermediária para código de máquina que é bem mais veloz de ser executada por computadores. A geração de um bom código objeto é difícil devido aos detalhes particulares das máquinas para os quais o código é gerado, no entanto, pode ser até duas vezes mais rápida que uma geração de código ineficiente que não tenha passado por otimizações.
...