Por que C ++ para escrever um compilador?

15

Eu queria saber por que C ++ é uma boa opção para escrever um compilador. É claro que C também é bom para esse propósito, porque muitos compiladores são escritos em C ou C ++, mas desta vez estou mais interessado em C ++. Alguma boa razão? Eu estava procurando isso na Internet, mas não consigo encontrar boas razões.

Kobra
fonte
3
"Muitos compiladores são escritos [...] em C ++" - alguma referência? Quais? O que faz você pensar que o C ++ é mais frequentemente usado para a construção do compilador do que outras linguagens populares?
Doc Brown
4
@DocBrown Bem, Clang e MSVC são escritos principalmente em C ++, o gcc possui um pouco de C ++ agora, Java JVM são escritos em C ++ stackoverflow.com/questions/410320/what-is-java-written-in e também superusuário. com / questions / 136136 /…
Klaim
@DocBrown DMD o compilador referência para D é escrita em C ++
roquete aberração
3
Quem disse que é uma boa escolha?
26512 Phil
1
@ Phil Você acha que eles fizeram essa escolha sem considerar alternativas? Não é uma escolha "boa", é uma escolha "eficiente".
Klaim

Respostas:

21

C ++ tem dois lados. Ele tem um lado de desenvolvimento de baixo nível, o que faz com que pareça uma linguagem natural para fazer coisas de baixo nível, como geração de código. Ele também possui um lado de alto nível (que C não possui) que permite estruturar um aplicativo complexo (como um compilador) de uma maneira lógica e orientada a objetos, mantendo o desempenho. Por possuir aspectos de baixo e alto nível, é uma boa opção para aplicativos grandes que exigem recursos ou desempenho de baixo nível.

Oleksi
fonte
9
Até onde eu sei, muita da lógica dentro de um compilador é de natureza funcional (transformando estruturas de dados complexas em outras estruturas de dados), portanto, não tenho certeza se as instalações orientadas a objetos (que são mais direcionadas à programação em geral) , aspectos arquitetônicos) trazem uma vantagem real para a construção do compilador em um estilo de programação procedural. Apenas meus 2 centavos.
Giorgio
5
@Giorgio Ter objetos ajuda em muitos outros aspectos da escrita do compilador. Por exemplo, há muito estado com o qual um compilador deve lidar ao otimizar e esse tipo de coisa se presta bem ao OOP. Além disso, o OOP e a programação funcional podem ser bastante complementares, apenas porque os algoritmos podem ser principalmente funcionais, não significa que os objetos não ajudem.
26712 Oleksi
3
@Giorgio e Oleksi: posso confirmar vocês dois. Eu escrevi um compilador com Haskell para uma linguagem do mundo real. Foi realmente um bom ajuste. Mas às vezes eu perdia alguns OO por aí. Se eu tivesse que escrever outro compilador, definitivamente escolheria Haskell, mas esse é realmente um caso especial. Eu não escolheria Haskell sem hesitação para outros tipos de projetos.
Scarfridge
23
Por que você precisa ter um idioma com um "lado de baixo nível" para gerar o código? Não vejo como esses dois estão conectados de forma alguma.
Phant0m
5
Você não precisa de um "lado de baixo nível" para gerar o código, assim como não precisa de identificadores Unicode para poder escrever texto em japonês em um arquivo.
Dan04
11

Minha experiência não concorda com sua premissa aqui. De fato, para linguagens de propósito geral de alto nível, é uma prática muito comum escrever o compilador no mesmo idioma que o idioma de origem (o idioma que está sendo compilado). Por exemplo:

  • O compilador Java da Sun é escrito em Java
  • O compilador Scala está escrito em Scala
  • O compilador C # do Mono é escrito em C #
  • O compilador Smalltalk do Squick está escrito em Smalltalk
  • ... e muitos mais

Uma exceção são os front-ends do compilador gravados para estruturas de compiladores existentes, como GCC, LLVM ou Polyglot, que são escritas na linguagem da estrutura ou compiladores que dependem de geradores de analisadores existentes, como o Yacc. Como GCC, LLVM e Yacc são ferramentas comuns e estabelecidas, escritas em C e C ++, isso incentiva os escritores de compiladores a usá-las, o que pode levar o C e C ++ a obter um grande compartilhamento na distribuição da linguagem de implementação do compilador.

Carvalho
fonte
2
Eu acho que isso tem muito mais a ver com as pessoas que escrevem o compilador conhecendo bem e gostando muito da linguagem para a qual estão escrevendo um compilador do que por razões técnicas objetivas.
Thomas Bonini
1
@Krelp Eu concordo que não se trata de uma razão técnica objetiva, mas também não é "gosto" - é apenas considerado um rito de passagem para uma linguagem - "ela é madura o suficiente para poder servir como a linguagem de implementação própria?" compilador".
Oak
1
Compilador Java da Sun é escrito em C ++: stackoverflow.com/questions/410320/what-is-java-written-in
Klaim
10
@Klaim, você está confundindo dois produtos aqui. Um deles é o compilador Java da Sun ( javaclinha de comando), que compila Java para Java Bytecode. Está escrito em Java - eu o modifiquei muitas vezes e você pode navegar on-line por suas fontes Java . O outro é o compilador just-in-time incorporado na JVM do Hotspot, que compila o Java Bytecode no código da máquina nativa. Como a maioria da JVM, ela é escrita em C ++, mas não é um compilador Java - na verdade, ela não sabe nada sobre a linguagem Java.
Oak
@ Oak, absolutamente correto! Em outras palavras, JVM! = Javac
Paul Draper
5

Para compilar o que para quê? Um compilador transforma um código-fonte de um idioma ( idioma de origem) para outro (idioma de destino), o que não indica nada sobre o baixo nível do idioma de destino.

  • O CoffeeScript é compilado em JavaScript, o compilador sendo escrito em CoffeeScript.
  • O script # compila C # em JavaScript, o compilador sendo escrito, se bem me lembro, C #.
  • etc.

O idioma que você escolhe para escrever um compilador depende do contexto. Por exemplo, trabalhando em um projeto que compila uma linguagem derivada do PHP para um código PHP nativo, usei uma mistura de PHP e C # para escrever o compilador, porque fazia mais sentido para mim, dadas minhas habilidades. Outra pessoa escolheria Python, Java e PHP, ou C ++ com um pouco de JavaScript, ou qualquer outra coisa.

C ou C ++ é uma escolha popular devido ao suporte de ferramentas relacionadas ao compilador (veja a resposta de Telastyn) e porque esses dois idiomas permitem que você seja realmente nativo. Mas não há nada errado em escolher outro idioma.

Observe que, para ser mais nerd , você pode escolher o idioma de origem para escrever o próprio compilador. Foi o que aconteceu com o compilador CoffeeScript e muitos outros compiladores. Também é popular entre os IDEs: um dos primeiros Visual Studio foi criado usando o mesmo Visual Studio.

Arseni Mourzenko
fonte
4
A hospedagem automática não é nerd, é uma propriedade importante para portar um compilador.
4
O motivo é que ele imediatamente permite que o próprio compilador seja um programa de teste. Provavelmente também será o maior programa desse compilador por um bom tempo.
5

Costumo questionar a premissa básica aqui. Enquanto C e C ++ funcionam perfeitamente bem para escrever compiladores, muitas outras linguagens parecem funcionar perfeitamente também para a tarefa.

Um pouco depende do idioma que você está compilando. Para linguagens pequenas e simples, C e Pascal funcionam muito bem. Se você for compilar algo grande e complexo, seu compilador também ficará grande e complexo - nesse caso, os recursos extras do C ++ para organizar e trabalhar com programas maiores obviamente serão úteis. Isso não é realmente muito específico para compilar, apenas recursos úteis para programas maiores em geral.

Eu acho que também vale a pena mencionar um outro ponto. Os iniciantes (parecem) pensam nos compiladores principalmente na manipulação de texto, então pensam que algo como Perl será uma grande ajuda para escrever compiladores. Na realidade, a maioria das partes interessantes da compilação não começa realmente depois que você cria seu AST. Embora eu tenha certeza que o Perl pode fazer o trabalho perfeitamente bem, sua capacidade de manipulação de texto também não oferece uma grande vantagem (a manipulação de texto está principalmente no lexer e os geradores de lexer para coisas como C suportam REs de qualquer maneira).

Jerry Coffin
fonte
2
AST = Sumário da árvore de sintaxe, RE = Expressões Regulares
chaotic3quilibrium
5

Compiladores podem ser implementados em qualquer linguagem moderna. No entanto, um dos requisitos mais importantes de um compilador é ser rápido.

C ++ tem uma clara vantagem aqui. A otimização em C ++ não é barata. No entanto, devido à natureza de baixo nível desse idioma, é possível otimizar manualmente o código C ++ mais do que em qualquer outro idioma (exceto o Assembly que não é portátil).

Lior Kogan
fonte
9
Outro requisito importante é que o código gerado esteja correto - eu prefiro ter um compilador lento em que posso confiar do que um rápido que gera código incorreto.
1
Embora seja certamente possível otimizar muito o C ++, há muito ... bem ... menos do que o código C ++ ideal por aí.
Donal Fellows
2
@DonalFellows Inversamente: é possível escrever um código abaixo do ideal em qualquer idioma, mas há otimizações impossíveis de serem ativadas em outros idiomas além do C ++ (além do Assembler. Não incluo C devido à falta estruturas de alto nível, permitindo um alinhamento mais forte).
Klaim
2

Suspeito que o principal motivador para o uso deles seja que a saída Lex / Yacc / Bison esteja (principalmente) em C. Como esse é o padrão há tanto tempo, ele tem impulso.

Não que essas sejam razões particularmente boas ...

Telastyn
fonte
Na verdade, isso não me satisfaz, mas obrigado pela tentativa.
Kobra
Isso não responde à pergunta "por que escolher C ++ em vez de C para a construção do compilador".
Doc Brown
2
Não é um bom motivo. Existem ferramentas análogas para Lex e Yacc para muitas plataformas. PLY e ANTLR, por exemplo.
User16764
Além disso, a maioria dos compiladores populares do mundo real (tenho certeza de que existem, por exemplo, Clang e GCC, por exemplo) usam analisadores escritos à mão.
@ delnan: Sim, mas eles provavelmente começaram usando um gerado para tirar as coisas do chão. A geração manual do analisador é uma etapa de otimização que você realmente não deseja fazer até poder provar que outras coisas estão funcionando.
Martin York