Démarrer un simple (le plus simple peut-être) compilateur C?

je suis tombé sur ceci: Écrire un compilateur en utilisant Turbo Pascal

je suis curieux s'il y a des tutoriels ou des références expliquant comment créer un simple compilateur C. Je veux dire, c'est assez si ça m'amène au niveau de lui faire comprendre les opérations arithmétiques. Je suis devenu vraiment curieux après avoir lu cet article par Ken Thompson . L'idée d'écrire quelque chose qui se comprend semble excitante.

Pourquoi ai-je posé cette question au lieu de poser la question à Google? J'ai essayé Google et le Pascal était le premier lien. Le reste ne semblait pas pertinent et ajouté à cela... Je ne suis pas un CS majeur (donc j'ai encore besoin d'apprendre ce que font tous ces outils comme yacc) et je veux apprendre cela en faisant et j'espère que les gens avec plus d'expérience sont toujours meilleurs à ces choses que Google. Je veux lire l'article écrit dans le même esprit que celui que j'ai énumérés ci-dessus, mais ce qui met en évidence au moins les phases de bootstrapping de la construction d'un simple compilateur C.

Aussi, je ne sais pas la meilleure façon d'apprendre. Est-ce que je commence à construire un compilateur C en C ou dans une autre langue? Est-ce que j'écris un compilateur C ou un autre langage? Je pense que les questions de ce genre sont mieux répondues une fois que j'ai une orientation à explorer. Toutes les suggestions?

des suggestions?

39
demandé sur Legend 2010-02-28 03:02:05

12 réponses

un compilateur se compose de trois pièces:

    "151930920 Un" analyseur
  1. Un arbre de syntaxe abstraite (AST)
  2. générateur de code

il y a beaucoup de générateurs d'analyseurs qui commencent avec des grammaires de langue. ANTLR serait peut-être un bon endroit pour commencer. Si vous voulez vous en tenir aux racines de C, essayez lex/yacc ou bison.

il y a des grammaires pour C, mais je pense que C dans son tout est complexe. Vous feriez bien de commencer avec un sous-ensemble de la langue et de travailler votre chemin jusqu'à.

une fois que vous avez un AST, vous l'utilisez pour générer le code machine que vous lancerez.

C'est faisable, mais pas triviale.

je vérifierais aussi Amazon pour des livres sur l'écriture de compilateurs. Le livre du Dragon est le classique, mais il y en a d'autres plus modernes disponibles.

mise à jour: Il ya eu des questions similaires sur Débordement de pile, comme celui-ci . Consultez ces ressources.

25
répondu duffymo 2017-05-23 12:17:47

je vous conseille ce tutoriel:

C'est un petit exemple sur la façon d'implémenter un compilateur "petit langage". Le code source est très petit et s'explique pas à pas.

il y a aussi la bibliothèque frontale C pour la bibliothèque LLVM (Low Level Virtual Machine qui représente la structure interne d'un programme):

25
répondu Phong 2010-02-28 00:12:05

pour ce que ça vaut, le Tiny C Compiler est un compilateur C assez complet dans un paquet source relativement petit. Vous pourriez bénéficier d'étudier cette source, car il est probablement beaucoup plus facile à comprendre que d'essayer de comprendre toute la base des sources de GCC, par exemple.

15
répondu Mark Rushakoff 2010-02-28 00:12:05

C'est mon opinion (et de la conjecture), il sera difficile d'écrire un compilateur sans la compréhension des structures de données normalement couverts de premier cycle (post-secondaire) des cours d'Informatique. Cela ne signifie pas que vous ne pouvez pas, mais vous aurez besoin de connaître les structures de données essentielles telles que les listes liées et les arbres.

plutôt que d'écrire un compilateur de langue C complet ou conforme aux normes (au moins au début), je suggérerais de vous limiter à un sous-ensemble de base de la le langage, comme les opérateurs communs, le support entier seulement, et les fonctions de base et les pointeurs. Un exemple classique en est le de Ron Cain, "Small-C , rendu populaire par une série d'articles écrits dans Dr. Dobbs Journal in I believe the 1980s. Ils publient un CD avec le livre out-of-print de James Hendrix, un petit-C compilateur .

ce que je suggère est de suivre Crenshaw tutoriel, mais écrivez-le pour un compilateur de langage de type C, et quelle que soit la cible CPU (Crenshaw cible le CPU Motorola 68000) que vous souhaitez cibler. Pour ce faire, vous aurez besoin de connaître l'assemblage de base sur lequel vous voulez lancer les programmes compilés. Cela pourrait inclure un émulateur pour un 68000, ou des MIPS qui sont sans doute plus agréables ensembles d'instruction d'assemblage que le vénérable ensemble D'instruction CISC du Intel x86 (16/32 bits).

là sont de nombreux livres potentiels qui peuvent être utilisés comme points de départ pour l'apprentissage de la théorie du compilateur / traducteur (et la pratique). Lisez le comp.compilateurs FAQ , et des critiques à divers vendeurs de livres en ligne. La plupart des livres d'introduction sont écrits comme des manuels pour les étudiants de deuxième et troisième cycle de premier cycle en informatique, de sorte qu'ils peuvent être la lecture lente sans un cs de base. Un vieux livre qui pourrait être plus introductif, mais plus facile à lire que le Dragon Livre " est Introduction à Compilateur Construction par Thomas Parsons. Il est plus ancien, donc vous devriez être en mesure de trouver une copie utilisée de votre choix de libraires en ligne à un prix raisonnable.

donc je dirais, essayer de commencer avec de Jack Crenshaw "construisons un compilateur tutoriel, écrivez votre propre, en suivant ses exemples comme un guide, et construire les bases d'un simple compilateur. Une fois que vous avez ce travail, vous pouvez mieux décider où vous souhaitez le prendre à partir de ce point.

ajouté:

en ce qui concerne le processus de bootstrapping. Comme il existe des compilateurs C disponibles gratuitement, vous n'avez pas à vous soucier de bootstrapping. Écrivez votre compilateur avec des outils séparés et existants (GCC, Visual C++ Express, Mingw / djgpp, tcc), et vous pouvez vous soucier de compiler vous-même votre projet à plus tard. J'ai été surpris par cette partie de la question jusqu'à ce que je réalise que vous avez été amenés à l'idée d'écrire votre propre compilateur en lisant le discours de Ken Thomas sur le prix ACM Turing, réflexions sur la confiance , qui va dans le processus de bootstrapping du compilateur. C'est un sujet avancé modéré, et est aussi tout simplement beaucoup de tracas ainsi. Je trouve même bootstrapping le compilateur GCC C sous des systèmes Unix plus anciens (OSF / 1 numérique sur le 64-bit Alpha) cela incluait un compilateur C, un processus lent et chronophage, sujet aux erreurs.

l'autre type de question était ce qu'un outil de compilation comme Yacc fait réellement. Yacc (encore un autre compilateur ou Bison de GNU) est un outil conçu pour faciliter l'écriture d'un analyseur de compilateur (ou Traducteur). Basé sur la "grammaire formelle pour votre langue cible que vous entrez à yacc, il génère un parser , qui est une partie d'un la conception globale du compilateur. Ensuite, Lex (ou flex de GNU) qui produisait un analyseur lexical ou scanner, qui est souvent utilisé en combinaison avec l'analyseur généré par le yacc pour former le squelette de la face avant d'un compilateur. Ces outils font de writer un front end sans doute plus facile que d'écrire un analyseur et un analyseur lexical vous-même. Le tutoriel de Crenshaw n'utilise pas ces outils, et vous n'en avez pas besoin non plus, de nombreux auteurs de compilateurs ne les utilisent pas toujours. Bien sûr Crenshaw admet que l'analyseur du tutoriel est assez basique.

le tutoriel de Crenshaw évite également de générer un AST (arbre de syntaxe abstraite), ce qui simplifie mais limite également le compilateur du tutoriel. Elle manque de la plupart sinon de la totalité de l'optimisation, et est très liée au langage de programmation spécifique et au langage de montage particulier émis par le "back-end" du compilateur. Normalement, L'AST est une pièce intermédiaire où une certaine optimisation peut être effectuée, et sert à découpler le compilateur le front-end et back-end dans la conception. Pour un débutant sans formation en informatique, je suggère de ne pas s'inquiéter de ne pas avoir un AST pour votre premier compilateur (ou au moins la première version de celui-ci). Je pense que le garder petit et simple vous aidera à finir d'écrire un compilateur, dans sa première version, et vous pourrez décider à partir de là comment vous voulez procéder alors.

11
répondu mctylr 2014-02-20 16:22:51

Comment puis-je [commencer à écrire] un simple compilateur C?

il n'y a rien de simple dans la compilation de C . Le meilleur compilateur C simple est lcc de Chris Fraser et David Hanson. Ils ont passé 10 ans à travailler sur la conception pour le rendre aussi simple que possible, tout en générant raisonnablement bon code. Si vous avez accès à une bibliothèque universitaire, vous devriez être en mesure d'obtenir leur livre.

est-ce que je commence à construire un compilateur C en C ou dans une autre langue?

une autre langue. Une fois, J'ai pu demander à Hanson quelles leçons lui et Fraser avaient apprises en passant 10 ans sur le projet du lcc. La principale chose Hanson a dit était

C est un langage nul pour écrire un compilateur.

il vaut mieux utiliser Haskell ou un dialecte de ML. Les deux langues offrent des fonctions sur les types de données algébriques, ce qui est une correspondance parfaite aux problèmes rencontrés par l'auteur du compilateur. Si vous voulez toujours poursuivre C , vous pouvez commencer avec CIL de George Necula, qui est un gros morceau d'un compilateur C écrit en ML.

je veux lire un article écrit dans le même esprit que celui que j'ai énuméré ci-dessus mais qui met en évidence au moins les phases de bootstrapping...

vous ne trouverez pas un autre article comme celui de Ken. Mais Andrew Appel a écrit un bel article intitulé Axiomatic Bootstrapping: A Guide for Compiler Hackers Je ne pouvais pas trouver une version gratuite, mais beaucoup de gens ont accès à la Bibliothèque numérique ACM.

des suggestions?

Si vous voulez écrire un compilateur,

  • utilisez Haskell ou ML comme votre la mise en œuvre de la langue.

  • pour votre premier compilateur, choisissez un langage très simple comme Oberon ou comme P0 du livre de Niklaus Wirth algorithmes + structures de données = programmes . Wirth est célèbre pour ses langages faciles à compiler.

vous pouvez écrire un compilateur C pour votre second compilateur.

6
répondu Norman Ramsey 2010-02-28 02:49:39

vous pourriez être intéressé par le livre/cours les éléments des systèmes informatiques:la construction D'un ordinateur moderne à partir des premiers principes .

notez qu'il ne s'agit pas de construire un "pc" à partir de trucs que vous avez acheté à newegg. Il commence par une description des fondamentaux de la logique booléenne, et construit un ordinateur virtuel des niveaux les plus bas de l'abstraction aux niveaux de plus en plus élevés de l'abstraction. Les supports de cours sont tout en ligne, et le livre lui-même est assez peu coûteux D'Amazon.

dans le cours, en plus de" construire le matériel", vous mettrez également en œuvre un assembleur, machine virtuelle, compilateur, et OS rudimentaire, d'une manière progressive. Je pense que cela vous donnerait suffisamment de renseignements généraux pour approfondir le sujet avec certaines des ressources les plus souvent recommandées dans les autres réponses.

6
répondu Joe Internet 2010-02-28 05:09:43

Dans L'Environnement Unix , Kernighan et le Brochet à pied à travers 5 itérations de faire une calculatrice de travail de la simple C basé sur l'analyse lexicale et l'exécution immédiate de yacc/lex analyse et de génération de code pour une machine abstraite. Parce qu'ils écrivent si merveilleusement que je ne peux pas Suggérer une introduction plus douce. Il est certainement plus petite que C, mais c'est probablement à votre avantage.

5
répondu msw 2010-02-28 01:57:08

un compilateur est une matière complexe qui couvre des aspects de

  • de traitement d'Entrée impliquant Lexing, l'Analyse des
  • construction d'un magasin de symboles de chaque variable utilisée telle Qu'un arbre de syntaxe abstraite (AST)
  • de L'arbre AST, transposer et construire un code machine binaire basé sur la syntaxe

ce document n'est en aucun cas exhaustif, car il s'agit d'une vue d'ensemble abstraite du sommet. d'une montagne, il se résume à obtenir la notation syntaxique correcte et s'assurer que les entrées mal formées ne le rejettent pas, en fait un bon traitement d'entrée ne devrait jamais tomber sur ses genoux, peu importe comment malformé, terrible, abusé cas d'entrée qui se jette à lui. Et, aussi en décidant et en sachant ce que la sortie va être, est-il en code machine, ce qui implique que vous pourriez avoir à connaître les instructions du processeur intimement...y compris l'adressage de la mémoire pour les variables et ainsi de suite...

Voici quelques liens pour commencer:

  • il y avait le "port de Jack Crenshaw de son code pour C....(Je rappel le téléchargement de ce mois...)
  • , Voici un lien vers une question similaire ici .
  • aussi, voici un autre petit tutoriel de compilateur pour le compilateur de base à x86 assembleur.
  • Tiny C Compiler
  • Hendrix Petit C Compilateur ici .
5
répondu t0mm13b 2017-05-23 11:54:18

il pourrait être intéressant d'en apprendre davantage sur la programmation fonctionnelle. Les langages fonctionnels sont bien adaptés pour écrire un compilateur à la fois dans et pour . Le cours d'Introduction aux compilateurs de mon école contenait une introduction aux langues fonctionnelles et les devoirs étaient tous en OCaml.

drôle que vous devriez demander cela aujourd'hui, car il ya quelques jours, j'ai écrit un lambda calcul interprète. Lambda calculus est le grand-père de tous les langues fonctionnelles. C'est juste 200 lignes (en C++, incl. rapport d'erreur, quelques belles impressions, quelques unicode) et a une structure en deux phases, avec un format intermédiaire qui pourrait être utilisé pour générer du code.

non seulement commence petit et la construction de l'approche la plus pratique aux compilateurs, il encourage également la bonne, modulaire, pratique organisationnelle.

3
répondu Potatoswatter 2010-02-28 00:37:02

un compilateur est un très grand projet, bien que je suppose que ça ne ferait pas de mal d'essayer.

je connais au moins un compilateur C écrit en Pascal, donc ce n'est pas la plus chose folle que vous pourriez faire. Personnellement, je choisirais un langage plus moderne dans lequel implémenter mon projet de compilateur C, à la fois pour la simplicité (c'est facile pour les paquets d/l pour Python, Ruby, C, C++ ou Java) et parce qu'il aura l'air mieux sur votre CV.

pour faire un compilateur en tant que projet débutant, cependant, vous aurez besoin de boire tout le Agile kool-aid .

a toujours quelque chose qui tourne, même si ça ne fait pas grand chose. N'ajoutez des choses à votre compilateur que par petits pas. ("Des sorties fréquentes".) Choisissez un sous-ensemble infime de la langue et mettez-le en œuvre en premier. (Support uniquement i = 0; au premier abord, et élargir les choses à partir de là.)

3
répondu DigitalRoss 2010-02-28 01:31:34

si vous voulez une expérience époustouflante qui vous enseigne comment écrire des compilateurs qui compilent eux-mêmes, vous devez lire ce papier de 1964 .

MÉTA II une syntaxe orientée compilateur langue d'écriture par Val Schorre.

en 10 pages, il vous dit comment écrire des compilateurs, comment écrire des méta-compilateurs, fournit un jeu d'instructions metacompiler virtuel, et un exemple de compilateur construit avec le metacompiler.

j'ai appris à écrire des compilateurs à partir de ce papier à la fin des années 60, et utilisé les idées pour construire C-like langauges pour plusieurs mini-ordinateurs et microprocesseurs.

si le papier est trop par lui-même (ce n'est pas!) Il ya un tutoriel en ligne qui vous guidera à travers toute la chose.

et si obtenir le papier à partir du lien original est maladroit parce que vous n'êtes pas un ACM membre, vous constaterez que le tutoriel contient tous les détails de toute façon. (À mon humble avis, pour le prix, le document lui-même est waaaaay vaut).

de 10 pages!

3
répondu Ira Baxter 2010-03-01 03:04:51

Je ne recommande pas de commencer avec C comme langage à mettre en œuvre, ni avec aucun des outils compilateur-générateur ou parser-générateur. C est une langue très délicate, et c'est probablement une meilleure idée de créer votre propre langue. Il peut s'agir d'un petit C-like (par exemple, utilisez des backets bouclés si vous voulez indiquer le corps de la fonction, utilisez les mêmes noms de type, de sorte que vous n'avez pas à vous souvenir de ce que vous avez appelé tout).

les outils pour la fabrication des compilateurs et des parseurs sont grands, mais le problème d'être vraiment une notation abrégée. Si vous ne savez pas comment créer un compilateur en longhand, la sténographie semblera cryptique, inutilement restrictive, etc. Alors écrivez d'abord votre propre compilateur simple, puis continuez à partir de là. Je vous recommande aussi de ne pas commencer à générer du code machine réel à moins que vous ne mangiez et respiriez assembleur. Créez votre propre interpréteur de bytecode avec une VM.

quant à la langue que vous devez utiliser pour créer votre premier compilateur: cela n'a pas vraiment d'importance, tant que la langue est assez complète. Vous allez lire le texte d'entrée, construire des structures de données à partir de celles-ci et écrire des données binaires. Donc si une langue rend ces choses plus faciles d'une façon ou d'une autre, c'est un point en sa faveur. Choisissez une langue que vous connaissez bien, vous pouvez donc vous concentrer sur la création d'un compilateur, pas l'apprentissage de la langue. J'utilise habituellement un langage OO, ce qui rend l'arbre de syntaxe plus facile à écrire, un langage fonctionnel fonctionnerait probablement aussi si vous êtes familier avec cela.

j'ai beaucoup blogué sur les langages de programmation, donc vous pourriez trouver quelques articles utiles ici: http://orangejuiceliberationfront.com/category/language-design /

En particulier, http://orangejuiceliberationfront.com/how-to-write-a-compiler/ est un starter sur les détails de l'analyse commune des constructions et de générer quelque chose d'utile, ainsi que http://orangejuiceliberationfront.com/generating-machine-code-at-runtime / qui parle de cracher des instructions Intel qui font quelque chose.

oh, en ce qui concerne le bootstrapping d'un compilateur: vous ne pourrez probablement pas le faire dès le début. Il y a beaucoup de travail à faire pour créer un compilateur. Donc non seulement l'écriture d'un amorçage compilateur d'écriture, le compilateur (dans une autre langue), une fois que vous l'avez, vous serait alors écrire une deuxième version du compilateur lui-même. C'est deux fois plus de travail, plus le débogage nécessaire dans l'existant et le nouveau compilateur bootstrapped jusqu'à ce que tout fonctionne. Cela dit, une fois que vous avez un compilateur fonctionnel, c'est une bonne façon de tester son exhaustivité. Ok, peut-être pas deux fois le travail, mais plus de travail. J'irais d'abord pour les succès faciles, puis j'irais de là.

En tout cas, amusez-vous!

2
répondu uliwitness 2014-03-08 12:23:17