Implantation des langages de
programmation –
compilateurs et interpr`etes
Licence d’Informatique, Caen 1997/1998
Jerzy Karczmarczuk
Partie II
Copyright c
Jerzy Karczmarczuk
Chapitre 4
Les tˆaches et la structure d’un
compilateur
4.1 Un peu d’anatomie et de physiologie
La “vraie” compilation est la g´en´eration du code. Le nom, d’ailleurs, est historique ;
il signifiait le ramassage des morceaux du programme en une entit´e organique,
ex´ecutable. Les morceaux r´esidaient sur cartes perfor´ees, et la compilation ´etait
moins une translation, que le montage d’une pile.
Avant qu’un “ouvrage litt´eraire”, le texte source d’un programme ne se trans-
forme en quelque chose d’ex´ecutable, en une application ind´ependante, ou un tableau
interne ex´ecut´e par un interpr`ete, il faut comprendre le texte du programme, l’anal-
yser, le d´ecomposer en unit´es primitives, et ensuite, `a partir d’une description tr`es
pr´ecise et compl`ete de ses ´el´ements et de sa structure, on peut cr´eer le code pour
une machine-cible. Alors la compilation se d´ecompose par convention en deux phases
majeures :
L’analyse,
La synth`ese
mais il est n´ecessaire de comprendre que cette division n’implique pas que les deux
phases soient vraiment distinctes, assez souvent elles se recouvrent partiellement,
elles se chevauchent, et le compilateur bascule entre deux modes de travail plusieurs
fois durant un cycle de travail. De plus, la phase d’optimisation de code poss`ede
d’habitude des modules analytiques et synth´etiques, et la table des symboles qui
assure la correspondance entre les noms et les r´ef´erences, est g´er´ee simultan´ement
par les deux cat´egories de modules.
L’analyse est d’habitude divis´e en analyses : lexicale, syntaxique et s´emantique,
ce qui facilite la conceptualisation et la modularisation de l’analyseur, et permet
l’usage des outils simples pour des tˆaches simples. Par exemple, l’analyse lexicale
s’appuie sur les automates finis, sans m´emoire, tandis que la structure r´ecursive
phrasale d’un langage nontrivial exige que l’analyseur syntaxique g`ere une pile.
Mais – soulignons – cette s´eparation est vraiment conventionnelle, et pour nous
elle sera secondaire. Une vision globale, homog`ene est pour nous plus importante
que la modularisation. Un officier, par exemple un strat`ege du Quartier G´en´eral
voit l’arm´ee `a travers les Forces, les Divisions, les Unit´es ; il distribue les tˆaches et
2
4.1 Un peu d’anatomie et de physiologie 3
organise la communication globale. Mais pour son sup´erieur, le P`ere de la Nation,
il existe une arm´ee qui doit gagner la guerre, et doit g´erer cette arm´ee de mani`ere
uniforme. Et vous pensez que le mot “uniforme” vient d’o`u ?
´
Egalement la synth`ese tout court couvre la synth`ese d’un code interm´ediaire,
son optimisation (qui partiellement appartient `a l’analyse, pour rendre cette toile
d’araign´ee un peu plus ineressante) et – ´eventuellement – la sortie du code final,
si telle est la strat´egie du compilateur. Parfois on arrˆete la synth`ese assez tˆot et on
ex´ecute directement le code interm´ediaire ; tel est le cas des interpr`etes classiques,
comme les interpr`etes du Basic,Lisp,Prolog ou FORTH. (Mais presque jamais cette
ex´ecution ne se fait “instruction par instruction”, ce que sugg`erent quelques auteurs
des livres sur la compilation.)
Cette “ex´ecution” ne doit pas forc´ement sugg´erer les calculs num´eriques sugg´er´es
par les machines virtuelles montr´ees pr´ec´edemment, ou la recherche dans les bases de
donn´ees. Il y a des compilateurs dont le code-cible sont des commandes graphiques
qui permettent de programmer un dessin technique ou une sc`ene d’animation. Ce
texte a ´et´e format´e par un metteur en page sp´ecialis´e, T
EX ´equip´e avec un interpr`ete
de commandes (macros) tr`es puissant. Nous l’avons tap´e en utilisant un ´editeur
textuel standard. Si nous voulions taper une formule math´ematique vraiment atroce,
comme, par exemple
X
n=0
αn
qn2+1
2
nous’´ecririons :
$$
\sum_{n=0}^\infty{{\alpha^n \over \sqrt{n^2+{1\over 2}}}}
$$
sans la moindre h´esitation. La tˆache de l’auteur humain est la logique de cette ex-
pression, sa structure correcte, sa signification, mais sa mise en page et les probl`emes
esth´etiques – on les laisse `a la discr´etion du T
EX. Il sait comment comprendre les
mots comme $\alpha$ et les “compiler” en α, il sait que les accolades d´elimitent
les arguments d’une forme fonctionnelle, comme \sqrt{...}, il sait appliquer la
r´ecursivit´e. Finalement, le “code” g´en´er´e – soit un fichier .dvi, soit un document
en format PDF – contient les instructions de positionnement des entit´es graphiques
sur les pages, les instructions de saut de page, etc., ex´ecut´es par l’interpr`ete Acrobat
Reader, ou l’interpr`ete PostScript de l’imprimante (apr`es une seconde compilation
qui transforme le code pr´ec´edent consid´er´e comme interm´ediaire, en PS).
Prenons cependant un exemple plus “classique”. Voici une instruction d’affectation
´ecrite en Pascal ou un autre langage de ce genre :
x := 5+alpha*3*(21 - x+3*alpha)-1.0
4.1.1 Le lexique
Ceci est un texte, une chaˆıne de caract`eres. Il est ´evident qu’il faut tout d’abord
reconnaˆıtre les mots, les unit´es lexicales, afin de pouvoir reconstruire les valeurs
4.1 Un peu d’anatomie et de physiologie 4
num´eriques comme “21” et de pouvoir reconnaˆıtre qu’il y a deux occurrences de
la mˆeme variable alpha. C’est le rˆole de l’analyseur lexical connu ´egalement sous
le nom de scanneur. Le scanneur doit reconnaˆıtre les commentaires et les espaces
sans signification, g´en´erer (ou pr´eparer la g´en´eration) les nombres, les symboles
identificateurs, et les mots-cl´es (il peut les distinguer, ou laisser cette tˆache au
module syntaxique), etc., et en g´en´eral, transformer le texte en une suite de lex`emes.
Ces lex`emes passent au module suivant, syntaxique, avec leurs cat´egories lexicales.
L’analyseur souvent n’est pas ineress´e par les noms concrets des variables ou par les
valeurs num´eriques d´efinies, mais uniquement par la cat´egorie des objets. Il suffit de
savoir qu’un lex`eme repr´esente un nombre flottant, pour pouvoir compiler le code qui
traite ce nombre. (Le module de synth`ese qui engendre les r´ef´erences aux donn´ees
doit, bien ´evidemment, donner au programme compil´e l’acc`es `a la valeur num´erique
d’un objet, mais ceci est une autre histoire).
Les cat´egories classiques sont : identificateurs, constantes enti`eres, r´eelles,
Bool´eennes, etc., op´erateurs binaires comme <> en Pascal ou != en “C”, mots-cl´e,
´eventuellement aussi les s´eparateurs ou les terminateurs comme le point-virgule. Il
faut y ajouter les parenth`eses, crochets, accolades, etc. On appelle ces cat´egories de
lex`emes des jetons (ou tokens).
Il faut parfois prendre des d´ecisions d´elicates. Qu’est-ce que c’est : 17alpha ? En
Pascal c’est une calamit´e, une erreur. En Lisp cela peut ˆetre un lex`eme normal, un
identificateur. Dans la plupart d’autres langages un caract`ere alphab´etique arrˆete le
scanning d’un nombre, donc nous aurons deux lex`emes : 17 et alpha. Mais ensuite :
est-ce l´egal, cette suite de lex`emes ? Cette d´ecision n’appartient plus `a l’analyse
lexicale, bien qu’un analyseur lexical peut diagnostiquer une faute lexicale si le
lex`eme est termin´e par un caract`ere consid´er´e ill´egal (par exemple : un nombre
suivi directement par une lettre). De tr`es rares langages (comme par exemple le
syst`eme Metapost l’acceptent et traitent comme 17 multipli´e par alpha, mais cette
interpr´etation n’appartient non plus au scanneur.
Une autre d´ecision d´elicate est la gestion de format du document d’entr´ee. Fortran
pr´evoyait une instruction par ligne, alors tout retour-chariot ´etait un caract`ere
sp´ecifique – le terminateur. La plupart de langages plus modernes consid`erent la
fin de ligne comme tout autre espace blanc qui s´epare les entit´es lexicales. Ceci
implique l’usage intense de caract`eres de s´eparation syntaxique : les points-virgules.
Cependant – pourquoi la philosophie de Fortran dans ce contexte est pire ? On note
donc actuellement plusieurs r´eponses `a la question concernant la signification du
layout.
En Matlab les points-virgules sont optionnels. On peut terminer une instruction
par ;”, mais si le terminateur est absent, si l’instruction se termine par fin
de ligne, le r´esultat est automatiquement affich´e, la pr´esence du point-virgule
bloque l’affichage. Ce caract`ere joue alors un rˆole s´emantique !
Le langage de calcul formel Maple pr´evoit deux terminateurs : point-virgule,
et deux points. Le second bloque l’affichage du r´esultat, le premier force
l’affichage. (Le paquetage Matlab poss`ede un module d’interfa¸cage avec Maple.
Le travail simultan´e sur les deux syst`emes est nuisible `a la sane psychique. . . )
Python consid`ere la fin de ligne comme terminateur, mais conditionnel ; si la
ligne suivante est indenee, elle est consid´er´ee comme continuation. Haskell suit
1 / 63 100%