Compilateur

Compilateur
Page d'aide sur l'homonymie Pour les articles homonymes, voir Compilation.

Un compilateur est un programme informatique qui traduit un langage (appelé le langage source) en un autre (le langage cible), généralement dans le but de créer un exécutable.

Un compilateur sert le plus souvent à traduire un code source écrit dans un langage de programmation en un autre langage, habituellement un langage d'assemblage ou un langage machine. Le programme en langage machine produit par un compilateur est appelé code objet.

Sommaire

Historique

Le premier compilateur, A-0 System, a été écrit en 1951 par Grace Hopper.

Structure et fonctionnement

Schéma de compilation multi-source multi-cible

La tâche principale d'un compilateur est de produire un code objet correct qui s'exécutera sur un ordinateur. La plupart des compilateurs permettent d'optimiser le code, c'est-à-dire qu'ils vont chercher à améliorer la vitesse d'exécution, ou réduire l'occupation mémoire du programme.

En général, le langage source est « de plus haut niveau » que le langage cible, c'est-à-dire qu'il présente un niveau d'abstraction supérieur. De plus, le code source du programme est généralement réparti dans plusieurs fichiers.

Un compilateur fonctionne par analyse-synthèse : au lieu de remplacer chaque construction du langage source par une suite équivalente de constructions du langage cible, il commence par analyser le texte source pour en construire une représentation intermédiaire qu'il traduit à son tour en langage cible.

On sépare le compilateur en au moins deux parties : une partie avant (ou frontale), parfois appelée « souche », qui lit le texte source et produit la représentation intermédiaire ; et une partie arrière (ou finale), qui parcourt cette représentation pour produire le texte cible. Dans un compilateur idéal, la partie avant est indépendante du langage cible, tandis que la partie arrière est indépendante du langage source. Certains compilateurs effectuent des traitements substantiels sur la partie intermédiaire, devenant une partie centrale à part entière, indépendante à la fois du langage source et de la machine cible. On peut ainsi écrire des compilateurs pour toute une gamme de langages et d'architectures en partageant la partie centrale, à laquelle on attache une partie avant par langage et une partie arrière par architecture.

Schéma d'une chaîne de compilation classique.

Les étapes de la compilation incluent :

  • le prétraitement, nécessaire pour certaines langues comme C, qui prend en charge la substitution de macro et de la compilation conditionnelle.
Généralement, la phase de prétraitement se produit avant l'analyse syntaxique ou sémantique ; par exemple dans le cas de C, le préprocesseur manipule les symboles lexicaux plutôt que des formes syntaxiques.
  • l'analyse lexicale, qui découpe le code source en petits morceaux appelés jetons (tokens).
Chaque jeton est une unité atomique unique de la langue (unités lexicales ou lexèmes), par exemple un mot-clé, un identifiant ou un symbole. La syntaxe de jeton est généralement un langage régulier, donc un automate à états finis construits sur une expression régulière peut être utilisé pour le reconnaître.
Cette phase est aussi appelée à balayage ou lexing ; le logiciel qui effectue une analyse lexicale est appelé un analyseur lexical ou un scanner. Deux exemples classiques : lex et flex.
  • l'analyse syntaxique implique l'analyse de la séquence jeton pour identifier la structure syntaxique du programme.
Cette phase s'appuie généralement sur la construction d'un arbre d'analyse ; on remplace la séquence linéaire des jetons par une structure en arbre construit selon la grammaire formelle qui définit la syntaxe du langage. Par exemple, une condition est toujours suivi d'un test logique (égalité, comparaison...). L'arbre d'analyse est souvent modifié et amélioré au fur et à mesure de la compilation. Yacc et GNU Bison sont les analyseurs syntaxiques les plus utilisés.
Cette phase vérifie le type (vérification des erreurs de type), ou l'objet de liaison (associant variables et références de fonction avec leurs définitions), ou une tâche définie (toutes les variables locales doivent être initialisées avant utilisation), peut émettre des avertissements, ou rejeter des programmes incorrects.
L'analyse sémantique nécessite habituellement un arbre d'analyse complet, ce qui signifie que cette phase fait suite à la phase d'analyse, et précède logiquement la phase de génération de code ; mais il est possible de replier ces phases en une seule passe.
  • la transformation du code source en code intermédiaire ;
  • l'application de techniques d'optimisation sur le code intermédiaire : c'est-à-dire rendre le programme « meilleur » selon son usage (voir infra).
  • la génération de code avec l'allocation de registres et la traduction du code intermédiaire en code objet, avec éventuellement l'insertion de données de débogage et d'analyse de l'exécution ;
  • et finalement l'édition des liens.

L'analyse lexicale, syntaxique et sémantique, le passage par un langage intermédiaire et l'optimisation forment la partie frontale. La génération de code et l'édition de liens constituent la partie finale.

Ces différentes étapes font que les compilateurs sont toujours l'objet de recherches.

Lien avec les interpréteurs

L'implémentation (réalisation concrète) d'un langage de programmation peut être interprétée ou compilée. Cette réalisation est un compilateur ou un interpréteur, et un langage de programmation peut avoir une implémentation compilée, et une autre interprétée.

Le problème de l'amorçage (bootstrap)

Article détaillé : Bootstrap (compilateur).

Les premiers compilateurs ont été écrits directement en langage assembleur, un langage symbolique élémentaire correspondant aux instructions du processeur cible et quelques structures de contrôle légèrement plus évoluées. Ce langage symbolique doit être assemblé (et non compilé) et lié pour obtenir une version exécutable. En raison de sa simplicité, un programme simple suffit à le convertir en instructions machines.

Les compilateurs actuels sont généralement écrits dans le langage qu'ils doivent compiler ; par exemple un compilateur C est écrit en C, SmallTalk en SmallTalk, Lisp en Lisp, etc. Dans la réalisation d'un compilateur, une étape décisive est franchie lorsque le compilateur pour le langage X est suffisamment complet pour se compiler lui-même : il ne dépend alors plus d'un autre langage (même de l'assembleur) pour être produit.

Il est complexe de détecter qu'un compilateur bug. Par exemple, si un compilateur C comporte un bug, les programmeurs en langage C auront naturellement tendance à mettre en cause leur propre code source, non pas le compilateur. Pire, si ce compilateur buggé (version V1) compile un compilateur (version V2) non buggé, l'exécutable compilé (par V1) du compilateur V2 pourrait être buggé. Pourtant son code source est bon. Le bootstrap oblige donc les programmeurs de compilateurs à contourner les bugs des compilateurs existants.

Compilateur simple passe et multi passe

Compilateur multi-passes typique

La classification des compilateurs par nombre de passes a pour origine le manque de ressources matérielles des ordinateurs. La compilation est un processus couteux et les premiers ordinateurs n'avaient pas assez de mémoire pour contenir un programme devant faire ce travail. Les compilateurs ont donc été divisés en sous programmes qui font chacun une lecture de la source pour accomplir les différentes phases d’analyse lexicale, d'analyse syntaxique et d'analyse sémantique.

La capacité de combiner le tout en un seul passage a été considérée comme un avantage car elle simplifie la tâche d'écriture d’un compilateur et il compile généralement plus rapidement qu’un compilateur multi passe. Ainsi, suivant les ressources limitées des premiers systèmes, de nombreux langages ont été spécifiquement conçus afin qu'ils puissent être compilés en un seul passage (par exemple, le langage Pascal).

Dans certains cas, la conception d'une fonctionnalité de langage a besoin d'un compilateur pour effectuer plus d'une passe sur la source. Par exemple, considérons une déclaration figurant à la ligne 20 de la source qui affecte la traduction d'une déclaration figurant à la ligne 10. Dans ce cas, la première passe doit recueillir des renseignements sur les déclarations figurant après les déclarations qu'ils affectent, avec la traduction proprement dite qui s’effectue lors d'un passage ultérieur.

L'inconvénient de la compilation en un seul passage est qu'il n'est pas possible d'exécuter la plupart des optimisations sophistiquées nécessaires pour générer du code de haute qualité. Il peut être difficile de dénombrer exactement le nombre de passes qu’un compilateur optimisant effectue.

Le fractionnement d'un compilateur en petits programmes est une technique utilisée par les chercheurs intéressés à produire des compilateurs performants. Prouver la justesse d'une série de petits programmes nécessite souvent moins d'effort que de prouver la justesse d'un plus grand programme unique équivalent.

Compilateur de compilateur

Article détaillé : Compilateur de compilateur.

Un compilateur de compilateur est un programme qui peut générer une, voir toutes les parties d'un compilateur.

Qualité

Article connexe : Optimisation de code.

Selon l'usage et la machine qui va exécuter un programme, on peut vouloir optimiser la vitesse d'exécution, l'occupation mémoire, la consommation d'énergie, la portabilité sur d'autres architectures, ou le temps de compilation.

Compilateurs particuliers

Compilateur croisé

Un compilateur croisé (en anglais Cross Compiler (en)) est un programme capable de traduire un code source en code objet ayant un environnement d'exécution (architecture matérielle, système d'exploitation) différent de celui où la compilation est effectuée. Ces compilateurs sont principalement utilisés en informatique industrielle et dans les Systèmes embarqués.

Byte code ou code octet

Certains compilateurs traduisent un langage source en langage machine virtuel, c'est-à-dire en un code (généralement binaire) exécuté par une machine virtuelle : un programme émulant les principales fonctionnalités d'un ordinateur. Le portage d'un programme ne requiert ainsi que le portage de la machine virtuelle. C'est le cas du compilateur Java, qui traduit du code Java en bytecode Java (code objet).

Autres compilateurs

Si la plupart des compilateurs traduisent un code d'un langage de programmation vers un autre, ce n'est pas le cas de tous les compilateurs. Par exemple, le logiciel LaTeX compile un code écrit dans le langage de formatage de texte LaTeX, pour le convertir en un autre langage de présentation, par exemple DVI, HTML, PostScript...

Certains compilateurs traduisent, de façon incrémentale ou interactive, le programme source (tapé par l'utilisateur) en code machine. Par exemple, certaines implémentations de Common Lisp (comme SBCL) traduisent un bout de programme en code machine (en mémoire).

Les compilateurs à la volée (Just in time) traduisent une représentation intermédiaire en code machine, de manière progressive.

Exemple

  • gcc est une suite de compilation particulièrement connue, beaucoup utilisée pour les langage C et C++, mais également Java ou encore Ada.
  • Clang est un front-end pour les langages de la famille du C, utilisant le back-end LLVM
  • Javac, le compilateur Java le plus répandu
  • GHC, un compilateur pour Haskell, lui aussi basé sur la LLVM
  • De nombreux autres, pour les mêmes langages et pour d'autres

Voir aussi

Bibliographie

  • Alfred Aho, Monica Lam, Ravi Sethi et Jeffrey Ullman (trad. Philippe Deschamp, Bernard Lorho, Benoît Sagot et François Thomasset), Compilateurs : principes, techniques et outils [« Compilers: Principles, Techniques, and Tools »], France, Pearson, novembre 2007, 2e éd. (1re éd. 1977), 928 p. (ISBN 978-2-7440-7037-2) [présentation en ligne].
    appelé aussi le Dragon Book
     

Articles connexes

Liens externes


Wikimedia Foundation. 2010.

Contenu soumis à la licence CC-BY-SA. Source : Article Compilateur de Wikipédia en français (auteurs)

Игры ⚽ Поможем сделать НИР

Regardez d'autres dictionnaires:

  • compilateur — compilateur, trice [ kɔ̃pilatɶr, tris ] n. • 1425; lat. compilator I ♦ 1 ♦ Didact. Personne qui réunit des documents dispersés. « Lecteurs, distinguez l auteur du compilateur » (Restif). 2 ♦ Péj. Auteur qui emprunte aux autres (opposé à créateur) …   Encyclopédie Universelle

  • compilateur — COMPILATEUR. s. m. Celui qui compile. Grand, habile compilateur. Cet Auteur n est qu un simple compilateur …   Dictionnaire de l'Académie Française 1798

  • compilateur — Compilateur. s. m. Celuy qui compile. Grand, habile, simple compilateur …   Dictionnaire de l'Académie française

  • compilateur — (kon pi la teur) s. m. Celui qui compile.    Dans un sens favorable. Celui qui réunit en un seul corps des documents dispersés. Duchêne, qui a donné cinq volumes de l histoire de France, est un utile compilateur. •   Tribonien, compilateur du… …   Dictionnaire de la Langue Française d'Émile Littré

  • COMPILATEUR — s. m. Celui qui compile. Grand compilateur. Laborieux, habile compilateur. Cet auteur n est qu un simple compilateur …   Dictionnaire de l'Academie Francaise, 7eme edition (1835)

  • compilateur — kompiliatorius statusas T sritis automatika atitikmenys: angl. compiler vok. Übersetzer, m; Kompilierer, m rus. компилятор, m pranc. compilateur, m …   Automatikos terminų žodynas

  • Compilateur croisé — Compilateur Pour les articles homonymes, voir Compilation. Un compilateur est un programme informatique qui traduit un langage, le langage source, en un autre, appelé le langage cible, en préservant la signification du texte source. Ce schéma… …   Wikipédia en Français

  • Compilateur De Compilateur — Un compilateur de compilateur est un programme informatique capable de produire la totalité ou certaines parties de compilateur (partie analyse lexicale, partie analyse syntaxique, partie analyse sémantique, partie synthèse, partie de gestion des …   Wikipédia en Français

  • Compilateur de compilateur — Un compilateur de compilateur est un programme informatique capable de produire la totalité ou certaines parties de compilateur (partie analyse lexicale, partie analyse syntaxique, partie analyse sémantique, partie synthèse, partie de gestion des …   Wikipédia en Français

  • Compilateur Java — Un compilateur Java est un compilateur pour le langage de programmation Java. Le format de sortie le plus courant pour un compilateur Java sont des fichiers .class contenant le bytecode Java plate forme agnostique. Il existe aussi des… …   Wikipédia en Français

Share the article and excerpts

Direct link
Do a right-click on the link above
and select “Copy Link”