Bootstrap (compilateur)

compilateur

Le bootstrapping ou auto-amorçage est, en informatique, une technique consistant à créer un compilateur (ou un programme assembleur) en utilisant le langage de programmation qu'il doit compiler (ou assembler). Pour cela, on part d'un premier compilateur minimal, appelé Amorce, écrit de façon classique, permettant de traduire un sous-ensemble réduit du langage; le compilateur définitif est alors écrit dans ce sous-langage et compilé avec l'amorce. Cette technique s'applique aussi bien sur un même système qu'en portage d'un système à l'autre. Vu leur complexité, l'auto-amorçage permet de réduire l'effort et le temps de développement des compilateurs, en utilisant un langage de plus haut niveau que ceux disponibles pour le système cible considéré[1].

Histoire modifier

NELIAC (en), un dialecte d'Algol 58, a été le premier langage à fournir un bootstrap.

Au début des années 1960, l'Algol du Burroughs 5 000, permit à Burroughs de développer ses futurs systèmes d'exploitation sur la base d'Algols étendus : Grands systèmes Burroughs (en) .

En 1962, Hart et Levin écrivent un compilateur Lisp en Lisp. Ils le testèrent à l'aide d'un interprète Lisp, assimilant tout programme à une expression Lisp .

En 1968-1969, PL1 Multics est développé ainsi chez GE.

Une présentation générale de la stratégie de bootstrapping a été faite en 1971[2] et fut l'occasion de présenter les diagrammes de Tombstone (en) qui permettent de la visualiser.

Phases modifier

Amorce modifier

Soit   le langage à traiter, et   un langage disponible : on commence par écrire en   un petit compilateur de  , produisant une image dans un langage   exécutable dans le même environnement. Il suffit que ce premier compilateur traduise exactement les programmes n'utilisant qu'un sous-ensemble   contenant les constructions nécessaires de  . Un tel compilateur sera noté symboliquement  .

De tels compilateurs furent longtemps développés en assembleur. Les premiers compilateurs peuvent être maintenant écrits en C ou dans un langage spécialisé dans l'écriture de compilateurs.

Améliorations modifier

Soit un premier compilateur noté  , écrit en   et traduisant un sous-ensemble   de L dans un langage exécutable  [3]. En transcrivant son analyse de   en  , nous obtenons un nouveau compilateur   . Compilé par le premier, il donne un nouveau  .

Soit maintenant   une version étendue de (2); compilée par (1), on obtiendra de même  .

(5) se présente alors comme une extension de (1) bénéficiant des extensions introduites par (4), et   peut être oublié au profit de  .

Avec (6) traitant en   une nouvelle extension  , on obtiendra de même (7), rendant   utilisable au lieu de   et  ...

Cette stratégie de prototypage évolutif (en) permet d'étendre la puissance du langage effectif, d'abord réduit au strict nécessaire (par exemple, la forme itérative la plus générale), puis étendu aux constructions "de confort" (comme les formes itératives secondaires), voire à d'éventuelles extensions ; c'est ainsi que des sur-ensembles de Java sont bootstrappés.

D'une version à l'autre, les développeurs du compilateur devenant leurs propres utilisateurs, les améliorations peuvent également porter sur la qualité de la détection d'erreurs et du code engendré.

L'équipe de Niklaus Wirth tenta de réaliser le premier compilateur Pascal en Fortran, qui se révéla insuffisant. Elle fit une nouvelle tentative en utilisant Pascal comme notation algorithmique du nouveau compilateur, et traduisit à la main cette spécification détaillée. Elle obtint ainsi un compilateur de type natif pour CDC 6600, et un compilateur auto-porteur qui lui permirent une succession d'améliorations.

Portage modifier

Supposons que l'on dispose d'un couple   .

En modifiant la génération de   on obtient un  ; en le compilant dans le premier environnement, on obtient le nouveau compilateur  .

En 1975, H.H. Nägeli écrivit un trunk compiler pour faciliter le portage de Pascal. C'était un compilateur de Pascal écrit en Pascal, séparant nettement les parties indépendantes des parties dépendantes de la machine-cible, comme les séquences de génération ; un commentaire détaillé pour ces dernières permettait à un compiliste de les adapter à une nouvelle machine. C'est ainsi que l'INRIA put faire en 9 mois-hommes un compilateur croisé, tournant sur CDC mais traduisant Pascal en code pour l'Iris 80 ainsi qu'un compilateur Pascal, fonctionnant pour et sur l'Iris 80. Ce dernier, écrit en Pascal, étant de ce fait facile à maintenir et à améliorer.

Cas de la semi-compilation modifier

On parle de semi-compilation quand le compilateur produit non un code machine natif (propre à l'environnement visé) mais un pseudo-code (ou bytecode ) P relatif à une machine virtuelle pouvant exécuter le langage au mieux.

Le produit générique est alors un couple   .

  •   est exécutable dès que P l'est dans l'environnement donné ; un interprète de P est alors suffisant pour la programmation exploratoire ;
  • au-delà, si on adjoint à   un générateur  , on obtient un compilateur  , et si nécessaire un compilateur  ,.

Cette technique a pu utiliser un P-code (Pascal), un M-code (Modula), un S-code (Simula), un J-code (Java) etc.

Intérêt modifier

Cette approche peut être à la fois le support d'un compilateur multi-cible, ayant un analyseur et un générateur d'un pseudo-code commun P, puis autant de générateurs finaux que de machines cibles.

Elle peut être au cœur d'un atelier logiciel dont les langages partageraient le même pseudo-code P, surtout si celui-ci reste réversible.

Exemples de langages informatiques bootstrappés modifier

  • Algol 58,
  • C,
  • Lisp, dont le compilateur original a été produit par un interpréteur (première occurrence de ce genre de bootstrap), puis compilé par ce même compilateur[4].

Emplois modifier

Les méthodes pour distribuer des compilateurs en code source incluent la fourniture d'un bytecode portable du compilateur, afin de bootstrapper le système de compilation du compilateur avec lui-même.

Aujourd'hui, une large proportion des langages de programmation sont bootstrappés : C, Scheme, Ocaml, Pascal, Modula-2, Oberon, Perl 6, Java, C#.

Notes modifier

  1. Alfred Aho, Compilateurs. Principes, techniques et outils, Paris, InterEditions, , 877 p. (ISBN 2-7296-0295-X), p. 789-793
  2. (en) William Marshall McKeeman, James J. Horning et David B. Wortman, A Compiler Generator, Prentice Hall, , 527 p. (ISBN 978-0131550773).
  3. code machine par exemple
  4. (en) Tim Hart, AI Memo 39 - The New Compiler (lire en ligne)

Voir aussi modifier

Liens externes modifier