Up Next

Qu’est-ce qu’un compilateur ?

Cette question est en fait bien de nature plus pratique que théorique. Étant acquis que l’on sait déjà ce qu’est un langage de programmation et un programme.

On constate en pratique deux façons d’exécuter ses programmes. La première technique est dite interprétation, un programme (l’interpréteur) lit votre programme à vous et l’exécute. Cette technique tend à disparaître pour les langages d’usage général, mais elle survit bien dans des contextes plus spécialisés. Par exemple, la vaste majorité des imprimantes fabriquent les pages qu’elles impriment en interprétant un langage (le Postscript), les commandes que vous tapez en Unix sont interprétées (et exécutées) par le shell qui n’est rien d’autre qu’un interpréteur, on peut aussi citer JavaScript, interprété par les brouteurs (browsers) web, etc. L’autre technique consiste à compiler. En pratique, un compilateur lit votre programme et le transforme en un exécutable, c’est à dire quelque chose que la machine peut exécuter directement, disons une suite d’entiers que le processeur de votre machine comprend comme des instructions.

L’expérience montre l’avantage principal de la compilation sur l’interprétation : les programmes s’exécutent plus rapidement. Cela s’explique par ce que certaines opérations sont faites par le compilateur et ne seront donc plus à faire lors de l’exécution. Pour bien comprendre prenons un programme qui contient l’affectation d’un entier 123 à une variable x. L’interpréteur doit lire les trois caractères, les transformer en un entier machine, puis ranger cet entier dans x. Le compilateur va, quant à lui, lire les caractères, les transformer en un entier machine, puis produire le code qui range l’entier dans la variable x. Dès lors, à l’exécution le programme compilé se contente de ranger l’entier machine dans x, soit grosso-modo une seule instruction machine, tandis que l’interpréteur doit exécuter des dizaines, voire des centaines d’instructions pour arriver au même résultat.

Bien sûr, dans la réalité, les choses sont moins nettes, (par exemple, si l’affectation précédente est dans une boucle, un interpréteur ne lira généralement les trois caractère qu’une seule fois) mais l’idée à retenir est que le compilateur réalise par avance certaines des opérations demandées par l’exécution du programme. Cette idée va assez loin, des opérations qui semblent élémentaires telles que « lire le contenu d’une variable », pouvant se décomposer en des opérations effectuées à la compilation (ici, associer le nom de la variable à disons un emplacement dans la mémoire) et des opérations effectuées à l’exécution (ici, lire le contenu de l’emplacement mémoire).

De façon parfois un peu abusive, on étend le sens du mot compilateur (présenté ci-dessus comme un traducteur d’un langage de programmation vers des instructions machines) pour l’appliquer à n’importe quel traducteur. Typiquement, toutefois on s’attend à ce que le langage d’entrée, ou langage source, soit de plus haut-niveau que le langage de sortie, ou langage cible. Cette idée de haut-niveau signifie que le langage source contient des construction synthétiques, faciles à comprendre par un homme, tandis que le langage cible exprime des opération élémentaires, faciles à réaliser par une machine. Par exemple, on peut légitiment considérer qu’un traducteur qui transforme la construction de filtrage de Caml (le match) en cascades de tests simples (des if) est bien un compilateur. En poussant un peu le raisonnement dans ses retranchements, un traducteur de Pascal vers C peut être vu comme un compilateur, car Pascal contient nombre de constructions qui n’existent pas en C (par exemple, les constructions d’ensemble ou les procédures locales).


Up Next