Je me demandais pourquoi C ++ est un bon choix pour écrire un compilateur. Bien sûr, C est également utile à cet effet, car de nombreux compilateurs sont écrits en C ou en C ++, mais je suis plus intéressé par C ++ cette fois. Des bonnes raisons? Je cherchais cela sur Internet, mais je ne trouve aucune bonne raison.
14
Réponses:
C ++ a deux faces. Il a un côté de développement de bas niveau qui le fait ressembler à un langage naturel pour faire des choses de bas niveau comme la génération de code. Il a également un côté de haut niveau (ce que C ne fait pas) qui vous permet de structurer une application complexe (comme un compilateur) de manière logique, orientée objet, tout en conservant les performances. Parce qu'il a à la fois des aspects de bas et de haut niveau, c'est un bon choix pour les grandes applications qui nécessitent des fonctionnalités ou des performances de bas niveau.
la source
Mon expérience ne correspond pas à votre prémisse ici. En fait, pour les langages généraux de haut niveau, il est très courant d'écrire le compilateur dans la même langue que la langue source (la langue en cours de compilation). Par exemple:
Une exception est les frontaux du compilateur écrits pour les frameworks de compilateur existants, tels que GCC, LLVM ou Polyglot, qui sont ensuite écrits dans le langage du framework, ou les compilateurs qui s'appuient sur des générateurs d'analyseurs existants tels que Yacc. Étant donné que GCC, LLVM et Yacc sont des outils communs établis établis en C et C ++, cela incite les rédacteurs de compilateurs à les utiliser, ce qui pourrait conduire C et C ++ à obtenir une large part de la distribution du langage d'implémentation du compilateur.
la source
javac
ligne de commande), qui compile Java en Java Bytecode. Il est écrit en Java - je l'ai moi-même modifié plusieurs fois et vous pouvez parcourir ses sources Java en ligne . L'autre est le compilateur juste à temps incorporé dans la machine virtuelle Java Hotspot, qui compile Java Bytecode en code machine natif. Comme la plupart des JVM, il est écrit en C ++, mais ce n'est pas un compilateur Java - en fait, il ne sait rien du langage Java.Pour compiler quoi à quoi? Un compilateur transforme un code source d'une langue ( langue source) en une autre (langue de destination), ce qui n'indique rien sur le faible niveau de la langue de destination.
La langue que vous choisissez pour écrire un compilateur dépend du contexte. Par exemple, en travaillant sur un projet qui compile un langage dérivé de PHP vers un code PHP natif, j'ai utilisé un mélange de PHP et C # pour écrire le compilateur, car cela avait le plus de sens pour moi étant donné mes compétences. Une autre personne choisirait Python, ou Java et PHP, ou C ++ avec un peu de JavaScript, ou quoi que ce soit.
C ou C ++ est un choix populaire en raison de la prise en charge des outils liés au compilateur (voir la réponse de Telastyn), et parce que ces deux langues vous permettent de devenir vraiment natif. Mais il n'y a rien de mal à choisir une autre langue.
Notez que pour être plus geek , vous pouvez choisir la langue source pour écrire le compilateur lui-même. C'est ce qui s'est produit pour le compilateur CoffeeScript et de nombreux autres compilateurs. Il est également populaire auprès des IDE: l'un des premiers Visual Studio a été construit en utilisant le même Visual Studio.
la source
J'ai tendance à remettre en question la prémisse de base ici. Alors que C et C ++ fonctionnent parfaitement bien pour l'écriture de compilateurs, un certain nombre d'autres langages semblent également parfaitement fonctionner pour la tâche.
Cela dépend cependant un peu de la langue que vous compilez. Pour les petits langages simples, C et Pascal fonctionnent très bien. Si vous allez compiler quelque chose de gros et de complexe, votre compilateur devient aussi gros et complexe - dans ce cas, les fonctionnalités supplémentaires de C ++ pour organiser et travailler avec des programmes plus grands sont évidemment utiles. Ce n'est pas vraiment très spécifique à la compilation, juste des fonctionnalités utiles pour les programmes plus grands en général.
Je pense qu'il vaut également la peine de mentionner un autre point. Les débutants (semblent) penser que les compilateurs font principalement de la manipulation de texte, ils pensent donc que quelque chose comme Perl sera d'une aide considérable pour écrire des compilateurs. En réalité, la plupart des parties intéressantes de la compilation ne commencent vraiment qu'après avoir construit votre AST. Bien que je sois sûr que Perl puisse parfaitement faire le travail, sa capacité de manipulation de texte ne lui donne pas vraiment un énorme avantage non plus (la manipulation de texte est principalement dans le lexer, et les générateurs de lexer pour des choses comme C supportent tous les RE de toute façon).
la source
Les compilateurs peuvent être implémentés dans n'importe quel langage moderne. Cependant, l'une des exigences les plus importantes d'un compilateur est d'être rapide.
C ++ a un net avantage ici. L'optimisation en C ++ n'est pas bon marché. Cependant, en raison de la nature de bas niveau de ce langage, il est possible d'optimiser manuellement le code C ++ plus que dans tout autre langage (sauf Assembly qui n'est pas portable).
la source
Je soupçonne que le principal facteur de motivation pour leur utilisation est que la sortie Lex / Yacc / Bison est (principalement) en C.Comme cela a été la norme depuis si longtemps, elle a un élan.
Ce ne sont pas des raisons particulièrement bonnes ...
la source
J'ai de l'expérience avec cette affaire. J'ai écrit des compilateurs en C et C ++. La principale différence entre C et C ++ est que C n'a pas de gestion dynamique de la mémoire de manière automatique. Toute la gestion de la mémoire en C doit être effectuée explicitement. L'écriture d'un compilateur traite beaucoup du traitement des chaînes et de la gestion des tableaux. En C, vous êtes obligé de penser à la taille de chaque chaîne et de chaque tableau que vous déclarez et vérifiez également les index lorsque vous accédez à ces objets (si vous voulez que votre code soit sûr et stable). En C, vous pouvez avoir une gestion dynamique de la mémoire, bien sûr, mais rien n'est automatique. Vous devez explicitement allouer et libérer de la mémoire en utilisant malloc () et free (), conserver la taille de vos objets dynamiques dans des variables séparées afin d'être sûr de ne pas y accéder hors des limites.
En C ++, vous pouvez avoir les mêmes mécanismes mais c'est vraiment un temps de développement efficace car toute votre gestion de la mémoire peut être encapsulée dans des constructeurs et des destructeurs que vous n'avez pas à appeler explicitement. Ainsi, le compilateur alloue et libère des ressources pour vous. La taille de vos objets dynamiques peut également être encapsulée si vous créez vos propres classes, et les index peuvent être vérifiés pour l'accès aux limites par l'opérateur de surcharge []. Ces abstractions aident à rendre votre code plus propre, plus facile à comprendre et à déboguer et accélèrent définitivement le développement.
Si vous créez un compilateur en C, cela vous prendra certainement plus de temps. C ++ vous fera terminer votre projet en moins de temps. C et C ++ ont les mêmes performances mais C ++ a beaucoup d'avantages que C n'a pas.
la source
Le projet CompCert est un compilateur C de recherche qui n'est pas écrit en C ou en C ++, mais plus en Ocaml et Coq.
Remarquez que C ++ était auparavant traduit en C (dans Cfront ). Vous pouvez maintenant utiliser l' interface GCC vers Gimple , puis vider le Gimple dans une base de données, puis écrire un Gimple dans votre traducteur d'assembleur. Mais pour des raisons juridiques (l' exception de la bibliothèque d'exécution GCC ), un tel compilateur doit être open source. Demandez des précisions à votre avocat, je ne suis pas avocat. Les anciennes variantes de GCC ont été écrites en C (+ plusieurs langages spécifiques au domaine) avec un front-end pour une variante de C ++. OpenWatcom pourrait être un compilateur C ++ écrit en C (je vous laisse le vérifier).
La source de Compcert est disponible gratuitement à des fins académiques et de recherche. Si vous souhaitez l'utiliser industriellement (et légalement), vous devez obtenir une licence d'Absint.
Voir aussi ceci et cela qui répond à deux questions connexes.
Si j'ai été chargé en 2020 d'écrire un compilateur C (ou C ++) à partir de zéro (fonctionnant sous Linux, peut-être un compilateur croisé ), je ne l'écrirai probablement pas en C ++. J'envisagerais de l' écrire en utilisant Ocaml , Go ou Rust . Et je pourrais le baser sur Frama-C si cela était permis. Si je devais coder en C ou C ++, je coderais d'abord une bibliothèque de garbage collector pour cela, probablement une couche de persistance - très utile pour l'optimisation de programme entier - et ensuite je considérerais une approche de métaprogrammation (générant la plupart du code C ou C ++ du compilateur avec mes outils ad-hoc, peut-être Bismon ou RefPerSys si cela est autorisé).
Vous pouvez trouver des compilateurs C (plus ou moins open source) codés en Common Lisp ou en Python (par exemple ShivyC ou nqcc ). Regardez également dans ZetaC .
Notez que les versions récentes de GCC ne sont pas techniquement codées en C ++ pur, elles sont une douzaine de langages spécifiques à un domaine impliqués dans GCC (plusieurs d'entre eux étant Turing-complete ). Voir aussi mon ancien projet GCC MELT .
Je ne serai pas surpris si, dans les futures versions de GCC, un interpréteur Python ou Guile serait intégré à l'intérieur (par exemple, en remplacement du gestionnaire de passes de GCC).
Consultez également le projet MILEPOST GCC .
la source