LRM Prof. Mantovani ← Aulas da disciplina
Semana 1 · Aula 1 de 14

Introdução à compilação

O que é um compilador, em que ele difere de um interpretador e o panorama completo das fases que transformam o código-fonte em um programa executável, com a tabela de símbolos e o tratamento de erros como apoios transversais.

📚 Compiladores📝 mini-quiz ao final
Objetivos da aula

O que você vai aprender

1

Explicar o papel de um compilador como tradutor que preserva o significado entre duas linguagens.

2

Distinguir compilação de interpretação e reconhecer as abordagens híbridas (bytecode, JIT).

3

Identificar, em alto nível, as fases de análise (front-end) e de síntese (back-end).

4

Classificar mensagens de erro em léxicas, sintáticas e semânticas.

1 · Motivação

Por que estudar compiladores?

Todo programa que você escreve passa por um compilador ou interpretador antes de rodar. Entender essa máquina invisível muda a forma como você programa, depura e raciocina sobre desempenho.

Compiladores reúnem três grandes áreas da computação: teoria das linguagens formais, estruturas de dados e arquitetura de máquinas. É um dos cursos em que a teoria vira, literalmente, um programa que funciona.

🔑
Quem entende compiladores entende mensagens de erro, otimizações, e por que uma linguagem se comporta de certo jeito. É conhecimento que vale para a carreira inteira.
2 · Mapa

O que veremos nesta aula

Esta aula abre o curso com o panorama geral. Vamos percorrer:

O que é compilarCompilar × interpretarAs fasesErros e tabela de símbolos
  • A definição precisa de compilador e o que significa preservar o significado.
  • O contraste com interpretadores e os modelos híbridos do mundo real.
  • A sequência de fases de análise e síntese.
  • As estruturas de apoio que atravessam todas as fases.
3 · Definição

O que é um compilador?

Compilador. Programa que recebe um texto na linguagem-fonte e produz um programa equivalente na linguagem-alvo, preservando o significado e reportando os erros encontrados.

A linguagem-fonte é aquela em que o humano escreve (C, Java, Rust). A linguagem-alvo é aquela que a máquina ou uma máquina virtual executa (código de máquina, assembly, bytecode).

O ponto central da definição é "equivalente": a saída deve fazer exatamente o que a entrada descreve.

4 · Aprofundamento

Tradutor, e não executor

Um compilador não roda o seu programa. Ele apenas o traduz. Quem executa é o processador (no caso de código nativo) ou uma máquina virtual (no caso de bytecode).

Isso tem uma consequência prática: erros descobertos pelo compilador aparecem antes de o programa rodar. Já erros que dependem de dados de entrada (uma divisão por zero, por exemplo) só aparecem em tempo de execução.

💡
O compilador também produz, além do programa-alvo, um relatório: avisos e mensagens de erro. Esse relatório é parte do produto, não um detalhe.
5 · Exemplo

Entrada e saída de um compilador

Considere a linha de código-fonte abaixo e uma tradução possível para uma linguagem de baixo nível:

// fonte (alto nível) x = a + b * 2; // alvo (tres enderecos, baixo nivel) t1 = b * 2 t2 = a + t1 x = t2

Observe que a multiplicação foi calculada antes da soma: o compilador respeitou a precedência dos operadores. Esse é o tipo de decisão que veremos formalizada nas próximas semanas.

6 · Interativo

Passo a passo: do fonte ao executável

Passo 1
O pré-processador resolve diretivas como includes e macros, produzindo um arquivo de texto expandido.
Passo 2
O compilador analisa o texto (léxica, sintática, semântica) e gera código assembly.
Passo 3
O montador (assembler) converte o assembly em código-objeto, em linguagem de máquina.
Passo 4
O ligador (linker) junta os objetos e as bibliotecas, resolvendo referências, e produz o executável final.
7 · Definição

O que é um interpretador?

Interpretador. Programa que lê o programa-fonte e o executa diretamente, comando a comando, sem produzir antes um programa-alvo separado.

Enquanto o compilador traduz tudo de uma vez e entrega um artefato, o interpretador é o próprio executor: ele percorre o código e realiza as ações descritas na hora.

8 · Aprofundamento

Como o interpretador trabalha

O interpretador também precisa entender o programa (faz análise léxica e sintática), mas em vez de gerar código de máquina, ele percorre a estrutura interna e executa cada operação.

Por isso ele costuma ser mais lento: a tradução acontece repetidas vezes, durante a execução. Em compensação, ele oferece flexibilidade — é mais fácil testar trechos isolados e inspecionar o estado em tempo real.

💡
Shells, consoles interativos (REPL) e linguagens de script tipicamente usam interpretação por causa dessa interatividade.
9 · Analogia

Tradutor de livro × intérprete simultâneo

🔧 Analogia
O compilador é como traduzir um livro inteiro do português para o inglês: dá trabalho uma vez, mas depois qualquer leitor lê a versão pronta rapidamente. O interpretador é como um intérprete simultâneo numa reunião: traduz fala por fala, na hora, mas precisa estar presente o tempo todo e cada frase custa um instante.
10 · Comparação

Compilador × interpretador

CompiladorInterpretador
Quando traduzAntes de executar (uma vez)Durante a execução (comando a comando)
SaídaPrograma-alvo (artefato)Resultado da execução
Velocidade de execuçãoAlta (código nativo)Menor (overhead de tradução)
DiagnósticoEm lote, antes de rodarNo ponto exato em que ocorre
ExemplosC, C++, Rust, GoPython (CPython), JavaScript
11 · Fluxo

As fases de um compilador

O caminho completo, que estudaremos semana a semana, é uma esteira de transformações:

Léxica
tokens
Sintática
árvore
Semântica
significado
Geração de RI Otimização Geração de código

As três primeiras formam o front-end (análise); as três últimas, o back-end (síntese).

12 · Aprofundamento

Análise × síntese

A grande divisão de um compilador é entre análise e síntese.

  • Análise (front-end): entende o programa — decompõe o texto, verifica sua correção e cria uma representação interna.
  • Síntese (back-end): constrói o programa-alvo a partir dessa representação interna.
🔑
Pense na análise como "ler e compreender" e na síntese como "reescrever na outra língua". Uma representação intermediária liga as duas pontas.
13 · Verifique

Verifique você mesmo: é qual fase?

Descobrir que o programa usa uma variável nunca declarada é tarefa de qual fase?

A léxica só agrupa caracteres em tokens; a sintática verifica a estrutura. Saber se um nome foi declarado exige checagem de significado e contexto — isso é semântica.
14 · Caso prático

Classificando erros reais

As mensagens de erro de um compilador real revelam em que fase o problema foi detectado:

MensagemFase
"caractere inesperado '@'"Léxica
"')' esperado antes de ';'"Sintática
"não é possível somar inteiro e string"Semântica
"variável 'x' não declarada"Semântica
15 · Erros comuns

Confusões frequentes

⚠️
Cuidado. "Compilar" não é o mesmo que "rodar". Um programa pode compilar sem erros e ainda assim travar na execução (por exemplo, dividir por zero com base num dado de entrada). O compilador só pega o que dá para verificar estaticamente.

Outra confusão comum: achar que linguagem é compilada ou interpretada "por natureza". Na prática, a mesma linguagem pode ter implementações dos dois tipos.

16 · Boas práticas

Lendo o relatório do compilador

Dica. Ataque sempre o primeiro erro da lista. Erros posteriores muitas vezes são consequência do primeiro: o compilador, perdido depois de um problema, gera mensagens em cascata que somem quando você corrige a causa raiz.

Trate os avisos (warnings) com seriedade. Muitos deles apontam bugs reais que ainda não causaram falha.

17 · Revelar

Reflita: por que duas etapas?

Por que separar o compilador em análise e síntese, em vez de traduzir diretamente?
Porque separar permite reaproveitar. A mesma análise (front-end) de uma linguagem pode alimentar back-ends para várias máquinas, e o mesmo back-end pode servir a várias linguagens, desde que todos falem uma representação intermediária comum. É a ideia que sustenta projetos como o LLVM.
18 · Flashcards

Termos-chave da aula

Front-endvirar
Fases de análise, dependentes da linguagem-fonte: léxica, sintática e semântica.
Back-endvirar
Fases de síntese, dependentes da máquina-alvo: otimização e geração de código.
Bytecodevirar
Código intermediário portátil, executado por uma máquina virtual (ex.: JVM).
Tabela de símbolosvirar
Estrutura que guarda nomes, tipos e escopos, consultada por várias fases.
19 · Conexões

Onde isto se encaixa no curso

Esta aula é o mapa. Cada fase que apareceu aqui vira uma ou mais semanas:

  • Análise léxica → aulas 3 e 4 (tokens, ER, autômatos).
  • Análise sintática → aulas 5, 6 e 7 (GLC, parsing, LL(1)).
  • Análise semântica → aulas 8 e 9 (atributos, tabela de símbolos, tipos).
  • Síntese → aulas 10 em diante (RI, ambiente de execução, código).
20 · Síntese

Resumo visual

🔑
Compilador = traduz fonte→alvo preservando o significado, em duas grandes etapas: análise (entende) e síntese (constrói). Interpretador = executa direto, sem artefato. Tabela de símbolos e tratamento de erros acompanham todas as fases.
21 · Simulador

Conheça o laboratório do curso

Ao longo do curso usaremos simuladores reais escritos em JavaScript: um analisador léxico, uma calculadora de FIRST/FOLLOW e um mini-compilador de expressões. Eles transformam a teoria em algo que você manipula com as próprias mãos.

Nesta aula introdutória, vale apenas conhecê-los pelo nome. A partir da aula 3, cada simulador entra em ação no momento certo do conteúdo.

Mão na massa · colaborativo

Atividade em grupo · Compilador na vida real

Em trios, investiguem um compilador/ferramenta real e apresentem em 5 minutos.

⏱️ 25 min👥 trios🧩 pesquisa + pitch

Roteiro

  1. Escolham uma ferramenta: GCC, Clang/LLVM, javac, TypeScript (tsc), Babel ou Roslyn.
  2. Descubram: que linguagem-fonte e alvo ela usa? É compilador, interpretador ou híbrido?
  3. Encontrem uma mensagem de erro real que ela emite e classifiquem: é erro léxico, sintático ou semântico?
  4. Montem 3 slides e apresentem.
Pesquisadorlevanta a documentação
Curador de erroscoleta e classifica mensagens
Apresentadorconduz o pitch
📤 Entrega: 3 slides + a classificação de um erro real da ferramenta escolhida.
Teste seu conhecimento

Mini-quiz · Aula 1

20 questões sobre esta aula. Escolha e veja a explicação na hora.

0/20

📌 Resumo — leve isto para a prova

  • Compilador traduz fonte→alvo preservando o significado e reportando erros.
  • Compilar traduz antes de executar; interpretar traduz/executa durante a execução.
  • Existem modelos híbridos (bytecode + JIT), como Java e Python.
  • O processo divide-se em análise (front-end) e síntese (back-end).
  • Tabela de símbolos e tratamento de erros são transversais a todas as fases.