1. Support de cours Compilation
Mastère Professionnel
Enseignant : Abdelkader Abdelkarim
Abdelkader.abdelkadrim@aposte.net
Faculté des Sciences de Gafsa
Année universitaire : 2009 – 2010
2. Chapitre 1 : Introduction à la compilation
Définitions :
Compilation : Étude des techniques permettant de traduire un programme
source en un programme objet
Programme source : écrit dans un langage de programmation
Programme objet : dépend de la machine
Pré-requis :
Algorithmes et structures de données (Piles, arbres, graphes,… ),
Théorie des langages (Notion de grammaires et langages, Classification
(Chomsky), Les langages réguliers et les automates, Les langages algébriques
(contexte libre) et les automates à pile)
Structure des machines (Représentation et codage de l’information , Techniques
d’adressage, Exécution d’une instruction, Les langages d’assemblage et les
assembleurs)
Programmation procédurale, programmation objet, quelques langages de
programmation (C, Java)
2
3. Chapitre 1 : Introduction à la compilation
Historique :
Dans les années 40, il n’y avait que de la programmation en code machine
Dans les années 50, les langages assembleur ralentissaient l’exécution. Difficiles à
utiliser dans la pratique
Le premier compilateur FORTRAN
Heureusement, depuis on a fait beaucoup de progrès
Langages de bas niveaux :
Difficile d’écrire des programmes
Code souvent verbeux (long, fastidieux, etc.)
Risque d’erreurs élevé
Langages de haut niveaux :
Rendre la programmation plus facile
Faciles à apprendre et a utiliser
Modularité
Portabilité
Lisibilité
Maintenance plus facile
Nombreux outils de développement associés
3
4. Chapitre 1 : Introduction à la compilation
Classification par paradigme :
Impératif : Séquence d’instructions à exécuter pour obtenir le résultat
Cobol (1959), Basic (1965), Pascal (1970), C (1978), etc.
Fonctionnel : Langages basés sur la récursivité (application de
fonctions) : LISP (1960), Scheme, CAML, etc.
Logique : Résolution d’un problème à l’aide d’un moteur d’inférence
PROLOG (1970)
Objet : C++, Samll Talk, Eiffel, Java, etc.
Classification par portée :
Langages généralistes : Permet de décrire tout type de programme
réalisant un calcul : C, Java, C++, Pascal, LISP, etc.
•Inconvénient : décrire le « comment faire »
Langages spécialisés (ou dédiés) : Ne permet de décrire qu’une
famille de programmes pour un domaine particulier exemples : TeX, sh,
make
4
5. Chapitre 1 : Introduction à la compilation
Compilateur :
5
6. Chapitre 1 : Introduction à la compilation
Compilateur / Interprète
6
7. Chapitre 1 : Introduction à la compilation
Définition d’un compilateur :
Un compilateur est un programme qui lit un programme écrit dans un premier langage –le
langage source- et le traduit en un programme équivalent écrit dans un autre langage –le
lange cibe- . Au cours de ce processus, un rôle important du compilateur est de signaler à
son utilisateur la présence d’erreurs dans le programme source.
programme programme
source compilateur cible
messages
d'erreur
Premier compilateur : compilateur Fortran de J. Backus (1957)
Langage source : langage de haut niveau (C, C++, Java, Pascal, Fortran...)
Langage cible : langage de bas niveau (assembleur, langage machine)
7
8. Chapitre 1 : Introduction à la compilation
Qualités d'un compilateur
Correction : le programme cible est équivalent au programme source
Rapidité (temps de compilation proportionnel à la taille du programme)
Production de code de bonne qualité : les programmes produits doivent
être efficaces en temps et en espace
Bons diagnostiques d'erreur
Possibilité d'utiliser un debugger sur le code produit
8
9. Chapitre 1 : Introduction à la compilation
Structure d'un compilateur
Phases d'analyse du texte source
• analyse lexicale
• analyse syntaxique
• analyse sémantique
Phases de synthèse (génération du programme cible)
• génération du code intermédiaire
• optimisation du code intermédiaire
• génération du code cible
Table des symboles (ident. utilisés et leurs attributs)
9
10. Chapitre 1 : Introduction à la compilation
Structure d'un compilateur
indépendant du langage source
dépendant du langage source dépendant du code cible
indépendant du code cible
10
11. Chapitre 1 : Introduction à la compilation
programme source
Les phases d’un
compilateur :
Analyseur lexical
Analyseur syntaxique
Analyseur sémantique
Gestion de la
table des symboles Générateur de code intermédiaire Gestion des erreurs
« Optimiseur" de code
Générateur de code cible
programme cible 11
12. Chapitre 1 : Introduction à la compilation
Analyse lexicale
Analyse du programme source en constituants minimaux, les lexèmes
On passe de
position = initial + vitesse * 60
à
[id, 1] [=] [id, 2] [+] [id, 3] [*] [60]
Les identificateurs rencontrés sont placés dans la table des symboles
Les blancs et les commentaires sont éliminés
12
13. Chapitre 1 : Introduction à la compilation
Analyse syntaxique
On reconstruit la structure syntaxique de la suite de lexèmes fournie par l'analyseur lexical
instruction
d'affectation
identificateur expression
position =
expression + expression
identificateur expression * expression
initial
identificateur nombre
Arbre de dérivation vitesse 60
13
14. Chapitre 1 : Introduction à la compilation
Analyse sémantique
vérifie que cela a un sens :
position = initial + vitesse * 60
– les opérandes sont-ils de même type?
•60 est un entier et vitesse est un réel
•60 devra être converti en réel
– les opérateurs sont de quel type?
•* et + seront des opérations sur réels
– pas est-il une variable modifiable?
14
16. Chapitre 1 : Introduction à la compilation
"Optimisation" de code
Elimination des opérations inutiles pour produire du code plus efficace.
temp1 := inttoreal(60) temp1 := id3 * 60.0
temp2 := id3 * temp1 id1 := id2 + temp1
temp3 := id2 + temp2
id1 := temp3
La constante est traduite en réel flottant à la compilation, et non à l'exécution
La variable temp3 est éliminée
16
17. Chapitre 1 : Introduction à la compilation
Génération de code cible
• La dernière phase produit du code en langage d'assemblage
Un point important est l'utilisation des registres
temp1 := id3 * 60.0 MOVF id3, R2
id1 := id2 + temp1 MULF #60.0, R2
MOVF id2,R1
ADDF R2, R1
MOVF R1, id1
F = flottant.
La première instruction transfère le contenu de id3 dans le registre R2
La seconde multiplie le contenu du registre R2 par la constante 60.0
• L’assemblage consiste à traduire ce code en code binaire
• Les langages d’assemblage ou assembleurs sont des versions un peu plus lisibles du code
machine avec des noms symboliques pour les opérations et pour les opérandes
MOV a, R1
ADD 2, R1
MOV R1, b
• Chaque processeur a son langage d'assemblage
17
19. Chapitre 1 : Introduction à la compilation
Outils logiciels :
Outils d’aide à la construction de compilateurs
Générateurs d’analyseurs lexicaux
Engendrent un analyseur lexical ( scanner, lexer) sous forme d’automate fini à partir d’une
spécification sous forme d’expressions régulières
Flex, Lex
Générateurs d’analyseurs syntaxiques
Engendrent un analyseur syntaxique ( parser) à partir d’une grammaire
Bison, Yacc
Générateurs de traducteurs
Engendrent un traducteur à partir d’un schéma de traduction (grammaire + règles sémantiques)
Bison, Yacc
19