Aprendendo a escrever um compilador [fechado]

699

Idiomas preferidos : C / C ++, Java e Ruby.

Estou procurando alguns livros / tutoriais úteis sobre como escrever seu próprio compilador simplesmente para fins educacionais. Eu estou mais familiarizado com C / C ++, Java e Ruby, então prefiro recursos que envolvam um desses três, mas qualquer bom recurso é aceitável.

Anton
fonte
ANTLR todo o caminho. Todos os recursos propostos abaixo parecem um exagero para mim. O ANTLR é sempre o melhor amigo do designer de compiladores. A
A_Var
Se seu foco principal é aprender como as idéias de compilação funcionam em geral - você pode verificar e abreviar o SICP para o programa de Interpretação Estruturada de Computador com base no Esquema (Lista), mas ensina os princípios gerais. mitpress.mit.edu/sicp . Fui recomendado por um veterano que trabalha em uma empresa e faz a compilação e interpretação desses trabalhos para ganhar a vida!
Nishant
Um plugue sem vergonha: minha resposta sobre uma pergunta semelhante .
9000
Eu escrevi um artigo sobre a criação de um compilador no meu blog: orangejuiceliberationfront.com/how-to-write-a-compiler Ele se concentra nos princípios básicos e na introdução, realmente. Há muitos outros artigos relacionados ao design de compilador / codegen / analisador / idioma por aí.
31514 uliwitness

Respostas:

1084

Grande lista de recursos:

Lenda:

  • ¶ Link para um arquivo PDF
  • $ Link para um livro impresso
Anton
fonte
22
Eu li a série Let's Build a Compiler[ compilers.iecc.com/crenshaw/] , é uma redação muito boa e é um bom ponto de partida.
TheVillageIdiot
5
Acho que vale a pena mencionar o curso de compiladores do Coursera. Possui vídeos agradáveis ​​e cria uma linguagem semelhante ao java / compilador simples. Link para compiladores do Coursera
QuantumKarl,
1
Queria manter a resposta postada o mais original possível, por isso decidi postar esta referência aqui: tutorialspoint.com/compiler_design/index.htm O que eu mais gostei neste site é que ele não se envolve em escrever nenhum código para criar um compilador, mas ele o divide em partes: fases e estágios. Ele descreve a abordagem de design lógico e algorítmico sem nenhum paradigma específico de linguagem, pois expressa as notações de uma linguagem e alfabeto arbitrários. É uma leitura rápida, mas fornece os conceitos do que é necessário para cada parte.
Francis Cugler
70

Esta é uma pergunta bastante vaga, eu acho; apenas por causa da profundidade do tópico envolvido. Um compilador pode ser decomposto em duas partes separadas, no entanto; uma metade superior e uma inferior. A metade superior geralmente pega o idioma de origem e o converte em uma representação intermediária, e a metade inferior cuida da geração de código específica da plataforma.

No entanto, uma idéia para uma maneira fácil de abordar esse tópico (a que usamos na minha classe de compiladores, pelo menos) é compilar o compilador nas duas partes descritas acima. Especificamente, você terá uma boa idéia de todo o processo apenas construindo a metade superior.

Apenas fazer a metade superior permite obter a experiência de escrever o analisador lexical e o analisador e gerar um "código" (a representação intermediária que mencionei). Portanto, o programa de código-fonte será convertido em outra representação e será otimizado (se você quiser), que é o coração de um compilador. A metade inferior pegará essa representação intermediária e gerará os bytes necessários para executar o programa em uma arquitetura específica. Por exemplo, a metade inferior pegará sua representação intermediária e gerará um executável PE.

Alguns livros sobre esse tópico que achei particularmente úteis foram os Princípios e Técnicas dos Compiladores (ou o Livro do Dragão, devido ao lindo dragão na capa). Ele tem uma ótima teoria e definitivamente cobre gramáticas livres de contexto de uma maneira realmente acessível. Além disso, para criar o analisador e analisador lexical, você provavelmente usará as ferramentas * nix lex e yacc. E, de maneira bastante interessante, o livro chamado " lex and yacc " foi retomado de onde o Livro dos Dragões parou nesta parte.

mrduclaw
fonte
55

Eu acho que a implementação do compilador moderno no ML é o melhor texto introdutório para escrever compiladores. Há também uma versão Java e uma versão C , que podem ser mais acessíveis devido ao seu conhecimento de idiomas. O livro contém muito material básico útil (varredura e análise, análise semântica, registros de ativação, seleção de instruções, geração de código nativo RISC e x86) e vários tópicos "avançados" (compilando OO e linguagens funcionais, polimorfismo, coleta de lixo, otimização e único formulário de atribuição estática) em relativamente pouco espaço (~ 500 páginas).

Prefiro Implementação do Compilador Moderno ao livro Dragon, porque a implementação do Compilador Moderno pesquisa menos do campo - em vez disso, possui uma cobertura realmente sólida de todos os tópicos que você precisa para escrever um compilador sério e decente. Depois de ler este livro, você estará pronto para abordar os trabalhos de pesquisa diretamente, para obter mais detalhes, se necessário.

Devo confessar que tenho um sério problema na construção de compiladores de Niklaus Wirth . Está disponível online como PDF. Acho a estética de programação de Wirth simplesmente bonita, no entanto, algumas pessoas acham seu estilo muito minimalista (por exemplo, Wirth favorece analisadores de descida recursivos, mas a maioria dos cursos de CS se concentra em ferramentas geradoras de analisadores; os projetos de linguagem de Wirth são bastante conservadores.) Compiler Construction é uma destilação muito sucinta das idéias básicas de Wirth, portanto, goste ou não do estilo dele, recomendo a leitura deste livro.

Dominic Cooney
fonte
Construção do compilador PDF ethoberon.ethz.ch/WirthPubl/CBEAll.pdf
matepal297
Eu recomendo fortemente contra a versão C de "Modern Compiler Implementação", é aleijado por detalhes de baixo nível devido a C. Ele enche completamente o livro. O Java 1st não é muito bom, pois seu design OO é ruim, o Java 2nd ed não é mais sobre a linguagem Tiger. Por isso, recomendo fortemente o ML: não é necessário ser fluente no ML para entendê-lo. ML é definitivamente adequado para o trabalho.
akim
44

Concordo com a referência do Dragon Book; IMO, é o guia definitivo para a construção do compilador. Prepare-se para alguma teoria hardcore, no entanto.

Se você quer um livro mais leve em teoria, o Game Scripting Mastery pode ser um livro melhor para você. Se você é um novato na teoria dos compiladores, ele fornece uma introdução mais suave. Ele não cobre métodos de análise mais práticos (optar por descendência recursiva não preditiva sem discutir a análise LL ou LR) e, pelo que me lembro, nem sequer discute qualquer tipo de teoria de otimização. Além disso, em vez de compilar no código da máquina, ele é compilado em um bytecode que deve ser executado em uma VM que você também escreve.

Ainda é uma leitura decente, principalmente se você puder comprá-lo barato na Amazon. Se você quer apenas uma introdução fácil aos compiladores, o Game Scripting Mastery não é um caminho ruim. Se você quer ir hardcore na frente, então não se esqueça de nada menos do que o Dragon Book.

user316
fonte
1
O domínio de scripts de jogos é um excelente recurso de aprendizado porque, quando terminar, você terá um jogo de aventura em 2D jogável e com script. Isso faz com que cada exercício seja focado em um propósito específico e mantém o leitor motivado.
Dour High Arch
1
O Dragon é um pouco focado demais na análise baseada em gramática. Se você não está tentando analisar algo completamente impossível, como o C ++, usando geradores de analisador, mas pode usar, por exemplo, uma gramática LL artesanal, talvez queira procurar algo que trate campos de compilador de porcentagem mais alta que não sejam a transformação e a prova gramatical
Marco van de Voort
27

"Vamos construir um compilador" é incrível, mas está um pouco desatualizado. (Não estou dizendo que isso o torna um pouco menos válido.)

Ou confira SLANG . Isso é semelhante a "Vamos criar um compilador", mas é um recurso muito melhor, especialmente para iniciantes. Isso vem com um tutorial em PDF, que usa uma abordagem de 7 etapas para ensinar um compilador. Adicionando o link quora, ele possui os links para todas as várias portas do SLANG, em C ++, Java e JS, também intérpretes em python e java, originalmente escritos usando C # e a plataforma .NET.

RBz
fonte
5
Concordo que esta série está um pouco desatualizada, embora ainda seja útil. No entanto, minha maior preocupação é com o fato de que ele tenta produzir diretamente para a linguagem assembly em vez de criar qualquer tipo de árvore de análise, o que significa (ao contrário do que é afirmado no primeiro artigo) que não é muito útil para escrever um interprete.
precisa saber é
23

Se você deseja usar ferramentas poderosas e de nível superior, em vez de criar tudo sozinho, passar pelos projetos e leituras deste curso é uma boa opção. É um curso de idiomas do autor do mecanismo de análise de Java ANTLR. Você pode obter o livro para o curso como PDF nos Pragmatic Programmers .

O curso aborda o material padrão do compilador que você veria em outros lugares: análise, verificação de tipos e tipos, polimorfismo, tabelas de símbolos e geração de código. Praticamente a única coisa que não é abordada são as otimizações. O projecto final é um programa que compila um subconjunto de C . Como você usa ferramentas como ANTLR e LLVM, é possível escrever o compilador inteiro em um único dia (eu tenho uma prova disso, embora eu queira dizer ~ 24 horas). É pesado em engenharia prática usando ferramentas modernas, um pouco mais leve em teoria.

A propósito, o LLVM é simplesmente fantástico. Em muitas situações em que você normalmente pode compilar até a montagem, seria muito melhor compilar na Representação Intermediária do LLVM . É de nível superior, multiplataforma e o LLVM é muito bom em gerar uma montagem otimizada a partir dele.

Peter Burns
fonte
O primeiro link está morto.
Lynn
20

Se você tiver pouco tempo, recomendo "Compiler Construction" de Niklaus Wirth (Addison-Wesley. 1996) , um livreto minúsculo que você pode ler em um dia, mas explica o básico (incluindo como implementar lexers, analisadores de descida recursivos, e suas próprias máquinas virtuais baseadas em pilha). Depois disso, se você quiser mergulhar fundo, não há como contornar o livro do Dragão, como sugerem outros comentaristas.

Matthieu
fonte
Se você não tiver muito tempo, não escreva um compilador.
Ingo
17

Você pode procurar no Lex / Yacc (ou no Flex / Bison, como quiser chamá-los). O Flex é um analisador lexical, que analisa e identifica os componentes semânticos ("tokens") do seu idioma, e o Bison será usado para definir o que acontece quando cada token é analisado. Isso pode ser, mas definitivamente não está limitado a, imprimir o código C, para um compilador que seria compilado em C, ou executar dinamicamente as instruções.

Esta FAQ deve ajudá-lo, e este tutorial parece bastante útil.

Zachary Murray
fonte
17

De um modo geral, não há um tutorial de cinco minutos para compiladores, porque é um tópico complicado e escrever um compilador pode levar meses. Você terá que fazer sua própria pesquisa.

Python e Ruby são geralmente interpretados. Talvez você queira começar com um intérprete também. Geralmente é mais fácil.

O primeiro passo é escrever uma descrição formal da linguagem, a gramática da sua linguagem de programação. Em seguida, você deve transformar o código-fonte que deseja compilar ou interpretar de acordo com a gramática em uma árvore de sintaxe abstrata, uma forma interna do código-fonte que o computador entende e pode operar. Essa etapa geralmente é chamada de análise e o software que analisa o código-fonte é chamado de analisador. Freqüentemente, o analisador é gerado por um gerador de analisador que transforma uma gramática formal em código-fonte ou código-máquina. Para uma explicação boa e não matemática da análise, recomendo Técnicas de Análise - Um Guia Prático. A Wikipedia tem uma comparação de geradores de analisador, dos quais você pode escolher aquele que é adequado para você. Dependendo do gerador de analisador escolhido,

Escrever um analisador para o seu idioma pode ser muito difícil, mas isso depende da sua gramática. Então, sugiro manter sua gramática simples (ao contrário do C ++); Um bom exemplo disso é o LISP.

Na segunda etapa, a árvore de sintaxe abstrata é transformada de uma estrutura de árvore em uma representação intermediária linear. Como um bom exemplo para o bytecode deste Lua é frequentemente citado. Mas a representação intermediária realmente depende do seu idioma.

Se você estiver construindo um intérprete, precisará simplesmente interpretar a representação intermediária. Você também pode compilá-lo na hora certa. Eu recomendo o LLVM e o libjit para compilação just-in-time. Para tornar o idioma utilizável, você também precisará incluir algumas funções de entrada e saída e talvez uma pequena biblioteca padrão.

Se você for compilar o idioma, será mais complicado. Você precisará escrever backends para diferentes arquiteturas de computadores e gerar código de máquina a partir da representação intermediária nesses backends. Eu recomendo o LLVM para esta tarefa.

Existem alguns livros sobre esse tópico, mas não posso recomendar nenhum deles para uso geral. A maioria deles é muito acadêmica ou muito prática. Não há "Aprenda a escrever o compilador em 21 dias" e, portanto, você terá que comprar vários livros para entender bem todo esse tópico. Se você pesquisar na Internet, encontrará alguns livros on-line e notas de aula. Talvez haja uma biblioteca universitária perto de você, onde você pode emprestar livros em compiladores.

Eu também recomendo um bom conhecimento de fundo em ciência da computação teórica e teoria dos grafos, se você quiser tornar seu projeto sério. Um diploma em ciência da computação também será útil.

user141335
fonte
++ Você está certo que é bom saber todas essas coisas, e pode ser um grande trabalho, mas também aprendi com alguns especialistas como não fazer das coisas um grande negócio. É bom saber as coisas e é ainda melhor saber quando não usá-las, o que é na maioria das vezes.
Mike Dunlavey
11

Um livro ainda não sugerido, mas muito importante, é "Linkers and Loaders", de John Levine. Se você não estiver usando um montador externo, precisará de uma maneira de gerar um arquivo de objeto que possa ser vinculado ao seu programa final. Mesmo se você estiver usando um montador externo, provavelmente precisará entender as realocações e como todo o processo de carregamento do programa funciona para criar uma ferramenta de trabalho. Este livro coleta muitas informações aleatórias sobre esse processo para vários sistemas, incluindo Win32 e Linux.

Ben Combee
fonte
10

O Dragon Book é definitivamente o livro dos "compiladores de construção", mas se o seu idioma não for tão complicado quanto a geração atual de idiomas, convém observar o padrão Interpreter nos Design Patterns .

O exemplo no livro cria uma linguagem semelhante à expressão regular e é bem pensado, mas, como dizem no livro, é bom pensar sobre o processo, mas é eficaz apenas em linguagens pequenas. No entanto, é muito mais rápido escrever um intérprete para um idioma pequeno com esse padrão do que ter que aprender sobre todos os diferentes tipos de analisadores, yacc e lex, etc.

Chris Bunch
fonte
10

Se você estiver disposto a usar o LLVM, verifique isso: http://llvm.org/docs/tutorial/ . Ele ensina como escrever um compilador do zero, usando a estrutura do LLVM, e não pressupõe que você tenha conhecimento sobre o assunto.

O tutorial sugere que você escreva seu próprio analisador e lexer, etc., mas aconselho que você procure o bison e flex quando tiver a idéia. Eles tornam a vida muito mais fácil.

wvdschel
fonte
Mas a documentação para configurá-lo do Visual Studio está mal escrito, mais nenhum exemplo
SpicyWeenie
10

Achei o livro Dragon muito difícil de ler, com muito foco na teoria da linguagem que não é realmente necessária para escrever um compilador na prática.

Eu acrescentaria o livro Oberon , que contém toda a fonte de um incrivelmente rápido e simples projeto Oberon, compilador Oberon .

texto alternativo

Lothar
fonte
10

Lembro-me de fazer essa pergunta cerca de sete anos atrás, quando eu era bastante novo em programação.

Tomei muito cuidado quando perguntei e surpreendentemente não recebi tantas críticas quanto você está chegando aqui. No entanto, eles me apontaram na direção do " Dragon Book ", que é, na minha opinião, um ótimo livro que explica tudo o que você precisa saber para escrever um compilador (é claro que você precisará dominar um ou dois idiomas). idiomas que você conhece, melhor.).

E sim, muitas pessoas dizem que ler esse livro é uma loucura e você não aprenderá nada com ele, mas eu discordo completamente disso.

Muitas pessoas também dizem que escrever compiladores é estúpido e inútil. Bem, existem várias razões pelas quais o desenvolvimento do compilador é útil:

  • Porque é divertido.
  • É educativo, ao aprender a escrever compiladores, você aprenderá muito sobre ciência da computação e outras técnicas que são úteis ao escrever outros aplicativos.
  • Se ninguém escrevesse compiladores, os idiomas existentes não melhorariam.

Não escrevi meu próprio compilador imediatamente, mas depois de perguntar, sabia por onde começar. E agora, depois de aprender muitas línguas diferentes e ler o Livro do Dragão, escrever não é um grande problema. (Também estou estudando atm de engenharia da computação, mas a maior parte do que sei sobre programação é autodidata.)

Em conclusão, The Dragon Book é um ótimo "tutorial". Mas gaste algum tempo dominando um ou dois idiomas antes de tentar escrever um compilador. Não espere ser um guru dos compiladores na próxima década ou mais.

O livro também é bom se você quiser aprender a escrever analisadores / intérpretes.

Pandafox
fonte
9

"... Vamos construir um compilador ..."

Gostaria http://compilers.iecc.com/crenshaw/ segundo por @sasb . Esqueça de comprar mais livros no momento.

Por quê? Ferramentas e idioma.

O idioma necessário é Pascal e, se bem me lembro, é baseado no Turbo-Pascal. Isso só acontece se você ir para http://www.freepascal.org/ e descarregue o compilador Pascal todos os exemplos trabalhar diretamente da página ~ http://www.freepascal.org/download.var A coisa beaut sobre Free Pascal é que você pode usá-lo em praticamente qualquer processador ou sistema operacional com o qual possa cuidar.

Depois de dominar as lições, tente o " Dragon Book " mais avançado ~ http://en.wikipedia.org/wiki/Dragon_book

bootload
fonte
9

Estou analisando o mesmo conceito e encontrei este artigo promissor de Joel Pobar,

Crie um compilador de idiomas para o .NET Framework - não sei para onde isso foi

Criar um compilador de idiomas para o .NET Framework - cópia em pdf do documento original

ele discute um conceito de alto nível de um compilador e passa a inventar seu próprio idioma para a estrutura .Net. Embora seu objetivo seja o .Net Framework, muitos dos conceitos devem poder ser reproduzidos. O artigo abrange:

  1. Definição de langauge
  2. Scanner
  3. Analisador (o bit no qual estou principalmente interessado)
  4. Direcionando o .NET Framework
  5. Gerador de código

existem outros tópicos, mas você entende o que é justo.

Destina-se a pessoas começando, escritas em C # (não exatamente Java)

HTH

ossos

dbones
fonte
O que significa "não exatamente Java"?
Hejazzman
haha, desculpe, eu quis dizer que está escrito para .Net, que em princípio é semelhante ao java. Ambos são em estilo JIT. :)
dbones
8

Uma maneira fácil de criar um compilador é usar bison e flex (ou similar), construir uma árvore (AST) e gerar código em C. Com a geração de código C, a etapa mais importante. Ao gerar o código C, seu idioma funcionará automaticamente em todas as plataformas que possuem um compilador C.

Gerar código C é tão fácil quanto gerar HTML (basta usar print ou equivalente), o que, por sua vez, é muito mais fácil do que escrever um analisador C ou HTML.

Peter Stuifzand
fonte
8

Nas perguntas frequentes do comp.compilers :

"Programando um computador pessoal" por Per Brinch Hansen Prentice-Hall 1982 ISBN 0-13-730283-5

Este livro, infelizmente intitulado, explica o design e a criação de um ambiente de programação de usuário único para micros, usando uma linguagem semelhante a Pascal chamada Edison. O autor apresenta todo o código-fonte e explicações para a implementação passo a passo de um compilador Edison e um sistema operacional de suporte simples, todos escritos no próprio Edison (exceto um pequeno núcleo de suporte gravado em um assembler simbólico para PDP 11/23; o a fonte completa também pode ser solicitada para o IBM PC).

As coisas mais interessantes sobre este livro são: 1) sua capacidade de demonstrar como criar um sistema operacional e compilador completo, independente, de manutenção e útil e 2) a discussão interessante sobre problemas de design e especificação de linguagem e resultados no capítulo 2.

"Brinch Hansen on Pascal Compilers" por Per Brinch Hansen Prentice-Hall 1985 ISBN 0-13-083098-4

Outro livro da teoria da luz sobre a pragmática pesada, aqui é como codificar. O autor apresenta o design, a implementação e o código-fonte completo para um compilador e intérprete de código-p para Pascal- (Pascal "minus"), um subconjunto Pascal com tipos booleanos e inteiros (mas sem caracteres, reais, tipos sub-agrupados ou enumerados) , definições de constante e variável e tipos de matriz e registro (mas nenhum tipo de pacote, variante, conjunto, ponteiro, sem nome, renomeado ou arquivo), expressões, instruções de atribuição, definições de procedimento aninhadas com parâmetros de valor e variável, instruções if, e blocos de início e fim (mas nenhuma definição de função, parâmetros procedimentais, instruções goto e rótulos, instruções de caso, instruções de repetição, para instruções e com instruções).

O compilador e o intérprete são escritos em Pascal * (Pascal "estrela"), um subconjunto Pascal estendido com alguns recursos no estilo Edison para criar sistemas de desenvolvimento de software. Um compilador Pascal * para o PC IBM é vendido pelo autor, mas é fácil portar o compilador Pascal do livro para qualquer plataforma Pascal conveniente.

Este livro facilita o design e a implementação de um compilador. Gosto particularmente da maneira como o autor se preocupa com a qualidade, a confiabilidade e os testes. O compilador e o intérprete podem ser facilmente usados ​​como base para um projeto de linguagem ou compilador mais envolvido, especialmente se você for pressionado a colocar rapidamente algo em funcionamento.

joe snyder
fonte
8

Você deve verificar os " ichbins " de Darius Bacon , que é um compilador para um pequeno dialeto Lisp, direcionado a C, em pouco mais de 6 páginas de código. A vantagem que tem sobre a maioria dos compiladores de brinquedos é que a linguagem é completa o suficiente para que o compilador seja escrito nele. (O tarball também inclui um intérprete para iniciar a coisa.)

Há mais coisas sobre o que achei útil em aprender a escrever um compilador na minha página da web do Ur-Scheme .

Kragen Javier Sitaker
fonte
8
  1. Este é um assunto vasto. Não subestime esse ponto. E não subestime meu argumento para não subestimá-lo.
  2. Ouvi dizer que o Dragon Book é um lugar (o?) Para começar, junto com a pesquisa. :) Melhore a busca, eventualmente será a sua vida.
  3. Construir sua própria linguagem de programação é absolutamente um bom exercício! Mas saiba que nunca será usado para nenhum propósito prático no final. Exceções a isso são poucas e muito distantes entre si.
280Z28
fonte
4
Se você não leu o livro do dragão. Por favor, não recomendo. De fato, você já implementou um compilador?
Sim, como o nome indica, o Dragon Book é um monstro. Muito profundo, mas um recurso muito bom, no entanto. Eu não recomendo para iniciantes, embora ...
Zachary Murray
2
@ Neil: Você não me pesquisou no google, não é? ri muito. blog.280z28.org Mas não, eu não li esse livro.
21310 Sam Harwell
Atualmente estou lendo (o livro do dragão) e também Lex / Yacc ao mesmo tempo, estou achando o livro muito bom. Pessoalmente.
Simeon Pilgrim
1
Para ser justo, eu o antecipei com "eu ouço ...". :) Os pontos 1 e 3 são extremamente importantes para saber, mas não são mencionados com tanta frequência.
21413 Sam Harwell
8

O compilador LCC ( wikipedia ) ( página inicial do projeto ) ( github.com/drh/lcc ) de Fraser e Hanson é descrito em seu livro "Um compilador C retargetável: design e implementação". É bastante legível e explica todo o compilador, até a geração do código.

mfx
fonte
Parece um recurso extremamente bom, obrigado.
Gideon
7

O Python vem com um compilador python escrito em Python. Você pode ver o código fonte, e inclui todas as fases, desde a análise, árvore de sintaxe abstrata, código emissor, etc.

Yeruham
fonte
7

Desculpe, está em espanhol, mas esta é a bibliografia de um curso chamado "Compiladores e Intérpretes" (Compiladores e Intérpretes) na Argentina.

O curso foi da teoria formal da linguagem à construção do compilador, e estes são os tópicos que você precisa para criar, pelo menos, um compilador simples:

  • Projeto de compiladores em C.
    Allen I. Holub

    Prentice-Hall. 1990.

  • Compiladores. Teoria e Construção.
    Sanchís Llorca, FJ, Galán Pascual, C. Editorial Paraninfo. 1988.

  • Construção do compilador.
    Niklaus Wirth

    Addison-Wesley. 1996.

  • Lenguajes, Gramáticas e Autómatas. Un enfoque práctico.
    Pedro Isasi Viñuela, Paloma Martínez Fernández, Daniel Borrajo Millán. Addison-Wesley Iberoamericana (Espanha). 1997.

  • A arte do design do compilador. A teoria e a prática.
    Thomas Pittman, James Peters.

    Prentice-Hall. 1992.

  • Construção do compilador orientado a objetos.
    Jim Holmes.
    Prentice Hall, Englewood Cliffs, NJ 1995

  • Compiladores. Conceitos Fundamentais.
    B. Teufel, S. Schmidt, T. Teufel.

    Addison-Wesley Iberoamericana. 1995.

  • Introdução à Teoria dos Autômatos, Idiomas e Computação.

    John E. Hopcroft. Jeffref D. Ullman.
    Addison-Wesley. 1979.

  • Introdução às linguagens formais.
    György E. Révész.

    Mc Graw Hill. 1983.

  • Técnicas de análise. Um guia prático.
    Dick Grune, Ceriel Jacobs.
    Impressão por autores. 1995
    http://www.cs.vu.nl/~dick/PTAPG.html

  • Yacc: Mais um compilador-compilador.
    Stephen C. Johnson
    Relatório Técnico de Ciência da Computação Nº 32, 1975. Bell Laboratories. Murray Hill, Nova
    Jersey.

  • Lex: Um gerador de analisador lexical.
    ME Lesk, E. Schmidt. Relatório Técnico de Ciências da Computação Nº 39, 1975. Bell Laboratories. Murray Hill, Nova Jersey.

  • Lex & Yacc.
    John R. Levine, Tony Mason e Doug Brown.
    O'Reilly & Associates. 1995.

  • Elementos da teoria da computação.
    Harry R. Lewis, Christos H. Papadimitriou. Segunda Edição. Prentice Hall. 1998.

  • Um Algoritmo Eficiente para Construção do Gráfico de Dependência de Controle.
    Salvador V. Cavadini.
    Trabalho final de classificação para obter o título de engenheiro em computação.
    Faculdade de Matemática Aplicada. UCSE 2001.

eKek0
fonte
6

Não é um livro, mas um documento técnico e uma experiência de aprendizado muito divertida, se você quiser saber mais sobre compiladores (e metacompiladores) ...

Tutorial: Metacompilers Parte 1

Tudo isso é baseado em um incrível pequeno artigo técnico de 10 páginas:

Val Schorre META II: uma linguagem de escrita de compilador orientada à sintaxe

de honesto a deus de 1964. Eu aprendi a construir compiladores disso em 1970. Há um momento alucinante em que você finalmente percebe como o compilador pode se regenerar ....

Conheço o autor do site nos meus dias de faculdade, mas não tenho nada a ver com o site.

Ira Baxter
fonte
Como outros dizem, é um argumento GRANDE, acho que uma tarefa de sushi é um trabalho final para um bacharel, exige conhecer MUITOS conceitos de matemática, ciência da computação e assim por diante.
ingconti
Se você não conhece esses tópicos, não deve realmente tentar criar um compilador sério. No entanto, se você tiver 2 ou 3 anos de graduação em ciências da computação (programação, estruturas de dados, linguagem assembly), o documento MetaII funcionará para você.
Ira Baxter
5

Também gostei do tutorial Crenshaw , porque deixa absolutamente claro que um compilador é apenas outro programa que lê algumas entradas e escreve algumas.

Leia-o.

Faça o trabalho se quiser, mas veja outra referência sobre como os compiladores maiores e mais completos são realmente escritos.

E leia On Trusting Trust , para obter uma pista sobre as coisas não óbvias que podem ser feitas nesse domínio.

dmckee
fonte
5

Se você estiver interessado em escrever um compilador para uma linguagem funcional (em vez de uma processual), Simon Peyton-Jones e David Lester, " Implementando linguagens funcionais: um tutorial ", é um excelente guia.

O básico conceitual de como funciona a avaliação funcional é guiado por exemplos em uma linguagem funcional simples mas poderosa chamada "Core". Além disso, cada parte do compilador da linguagem Core é explicada com exemplos de código no Miranda (uma linguagem funcional pura muito semelhante à Haskell).

Vários tipos diferentes de compiladores são descritos, mas mesmo se você seguir apenas o chamado compilador de modelos para o Core, terá um excelente entendimento do que faz a programação funcional funcionar.

Mark Reid
fonte
5

Você pode usar o BCEL pela Apache Software Foundation. Com essa ferramenta, você pode gerar código do tipo assembler, mas é Java com a API BCEL. Você pode aprender como gerar código de idioma intermediário (nesse caso, código de byte).

Exemplo simples

  1. Crie uma classe Java com esta função:

    public String maxAsString(int a, int b) {
        if (a > b) {
            return Integer.valueOf(a).toString();
        } else if (a < b) {
            return Integer.valueOf(b).toString();
        } else {
            return "equals";
        }
    }
    

Agora execute o BCELifier com esta classe

BCELifier bcelifier = new BCELifier("MyClass", System.out);
bcelifier.start();

Você pode ver o resultado no console para toda a classe (como criar o código de bytes MyClass.java). O código para a função é este:

private void createMethod_1() {
  InstructionList il = new InstructionList();
  MethodGen method = new MethodGen(ACC_PUBLIC, Type.STRING, new Type[] { Type.INT, Type.INT }, new String[] { "arg0", "arg1" }, "maxAsString", "MyClass", il, _cp);

  il.append(InstructionFactory.createLoad(Type.INT, 1)); // Load first parameter to address 1
  il.append(InstructionFactory.createLoad(Type.INT, 2)); // Load second parameter to adress 2
    BranchInstruction if_icmple_2 = InstructionFactory.createBranchInstruction(Constants.IF_ICMPLE, null); // Do if condition (compare a > b)
  il.append(if_icmple_2);
  il.append(InstructionFactory.createLoad(Type.INT, 1)); // Load value from address 1 into the stack
  il.append(_factory.createInvoke("java.lang.Integer", "valueOf", new ObjectType("java.lang.Integer"), new Type[] { Type.INT }, Constants.INVOKESTATIC));
  il.append(_factory.createInvoke("java.lang.Integer", "toString", Type.STRING, Type.NO_ARGS, Constants.INVOKEVIRTUAL));
  il.append(InstructionFactory.createReturn(Type.OBJECT));
  InstructionHandle ih_13 = il.append(InstructionFactory.createLoad(Type.INT, 1));
  il.append(InstructionFactory.createLoad(Type.INT, 2));
    BranchInstruction if_icmpge_15 = InstructionFactory.createBranchInstruction(Constants.IF_ICMPGE, null); // Do if condition (compare a < b)
  il.append(if_icmpge_15);
  il.append(InstructionFactory.createLoad(Type.INT, 2));
  il.append(_factory.createInvoke("java.lang.Integer", "valueOf", new ObjectType("java.lang.Integer"), new Type[] { Type.INT }, Constants.INVOKESTATIC));
  il.append(_factory.createInvoke("java.lang.Integer", "toString", Type.STRING, Type.NO_ARGS, Constants.INVOKEVIRTUAL));
  il.append(InstructionFactory.createReturn(Type.OBJECT));
  InstructionHandle ih_26 = il.append(new PUSH(_cp, "equals")); // Return "equals" string
  il.append(InstructionFactory.createReturn(Type.OBJECT));
  if_icmple_2.setTarget(ih_13);
  if_icmpge_15.setTarget(ih_26);
  method.setMaxStack();
  method.setMaxLocals();
  _cg.addMethod(method.getMethod());
  il.dispose();
}
timaschew
fonte
5

Há muitas boas respostas aqui, então pensei em adicionar mais uma à lista:

Eu recebi um livro chamado Project Oberon há mais de uma década, que tem um texto muito bem escrito no compilador. O livro realmente se destaca no sentido de que a fonte e as explicações são muito práticas e legíveis. O texto completo (edição de 2005) foi disponibilizado em pdf, para que você possa fazer o download agora mesmo. O compilador é discutido no capítulo 12:

http://www.ethoberon.ethz.ch/WirthPubl/ProjectOberon.pdf

Niklaus Wirth, Jürg Gutknecht

(O tratamento não é tão extenso quanto o seu livro sobre compiladores)

Eu já li vários livros sobre compiladores e posso acompanhar o livro do dragão, o tempo gasto neste livro vale muito a pena.

tovare
fonte
4

Até o momento, este livro não está incluído na lista:

Fundamentos do Design de Compiladores (Torben Mogensen) (do departamento de Ciência da Computação da Universidade de Copenhague)

Também estou interessado em aprender sobre compiladores e planejar entrar nesse setor nos próximos dois anos. Este livro é o livro de teoria ideal para começar a aprender compiladores, tanto quanto eu posso ver. É GRATUITO copiar e reproduzir, de maneira limpa e cuidadosa, e fornece a você em inglês simples, sem qualquer código, mas ainda apresenta a mecânica por meio de instruções e diagramas etc. Vale a pena conferir.

magneto12321
fonte
Adicionado à lista obrigado :)
Anton