O que é um compilador de código e o que ele faz?

UMA compilador é um programa que traduz legível por humanos Código fonte em código de máquina executável por computador. Para fazer isso com sucesso, o código legível por humanos deve estar em conformidade com as sintaxe regras da linguagem de programação em que está escrita. O compilador é apenas um programa e não pode corrigir seu código para você. Se você cometer um erro, precisará corrigir a sintaxe ou ela não será compilada.

O que acontece quando você compila código?

A complexidade de um compilador depende da sintaxe da linguagem e da quantidade de abstração essa linguagem de programação fornece. Um compilador C é muito mais simples que um compilador para C ++ ou C #.

Análise Lexical

Ao compilar, o compilador primeiro lê um fluxo de caracteres de um arquivo de código-fonte e gera um fluxo de tokens lexicais. Por exemplo, o código C ++:

int C = (A * B) +10;

pode ser analisado como estes tokens:

  • digite "int"
  • variável "C"
  • é igual a
  • suporte esquerdo
  • variável "A"
  • vezes
  • variável "B"
  • suporte direito
  • mais
  • literal "10"
instagram viewer

Análise sintática

A saída lexical vai para a parte do analisador sintático do compilador, que usa as regras da gramática para decidir se a entrada é válida ou não. A menos que variáveis A e B foram declarados anteriormente e estavam no escopo, o compilador pode dizer:

  • 'A': identificador não declarado.

Se eles foram declarados, mas não inicializados. o compilador emite um aviso:

  • variável local 'A' usada sem ser inicializada.

Você nunca deve ignorar avisos do compilador. Eles podem quebrar seu código de maneiras estranhas e inesperadas. Sempre corrija os avisos do compilador.

Um passe ou dois?

Algumas linguagens de programação são escritas para que um compilador possa ler o código fonte apenas uma vez e gerar o código da máquina. Pascal é uma dessas línguas. Muitos compiladores requer pelo menos dois passes. Às vezes, é por causa de declarações avançadas de funções ou classes.

No C ++, uma classe pode ser declarada, mas não definida até mais tarde. O compilador é incapaz de calcular quanta memória a classe precisa até compilar o corpo da classe. Ele deve reler o código-fonte antes de gerar o código de máquina correto.

Gerando código de máquina

Supondo que o compilador conclua com êxito as análises lexicais e sintáticas, o estágio final está gerando código de máquina. Este é um processo complicado, especialmente com CPUs modernas.

A velocidade do compilado executável o código deve ser o mais rápido possível e pode variar enormemente de acordo com a qualidade do código gerado e a quantidade de otimização solicitada.

A maioria dos compiladores permite especificar a quantidade de otimização - normalmente conhecida por compilações de depuração rápida e otimização completa do código liberado.

A geração de código é desafiadora

O escritor do compilador enfrenta desafios ao escrever um gerador de código. Muitos processadores aceleram o processamento usando

  • Pipelining de instruções
  • interno caches.

Se todas as instruções em um código ciclo pode ser realizada no CPU cache, esse loop é executado muito mais rápido do que quando a CPU precisa buscar instruções na RAM principal. O cache da CPU é um bloco de memória embutido no chip da CPU que é acessado muito mais rápido que os dados na RAM principal.

Cache e Filas

A maioria das CPUs possui uma fila de busca prévia, na qual a CPU lê as instruções no cache antes de executá-las. Se ocorrer uma ramificação condicional, a CPU precisará recarregar a fila. O código deve ser gerado para minimizar isso.

Muitas CPUs possuem partes separadas para:

  • Aritmética inteira (números inteiros)
  • Aritmética de ponto flutuante (números fracionários)

Essas operações geralmente podem ser executadas em paralelo para aumentar a velocidade.

Compiladores geralmente geram código de máquina em arquivos de objetos que são então ligado juntos por um programa vinculador.