BT

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

| por Pierre-Luc Maheu Seguir 3 Seguidores , traduzido por Talles Lasmar Seguir 27 Seguidores em 17 jun 2016. Tempo estimado de leitura: 2 minutos |

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

Olá visitante

Você precisa cadastrar-se no InfoQ Brasil ou para enviar comentários. Há muitas vantagens em se cadastrar.

Obtenha o máximo da experiência do InfoQ Brasil.

Dê sua opinião

HTML é permitido: a,b,br,blockquote,i,li,pre,u,ul,p

Receber mensagens dessa discussão
Comentários da comunidade

HTML é permitido: a,b,br,blockquote,i,li,pre,u,ul,p

Receber mensagens dessa discussão

HTML é permitido: a,b,br,blockquote,i,li,pre,u,ul,p

Receber mensagens dessa discussão

Dê sua opinião

Faça seu login para melhorar sua experiência com o InfoQ e ter acesso a funcionalidades exclusivas


Esqueci minha senha

Follow

Siga seus tópicos e editores favoritos

Acompanhe e seja notificados sobre as mais importantes novidades do mundo do desenvolvimento de software.

Like

Mais interação, mais personalização

Crie seu próprio feed de novidades escolhendo os tópicos e pessoas que você gostaria de acompanhar.

Notifications

Fique por dentro das novidades!

Configure as notificações e acompanhe as novidades relacionada a tópicos, conteúdos e pessoas de seu interesse

BT