flowchart LR
M00["Módulo 0<br/>Nivelamento<br/>estruturas, grafos,<br/>conjuntos e relações"]
M01["Módulo 1<br/>Panorama da compilação<br/>e linguagens formais<br/>MAPA DO SEMESTRE"]
M02["Módulo 2<br/>Alfabetos, linguagens<br/>e expressões regulares"]
M03["Módulos 3 a 7<br/>Autômatos finitos<br/>até o analisador léxico"]
M00 --> M01 --> M02 --> M03
subgraph ENTREGA["O que o módulo 1 deixa pronto"]
D1["Vocabulário de fases<br/>e interfaces"]
D2["Mapa da hierarquia<br/>de gramáticas"]
D3["Grupos formados e<br/>domínio da linguagem<br/>escolhido e validado"]
D4["Ambiente sob modo<br/>estrito e esqueleto<br/>do repositório"]
end
M01 --- ENTREGA
D2 -.->|"andar regular"| M02
D4 -.->|"base de todas as fases"| M03
Módulo 01: Plano de Aula — Panorama da Compilação e Linguagens Formais
Documento exclusivo do professor. Este é o guia operacional das seis aulas do módulo 1: roteiro por blocos das duas aulas teóricas, plano das quatro aulas de tutoria, entregáveis e riscos antecipados. Não distribua à turma — as questões de discussão e a leitura pedagógica dos erros perdem função assim que o estudante as lê antes da aula.
Visão Geral do Módulo
Onde este módulo fica — é o mapa que o semestre inteiro vai usar para se localizar.
Este é o único módulo do semestre cujo critério de sucesso é situar, e não operar. Nada aqui é esgotado: nem as fases, nem a hierarquia de gramáticas, nem a distinção entre as famílias de tradutores. O que se pede ao fim é que o estudante consiga pegar qualquer assunto dos catorze módulos seguintes e dizer, antes de estudá-lo, a que pergunta ele responde e em que andar da teoria ele mora.
Isso muda a forma de conduzir. A tentação, num módulo panorâmico, é aprofundar o que se domina melhor e passar rápido pelo resto — normalmente aprofundar as fases e correr na hierarquia. Resista: a hierarquia é o que vai sustentar os módulos 2 a 11, e um estudante que sai daqui sem a escala de memória (estado fixo, pilha, memória livre) chega ao módulo 9 sem entender por que existe um segundo modelo de máquina.
O módulo também carrega a partida do Projeto Integrador, e essa metade tem peso próprio. É aqui que os grupos se formam e escolhem o domínio da linguagem que construirão até dezembro. Uma escolha ruim aprovada nesta semana custa o semestre do grupo, e o instrumento de controle é o veredito explícito ao fim da tutoria.
Objetivos, Competências e Habilidades
Objetivos de aprendizagem. Estabelecer o mapa conceitual que orientará o semestre inteiro, de modo que o estudante saiba situar qualquer assunto posterior antes de estudá-lo. Delimitar o que é um compilador e o que o distingue de programas aparentados. Apresentar a hierarquia de gramáticas e linguagens como o mapa teórico do curso, indicando quais níveis serão percorridos e por quê. Constituir os grupos e dar partida ao Projeto Integrador.
Competências a desenvolver. Capacidade de situar um problema técnico dentro de um quadro teórico mais amplo antes de atacá-lo. Capacidade de compreender uma arquitetura de software pela função de cada parte e pelas razões que justificam a separação entre elas, e não pela enumeração de componentes.
Habilidades a adquirir. Distinguir compilador, interpretador, montador e tradutor entre linguagens de alto nível, reconhecendo que sistemas reais combinam as abordagens. Nomear as fases da compilação e dizer o que cada uma recebe e produz. Localizar as quatro classes da hierarquia de gramáticas e associar a cada uma o modelo de máquina correspondente.
Estrutura das Aulas
Aulas 1 e 2 — Aula Teórica
Roteiro por blocos — a ordem importa, porque cada bloco é a resposta a uma insuficiência deixada pelo anterior.
Bloco de abertura — três programas defeituosos
Chegue com os três programas já projetados, lado a lado, sem título e sem explicação. O primeiro sem um ponto e vírgula. O segundo somando um texto a um número. O terceiro sintaticamente e semanticamente impecável, entrando num laço que nunca termina.
Pergunte apenas isto: por que o compilador reclama dos dois primeiros e aceita o terceiro? Deixe a sala responder em voz alta e anote as hipóteses no quadro sem julgá-las. A hipótese que quase sempre aparece é “porque o terceiro é mais difícil de detectar”, e ela é o gancho: responda que não é difícil, é impossível, e que existe demonstração matemática disso desde 1936 — e não diga mais nada sobre o assunto até o bloco de indecidibilidade da segunda aula. A pendência declarada segura a atenção melhor do que a resposta imediata.
Feche o bloco nomeando o que acabou de acontecer: para explicar três reações diferentes a três programas quebrados foram necessárias uma noção de forma, uma noção de significado e um teorema de indecidibilidade. Escreva as três palavras no canto do quadro e não as apague durante as duas aulas — você voltará a elas no fechamento.
Bloco seguinte — o contrato de correção
Escreva no quadro a função parcial de tradução e a igualdade de correção:
\llbracket T(p) \rrbracket_{L_a}(x) = \llbracket p \rrbracket_{L_f}(x).
Dois pontos merecem verbalização explícita, porque a turma passa por eles sem notar. O primeiro é a parcialidade: nem todo texto é programa, e o tradutor tem obrigação de dizer isso em vez de produzir código sem sentido. O segundo é o plural dos diagnósticos — quem reporta só o primeiro problema é insuportável de usar, e essa observação prosaica é o que justifica, mais adiante, a infraestrutura de erro que vocês vão construir.
Amarre a igualdade à otimização já aqui, porque é o que a torna memorável: otimizar é trocar um programa por outro mais rápido mantendo a igualdade, e uma transformação que altera o resultado em um único caso de fronteira não é otimização agressiva, é defeito.
Bloco seguinte — compilar, interpretar e os parentes
Conduza este bloco pela pergunta “quando”, não pela lista de diferenças. Compilador e interpretador fazem a mesma análise; o que muda é o momento em que ela é paga. Do “quando” saem, sem decorar, as duas consequências que interessam: quem compila paga a análise uma vez e amortiza, mas gera código que precisa servir a todos os valores possíveis; quem interpreta paga a cada execução, às vezes a cada iteração, e em troca sabe o valor de cada variável.
Sobre os parentes, seja econômico. O montador é formalmente um compilador cuja fonte já corresponde um a um às instruções da máquina, e o nome separado existe porque nenhuma dificuldade interessante sobra — não há instrução a escolher nem registrador a alocar. O tradutor entre linguagens de alto nível precisa preservar estrutura, nomes e formatação, o que um compilador para código de máquina pode dissolver sem culpa.
Primeira questão de discussão em duplas. “Um sistema traduz o programa para instruções de uma máquina virtual, e outro programa executa essas instruções, compilando em tempo de execução os trechos mais frequentes. Esse sistema é: (a) um compilador; (b) um interpretador; (c) os dois, porque as definições falam de objetos diferentes; (d) nenhum dos dois, porque é um caso híbrido sem classificação.”
Aplique o procedimento inteiro: voto individual primeiro, sem comentário seu; discussão em duplas; segundo voto. A resposta é (c). Quem vota (a) ou (b) está tentando encaixar o sistema numa gaveta única; quem vota (d) percebeu o problema da gaveta e concluiu que não há classificação — é o erro mais interessante da questão, e é dele que você fecha o conceito: as duas dimensões são independentes, e a pergunta produtiva não é “isso é compilador ou interpretador”, e sim “o que foi decidido antes da execução e o que foi adiado”. Não revele a resposta antes da discussão em duplas; fazer isso anula o efeito da técnica.
Bloco seguinte — as fases pelas interfaces
Aqui está o erro de condução mais comum do módulo: fazer a turma decorar seis nomes. Defina fase pela tripla — o que recebe, o que produz e que erros só ela tem condições de detectar — e construa a tabela de interfaces no quadro com a participação da sala, uma linha por vez, perguntando antes de escrever.
Dê o critério prático que sobrevive ao semestre: em dúvida sobre onde colocar uma verificação, pergunte qual é a primeira fase que dispõe da informação necessária.
O argumento da representação intermediária pede número no quadro, não retórica. Faça a conta na frente deles: para suportar quatro linguagens de origem e três máquinas de destino sem representação intermediária são necessários 4 \times 3 = 12 tradutores; com ela no meio, 4 + 3 = 7 peças. Depois amplie para dez de cada lado — cem contra vinte — e deixe a sala ver a diferença crescer. Complete com o argumento que vale mais e é menos citado: o ganho maior é de manutenção, porque um defeito na análise de uma linguagem se corrige num lugar só e beneficia todas as máquinas.
Termine o bloco com a assimetria que quase nunca é dita: a análise é reconhecimento, com teoria madura e algoritmos ótimos; a síntese é otimização combinatória, com subproblemas difíceis no caso geral. Avise que o tom da segunda metade do curso muda por causa disso, e que a mudança é do objeto, não do professor.
Segunda questão de discussão em duplas. “Um programa está corretamente pontuado e usa, numa expressão, um nome que nunca foi declarado. Qual é a primeira fase capaz de detectar esse defeito? (a) análise léxica; (b) análise sintática; (c) análise semântica; (d) geração de código.”
A resposta é (c). Quem vota (a) supõe que o analisador léxico conhece os nomes do programa — confunde reconhecer a categoria de um lexema com saber o que ele denota. Quem vota (b) confunde “estar de acordo com as regras da linguagem” com “derivar da gramática”: a sequência de tokens deriva perfeitamente, e é justamente por isso que a fase seguinte existe. Esse segundo erro costuma ser majoritário no primeiro voto e cair muito no segundo, o que torna a questão um bom argumento para a própria técnica — comente isso com a turma quando o resultado aparecer.
Bloco de abertura da segunda aula — retomada pela pergunta pendente
Não recapitule a aula anterior em forma de resumo. Retome pelas três palavras que ficaram no canto do quadro e pergunte à turma qual delas ainda não foi tratada. A resposta é a indecidibilidade, e ela abre naturalmente a segunda aula — mas antes dela vem o mapa teórico, e é você quem faz essa inversão explícita: “para explicar por que aquilo é impossível, preciso primeiro mostrar o mapa em que a impossibilidade mora”.
Bloco seguinte — o mapa teórico
Comece pelos objetos elementares, rápido e sem cerimônia: alfabeto finito e não vazio, cadeia como sequência finita, \varepsilon de comprimento zero, \Sigma^* infinito enumerável. Então dê a definição que carrega o poder do aparato — uma linguagem sobre \Sigma é qualquer subconjunto de \Sigma^* — e pare para explorar a generalidade dela, porque é o que a turma não vê sozinha: o conjunto dos programas corretos é uma linguagem nesse sentido, e o conjunto dos programas que terminam também é. A diferença entre as duas está na dificuldade de decidir a pertinência.
Escreva a quádrupla da gramática e a linguagem gerada, e apresente a ideia de Chomsky pela restrição progressiva da forma das produções, não pela lista dos quatro tipos.
O exemplo numérico deste bloco tem de ser feito no quadro, com derivação passo a passo. Tome S \to a\,S\,b \mid \varepsilon e derive: S \Rightarrow aSb \Rightarrow aaSbb \Rightarrow aabb. Faça a turma notar que a única produção que introduz um a também introduz um b, e conclua que a linguagem gerada é \{a^n b^n \mid n \ge 0\}. Ao lado, derive A \to a\,A \mid b: A \Rightarrow aA \Rightarrow aaA \Rightarrow aab, gerando a^n b. Pergunte o que mudou. A resposta que você quer ouvir é que no segundo caso não há nada a lembrar, e no primeiro é preciso contar. Registre a inclusão própria
\mathcal{L}_3 \subsetneq \mathcal{L}_2 \subsetneq \mathcal{L}_1 \subsetneq \mathcal{L}_0
e monte a tabela dos reconhecedores, lendo-a como escala de memória: sem memória além do estado atual, memória ilimitada com disciplina de topo, memória de acesso livre limitada pela entrada, memória livre ilimitada.
Guarde dois avisos para o fim do bloco. O primeiro: para autômatos finitos o não determinismo não aumenta o poder de reconhecimento, e para autômatos de pilha isso é falso — diferença que é a origem de metade das dificuldades da análise sintática. O segundo: a hierarquia é um mapa elegante demais, porque classifica por poder de descrição e não por custo de reconhecimento, e não captura ambiguidade.
Terceira questão de discussão em duplas. “Considere as linguagens sobre o alfabeto \{a, b\}. Qual delas não é regular? (a) as cadeias com número par de a; (b) as cadeias da forma a^n b^n; (c) as cadeias que começam por a e terminam por b; (d) as cadeias que contêm abba como subcadeia.”
A resposta é (b). Quem vota (a) supõe que contar é sempre proibido a uma máquina de estados finitos — mas contar módulo dois exige apenas dois estados, e desfazer essa confusão é o principal ganho da questão. Quem vota (d) acha que reconhecer uma subcadeia exige memória do que passou, quando basta lembrar quanto do padrão já foi casado. Feche com a frase que os módulos 3 a 6 vão formalizar: reconhecer a^n b^n exige lembrar um número ilimitado, e nenhum conjunto fixado de estados guarda um número ilimitado.
Bloco seguinte — o que nenhum compilador pode fazer
Volte ao terceiro programa da abertura e pague a dívida. Turing mostrou, em 1936, que não existe procedimento mecânico que decida corretamente, para todo programa e toda entrada, se a execução termina; o argumento é de autorreferência, supondo o procedimento e construindo com ele um programa que termina exatamente quando o procedimento afirma que não termina. Esboce o argumento no quadro em três linhas e não vá além — a demonstração completa não é conteúdo desta disciplina, e forçá-la aqui consome o bloco seguinte.
O que precisa ficar é o critério prático, e ele merece ser escrito: perguntas sobre a forma do texto são decidíveis e são todas as que o compilador responde; perguntas sobre o comportamento do programa não são. E há a saída intermediária, que reaparecerá na análise de fluxo — em vez de responder “sim” ou “não”, o analisador responde “certamente não” ou “talvez sim”, errando sempre para o mesmo lado.
Bloco de construção ao vivo — a infraestrutura que antecede a primeira fase
Este é o bloco de code-along, e o ponto de partida é o repositório vazio. Avise a sala para abrir o editor e digitar junto; quem só assiste não aprende este bloco. Pause duas vezes, ao fim de cada peça, e espere as duplas alcançarem o mesmo ponto antes de continuar — cheque isso circulando, não perguntando “todo mundo conseguiu?”, que sempre recebe silêncio afirmativo.
Comece defendendo a decisão, porque ela é contraintuitiva: não se começa pelo analisador léxico, e sim pela camada que todas as fases usam. Quem enfia o tratamento de posição dentro do analisador léxico está criando dívida garantida.
A primeira peça é o arquivo-fonte com posições indexadas. Construa ao vivo o carregamento do texto e o índice dos deslocamentos de início de cada linha, e demonstre a conversão com números concretos no quadro. Suponha as linhas começando nos deslocamentos 0, 18, 45, 72 e 96. Para o deslocamento 60, a busca binária encontra a maior entrada não superior a ele, que é 45, na terceira linha; a coluna é 60 - 45 + 1 = 16. Faça a conta ingênua ao lado para mostrar o que se evita: varrer o texto contando quebras de linha custa tempo proporcional ao arquivo a cada erro reportado, de modo que cinquenta erros num arquivo de vinte mil caracteres percorrem um milhão de caracteres; com o índice de mil linhas, cada conversão custa cerca de dez comparações, e as cinquenta somam quinhentas.
Mencione, ao digitar a leitura do arquivo, a armadilha do nosso ambiente: o fim de linha usa dois caracteres, e lido em modo texto o par pode virar um só, fazendo os deslocamentos deixarem de corresponder aos bytes. Leia em modo binário. É o tipo de detalhe que ninguém descobre por raciocínio e todo mundo descobre depurando.
A segunda peça é a coleção de diagnósticos. Construa o diagnóstico como tripla de severidade, posição e mensagem, e defenda a política: cada fase registra o que encontra e segue, e quem decide parar é o programa principal. Alguém vai objetar que isso é exagero num projeto sem fase alguma. Responda com o benefício datado: é o que torna possível, no módulo 10, um analisador sintático que reporta três erros de uma vez em vez de obrigar quem escreve o programa a corrigir e recompilar três vezes.
Encerre a construção ligando o modo estrito antes de qualquer outra coisa, e diga em voz alta por quê: ligar as verificações rigorosas sobre uma base já escrita produz dezenas de erros de uma vez, e a reação natural diante desse muro é desligá-las de novo.
Bloco de fechamento — compilar e interpretar a mesma árvore, e volta ao gancho
Feche com uma demonstração curta que torna concreta a distinção da primeira aula. Desenhe no quadro a árvore da expressão (2 + 3) \times 4 - 5 e submeta-a aos dois tratamentos. O interpretador percorre a árvore em profundidade e devolve 15 agora. O compilador percorre a mesma árvore e devolve sete instruções — empilhar 2, empilhar 3, somar, empilhar 4, multiplicar, empilhar 5, subtrair — que uma máquina de pilha executa, também chegando a 15. Os dois caminhos chegam ao mesmo número, e essa igualdade é exatamente o contrato escrito no início da primeira aula.
Chame a atenção para a ordem da emissão: as instruções saem em pós-ordem, primeiro os operandos e depois a operação, e essa ordem é a única que funciona numa máquina de pilha, porque no momento em que a operação executa os dois valores já precisam estar empilhados. Aponte que é a mesma ordem que reaparece na geração de código, no módulo 14.
Registre também a armadilha, porque ela apanha quase todo mundo uma vez na vida: ao desempilhar, o segundo operando sai primeiro, por ter entrado por último. Trocar a ordem não altera nada na soma nem na multiplicação, e produz resultado errado na subtração. Explique que a expressão termina em subtração de propósito, e não por acaso — é uma lição sobre escolher o caso de teste que revela o defeito.
Termine voltando ao quadro da abertura, às três palavras que ficaram no canto. O primeiro programa morre na análise sintática, porque a sequência de tokens não deriva da gramática. O segundo morre na análise semântica, porque a condição violada depende de contexto. O terceiro não morre em lugar nenhum, porque pergunta sobre comportamento. Três defeitos, três destinos, e o semestre inteiro entre eles.
Aulas 3 a 6 — Tutoria do Projeto Integrador
Quatro aulas de tutoria — formação dos grupos, escolha do domínio da linguagem, programas de exemplo, ambiente sob modo estrito e esqueleto do repositório.
Este é o módulo de andaime máximo. Aqui você fornece o critério, o modelo e o veredito; a partir do módulo 8 fornecerá apenas o objetivo. Diga isso à turma em voz alta na primeira sessão — “neste módulo eu digo se está bom; no fim do semestre quem diz é você” —, porque o desvanecimento posterior só não é lido como abandono quando foi anunciado antes.
Tenha o seu próprio projeto aberto e projetado durante as duas sessões. O grupo que vê a justificativa de domínio já escrita, com as seis capacidades conferidas uma a uma, entende o formato em um minuto; o grupo que só ouve a descrição da tarefa escreve meia página de intenções.
Primeira sessão de tutoria — formar os grupos e decidir o domínio
Comece pela formação, e não a deixe inteiramente ao acaso das afinidades. Grupos de dois ou três, composição fixa para o semestre inteiro. Enquanto se formam, circule perguntando a cada grupo quem já escreveu código recursivo sem consultar material — a resposta identifica na hora as composições em que só um integrante programa com autonomia. Quando encontrar uma, intervenha antes que o grupo se consolide: “vocês três têm o mesmo perfil; troquem um integrante com aquele grupo ali”. Depois da primeira entrega essa conversa fica muito mais difícil.
Fechados os grupos, entregue o contrato de capacidades e peça que cada grupo o copie no seu documento de proposta antes de propor qualquer domínio: mais de uma categoria léxica com pelo menos uma descrita por padrão, uma construção aninhada de profundidade arbitrária, nomes declarados em um ponto e usados em outro, mais de um tipo de valor com operação restrita a um deles, efeito observável na execução, e tamanho pequeno. O contrato precisa estar escrito na frente deles enquanto discutem, senão viram-se para o domínio que acham divertido e conferem as capacidades depois — o que sempre resulta em conferência complacente.
Enquanto os grupos discutem, projete a justificativa do seu próprio projeto e leia em voz alta a defesa do domínio de reconhecimento de padrões: a razão é que o produto da compilação é ele mesmo um motor de autômatos, de modo que a teoria aparece duas vezes no mesmo artefato e o mesmo módulo de construção de autômatos serve aos dois níveis. Não peça que copiem o domínio. Peça que produzam um argumento com essa forma — uma razão de projeto, não uma preferência.
Feche a sessão com a rodada de propostas orais, um grupo de cada vez, sem apresentação preparada. Para cada proposta faça sempre as mesmas três perguntas, na ordem: onde está o aninhamento de profundidade arbitrária, qual é a operação que só se aplica a um dos tipos, e o que o programa faz de observável ao rodar. Grupos que travam na primeira quase sempre propuseram uma linguagem de configuração disfarçada, sem estrutura recursiva; a correção é acrescentar uma construção que se contenha, não trocar o domínio inteiro.
Segunda sessão de tutoria — exemplos, ambiente e esqueleto
Abra exigindo o que os grupos mais subestimam: dois ou três programas de exemplo escritos, com a aparência pretendida, antes de qualquer formalização. Recuse gramática nesta sessão, mesmo de quem se antecipou. A ordem é escrever o programa que se quer poder escrever e depois descobrir a gramática que o descreve, e essa ordem é ela própria conteúdo.
Enquanto escrevem, projete o exemplo do meu projeto e mostre quanta decisão de projeto sete linhas já contêm: declaração antes do uso, que implica tabela de símbolos com ordem a verificar; condição opcional marcada por palavra reservada, que implica produção com parte opcional; extração de valor explícita, que evita regras de coerção de tipo; e emissão com rótulo, que dá o efeito observável. Conte também o erro da primeira versão — a condição sem palavra separadora, que parecia mais limpa e era ambígua, porque o analisador não sabia onde a ligação terminava e a condição começava. Esse relato de erro próprio vale mais do que a advertência genérica de evitar ambiguidade, e é o que faz os grupos relerem os próprios exemplos com desconfiança.
A segunda metade da sessão é ambiente e repositório, e é onde a sala se espalha em problemas individuais. Antecipe os dois que consomem mais tempo. O primeiro é a instalação incompleta do compilador: o pacote está lá, mas o ambiente de linha de comando não foi carregado, e o grupo conclui que “não funciona”. O segundo é a tentação de deixar as flags estritas para depois. Corte essa na hora, sem negociar, com o argumento que você já usou na aula teórica: ligar sobre base escrita produz dezenas de erros de uma vez, e a reação natural é desligar de novo.
Circule cobrando o revezamento de papéis já nesta primeira tutoria, mesmo que o trabalho seja mais de escrita do que de código. Quem digita a proposta é o piloto, quem lê e questiona é o navegador, e os papéis trocam quando o grupo terminar um item. Se você não instituir o revezamento agora, no módulo em que ele é barato, não conseguirá instituí-lo no módulo 10, quando o custo de trocar as mãos no teclado for real.
O veredito, e por que ele acontece aqui
Feche o módulo dando parecer explícito sobre cada proposta: aprovada, aprovada com redução de escopo, ou recusada. A recusa é uma possibilidade real e o critério mais frequente é o tamanho — especificação que não cabe em duas páginas está grande demais para o prazo. Use a pergunta de controle em voz alta: “escreva a gramática inteira em uma página; se não couber, corte”. Recusar aqui custa uma sessão de trabalho. Recusar no módulo 8, quando a gramática já está escrita e o analisador léxico funcionando, custa o semestre do grupo.
Registre no seu diário, ao fim da segunda sessão, três coisas por grupo: o domínio aprovado, a redução de escopo que você impôs (se impôs) e o nome do integrante que mais falou. A terceira anotação é a que se paga: no módulo 7, quando a compreensão tiver de ser demonstrável por qualquer integrante, você vai querer saber quem estava calado desde o começo.
Entregáveis e Avaliação
Ao fim do módulo, cada grupo entrega o repositório na estrutura exigida, com o arquivo de instruções gerais preenchido, o documento de proposta contendo a justificativa do domínio escolhido e os programas de exemplo pretendidos, e a evidência de que o ambiente compila e executa sob o modo estrito. A evidência de ambiente não é uma afirmação: é a saída do build sem nenhuma linha de aviso e a execução do programa produzindo o relatório de fases pendentes.
Confira cada entrega contra seis itens, na mesma ordem para todos os grupos: o domínio está justificado demonstrando as seis capacidades do contrato, uma a uma; existe pelo menos um programa de exemplo completo; o build termina sem aviso; o executável aceita um arquivo, imprime o relatório e reclama de arquivo vazio indicando posição; o repositório separa instruções gerais, documentos e código; e não há tipo apagado nem verificação descartada no código escrito.
Registre no componente contínuo do módulo a pontualidade da entrega, a contribuição nas discussões em duplas das aulas teóricas e o engajamento nas atividades colaborativas da tutoria. Deixe claro à turma, já neste módulo, que a entrega do módulo 1 não compila linguagem nenhuma e que isso está certo: o que se entrega aqui é decisão de projeto e infraestrutura, não funcionalidade. Grupos que tentam antecipar o analisador léxico chegam ao módulo 7 tendo de refazê-lo sobre uma teoria que ainda não conheciam.
Orientações Sobre o Aplicativo
Use o aplicativo da disciplina para as três votações das aulas teóricas, e mantenha a votação anônima na projeção. O valor do primeiro voto está na dispersão: uma turma que se divide entre duas alternativas na questão sobre a fase que detecta o nome não declarado precisa de mais tempo de discussão em duplas do que uma turma que já converge; uma turma que converge para a alternativa errada precisa que você refaça a definição antes de qualquer discussão, porque a discussão em duplas só corrige quando há quem tenha entendido.
Guarde os dois histogramas de cada questão. A distância entre o primeiro e o segundo voto é o dado mais útil que você vai ter sobre a turma neste módulo, e é ele que orienta quanto tempo dedicar à revisão de vocabulário formal na abertura do módulo 2.
Acompanhe também, no aplicativo, o engajamento no estudo do material — que responde por metade do componente contínuo. No primeiro módulo esse número costuma ser alto e enganoso, porque a turma está curiosa; o sinal que importa aparece na comparação com o módulo 2, quando o conteúdo deixa de ser panorâmico. Não faça inferência sobre indivíduos com base numa única semana.
Pontos de Atenção Específicos
O panorama vira lista se você deixar. O risco número um deste módulo é a aula degenerar em enumeração — seis fases, quatro tipos de gramática, quatro máquinas — que a turma copia e não usa. O antídoto é conduzir cada bloco por uma pergunta, não por uma lista, e verificar isso no fechamento: se você conseguir reconstruir a tabela das fases perguntando “qual é a primeira fase que tem a informação necessária?”, o bloco funcionou.
Não antecipe a formalização. Alguém sempre pergunta, no bloco da hierarquia, como se demonstra que a^n b^n não é regular. Responda que a demonstração é do módulo 6, dê a frase intuitiva — exige lembrar um número ilimitado — e siga. Ceder aqui consome o bloco de indecidibilidade e adianta uma demonstração que a turma ainda não tem ferramenta para acompanhar.
O bloco de construção ao vivo não é demonstração. Se metade da turma estiver olhando em vez de digitando, pare e espere. A tentação de seguir para não perder o roteiro é forte e o custo é alto: o estudante que não digitou a infraestrutura neste módulo chega ao módulo 3 sem projeto onde escrever o autômato.
A escolha do domínio é irreversível na prática. Um grupo pode trocar de domínio no módulo 2 sem grande custo, e não pode mais no módulo 5. Por isso o veredito é dado ainda dentro deste módulo, com critério de tamanho objetivo e não com recomendação genérica de moderação.
A composição dos grupos concentra competência se você não intervier. Grupos formados apenas por afinidade tendem a reunir perfis parecidos, e o padrão que aparece é o grupo em que só um integrante programa com autonomia. Intervir na formação é desconfortável e é muito mais barato do que administrar o desequilíbrio a partir do módulo 7, quando a compreensão passa a ser exigida de qualquer integrante.
Cuidado com a digressão sobre linguagens da moda. A pergunta “e por que a linguagem X é mais rápida que a linguagem Y” aparece com frequência no bloco de compilar e interpretar, e é legítima. Responda em duas frases, reconduzindo à distinção estrutural — o custo da análise pago a cada execução contra o pago uma vez —, e proponha que a comparação concreta volte no módulo 15, quando houver vocabulário de otimização para sustentá-la.