Introdução1.1
Nesta disciplina iremos nos dedicar a um dos temas mais centrais e estimulantes da Computação, a construção de linguagens de programação. Apesar do nome, o estudo de compiladores abrange um conjunto amplo de conceitos e técnicas, como interpretadores, linguagens formais, linguagens livres de contexto, representação intermediária e geração de código. Por conveniência didática, todos esses tópicos serão tratados sob um mesmo guarda-chuva conceitual, ao qual nos referiremos simplesmente como compiladores.
O módulo inicial será dedicado à discussão dos fundamentos teóricos sobre os quais os compiladores são construídos. Muitos desses conceitos já foram apresentados, ou ao menos deveriam ter sido, ao longo da graduação em Computação. Ainda assim, neste capítulo introdutório o foco estará no curso em si: sua estrutura, seus objetivos e sua proposta pedagógica. Como é comum em disciplinas obrigatórias, também há aqui uma tentativa explícita de motivá-lo a enxergar este conteúdo não apenas como relevante para sua formação, mas como um campo genuinamente interessante e formativo.
O que iremos implementar1.2
Nos próximos capítulos iniciaremos uma discussão mais sistemática sobre o que caracteriza um compilador. Desde já, porém, é importante deixar claro que esta disciplina não se limita à apresentação teórica dos tópicos definidos pela ementa. O curso é estruturado em torno de um projeto prático guiado, cuidadosamente descrito, que poderá ser seguido passo a passo a partir destas notas.
Utilizaremos uma linguagem alvo definida especificamente para fins pedagógicos. O objetivo será desenvolver um programa capaz de executá-la. Inicialmente, esse programa será um interpretador. Ao longo do curso, ele será gradualmente transformado em um compilador tradicional, por meio da geração de código. Isso incluirá a emissão de instruções de CPU capazes de representar não apenas expressões matemáticas e lógicas, mas também estruturas de controle, como condicionais, laços de repetição e funções.
A linguagem será compilada para uma máquina virtual fornecida pela disciplina, note que, nesse contexto, uma máquina virtual é uma abstração de um computador que irá executar o código intermediário que nosso compilador irá gerar, tal qual a JVM é para o JAVA. Além disso, havendo tempo disponível, poderemos discutir extensões e tópicos adicionais, como geração de código para arquiteturas reais, coleta de lixo, orientação a objetos e, eventualmente, a implementação parcial de algumas dessas funcionalidades mais avançadas.
O foco do curso não estará na construção das soluções mais eficientes possíveis, mas na compreensão dos conceitos e na experimentação prática. A principal recomendação desta disciplina é: programe e desenvolva o projeto em conjunto com o material apresentado.
Por que você deveria aprender isso?1.3
O estudo de compiladores estimula uma forma particularmente rigorosa de pensamento estruturado. Ao longo da disciplina, você lidará com árvores, grafos, autômatos e estratégias de gerenciamento de recursos. Mesmo que você nunca venha a desenvolver um compilador profissionalmente, as habilidades de abstração e resolução de problemas complexos adquiridas aqui terão impacto direto na sua capacidade de escrever código de melhor qualidade e de compreender, em nível mais profundo, como programas são efetivamente executados pelo computador.
Tecnologias e linguagem adotadas1.4
Embora seja possível levantar diferentes argumentos a favor ou contra essa decisão, ao longo da disciplina utilizaremos a linguagem C como base para todas as implementações. Evidentemente, outras linguagens poderiam cumprir esse papel de maneira satisfatória. Contudo, ao lidarmos com conceitos de baixo nível, como representação de dados, organização de memória e interação direta com a máquina, a linguagem C oferece um grau de controle e transparência que se mostra especialmente valioso. Além disso, sua proximidade com o hardware e a facilidade de integração com APIs e bibliotecas de baixo nível tornam-na mais adequada para os objetivos pedagógicos do curso do que alternativas de mais alto nível, como Python, que também poderia ser empregada, mas abstrai justamente muitos dos detalhes que desejamos explorar.
O uso sistemático da linguagem C ao longo da disciplina traz ainda benefícios que extrapolam o escopo imediato do projeto de compiladores. A exposição explícita a mecanismos como alocação manual de memória, manipulação direta de estruturas de dados e modelos de execução mais próximos do funcionamento real da máquina contribui para a formação de uma base conceitual sólida. Essa base facilita não apenas o aprendizado posterior de outras linguagens de programação, mas também a leitura, compreensão e manutenção de implementações reais de compiladores, sistemas operacionais e outras ferramentas fundamentais da área.
Para aqueles que nunca tiveram contato prévio com a linguagem C, ou que não se sentem confortáveis com seus conceitos, é recomendável a utilização do material da disciplina TEP II na seção de apêndices (TEP II) cobrindo tudo o que será necessário ao longo da disciplina. Vale destacar que, apesar de sua reputação, a linguagem C corresponde a um subconjunto relativamente pequeno e enxuto, especialmente quando comparado à complexidade de linguagens modernas como o próprio Python.
Próximos passos1.5
No próximo capítulo, Compilador como tradutor, iremos estudar o funcionamento do computador. Esse entendimento será fundamental para, em seguida, analisarmos como o compilador transforma código de alto nível em instruções que podem ser diretamente executadas pela máquina.