BT

Disseminando conhecimento e inovação em desenvolvimento de software corporativo.

Contribuir

Tópicos

Escolha a região

Início Notícias Anders Hejlsberg explica como é a construção de compiladores modernos

Anders Hejlsberg explica como é a construção de compiladores modernos

Favoritos

A principal característica de um compilador clássico é o processamento sequencial de sua entrada. As fases podem ser vistas como um pipeline de seus principais componentes:

Lexer -> Parser -> Type Checker -> Code Generator -> Emitter

Ao longo da última década, as expectativas tem crescido progressivamente sobre as IDEs e as ferramentas do tipo que fornecem funcionalidades como auto-completar, utilitários de refatoração, navegação de código, análise estática e assim em diante. Estudos com usuários realizados pela Microsoft têm mostrado que tais funcionalidades devem responder a uma ação em menos de 100 ms, caso contrário a funcionalidade é considerada lenta. Isso contrasta com o tempo de compilação de um projeto inteiro, que pode levar mais de um minuto em uma solução de médio porte.

Para dar um feedback rápido em uma IDE, um compilador deve limitar o máximo possível o processamento que faz em tempo real. Isso significa que compilar todo o programa a cada novo caractere inserido não é uma opção. Como alternativa, o compilador constrói apenas o necessário para dar uma resposta ao usuário.

Um tempo de resposta rápido é alcançado não só limitando o processamento mas como também reutilizando antigas estruturas de dados ao máximo possível. Cada vez que o usuário insere um caractere, cada estrutura de dado na memória é candidata a ser apagada. No entanto, para aumentar a capacidade de resposta, tudo que não foi modificado é reaproveitado. A Árvore Sintática (AST), por exemplo, pode ser reutilizada se o arquivo de código fonte que ela representa não foi modificado.

Reuso também é possível até mesmo quando uma estrutura de dados é modificada. Estruturas de dados persistentes, que são imutáveis, lidam com modificações criando e retornando novas instâncias enquanto as referências antigas são mantidas internamente. Para uma árvore sintática isso significa modificar o nó atual e todos seus antecessores até a raiz. Já o resto da árvore, no entanto, pode ser mantido para ser reutilizado em novas instâncias.

Há anos atrás, a necessidade da IDE em prover funcionalidades em tempo real levava a duplicação de código entre o compilador C# e a implementação da funcionalidade na IDE. Essa foi uma das principais razões por trás da criação do compilador Roslyn. O Roslyn foi desenhado desde o princípio para ser utilizado tanto por uma IDE como por linha de comando.

Anders e o entrevistador discutem ao final a respeito de materiais disponíveis sobre a construção de compiladores modernos. Os projetos Roslyn e TypeScript são dados como exemplo, eles são open source e estão disponíveis no GitHub.

Avalie esse artigo

Relevância
Estilo/Redação

Conteúdo educacional

BT