Autor
Afiliações

Moacyr Francischetti Corrêa, Bacharel em Ciência da Computação, Licenciado em Computação, Especialista em Ciência de Dados e Inteligência Artificial, PhD em Biotecnologia in Silico

Plano de Aulas

Este documento é o plano global da disciplina e a fonte autoritativa do escopo de cada módulo. Ele define, para os quinze módulos, os objetivos, as competências, as habilidades, o conteúdo a apresentar e as estratégias de condução. É documento do professor.

Fluxo de Aprendizagem e Integração com o Projeto Integrador

Cada módulo dispõe de seis aulas. As duas primeiras são de exposição teórica conduzida pelo professor; as quatro seguintes são de tutoria, dedicadas ao Projeto Integrador desenvolvido pelos grupos. Essa proporção é o dado estrutural mais importante do planejamento e tem uma consequência que precisa ser assimilada antes de qualquer preparação de aula: a exposição teórica é curta, e tentar cobrir todo o conteúdo de um módulo em profundidade máxima produz cobertura superficial de tudo. O plano por módulo indica a profundidade pretendida de cada tópico justamente para orientar o que aprofundar e o que apenas situar.

Todo o trabalho da disciplina acontece dentro do horário de aula. Não há tarefa a ser cumprida fora dele, e não há atividade prática que não pertença ao Projeto Integrador. Isso restringe o planejamento de forma produtiva: se um conteúdo precisa ser exercitado, o exercício acontece nas aulas teóricas, na forma de discussão conceitual, ou nas de tutoria, incorporado ao projeto. A técnica de discussão em duplas usada nas aulas teóricas foi escolhida também por essa razão — ela opera inteiramente dentro da aula e não pressupõe estudo prévio.

A relação entre teoria e projeto é de sincronia estrita. O que se estuda no módulo é o que se constrói no módulo, e cada tarefa do projeto corresponde a um conteúdo teórico daquele mesmo módulo. Essa correspondência é o principal instrumento de verificação do plano: quando não for possível apontar que conteúdo da exposição uma tarefa exercita, ou a tarefa está deslocada ou o conteúdo não foi coberto.

Os três marcos de consolidação. O semestre tem três pontos em que uma peça completa fica pronta e o acúmulo anterior se torna verificável: o módulo 7, o módulo 10 e o módulo 15. Nesses módulos a entrega é consolidada e a avaliação é mais pesada. A função dos marcos é impedir que pendências atravessem o semestre despercebidas — a partir de cada um deles, uma dificuldade não resolvida deixa de ser um incômodo e passa a ser um impedimento para o bloco seguinte.

Estrutura Geral de Cada Módulo

As duas aulas teóricas seguem um padrão constante de abertura. Cada módulo começa com uma situação concreta que o conteúdo daquele módulo resolve, ou com uma limitação do que já foi construído que o conteúdo virá superar. Não é ornamento motivacional: é o mecanismo pelo qual a sequência do curso se justifica sozinha, já que a disciplina inteira é organizada como uma cadeia de insuficiências superadas. O plano de cada módulo indica qual é essa abertura.

A exposição é intercalada com questões conceituais de múltipla escolha. Os estudantes respondem individualmente, discutem com um colega ao lado e respondem de novo. O segundo voto costuma convergir para a alternativa correta, e o valor da técnica está tanto na convergência quanto no diagnóstico: o professor descobre na hora onde a turma tropeça. As questões são escolhidas para exigir compreensão, não memorização, e o banco de questões do módulo é fonte natural delas. Um erro comum de condução é revelar a resposta certa antes da discussão em duplas, o que anula o efeito.

Sempre que o módulo tiver conteúdo implementável, parte da exposição é feita construindo código ao vivo, com os estudantes acompanhando e reproduzindo em seus próprios ambientes, e o professor verbalizando cada decisão. O artefato assim construído permanece disponível como exemplo resolvido. Essa construção é a peça central da condução da disciplina e o modelo que os grupos espelharão nos seus próprios projetos.

As quatro aulas de tutoria seguem um padrão próprio. A primeira é de planejamento: cada grupo define o que vai construir naquele módulo, como saberá que funcionou e como dividirá o trabalho. As duas intermediárias são de construção e teste. A última é de fechamento, com correções finais, atualização de documentação e registro no diário de atividades. Grupos que pulam o planejamento produzem partes que não se encaixam, e o professor deve resistir à tentação de deixá-los começar a programar antes do acordo.

Durante a tutoria, o trabalho dentro de cada grupo é feito em pares, com revezamento obrigatório de papéis entre quem escreve e quem revisa. A verificação desse revezamento é responsabilidade do professor durante a circulação pelas equipes, e é o principal instrumento contra a concentração do trabalho em um único integrante.

O andaime diminui ao longo do semestre. Nos módulos iniciais, a tarefa vem descrita com detalhe, os critérios de aceitação são fornecidos pelo professor e a tutoria é próxima e frequente. Nos módulos intermediários, o objetivo permanece definido, mas o caminho é escolhido pelo grupo e os critérios de aceitação passam a ser propostos por ele e validados pelo professor. Nos módulos finais, apenas o resultado esperado é enunciado, e a tutoria funciona como revisão crítica. Essa redução é deliberada e precisa ser sustentada mesmo quando os grupos pedirem mais orientação — a capacidade de conduzir uma etapa sem roteiro é um dos resultados perseguidos, e ela não se desenvolve enquanto o roteiro existir.

Módulo 1: Panorama da Compilação e Linguagens Formais

Objetivos do Módulo

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 Serem Desenvolvidas

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 Serem Adquiridas

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.

Conteúdo a Ser Apresentado

O que significa compilar e as distinções entre os programas aparentados. A decomposição clássica em fases, com a separação entre análise e síntese e o argumento de engenharia que a justifica. Panorama da hierarquia de gramáticas e linguagens, com a indicação dos níveis que a disciplina percorrerá. Apresentação do artefato condutor que será construído ao longo do semestre. Organização do ambiente de trabalho e da estrutura de projeto.

O tratamento é panorâmico em todos os tópicos: nada é esgotado, e o critério de sucesso é a capacidade de situar, não de operar.

Tarefas do Projeto Integrador

Formação dos grupos, de dois ou três integrantes, com composição fixa para todo o semestre, e primeira decisão de projeto: o domínio da linguagem que cada grupo construirá. A escolha precisa ser argumentada e demonstrar que o domínio comporta as capacidades mínimas exigidas — símbolos léxicos descritos por padrões, ao menos uma construção aninhada, nomes declarados em um ponto e usados em outro, mais de um tipo de valor com operação restrita a um deles, e efeito observável na execução. O grupo redige dois ou três exemplos da aparência pretendida dos programas antes de qualquer formalização, configura o ambiente sob o modo estrito de compilação e cria o repositório na estrutura exigida.

A validação da proposta acontece neste módulo e a recusa é uma possibilidade real. O critério mais frequente de recusa é o tamanho: especificação que não cabe em duas páginas está grande demais para o prazo. Recusar aqui custa uma sessão; recusar no módulo 8 custa o semestre.

Entrega: repositório estruturado, arquivo de instruções gerais preenchido, documento de proposta com justificativa do domínio e exemplos pretendidos, e evidência de ambiente funcional.

Estratégias Pedagógicas e Pontos de Atenção na Tutoria

A abertura mais eficaz deste módulo é apresentar três programas com defeitos de naturezas distintas — um erro de forma, um erro de sentido e um erro que só se manifesta em execução — e perguntar por que o compilador detecta os dois primeiros e não pode detectar o terceiro. A pergunta antecipa a arquitetura do curso inteiro e costuma gerar discussão produtiva antes de qualquer definição formal.

O ponto de atenção principal da tutoria é o dimensionamento do escopo proposto pelos grupos. A tendência universal é propor algo grande demais, e a correção precisa acontecer aqui, com firmeza. Um critério objetivo de tamanho ajuda mais do que uma recomendação genérica de moderação. Vale também observar a formação dos grupos: composições formadas apenas por afinidade tendem a concentrar competência, e cabe ao professor intervir quando perceber um grupo em que só um integrante programa com autonomia.

Módulo 2: Alfabetos, Linguagens e Expressões Regulares

Objetivos do Módulo

Estabelecer o vocabulário formal sobre o qual toda a primeira metade da disciplina será construída. Levar o estudante da familiaridade prática com expressões regulares à compreensão de sua definição formal e de suas propriedades algébricas. Distinguir a classe das linguagens regulares das notações que apenas se parecem com ela.

Competências a Serem Desenvolvidas

Capacidade de operar com definições formais recursivas, entendendo a semântica de uma notação a partir da estrutura sintática que a produz. Capacidade de reconhecer, numa ferramenta de uso cotidiano, a teoria que a fundamenta e os limites que decorrem dela.

Habilidades a Serem Adquiridas

Manipular cadeias e linguagens com as operações definidas. Ler e escrever expressões regulares com fluência. Demonstrar equivalências simples entre expressões por manipulação algébrica, sem recorrer a autômatos. Identificar, em uma notação de biblioteca, quais construções extrapolam a classe regular.

Conteúdo a Ser Apresentado

Símbolos, alfabetos, cadeias e as operações sobre cadeias, incluindo a cadeia vazia e suas propriedades. Linguagens como conjuntos de cadeias, com as operações de união, concatenação, fecho de Kleene e fecho positivo. Expressões regulares: sintaxe, semântica definida por indução sobre a estrutura, e identidades algébricas. A distinção entre a notação teórica e as notações de biblioteca.

O tratamento é instrumental: espera-se fluência operacional ao final.

Tarefas do Projeto Integrador

Conversão da intuição do módulo anterior em especificação formal. Cada grupo identifica as categorias de símbolos léxicos da própria linguagem e descreve cada uma na notação de expressões regulares, com precisão total — não basta afirmar que a linguagem tem números, é preciso definir exatamente que sequências constituem um número válido, o que ocorre com sinal, parte fracionária e zeros à esquerda.

Produz também, por categoria, o conjunto de cadeias que devem ser aceitas e o das que devem ser rejeitadas, com casos de fronteira escolhidos deliberadamente por serem difíceis. Esse conjunto é o critério de verificação usado do módulo 3 em diante; construí-lo antes de qualquer implementação é o que permitirá saber depois se o que foi construído está correto.

Entrega: documento de especificação léxica completo, com todas as categorias em notação de expressões regulares e os conjuntos de aceitação e rejeição por categoria, com os casos de fronteira identificados como tais. Não há código exigido — avalia-se a precisão da especificação.

Estratégias Pedagógicas e Pontos de Atenção na Tutoria

Dois pontos concentram o erro conceitual e merecem questão de discussão dedicada. O primeiro é o fecho de Kleene do conjunto vazio, que contém a cadeia vazia — resultado que contraria a intuição de praticamente toda a turma e que revela quem entendeu a definição de quem a decorou. O segundo é a diferença entre a linguagem vazia e a linguagem que contém apenas a cadeia vazia.

Na tutoria, o erro sistemático é a especificação frouxa. Grupos escrevem descrições que parecem completas e deixam casos indefinidos — o que acontece com um sinal isolado, com um separador decimal sem dígitos depois, com uma cadeia de tamanho zero. A intervenção mais eficaz não é apontar a falha, e sim pedir que o grupo classifique uma cadeia de fronteira que você escolher: a hesitação revela a indefinição melhor do que qualquer correção. Vale insistir na construção dos conjuntos de teste antes de qualquer código, porque grupos que pulam essa etapa passam os módulos seguintes sem critério de verificação.

Módulo 3: Autômatos Finitos Determinísticos

Objetivos do Módulo

Introduzir o primeiro modelo de máquina do curso e estabelecer a correspondência entre sua definição matemática e a estrutura de dados que a realiza. Desenvolver a habilidade de projetar autômatos a partir da descrição informal de uma linguagem.

Competências a Serem Desenvolvidas

Capacidade de transitar entre a formulação matemática de um modelo e sua implementação, reconhecendo que são a mesma coisa expressa em registros diferentes. Capacidade de escolher representações de dados com base em consequências previstas, e não por hábito.

Habilidades a Serem Adquiridas

Definir formalmente um autômato finito determinístico e explicar o papel de cada componente. Converter entre diagrama de estados e tabela de transição em ambos os sentidos. Projetar o autômato de uma linguagem descrita informalmente, tratando corretamente o estado de erro e a completude da função de transição. Implementar o reconhecimento de cadeias a partir da descrição do autômato.

Conteúdo a Ser Apresentado

Definição formal como quíntupla, com exame do papel de cada componente. Configuração instantânea e extensão da função de transição a cadeias, definida por indução. Linguagem reconhecida. Representação por diagrama e por tabela, e a conversão entre elas. Projeto de autômatos a partir de descrições informais. Implementação do reconhecedor, com discussão das escolhas de representação.

O tratamento é instrumental, com ênfase na correspondência entre definição e estrutura de dados.

Tarefas do Projeto Integrador

Primeiro código do projeto, e deliberadamente manual. Cada grupo escolhe uma categoria léxica da própria especificação, de preferência não trivial, e projeta à mão o autômato determinístico que a reconhece, desenhando o diagrama de estados e derivando dele a tabela de transição. O projeto manual é entregue como documento e é onde se verifica se o modelo foi de fato compreendido.

Em seguida implementa o reconhecedor: um programa que, dada a descrição do autômato e uma cadeia, decide se a cadeia é aceita. A representação da descrição e a organização do reconhecimento são decisões do grupo, discutidas na tutoria — há escolhas melhores e piores, e distinguir umas das outras faz parte do exercício. O reconhecedor é verificado contra o conjunto de cadeias do módulo anterior.

Entrega: documento com diagrama e tabela de transição do autômato projetado à mão, com justificativa das escolhas; código do reconhecedor funcionando; e registro da execução sobre o conjunto de cadeias do módulo 2. Divergências entre o esperado e o obtido devem ser documentadas e compreendidas, não ocultadas.

Estratégias Pedagógicas e Pontos de Atenção na Tutoria

Este é o primeiro módulo com construção de código ao vivo, e convém que ela seja completa: da tabela de transição desenhada no quadro até o reconhecedor rodando, com o professor verbalizando cada decisão de representação e as alternativas descartadas. É o momento em que o padrão de qualidade do semestre é estabelecido por demonstração, e vale tratá-lo como tal.

O erro conceitual mais comum é o estado de erro implícito. Estudantes desenham autômatos incompletos, sem transição para símbolos inesperados, e depois se surpreendem quando a implementação falha. Uma questão de discussão sobre o que acontece quando não há transição definida resolve isso melhor do que a advertência direta.

Na tutoria, o ponto de atenção é a escolha de representação. Grupos que representam estados por referências encadeadas terão dificuldade crescente a partir do módulo 5, quando os autômatos passarem a ser construídos e transformados por algoritmo. A orientação deve ser conduzida por perguntas — como você vai percorrer todos os estados, como vai comparar dois estados, como vai serializar isso — e não por prescrição, porque descobrir a consequência é parte do exercício. Grupos que insistirem em uma escolha ruim devem ser deixados prosseguir, com o problema registrado no diário para retomada posterior.

Módulo 4: Não Determinismo e a Construção de Thompson

Objetivos do Módulo

Introduzir o não determinismo como recurso de especificação e estabelecer sua equivalência com o modelo determinístico. Construir a ponte automática entre a notação de expressões regulares e o modelo de máquina, eliminando a necessidade de projeto manual de autômatos.

Competências a Serem Desenvolvidas

Capacidade de reconhecer, num par de formalismos equivalentes, qual serve melhor a cada finalidade — especificar ou executar — e de projetar sistemas que usem cada um onde é adequado. Capacidade de apreciar construções composicionais e o que elas simplificam.

Habilidades a Serem Adquiridas

Definir autômatos não determinísticos, com e sem transições vazias. Calcular o fecho vazio de um conjunto de estados. Enunciar a equivalência entre os modelos e explicar por que ela não é óbvia. Aplicar a construção de Thompson manualmente e implementá-la sobre a estrutura de uma expressão regular.

Conteúdo a Ser Apresentado

Autômatos não determinísticos com e sem transições vazias, e a motivação para introduzi-los. Fecho vazio e seu algoritmo. Enunciado da equivalência entre os modelos, com o sentido simples demonstrado e o outro adiado para o módulo seguinte. A construção de Thompson operador a operador, com destaque para a composicionalidade dos fragmentos. Implementação da tradução.

O tratamento é instrumental.

Tarefas do Projeto Integrador

O projeto deixa de depender de autômatos desenhados à mão. Cada grupo implementa a tradução automática de uma expressão regular para o autômato não determinístico correspondente, seguindo a construção estudada. Antes disso precisa fazer o programa ler a própria expressão regular e apreender sua estrutura, o que exige construir um pequeno analisador para a notação de expressões regulares que decidir suportar — primeiro momento em que o projeto tem um analisador dentro de si.

O grupo decide e documenta quais operadores da notação sua ferramenta suportará. Não é preciso suportar tudo; é preciso suportar o suficiente para descrever as categorias léxicas já especificadas, e é preciso que a decisão seja consciente.

O autômato não determinístico pode ser executado, acompanhando um conjunto de estados em vez de um só — e é assim que o grupo verifica a tradução, confrontando o autômato gerado com o que foi construído à mão no módulo anterior sobre as mesmas cadeias. O que essa execução não é, é eficiente: ela refaz a cada entrada um trabalho que poderia ser feito uma vez só, e é justamente esse desperdício que o módulo 5 elimina.

Entrega: código que lê expressão regular e produz o autômato não determinístico; documento registrando os operadores suportados e o motivo da escolha; evidência de funcionamento sobre as categorias léxicas da linguagem do grupo.

Estratégias Pedagógicas e Pontos de Atenção na Tutoria

A abertura natural é o desconforto do não determinismo: uma máquina que faz todas as escolhas ao mesmo tempo parece trapaça, e a turma costuma dividir-se sobre se ela é mais poderosa que a determinística. Levantar essa questão antes de responder cria a tensão que o módulo seguinte resolverá, e vale registrar a votação para retomá-la no módulo 5.

A composicionalidade da construção merece ênfase explícita, porque é o que a torna implementável sem casos especiais. Um bom exercício de discussão é perguntar o que quebraria se um fragmento tivesse dois estados finais.

Na tutoria, o ponto de atenção é que os grupos precisam construir um analisador para a notação de expressões regulares antes de traduzi-la, e muitos não percebem isso ao planejar. Vale antecipar a questão na sessão de planejamento, sem entregar a solução — a pergunta “como o seu programa vai saber que o asterisco se aplica só ao último elemento?” costuma bastar. O segundo ponto é o escopo da notação suportada: grupos ambiciosos tentam suportar operadores que não usarão, e a orientação é suportar o mínimo que descreva a própria especificação léxica.

Módulo 5: Determinização e Minimização

Objetivos do Módulo

Completar o caminho da notação até a máquina executável e eficiente. Estabelecer o resultado de unicidade do autômato mínimo e o que ele permite decidir. Dotar o projeto de uma ferramenta de visualização que servirá de instrumento de depuração pelo resto do semestre.

Competências a Serem Desenvolvidas

Capacidade de avaliar um algoritmo pelo comportamento típico e pelo pior caso separadamente, sem confundir os dois. Capacidade de reconhecer, num resultado de unicidade, uma ferramenta de decisão prática e não apenas uma curiosidade teórica.

Habilidades a Serem Adquiridas

Aplicar a construção de subconjuntos manualmente e implementá-la, tratando corretamente as transições vazias. Identificar e eliminar estados inalcançáveis. Distinguir estados equivalentes de estados distinguíveis e aplicar o algoritmo de particionamento. Explicar a unicidade do autômato mínimo e usá-la para decidir equivalência de linguagens. Exportar um autômato para visualização.

Conteúdo a Ser Apresentado

Construção de subconjuntos, com o tratamento das transições vazias e a análise do crescimento exponencial no pior caso contrastado com o comportamento típico. Eliminação de estados inalcançáveis. Equivalência e distinguibilidade de estados. Minimização por particionamento, com menção ao refinamento de complexidade menor e sua análise. Unicidade do autômato mínimo e suas consequências. Exportação para formato de visualização.

O tratamento é instrumental para a determinização e para a minimização por particionamento, e conceitual para o algoritmo de menor complexidade.

Tarefas do Projeto Integrador

Fechamento do motor de reconhecimento de padrões. Cada grupo implementa, encadeadas, a conversão do autômato não determinístico em determinístico com tratamento correto das transições vazias, a minimização até o menor autômato equivalente, e a exportação para formato de visualização gráfica.

A exportação parece acessória e não é: a partir daqui, diante de um reconhecimento incorreto, a diferença entre um grupo que visualiza o autômato e um que não visualiza é a diferença entre depurar em uma tarde e depurar em uma semana.

Cada grupo mede e registra o número de estados nas três etapas — não determinístico, determinístico e mínimo — para cada categoria léxica. Esses números são a evidência concreta do crescimento discutido em aula e serão retomados na apresentação final.

Entrega: ferramenta completa convertendo expressão regular em autômato determinístico mínimo; exportação visual funcionando, com os diagramas salvos; tabela de contagem de estados nas três etapas por categoria; e verificação de que o autômato mínimo aceita e rejeita exatamente o mesmo que o reconhecedor manual do módulo 3.

Estratégias Pedagógicas e Pontos de Atenção na Tutoria

Retomar a votação do módulo anterior sobre o poder do não determinismo é a abertura mais econômica: o algoritmo deste módulo é a resposta, e apresentá-lo como resolução de uma pergunta já formulada pela turma economiza a motivação.

A honestidade sobre o pior caso importa. Apresentar o crescimento exponencial, exibir uma família de linguagens que o exibe, e em seguida explicar por que ele raramente aparece em expressões regulares reais, é mais formativo do que omitir a questão ou dramatizá-la.

A noção de estados distinguíveis é o ponto de maior dificuldade conceitual do módulo e merece a questão de discussão mais elaborada. A intuição errada frequente é que estados com o mesmo conjunto de transições de saída são equivalentes.

Na tutoria, dois pontos. O primeiro é que a exportação para visualização será tratada como acessória pelos grupos apressados, e não é: a partir daqui ela é o principal instrumento de depuração, e vale exigi-la funcionando antes de aceitar a entrega. O segundo é a verificação de equivalência entre o autômato mínimo e o reconhecedor construído manualmente no módulo 3 — é a primeira vez que o projeto tem uma verificação cruzada real, e grupos que a executam encontram defeitos que os testes diretos não revelaram.

Módulo 6: Limites das Linguagens Regulares

Objetivos do Módulo

Estabelecer a fronteira da classe regular e desenvolver a capacidade de demonstrar que uma linguagem está fora dela. Conectar o resultado teórico a uma limitação concreta e observável do artefato construído, produzindo a motivação para o modelo mais forte do bloco seguinte.

Competências a Serem Desenvolvidas

Capacidade de conduzir uma demonstração formal com estrutura lógica correta, entendendo que uma prova incompleta não prova nada. Capacidade de reconhecer, ao encontrar um obstáculo de implementação, quando ele decorre de uma limitação teórica do modelo adotado e não de erro de programação — distinção que separa quem insiste inutilmente de quem troca de abordagem.

Habilidades a Serem Adquiridas

Enunciar e aplicar as propriedades de fechamento da classe regular, com as construções que as demonstram. Enunciar o lema do bombeamento com a ordem correta dos quantificadores. Produzir uma demonstração completa de não regularidade na forma contrapositiva. Reconhecer, em uma linguagem, os indícios que sugerem não regularidade.

Conteúdo a Ser Apresentado

Propriedades de fechamento sob união, concatenação, fecho, complemento e interseção, com as construções correspondentes e seu uso como ferramenta de prova. O lema do bombeamento, apresentado primeiro pela intuição do estado repetido e depois no enunciado formal, com atenção à alternância de quantificadores. Uso na forma contrapositiva, com a metáfora do jogo entre adversários. Aplicação a exemplos canônicos. Caracterização alternativa por classes de equivalência, em tratamento conceitual. Demonstração prática da falha do artefato construído diante de uma construção aninhada.

O tratamento é conceitual com exigência de demonstração.

Tarefas do Projeto Integrador

Módulo de demonstração matemática combinada com experimento. Na parte formal, cada grupo identifica dentro da própria linguagem alguma construção não regular — tipicamente a construção aninhada exigida no contrato de capacidades — e demonstra rigorosamente que autômato finito algum a reconhece, seguindo a técnica estudada, com todos os passos explícitos. Demonstrações incompletas ou com a ordem dos quantificadores trocada retornam para correção.

Na parte experimental, o grupo confronta a ferramenta do módulo 5 com essa construção: escreve a expressão regular que tentaria usar, observa o comportamento e documenta exatamente como e por que falha. A articulação entre as duas partes é o que se avalia — o experimento sozinho é anedota, a prova sozinha é abstração.

O documento fecha explicitando a consequência para o projeto: que parte da linguagem exigirá mecanismo mais forte e onde ele entrará.

Entrega: documento com a demonstração formal, o registro do experimento, a articulação entre ambos e a conclusão sobre os módulos seguintes, acompanhado do código usado no experimento.

Estratégias Pedagógicas e Pontos de Atenção na Tutoria

Este módulo tem a melhor abertura possível disponível no semestre e vale usá-la: pedir à turma que escreva uma expressão regular para parênteses balanceados, deixar que tentem, e deixar que descubram sozinhos que conseguem para dois níveis, para três, e nunca para todos. A frustração produzida é exatamente a motivação do conteúdo.

O erro dominante nas demonstrações é a inversão da ordem dos quantificadores — o estudante escolhe a decomposição em vez de deixá-la ao adversário. Vale apresentar uma demonstração errada e pedir que a turma encontre o defeito, técnica mais eficaz do que apresentar apenas demonstrações corretas. A metáfora do jogo, com o professor assumindo o papel do adversário no quadro, torna a estrutura lógica tangível.

Na tutoria, o ponto de atenção é que este é um módulo de escrita, e grupos acostumados a programar tendem a subestimá-lo, produzindo demonstrações apressadas. O critério de correção precisa ser explícito e rigoroso desde o início, e demonstrações incompletas devem retornar para correção — aceitar uma prova “quase certa” aqui compromete o padrão de rigor pelo resto do semestre. O segundo ponto é a articulação entre a prova e o experimento: grupos entregam as duas partes desconectadas, e é a conexão que se avalia.

Módulo 7: Análise Léxica

Objetivos do Módulo

Consolidar todo o eixo regular em uma fase de compilador funcionando. Introduzir as decisões práticas que a teoria não menciona e que constituem a maior parte do esforço de um analisador léxico real. Estabelecer a qualidade do relato de erro como critério permanente.

Competências a Serem Desenvolvidas

Capacidade de transformar um componente teórico em uma peça de software com interface definida, tratamento de casos excepcionais e comportamento previsível diante de entrada malformada. Capacidade de avaliar uma ferramenta automática a partir do conhecimento do que ela implementa.

Habilidades a Serem Adquiridas

Distinguir padrão, lexema, símbolo léxico e atributo. Aplicar as regras de casamento mais longo e de prioridade entre padrões. Tratar espaços, comentários e fim de entrada. Detectar erros léxicos e produzir mensagens que indiquem posição e causa provável. Explicar o que um gerador automático de analisadores léxicos faz e quando usá-lo.

Conteúdo a Ser Apresentado

O papel do analisador léxico no front-end e sua interface sob demanda com a fase seguinte. Os quatro conceitos que se confundem: padrão, lexema, símbolo e atributo. Regra do casamento mais longo e regra de prioridade, com o caso das palavras reservadas e as duas estratégias de tratá-lo. Espaços, comentários com e sem aninhamento, fim de entrada. Detecção e recuperação de erros léxicos. Buffers de entrada e o efeito do retrocesso. Geradores automáticos, apresentados em termos do que fazem e da relação com a construção manual estudada.

O tratamento é instrumental e integrador; os geradores recebem tratamento conceitual.

Tarefas do Projeto Integrador

Marco de consolidação. Tudo o que foi construído desde o módulo 2 se integra numa peça com nome próprio, e os grupos passam a ter a primeira fase de um compilador funcionando.

Cada grupo constrói o analisador léxico completo da própria linguagem: componente que recebe o texto de um programa e produz a sequência de símbolos léxicos, reutilizando o motor de autômatos já pronto. Todas as decisões práticas estudadas precisam aparecer — desempate entre padrões que casam a mesma entrada, tratamento de espaços e comentários, detecção do fim da entrada, e mensagens de erro que informem posição e causa provável.

A qualidade das mensagens de erro passa a ser critério explícito de avaliação a partir deste módulo.

Entrega consolidada: analisador léxico completo funcionando sobre programas de exemplo reais; casos de teste cobrindo todas as categorias e os casos de erro; documentação revisada de tudo o que foi produzido do módulo 1 ao 7, incluindo a especificação léxica atualizada; diário de atividades em dia; e avaliação por pares preenchida por cada integrante. Esta entrega é avaliada com o mesmo rigor da entrega final.

Estratégias Pedagógicas e Pontos de Atenção na Tutoria

A apresentação dos geradores automáticos deve vir ao final e não ao início, e a razão precisa ser dita à turma explicitamente: quem implementou a determinização entende o que a ferramenta faz, quem não implementou apenas a utiliza. Apresentá-los antes esvazia os cinco módulos anteriores.

A distinção entre padrão, lexema, símbolo e atributo é fonte constante de confusão terminológica e vale uma questão de discussão dedicada, com exemplos em que os quatro aparecem simultaneamente.

Na tutoria, este é um marco de consolidação e a carga é maior do que a de um módulo comum. Vale reservar a primeira sessão inteira para o levantamento do que está pendente desde o módulo 1, porque grupos chegam aqui com documentação atrasada e testes não escritos, e a entrega consolidada exige tudo em dia. O ponto de atenção técnico é a interface entre o analisador léxico e a fase seguinte: grupos que a definem mal terão retrabalho no módulo 10, e vale exigir que a interface seja explicitada e justificada antes da implementação. É também nesta entrega que ocorre a primeira avaliação por pares, e convém explicar seu propósito antes de aplicá-la, para que não seja lida como delação.

Módulo 8: Gramáticas Livres de Contexto

Objetivos do Módulo

Introduzir o formalismo que descreve estruturas aninhadas e estabelecer a ambiguidade como problema central do projeto de linguagens. Desenvolver a capacidade de escrever e transformar gramáticas.

Competências a Serem Desenvolvidas

Capacidade de especificar formalmente a estrutura de uma linguagem e de avaliar criticamente uma especificação quanto a ambiguidade. Capacidade de reconhecer, num formalismo, a origem de propriedades desejáveis do artefato que dele decorre.

Habilidades a Serem Adquiridas

Definir formalmente uma gramática livre de contexto. Distinguir derivações mais à esquerda e mais à direita e relacioná-las à árvore de derivação. Identificar ambiguidade e eliminá-la por estratificação de precedência e escolha do lado da recursão. Simplificar gramáticas removendo símbolos inúteis e produções vazias e unitárias.

Conteúdo a Ser Apresentado

Definição formal e o significado do nome do formalismo. Derivações e árvores de derivação, com a relação precisa entre elas. Ambiguidade: definição, por que é inaceitável em linguagens de programação, e as técnicas de eliminação, com os dois exemplos clássicos. Ambiguidade inerente e indecidibilidade da ambiguidade, em tratamento conceitual. Simplificação de gramáticas. Formas normais, apresentadas pelo que garantem.

O tratamento é instrumental para escrita, transformação e desambiguação, e conceitual para as formas normais e os resultados de indecidibilidade.

Tarefas do Projeto Integrador

Os grupos passam a descrever não mais as palavras da linguagem, mas a forma como se combinam. Escrevem a gramática completa da própria linguagem no formalismo estudado. Ela precisa ser não ambígua, e o grupo precisa argumentar por que é — argumento que, em gramáticas pequenas, normalmente passa pela estratificação de precedência e associatividade dos operadores. Havendo operadores de precedências distintas, a estratificação é exigida e verificada.

O grupo produz também, para pelo menos três programas de exemplo, a árvore de derivação completa. O exercício revela erros que a leitura não revela, e é frequente que ambiguidades apareçam justamente ao tentar desenhar a segunda árvore de um mesmo programa.

É neste módulo que muitos grupos percebem que a linguagem projetada é maior do que conseguirão implementar. Reduzir escopo aqui custa uma sessão de tutoria; perceber isso no módulo 13 custa o semestre.

Entrega: gramática completa com todas as produções, argumento de não ambiguidade e justificativa das escolhas de precedência e associatividade; árvores de derivação de ao menos três exemplos; e, havendo redução de escopo, o registro da mudança e do motivo.

Estratégias Pedagógicas e Pontos de Atenção na Tutoria

A abertura eficaz é exibir uma expressão aritmética simples e duas árvores distintas para ela, com dois resultados numéricos diferentes, perguntando qual está certa. A resposta — que a gramática não permite decidir — comunica o problema da ambiguidade melhor que qualquer definição.

O reconhecimento de que a notação de gramáticas é a mesma que aparece nos manuais das linguagens que os estudantes já usam costuma produzir um momento de reconhecimento útil, e vale provocá-lo.

Na tutoria, este é o módulo em que muitos grupos descobrem que a linguagem que projetaram é grande demais. Essa descoberta é saudável e deve ser facilitada, não amortecida: a pergunta “quantas produções sua gramática tem, e você consegue escrever um analisador para cada uma nas quatro sessões do módulo 10?” costuma provocá-la no momento certo. Redução de escopo aqui deve ser registrada e não penalizada. O segundo ponto de atenção é o desenho das árvores de derivação, que grupos tendem a considerar burocracia — é justamente ao desenhar a segunda árvore de um mesmo programa que ambiguidades escondidas aparecem, e vale exigir o exercício.

Módulo 9: Autômatos de Pilha

Objetivos do Módulo

Apresentar o modelo de máquina correspondente às gramáticas livres de contexto e estabelecer a equivalência entre os dois formalismos. Introduzir o resultado que distingue este nível do anterior — a não equivalência entre determinismo e não determinismo — e suas consequências para a prática da análise sintática.

Competências a Serem Desenvolvidas

Capacidade de reconhecer que uma propriedade válida num nível de abstração não se transfere automaticamente para outro. Capacidade de compreender por que uma restrição teórica se traduz em uma escolha de engenharia, e de aceitar limitações de método com base em razão e não em convenção.

Habilidades a Serem Adquiridas

Definir formalmente o autômato de pilha e suas duas convenções de aceitação. Traduzir uma gramática para o autômato de pilha correspondente. Traçar manualmente o reconhecimento de uma cadeia, acompanhando a evolução da pilha. Explicar por que o determinismo restringe a classe reconhecida neste nível e o que isso implica para a análise sintática prática.

Conteúdo a Ser Apresentado

Definição formal com alfabeto de pilha e transições que consultam estado, entrada e topo. As duas convenções de aceitação e sua equivalência. Equivalência entre gramáticas livres de contexto e autômatos de pilha, com as construções nos dois sentidos, com ênfase na que parte da gramática por prefigurar o analisador do módulo seguinte. Não equivalência entre determinismo e não determinismo, e suas consequências. Lema do bombeamento para este nível e propriedades de fechamento da classe, incluindo as que não valem. Retomada da hierarquia e panorama dos níveis restantes.

O tratamento é conceitual, com formalização rigorosa e sem implementação do modelo abstrato.

Tarefas do Projeto Integrador

Módulo sem tarefa de implementação. O conteúdo é o modelo formal correspondente às gramáticas do módulo anterior, e sua realização concreta no projeto é o analisador sintático do módulo 10. A entrega deste módulo é teórica.

Cada grupo produz um documento de fundamentação conectando a gramática escrita no módulo 8 ao modelo de máquina estudado: explica como a gramática se traduziria em um autômato de pilha, seguindo a construção vista em aula, e ilustra com o traçado manual do reconhecimento de um programa curto da própria linguagem, mostrando o conteúdo da pilha a cada passo. O traçado é feito à mão, em tabela, e é o exercício que torna o módulo seguinte compreensível em vez de mágico.

O grupo discute ainda por que a análise sintática prática se restringe a subclasses determinísticas e o que isso implica para as escolhas do módulo 10.

As sessões de tutoria são usadas para saldar dívidas acumuladas — casos de erro sem tratamento, documentação atrasada, testes nunca escritos — e para preparar o módulo mais denso do semestre.

Entrega: documento de fundamentação com a tradução para o modelo de pilha, o traçado manual passo a passo, a discussão sobre determinismo, e o registro das pendências saldadas.

Estratégias Pedagógicas e Pontos de Atenção na Tutoria

A construção que parte da gramática merece tempo desproporcional à sua dificuldade, porque quem a entende chega ao módulo 10 já compreendendo o analisador descendente. Vale conduzi-la no quadro com um traçado completo, passo a passo, sobre uma cadeia curta.

A não equivalência entre determinismo e não determinismo é o resultado mais surpreendente do módulo e contradiz a intuição formada no módulo 5. Retomar explicitamente o contraste é o que fixa os dois resultados.

Na tutoria, este é o primeiro dos dois módulos sem tarefa de implementação, e o risco é que os grupos o tratem como folga. Vale ser explícito quanto ao contrário: as quatro sessões destinam-se a saldar dívidas antes do módulo mais denso do semestre, e o professor deve chegar à primeira sessão com o levantamento das pendências de cada grupo em mãos, feito a partir das entregas anteriores. Grupos sem pendências devem usar o tempo para o traçado manual exigido e para antecipar a preparação da gramática do módulo 10.

Módulo 10: Análise Sintática Descendente

Objetivos do Módulo

Converter o modelo abstrato do módulo anterior em um analisador real e completar o front-end. Estabelecer a leitura de conflitos como instrumento de diagnóstico de gramáticas. Introduzir a recuperação de erros e o critério de qualidade que a orienta.

Competências a Serem Desenvolvidas

Capacidade de preparar uma especificação para atender às restrições de um método, preservando o que ela especifica. Capacidade de ler um conflito de análise como informação sobre a gramática, e não como falha da ferramenta. Capacidade de projetar comportamento diante de entrada malformada, tratando a qualidade do diagnóstico como requisito.

Habilidades a Serem Adquiridas

Eliminar recursão à esquerda nos casos imediato e indireto, e aplicar fatoração. Calcular os conjuntos de primeiros e de seguidores, incluindo o tratamento das variáveis que derivam a cadeia vazia. Construir a tabela de análise e interpretar seus conflitos. Implementar um analisador por descida recursiva. Construir a árvore sintática abstrata, distinguindo-a da árvore de derivação concreta. Implementar recuperação de erros.

Conteúdo a Ser Apresentado

A análise sintática como construção da árvore de derivação, e a estratégia descendente como derivação mais à esquerda guiada pela entrada. Preparação da gramática: eliminação de recursão à esquerda e fatoração. Conjuntos de primeiros e de seguidores, com os algoritmos de cálculo. A condição que caracteriza as gramáticas tratáveis e a construção da tabela. Leitura dos conflitos como diagnóstico. Analisador recursivo e analisador dirigido por tabela, com a comparação entre as duas realizações. Recuperação de erros em modo pânico e em nível de frase, com o critério de qualidade. Construção da árvore sintática abstrata.

O tratamento é instrumental e aprofundado — é o módulo de maior exigência do eixo sintático.

Tarefas do Projeto Integrador

Módulo mais pesado do semestre e segundo marco de consolidação. Ao final dele, os grupos têm o front-end completo: um programa que lê texto e produz estrutura.

O trabalho começa pela preparação da gramática, que provavelmente não está na forma exigida pelo método. O grupo elimina recursão à esquerda, aplica fatoração onde necessário, documenta cada transformação e verifica que a linguagem gerada não mudou. Calcula então os conjuntos que orientam as decisões do analisador e verifica a condição estudada. Havendo conflito, ele precisa ser interpretado e resolvido — e a interpretação vale mais, na avaliação, do que a solução.

Implementa o analisador por descida recursiva e produz a estrutura em árvore que representa o programa, distinta da árvore de derivação concreta, contendo apenas o que as fases seguintes usarão. Decidir o que entra e o que sai dessa estrutura é decisão de projeto relevante.

O analisador precisa recuperar-se de erros sintáticos e prosseguir. Reportar um erro real seguido de vinte inventados é pior do que reportar apenas o primeiro.

Entrega consolidada: gramática transformada com registro de cada transformação e verificação de equivalência; conjuntos calculados apresentados em tabela; analisador funcionando e produzindo a árvore; recuperação de erros com exemplos de programas malformados e as mensagens produzidas; front-end demonstrado ponta a ponta.

Estratégias Pedagógicas e Pontos de Atenção na Tutoria

A correspondência entre a estrutura do código do analisador recursivo e a estrutura da gramática é o ativo didático central do módulo e deve ser explorada na construção ao vivo: escrever a gramática de um lado do quadro e o código do outro, produção a produção, torna a relação evidente de um modo que a descrição verbal não alcança.

O cálculo dos conjuntos é o ponto de erro sistemático, especialmente na presença de variáveis que derivam a cadeia vazia. Vale um exercício de cálculo conduzido coletivamente antes de qualquer implementação.

Na tutoria, este é o módulo mais pesado e o segundo marco. Três pontos de atenção. O primeiro é que a preparação da gramática precisa vir antes da implementação, e grupos ansiosos tentam programar sobre uma gramática com recursão à esquerda, produzindo recursão infinita que consome uma sessão inteira de depuração — a verificação da forma da gramática deve ser condição para começar a codificar. O segundo é a definição da árvore sintática abstrata: decidir o que ela carrega é decisão de projeto com consequências nos módulos 12 a 14, e merece discussão explícita na sessão de planejamento. O terceiro é a recuperação de erros, que grupos deixam por último e acabam não fazendo; vale tratá-la como parte do escopo mínimo e não como refinamento.

Módulo 11: Análise Sintática Ascendente

Objetivos do Módulo

Apresentar a família de métodos dominante nos compiladores de produção e desenvolver a capacidade de escolher entre as duas famílias com base em critérios técnicos. Habilitar a leitura de relatórios de conflito produzidos por ferramentas automáticas.

Competências a Serem Desenvolvidas

Capacidade de avaliar alternativas técnicas por poder, custo e adequação ao contexto, em vez de por preferência ou familiaridade. Capacidade de operar uma ferramenta cujo funcionamento interno se compreende, interpretando seus diagnósticos em termos da especificação fornecida.

Habilidades a Serem Adquiridas

Explicar a estratégia ascendente em termos de deslocamento, redução e alça. Construir manualmente a tabela de análise para uma gramática pequena. Identificar e classificar conflitos de deslocamento-redução e de redução-redução, e explicar sua origem. Comparar as duas famílias quanto a poder, legibilidade, qualidade de diagnóstico e manutenção. Interpretar o relatório de conflitos de um gerador.

Conteúdo a Ser Apresentado

A estratégia ascendente como redução ao símbolo inicial, com as operações e o papel da pilha, contrastado com o método anterior. Itens, autômato de itens e conjunto canônico. Os métodos da família como escala crescente de poder e custo, com a explicação de qual conflito cada nível resolve. Conflitos, sua leitura e as estratégias de resolução, incluindo declarações de precedência e o caso clássico do condicional sem alternativa obrigatória. Comparação fundamentada entre as famílias. Geradores de analisadores e a leitura de seus relatórios.

O tratamento é conceitual, com exercício de traçado manual e sem implementação de gerador.

Tarefas do Projeto Integrador

Módulo sem tarefa de implementação. O método estudado aqui é o que a maioria dos compiladores de produção usa, mas o projeto segue deliberadamente o caminho do módulo anterior. A entrega deste módulo é um estudo.

Cada grupo toma um recorte pequeno da própria gramática — três ou quatro produções, escolhidas por conterem algum ponto de decisão interessante — e constrói manualmente, com lápis e papel, a tabela de análise ascendente correspondente. Havendo conflitos, identifica, classifica e explica cada um.

Sobre essa base concreta escreve a análise comparativa: o que o método ascendente resolveria melhor no caso daquela gramática, o que custaria mais, e qual teria sido a escolha se o projeto não tivesse a restrição pedagógica de construir tudo à mão. A comparação precisa ser específica à gramática do grupo; afirmações que valeriam para qualquer projeto não demonstram entendimento.

As sessões de tutoria são usadas para revisar o front-end à luz do que vem adiante e para planejar o terceiro bloco, cujas fases dependem umas das outras de forma mais rígida que as anteriores.

Entrega: estudo comparativo com a tabela construída à mão, a explicação dos conflitos encontrados e a análise específica ao caso do grupo; mais o plano para os módulos 12 a 15, com a divisão prevista do trabalho.

Estratégias Pedagógicas e Pontos de Atenção na Tutoria

A inversão do papel da pilha em relação ao método anterior — aqui ela guarda o que já foi reconhecido, lá guardava o que faltava reconhecer — é o eixo de compreensão do módulo e deve ser explicitada cedo, de preferência com os dois traçados lado a lado sobre a mesma cadeia.

A escala dos quatro métodos deve ser apresentada como progressão motivada, e não como catálogo: para cada nível, mostrar o conflito concreto que o nível anterior não resolvia. O que se espera que fique é a progressão, não as tabelas.

Na tutoria, o segundo e último módulo sem implementação. O risco aqui é o oposto do módulo 9: grupos tratam o estudo comparativo como redação genérica, produzindo texto que valeria para qualquer projeto. A exigência de que a comparação parta da tabela construída à mão sobre a própria gramática é o que impede isso, e a tabela deve ser verificada antes do texto. As sessões restantes destinam-se ao planejamento do terceiro bloco, cujas fases são mais acopladas que as anteriores — vale exigir de cada grupo um plano escrito para os módulos 12 a 15, com divisão de trabalho, e discuti-lo.

Módulo 12: Análise Semântica

Objetivos do Módulo

Estabelecer o que a gramática não captura e por que. Introduzir a tabela de símbolos e a tradução dirigida por sintaxe como o arcabouço da fase. Desenvolver a verificação de tipos como aplicação concreta.

Competências a Serem Desenvolvidas

Capacidade de identificar os limites de um formalismo e de escolher o mecanismo adequado ao que está fora deles. Capacidade de projetar estruturas de dados a partir do padrão de uso previsto, e não da estrutura conceitual do problema.

Habilidades a Serem Adquiridas

Distinguir correção sintática de correção semântica com exemplos. Projetar e implementar uma tabela de símbolos com tratamento de escopos aninhados. Especificar traduções com atributos sintetizados e herdados, e determinar a ordem de avaliação a partir das dependências. Implementar verificações de declaração e de compatibilidade de tipos. Produzir diagnósticos semânticos informativos e prosseguir após o primeiro erro.

Conteúdo a Ser Apresentado

Correção sintática versus semântica, com exemplos de programas bem formados e sem sentido, e o argumento de por que essas verificações não cabem na gramática. Tabela de símbolos: informação armazenada, estruturas adequadas ao padrão de consulta, operações. Escopos aninhados e regras de visibilidade, com as duas estratégias de implementação e seu compromisso. Tradução dirigida por sintaxe: atributos sintetizados e herdados, gramáticas de atributos, esquemas de tradução, ordem de avaliação e dependências. Verificação de tipos: sistema de tipos, regras de inferência, equivalência estrutural e por nome, conversões implícitas. Percursos sobre a árvore como organização das verificações.

O tratamento é instrumental para tabela de símbolos e verificações, e conceitual aprofundado para gramáticas de atributos.

Tarefas do Projeto Integrador

O compilador passa a verificar não apenas se o programa está bem formado, mas se faz sentido. Cada grupo constrói a tabela de símbolos da própria linguagem e implementa as verificações exigidas pelo contrato de capacidades: detectar o uso de nome não declarado e detectar a aplicação de operação a valor de tipo incompatível. Havendo escopos aninhados na linguagem, a tabela precisa tratá-los; não havendo, o grupo registra e justifica essa característica.

As verificações são organizadas como percursos sobre a estrutura em árvore produzida no módulo 10. Que informação cada percurso coleta, quantos percursos são necessários e em que ordem ocorrem são decisões do grupo, discutidas na tutoria.

A qualidade do relato de erro continua sendo avaliada: um erro semântico bem reportado indica o nome envolvido, o ponto do programa e a natureza do problema. O compilador deve prosseguir após o primeiro erro semântico, reportando os demais.

Entrega: tabela de símbolos com tratamento de escopo adequado à linguagem; verificações de declaração e de compatibilidade funcionando; programas de exemplo com erros semânticos deliberados, acompanhados das mensagens produzidas; e documento com as decisões sobre a organização dos percursos.

Estratégias Pedagógicas e Pontos de Atenção na Tutoria

A abertura mais direta é um programa sintaticamente impecável e semanticamente absurdo, seguido da pergunta de por que a gramática não o rejeita. A resposta — que gramáticas livres de contexto não conseguem exprimir a correspondência entre declaração e uso à distância — conecta o módulo ao resultado teórico do módulo 9 e vale ser feita explicitamente.

A distinção entre atributos sintetizados e herdados é abstrata e melhora muito com um exemplo em que ambos aparecem na mesma árvore, com as setas de dependência desenhadas.

Na tutoria, o ponto de atenção é a organização dos percursos. Grupos tendem a tentar fazer todas as verificações em um único percurso e travam quando descobrem que uma delas depende de informação que só existe depois. Conduzir por pergunta — que informação você precisa ter coletado antes de poder verificar isto? — costuma levar o grupo à decomposição correta sem entregá-la. O segundo ponto é a qualidade da mensagem de erro, que agora tem informação suficiente para ser boa: um diagnóstico semântico que nomeia o identificador envolvido e o ponto do programa é padrão exigível a partir deste módulo.

Módulo 13: Representações Intermediárias e Ambientes de Execução

Objetivos do Módulo

Estabelecer a camada intermediária entre análise e síntese e o argumento de engenharia que a justifica. Apresentar a organização da memória do programa em execução e o que o compilador precisa emitir para sustentá-la. Produzir a especificação do formato de saída do compilador.

Competências a Serem Desenvolvidas

Capacidade de reconhecer, numa decisão de arquitetura, o ganho combinatório que justifica uma camada de indireção. Capacidade de redigir uma especificação técnica completa o bastante para permitir implementação independente — critério de qualidade documental que se aplica muito além desta disciplina.

Habilidades a Serem Adquiridas

Justificar a existência de uma representação intermediária. Comparar as formas usuais quanto ao que facilitam. Traduzir expressões, condicionais e laços para código de três endereços, tratando rótulos e desvios. Descrever a organização da memória em execução e a composição de um registro de ativação. Explicar o protocolo de chamada e retorno e a divisão de responsabilidades entre chamador e chamado. Especificar formalmente um formato de programa objeto e um modelo de execução.

Conteúdo a Ser Apresentado

Justificativa da representação intermediária, com o argumento de reaproveitamento entre origens e destinos. Formas usuais: árvore sintática abstrata, notação pós-fixada, código de três endereços com suas variantes, e menção à forma de atribuição única estática. Tradução das construções usuais, com rótulos, desvios e o preenchimento de endereços ainda desconhecidos. Ambientes de execução: divisão da memória, registros de ativação, protocolo de chamada e retorno, escopo em tempo de execução, cadeias de acesso e de controle. Gerência de memória, com alocação explícita e panorama da coleta automática.

O tratamento é instrumental para as representações efetivamente usadas e conceitual para registros de ativação e coleta automática.

Tarefas do Projeto Integrador

Módulo de projeto no sentido mais literal: quase todo o trabalho é decidir e documentar, e o código resulta dessas decisões.

Cada grupo define a representação intermediária que o compilador usará entre a análise e a geração de código, justificando a escolha à luz das alternativas estudadas e das características da própria linguagem. Especifica então o formato do programa objeto que o compilador produzirá e o modelo de execução que o interpretará — o que o objeto contém, como se organiza, e o que acontece quando é executado.

Essa especificação é um documento formal e precisa ser completa o bastante para que outra pessoa, lendo apenas ela, escreva um executor compatível. Esse critério é o teste de qualidade da entrega e deve ser aplicado literalmente na correção: ler procurando pelo que falta.

A implementação do módulo é a tradução da estrutura em árvore verificada para a representação intermediária escolhida. A geração do objeto vem no módulo seguinte.

Entrega: especificação do formato do objeto e do modelo de execução, completa o bastante para implementação independente; documento justificando a representação intermediária escolhida; e a tradução para essa representação implementada e demonstrada sobre programas de exemplo.

Estratégias Pedagógicas e Pontos de Atenção na Tutoria

O argumento combinatório a favor da representação intermediária é imediato e convincente quando apresentado com números: suportar cinco origens e cinco destinos custa dez peças com a camada intermediária e vinte e cinco sem ela. Vale abrir por aí.

Os registros de ativação recebem tratamento conceitual porque o artefato da disciplina normalmente não tem procedimentos definidos pelo usuário, mas o conteúdo não deve ser omitido: é o repertório que o estudante precisará ao ler sobre qualquer linguagem real, e a conexão com a disciplina de arquitetura de computadores já cursada é produtiva.

Na tutoria, o ponto de atenção é a qualidade da especificação, que é o principal entregável do módulo. O critério de completude deve ser anunciado antes e aplicado literalmente na correção: outra pessoa consegue escrever um executor compatível lendo apenas este documento? Uma dinâmica eficaz é a troca de especificações entre grupos, com cada um apontando o que não conseguiria implementar a partir do texto do outro. O segundo ponto é que grupos tendem a especificar o formato depois de implementá-lo, invertendo a ordem; vale exigir a especificação aprovada antes do código.

Módulo 14: Geração de Código

Objetivos do Módulo

Completar a síntese, produzindo saída concreta a partir da representação intermediária. Apresentar os subproblemas clássicos da geração de código e o modelo de máquina de destino adotado. Evidenciar o reencontro entre o conteúdo do primeiro bloco e o produto final do compilador.

Competências a Serem Desenvolvidas

Capacidade de reconhecer, num problema de otimização com subproblemas interdependentes, por que a decomposição é necessária apesar de subótima. Capacidade de projetar um conjunto de instruções adequado a um propósito, avaliando o compromisso entre simplicidade de geração e eficiência de execução.

Habilidades a Serem Adquiridas

Enunciar os três subproblemas da geração de código e explicar sua interdependência. Comparar máquinas de pilha e de registradores quanto ao que facilitam. Projetar um conjunto de instruções para uma máquina abstrata de pilha. Gerar código por percurso sobre a árvore, tratando expressões aninhadas e curto-circuito em operadores lógicos. Explicar a alocação de registradores pelo modelo de coloração. Resolver referências pendentes.

Conteúdo a Ser Apresentado

O problema da geração de código e seus três subproblemas: seleção de instruções, alocação de registradores e ordenação da avaliação, com a discussão de sua interdependência. Máquinas de pilha e de registradores como modelos de destino. Projeto do conjunto de instruções da máquina abstrata adotada. Geração por percurso sobre a árvore, com expressões aninhadas e avaliação com curto-circuito, que exige emissão de desvios. Alocação de registradores pelo modelo de coloração de grafo de interferência, em tratamento conceitual. Endereçamento e resolução de referências.

O tratamento é instrumental para a máquina de pilha e conceitual para alocação de registradores e arquiteturas reais.

Tarefas do Projeto Integrador

O compilador começa a produzir saída. Passa a existir um artefato que não é mais estrutura interna, e sim um arquivo representando o programa traduzido.

Cada grupo implementa o gerador que percorre a representação intermediária e emite o programa objeto no formato especificado no módulo anterior. Havendo operadores lógicos na linguagem, a avaliação com curto-circuito precisa ser tratada, o que exige emissão de desvios e não apenas de operações — é o ponto do módulo em que a maioria dos grupos encontra dificuldade, e convém antecipá-lo na tutoria.

O grupo implementa também um executor mínimo, capaz de rodar o objeto sobre uma entrada simples e produzir o efeito observável exigido pelo contrato de capacidades. Mínimo significa suficiente para demonstrar que o objeto está correto; o executor completo é assunto do módulo 15.

Para grupos cuja linguagem envolva reconhecimento de padrões, é aqui que os autômatos do primeiro bloco reaparecem dentro do arquivo gerado — evidência direta da unidade da disciplina, que vale documentar explicitamente na entrega.

Entrega: gerador funcionando e produzindo o objeto no formato especificado; executor mínimo rodando o objeto; ao menos três programas compilados e executados, com entrada e saída registradas; e os objetos gerados salvos para inspeção.

Estratégias Pedagógicas e Pontos de Atenção na Tutoria

Este é o módulo em que o material do primeiro bloco reaparece dentro do produto final do compilador, e a observação merece ser feita explicitamente em aula: os autômatos estudados em fevereiro estão dentro do arquivo gerado. É o fechamento conceitual mais forte disponível na disciplina e costuma ser o momento em que a unidade do curso fica evidente para a turma.

A avaliação com curto-circuito é o ponto técnico de maior dificuldade e merece construção ao vivo completa, porque é onde a geração deixa de ser tradução direta e passa a exigir estrutura de controle.

Na tutoria, o ponto de atenção é o acoplamento com o módulo anterior: grupos cuja especificação de formato ficou incompleta descobrem aqui, com custo alto. Vale revisitar a especificação na sessão de planejamento antes de gerar qualquer coisa. O segundo ponto é o executor mínimo, que grupos confundem com o executor completo e superdimensionam; a orientação é que ele precisa apenas demonstrar que o objeto está correto, e que o tratamento completo é do módulo seguinte.

Módulo 15: Otimização e Integração Final

Objetivos do Módulo

Introduzir a estrutura sobre a qual a otimização opera e as transformações locais fundamentais. Estabelecer a preservação de semântica como requisito absoluto. Concluir a integração do artefato e conduzir o fechamento conceitual do semestre.

Competências a Serem Desenvolvidas

Capacidade de aplicar transformações a um artefato preservando propriedades que precisam ser mantidas, e de justificar essa preservação. Capacidade de avaliar um sistema completo quanto ao comportamento diante de entrada real, e não apenas de exemplos preparados. Capacidade de comunicar tecnicamente o resultado de um projeto longo.

Habilidades a Serem Adquiridas

Identificar blocos básicos e construir o grafo de fluxo de controle. Aplicar dobramento de constantes, propagação de cópias, eliminação de subexpressões comuns e eliminação de código morto, justificando a segurança de cada uma. Explicar o papel da análise de fluxo de dados e a noção de solução por ponto fixo. Integrar as fases e diagnosticar falhas ponta a ponta. Apresentar tecnicamente o projeto.

Conteúdo a Ser Apresentado

Blocos básicos, com o algoritmo de identificação de líderes, e o grafo de fluxo de controle. Otimizações locais, cada uma com a condição que a torna segura, e a exigência de preservação de semântica. Panorama das otimizações globais e da análise de fluxo de dados, com a noção de ponto fixo. O compromisso entre tempo de compilação, tempo de execução e agressividade das transformações. Integração final: execução ponta a ponta sobre entrada real e tratamento de erro em todas as fases, com a qualidade das mensagens como atributo de projeto. Retrospectiva do percurso e panorama de temas adjacentes.

O tratamento é instrumental para blocos básicos e otimizações locais, e panorâmico para análise de fluxo de dados.

Tarefas do Projeto Integrador

Último módulo. O compilador fica pronto, o grupo mede o que construiu e apresenta o resultado.

Na frente de otimização, cada grupo identifica os blocos básicos na representação intermediária, constrói o grafo de fluxo de controle e implementa ao menos duas das transformações locais estudadas, verificando em cada caso que a semântica do programa foi preservada. A escolha de quais transformações implementar é do grupo e deve ser justificada pelo que faz sentido na linguagem projetada.

Na frente de integração, entrega o executor completo, com todo o tratamento de erro, rodando sobre entradas reais e não apenas sobre exemplos preparados, com todas as fases em sequência do texto de entrada ao efeito observável.

Na frente de consolidação, revisa todo o material produzido no semestre, atualiza o que ficou defasado e prepara a demonstração final.

Entrega final: compilador completo funcionando ponta a ponta; otimizações locais implementadas com demonstração de preservação de semântica; documentação integral revisada e coerente; diário de atividades completo; avaliação por pares preenchida por cada integrante; e apresentação preparada. A entrega ocorre na semana seguinte ao término deste módulo.

Estratégias Pedagógicas e Pontos de Atenção na Tutoria

A exigência de preservação de semântica deve ser apresentada como requisito absoluto e ilustrada com uma transformação plausível que quebra a semântica em um caso de fronteira. Estudantes tendem a tratar otimização como esperteza; o objetivo é que passem a tratá-la como transformação com condição de aplicabilidade.

A retrospectiva final merece preparação. Percorrer o caminho da expressão regular até o programa executável, apontando em que módulo cada peça entrou, é o que consolida a disciplina como uma coisa só em vez de quinze assuntos.

Na tutoria, o risco é o acúmulo: grupos chegam ao último módulo com pendências dos anteriores e tentam fazer tudo. A orientação é priorizar a integração sobre a otimização — um compilador completo com duas transformações simples vale mais que um compilador incompleto com otimização sofisticada. Vale também reservar tempo explícito para a preparação da apresentação, que grupos deixam para o fim e conduzem mal. A segunda avaliação por pares ocorre nesta entrega.

Avaliação e Critérios

A avaliação combina um componente contínuo, acumulado ao longo dos módulos, e um componente final, aplicado ao Projeto Integrador completo. Os pesos são fixos e não devem ser alterados.

Avaliação contínua — 50% da nota, apurada por módulo

Engajamento no estudo pelo aplicativo da disciplina, correspondente a 50% do componente contínuo.

Engajamento nas atividades colaborativas, correspondente a 20% do componente contínuo.

Pontualidade nas entregas, correspondente a 20% do componente contínuo.

Contribuição nas discussões em sala, correspondente a 10% do componente contínuo.

Avaliação final — Projeto Integrador, 50% da nota

Avaliação do projeto completo, considerando a implementação, a documentação e a apresentação.

Convém explicitar o que se examina ao avaliar o projeto, porque os critérios não são autoevidentes e a consistência entre módulos depende de aplicá-los da mesma forma.

A correção precede a sofisticação. Um artefato que trata bem um escopo pequeno vale mais que um que trata mal um escopo ambicioso. Grupos que reduziram escopo de forma consciente e documentada não devem ser penalizados por isso; grupos que mantiveram escopo grande e entregaram partes quebradas, sim.

A compreensão precisa ser demonstrável por qualquer integrante. Durante a tutoria e na apresentação, qualquer integrante pode ser questionado sobre qualquer parte do projeto, e a resposta que atribui a parte a outro integrante é, em si, informação avaliada. É o principal instrumento contra a divisão do trabalho em silos e a razão do revezamento obrigatório de papéis.

A qualidade do relato de erro é critério explícito a partir do módulo 7. Mensagens que indicam posição, causa provável e, quando possível, sugestão de correção distinguem um projeto cuidadoso de um projeto apenas funcional, e a exigência deve crescer ao longo do semestre.

A rastreabilidade das decisões é avaliada pelo diário de atividades e pelo registro de decisões. Uma escolha documentada com suas alternativas vale mais que a mesma escolha sem registro, porque demonstra que houve deliberação.

A pontualidade tem efeito direto sobre o componente contínuo. Como o projeto é cumulativo, um módulo entregue com atraso desloca todos os seguintes, e a penalidade existe para proteger o grupo do próprio acúmulo.

A distribuição real do trabalho é verificada por três fontes independentes: o diário de atividades, a avaliação por pares e a observação durante a tutoria. Quando as três divergirem, a observação direta prevalece.

A avaliação por pares é aplicada nas duas entregas de maior peso, a consolidação parcial e a entrega final, com cada integrante avaliando a contribuição dos demais. Seu propósito precisa ser explicado à turma antes da primeira aplicação, sob pena de ser lida como delação e preenchida de forma inútil. O instrumento não determina nota isoladamente: ele sinaliza divergências que serão confrontadas com o diário e com a observação em tutoria.