Comentários
- Veja os artigos da Wikipedia sobre Auto-hospedagem e Inicialização do compilador .
- Consulte também programmers.stackexchange.com/questions/167277
- Eles fornecem apenas uma visão geral, conheço o programa de inicialização e auto-hospedagem, mas quero dar uma olhada em alguns exemplos simples
- rano. org / bcompiler.html
- veja também: Por que os compiladores de auto-hospedagem são considerados um rito de passagem para novas linguagens?
Resposta
Digamos que você esteja escrevendo uma nova linguagem de programação chamada “XYZ”. O primeiro passo é escrever um compilador para esta linguagem. Como essa nova linguagem ainda não existe, você escreve o compilador em … digamos java. Vamos chamá-lo de jxyz. Esse processo é uma aula típica na faculdade .
Agora você tem um programa java (jxyz) que pega um arquivo fonte XYZ e produz um executável. É então possível escrever um compilador para XYZ em XYZ que é compatível com jxyz.
Neste ponto, você tem um compilador para XYZ que é compatível com jxyz. Bem, chame este programa de “xyzFromJ”.
“xyzFromJ” deve ser capaz de se tomar como uma entrada e se compilar removendo completamente qualquer coisa criada por jxyz das dependências e definição da linguagem. Deste ponto em diante, qualquer alteração na linguagem XYZ pode ser feita no compilador escrito em XYZ e compilado usando ele mesmo.
Resposta
Etapa 1. Escreva seu compilador em uma linguagem diferente.
Etapa 2. Compile o código da Etapa 1.
Etapa 3. Escreva seu compilador na mesma linguagem.
Etapa 4. Compile o código de etapa 3.
Repita as etapas 3 a 4 para quaisquer atualizações futuras do compilador.
Observe que as etapas 1 e 3 podem acontecer simultaneamente ou em uma ordem diferente.
Admito que se trata de uma simplificação excessiva.
Comentários
- @RobertHarvey: Na etapa 4, não especifiquei qual compilador usar propositalmente para que " Repita as etapas 3-4 " faça mais sentido.
- Ganhou ' a etapa 4 só funciona se você usar um compilador que reconhece a nova linguagem?
- @RobertHarvey: Sim, mas deliberadamente não ' t specif y it para que " Repita as etapas 3-4 " não significasse que " use o compilador da Etapa 1 ", pois isso anularia o objetivo do exercício. Presumi que nem era preciso dizer que você deveria usar o compilador da Etapa 1 na primeira iteração (é ' so único compilador que você tem) e o compilador gerado na iteração anterior da Etapa 3 em cada iteração adicional.
Resposta
Ao contrário de algumas outras respostas que sugerem escrever o compilador em alguma outra linguagem (presumível que seja executado na mesma máquina que você deseja), também é possível (na verdade preferível) escrever o compilador na linguagem de destino desde o início.
Digamos que você queira escrever um compilador para C para um processador ARM. Você já tem um compilador C que roda no Windows (arquitetura Intel). Você escreve seu novo compilador em C, tanto no front end (análise lexical e análise) quanto no back end (geração de código). O back-end do curso é escrito para gerar código para o ARM, não para a Intel.
Você então compila o código-fonte para o novo compilador com o compilador existente. Quando estiver satisfeito com o fato de que o compilador está gerando um código válido para o ARM, você pega o código ARM compilado e o executa na arquitetura ARM de destino. Agora você tem o código-fonte do novo compilador, que pode ser modificado e alimentado em seu executável e gerar uma nova versão.
Este processo é chamado de compilação cruzada. A vantagem é que você só tem para escrever o compilador uma vez.
Resposta
de outra resposta:
Step 1. Write your compiler in a different language. Step 2. Compile the code from Step 1. Step 3. Write your compiler in the same language. Step 4. Compile the code from step 3.
As etapas 1 e 2 são necessárias apenas para o “primeiro” compilador para uma nova linguagem. Existem muitas variações nas etapas 3 e 4, portanto, por exemplo, você pode escrever o gerador de código para uma nova arquitetura, compile cruzado e execute o mesmo compilador em uma nova máquina.Ou você pode estender seu compilador para lidar com novas sintaxes e construções sem usar nenhuma das extensões e, em seguida, reescrever o compilador para usar as extensões e compilar a si mesmo.