LRM Prof. Mantovani ← Aulas da disciplina

Minha pequena linguagem

Um compilador só, que atravessa o semestre inteiro: começa reconhecendo tokens e termina executando, numa máquina virtual escrita por vocês, um programa escrito por vocês. As quatro fases da disciplina viram quatro entregas sobre o mesmo código.

👥 grupos de até 3🧪 4 entregas + apresentação🐍 só Python 3🎯 6,0
🐍
Não precisa instalar nada além do Python 3. Um compilador é um programa de texto: entra texto, sai texto. Roda no notebook de vocês, no laboratório da faculdade ou no Google Cloud Shell — que é gratuito, não pede cartão e é o ambiente da correção. Se passar lá, passa aqui.
🚦
A primeira verificação é vermelha — isso é o enunciado, não um defeito. O esqueleto já responde à linha de comando, mas nenhuma fase está escrita. O vermelho é o ponto de partida, e ele vai virando verde conforme vocês preenchem mplc/.

A linguagem que vocês vão compilar

A MPL — Minha Pequena Linguagem — tem quatro tipos, funções com recursão, se, enquanto e palavras-chave em português. É pequena de propósito: cabe num semestre e não cabe num tutorial pronto da internet.

// fatorial, em MPL funcao inteiro fatorial(inteiro n) { se (n <= 1) { retorne 1; } senao { retorne n * fatorial(n - 1); } } funcao vazio principal() { inteiro i = 1; enquanto (i <= 6) { escreva(fatorial(i)); i = i + 1; } }

O compilador de vocês vai atravessar essas cinco etapas, e cada uma tem que saber mostrar o próprio trabalho:

--tokensa lista de tokens com linha e coluna
--asta árvore, que prova a precedência
--tabelaos escopos e o que vive em cada um
--iro código de três endereços
.mplbo executável, em texto legível

É a memória de cálculo do compilador. Um compilador que só cospe o resultado final é uma caixa preta: não dá para corrigir a fase, só o produto — e vocês não conseguem enxergar onde ele errou.

Antes da primeira entrega

Você já clonou o laboratório neste navegador. Não clone de novo — abra o terminal e digite cd ~/compiladores-lab. Se quiser trazer as correções mais recentes, o mesmo comando serve: ele atualiza sem duplicar nada.

Uma vez só, e vale o semestre inteiro. O comando abaixo cria a pasta ~/compiladores-lab se ela não existir, e atualiza se já existir — rodar de novo nunca duplica nada nem apaga o trabalho de vocês.

▶ Abrir o Cloud Shell (opcional — gratuito, sem cartão)

[ -d ~/compiladores-lab ] || git clone https://github.com/LuizRMSilva1973/compiladores-lab ~/compiladores-lab; cd ~/compiladores-lab && git pull

Depois, para ver o ponto de partida — e o primeiro vermelho:

[ -d ~/compiladores-lab ] || git clone https://github.com/LuizRMSilva1973/compiladores-lab ~/compiladores-lab; cd ~/compiladores-lab && make verificar E=1
♻️
Todo comando desta página serve sozinho. Cada um começa clonando o laboratório se ele ainda não existir — por isso a linha é comprida. Isso quer dizer que não existe ordem obrigatória: dá para pular direto para a Entrega 2 sem ter passado pela seção acima, e nada é duplicado nem apagado se você rodar duas vezes.
📖
Três documentos mandam no trabalho. LINGUAGEM.md diz o que o compilador aceita; CONTRATOS.md diz como ele se comunica — a linha de comando e o formato de cada despejo; e entregas/ traz o enunciado de cada uma. Quando a intuição de vocês discordar de um deles, é o arquivo que vale. Quinze minutos de leitura economizam uma tarde.

As quatro entregas

1Analisador léxicoSemana 5 · 0,8

Transformar o texto do programa numa lista de tokens, com a posição exata de cada um. É a fase que parece a mais fácil e é a que mais cobra precisão: a coluna errada aqui aparece como um erro incompreensível na Entrega 2.

O que fazer

  • Preencher mplc/lexico.py: os quatro tipos de literal, as palavras reservadas, os dois tipos de comentário e os escapes.
  • A primeira coluna de cada linha é 1, não 0.
O que prova: a saída do --tokens bate byte a byte com o gabarito nos dez programas do corpus, e os seis programas com erro léxico são recusados na linha e coluna exatas. Só a primeira metade não provaria nada: um analisador que aceita qualquer coisa passa em todos os programas válidos.
🪤
A armadilha: o <= tem que ser reconhecido antes do <. Se o laço testar os símbolos de um caractere primeiro, x <= 3 vira quatro tokens em vez de três — e o defeito só aparece na entrega seguinte, num lugar que não tem nada a ver.
Verificação verde numa máquina limpa0,4
Tabela de tokens no README, coerente com o código0,2
Os seis erros léxicos com linha e coluna certas0,2
[ -d ~/compiladores-lab ] || git clone https://github.com/LuizRMSilva1973/compiladores-lab ~/compiladores-lab; cd ~/compiladores-lab && make verificar E=1
2Analisador sintático e árvoreSemana 9 · 1,2

Transformar os tokens numa árvore que mostra, na própria forma, a estrutura do programa. Descida recursiva, uma função por nível de precedência.

🚫
Gerador de parser proibido nesta entrega e na anterior. ANTLR, PLY, yacc e parentes escondem exatamente a parte que está sendo ensinada. Da Entrega 3 em diante o assunto é outro e não faz diferença — e na apresentação vocês devem comparar o parser de vocês com o que um gerador produziria.
O que prova: a árvore de 1 + 2 * 3 tem o + na raiz. Se vier o *, a precedência está trocada — e isso aparece no --ast mesmo que o compilador ainda não calcule nada. Não é formatação: é a estrutura.
🪤
A armadilha: 10 - 4 - 3 tem que dar (10 - 4) - 3. Se a sua função de nível chamar a si mesma à direita, sai 10 - (4 - 3) — que vale 9 em vez de 3. Esse defeito sobrevive a todo teste com dois operandos e só aparece com três.
Verificação verde (Entregas 1 e 2)0,6
Gramática em BNF no README, coerente com o parser0,3
Os seis erros sintáticos com linha e coluna certas0,3
[ -d ~/compiladores-lab ] || git clone https://github.com/LuizRMSilva1973/compiladores-lab ~/compiladores-lab; cd ~/compiladores-lab && make verificar E=2
3Tabela de símbolos e tiposSemana 13 · 1,2

Descobrir o que cada nome significa, em que escopo ele vive, e recusar o que não faz sentido. É aqui que o compilador deixa de olhar a forma e passa a olhar o significado.

O que fazer

  • Escopos aninhados com sombreamento: a variável de dentro esconde a de fora enquanto durar.
  • Duas passadas — a primeira só coleta assinaturas, para que uma função possa ser chamada antes de aparecer no arquivo.
  • A conversão inteiroreal, e só ela.
O que prova: os catorze programas semanticamente errados do corpus são recusados, cada um na linha certa — e os dez válidos continuam compilando. É o par que importa: recusar tudo é tão errado quanto aceitar tudo.
🪤
A armadilha: um se sem senao nunca garante retorno, por mais que a condição pareça sempre verdadeira para vocês. O compilador não avalia condições — ele olha a estrutura.
Verificação verde (Entregas 1 a 3)0,6
Os catorze erros semânticos, na linha certa0,3
Explicação da estrutura de escopos no README0,3
[ -d ~/compiladores-lab ] || git clone https://github.com/LuizRMSilva1973/compiladores-lab ~/compiladores-lab; cd ~/compiladores-lab && make verificar E=3
4Código intermediário, geração e VMSemana 16 · 1,8

A entrega em que o compilador deixa de analisar e passa a produzir. São três peças — código de três endereços, geração do executável e a máquina virtual — e é por isso que ela vale mais que as outras. No fim dela, um programa em MPL roda.

O que prova: os dez programas do corpus executam com a saída exata, e o --ir tem no máximo um operador por linha. Essa é a propriedade que define o código de três endereços, e é ela que o verificador mede — o formato do despejo fica a critério de vocês.

As três armadilhas

  • A divisão inteira. 7 / 2 é 3, e real x = 7 / 2; é 3.000000 — a divisão acontece antes da conversão. Quem promove cedo demais escreve 3.500000 e passa em todo o resto do corpus. Tem um programa lá só para isso.
  • O sinal do resto. -7 % 3 é -1, não 2: o resto tem o sinal do dividendo. O % do Python segue o sinal do divisor e devolve 2.
  • O registro de ativação. A recursão só funciona se cada chamada tiver o seu próprio espaço de locais. Se os locais forem globais da VM, fatorial(5) devolve lixo — e, pior, fatorial(1) funciona perfeitamente.
Verificação verde nas quatro entregas0,9
Três endereços de verdade no --ir0,3
Conjunto de instruções da VM documentado0,3
Um programa MPL escrito pelo grupo, funcionando0,3
[ -d ~/compiladores-lab ] || git clone https://github.com/LuizRMSilva1973/compiladores-lab ~/compiladores-lab; cd ~/compiladores-lab && make verificar E=4
5Apresentação: demonstração e defesaSemana 17 · 1,0

Oito minutos por grupo: cinco de apresentação e três de alteração ao vivo.

Os cinco minutos

  • O programa de vocês rodando (30 s) — comece pelo fim: o programa MPL que o grupo escreveu, compilado e executado na hora.
  • Uma expressão atravessando as quatro fases (2 min) — escolham uma linha, como x = a + b * 2;, e mostrem os tokens, o pedaço da árvore, o que a tabela sabe sobre ela, o código de três endereços e as instruções da VM. É a disciplina inteira numa linha só.
  • O .mplb aberto (1 min) — a gente lê junto um trecho do que o compilador de vocês gerou. É por isso que o contrato exige texto legível.
  • O defeito mais difícil (1,5 min) — sintoma, diagnóstico, correção. Provavelmente é onde vocês mais aprenderam.

Os três minutos de alteração ao vivo

Cada grupo recebe uma alteração pequena na linguagem, sorteada na hora, e tem dez minutos para fazê-la funcionar: aceitar o operador ** com a precedência certa, encadear senaose, fazer o escreva aceitar dois argumentos, acrescentar o pare ao enquanto, ou pôr e e ou em curto-circuito. Todas mexem em pelo menos duas fases e todas têm tamanho parecido.

Podem consultar o código de vocês, a internet e o que quiserem. O que não dá para consultar é o entendimento de onde mexer. Quem não terminar mostra até onde chegou e explica o que faltava — grupo que sabe dizer exatamente onde mexeria perde pouco.

A demonstração funciona e a expressão é rastreada pelas quatro fases0,4
A alteração ao vivo0,3
O defeito contado com honestidade0,2
Todos falam, e o tempo é respeitado0,1

Regras do jogo

📦A entrega é o repositório, nunca a máquina de vocês. A correção clona o repositório do grupo numa máquina limpa e roda make verificar E=n. Se não passar lá, não entregou.
🧱São quatro entregas sobre o mesmo compilador, não quatro trabalhos. O verificador da Entrega 4 confere tudo o que veio antes — deixar a Entrega 1 pela metade custa caro em novembro.
🧾Evidência é obrigatória. make evidencias E=<n> grava a saída da verificação, e é ela que vai anexada no formulário.
🗣️A linguagem de implementação é de vocês — Python, Java, C, o que preferirem. O verificador não olha para dentro: ele roda ./compilar e ./executar e compara o que sai. Só não dependam de biblioteca que precise ser instalada.
🤖Escrever o compilador é a tarefa. Usar IA para explicar um conceito ou entender um trecho é bem-vindo, e eu faço isso também. Entregar um compilador que vocês não sabem alterar é outra coisa — e é para separar os dois casos que existe a alteração ao vivo na apresentação. Não é desconfiança; é o formato.
Mão na massa · colaborativo

Trabalho semestral · Minha pequena linguagem

Identifiquem o grupo uma vez — fica salvo neste navegador e serve para as quatro entregas. Escolham qual entrega estão enviando, colem a URL do repositório e anexem a evidência da verificação.

👥 grupos de até 3🔁 4 entregas📧 recibo por e-mail
Léxico e sintaxetokens, gramática e árvore
Semânticaescopos, tipos e mensagens de erro
Geração e VMtrês endereços, bytecode e execução
📤 Entrega: link do repositório + evidencias/verificacao-N.txt.