Post on 08-Jul-2015
Support de cours Compilation
Enseignant : Abdelkader Abdelkarim Abdelkader.abdelkadrim@aposte.net
Année universitaire : 2009 – 2010
Faculté des Sciences de Gafsa
Mastère Professionnel
2
Chapitre 1 : Introduction à la compilation
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
Définit ions :
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)
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
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
5
Chapitre 1 : Introduction à la compilation
Compilateur :
6
Chapitre 1 : Introduction à la compilation
Compilateur / Interprète
7
Chapitre 1 : Introduction à la compilation
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.
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)
compilateurprogrammesource
messagesd'erreur
programmecible
Définition d’un compilateur :
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
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)
10
Chapitre 1 : Introduction à la compilation
Structure d'un compilateur
dépendant du langage source indépendant du code cible
indépendant du langage source dépendant du code cible
11
Chapitre 1 : Introduction à la compilation
programme cible
Gestion de latable des symboles
programme source
Analyseur lexical
Gestion des erreurs
Analyseur syntaxique
Analyseur sémantique
Générateur de code intermédiaire
« Optimiseur" de code
Générateur de code cible
Les phases d’un compilateur :
12
Chapitre 1 : Introduction à la compilation
Analyse lexicale
Analyse du programme source en constituants minimaux, les lexèmesOn passe de position = initial + vitesse * 60
à[id, 1] [=] [id, 2] [+] [id, 3] [*] [60]
Les identificateurs rencontrés sont placés dans la table des symbolesLes blancs et les commentaires sont éliminés
13
Chapitre 1 : Introduction à la compilation
Analyse syntaxique
On reconstruit la structure syntaxique de la suite de lexèmes fournie par l'analyseur lexical
instructiond'affectation
expression
expression expression
expression
identificateurposition
identificateurinitial
identificateurvitesse
nombre60
expression
=
+
*
Arbre de dérivation
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?
15
Chapitre 1 : Introduction à la compilation
Génération de code intermédiaire
Représentations ut i l iséestemp1 := inttoreal(60)
temp2 := id3 * temp1
temp3 := id2 + temp2
id1 := temp3
16
Chapitre 1 : Introduction à la compilation
"Optimisation" de code
Elimination des opérations inutiles pour produire du code plus efficace.
temp1 := inttoreal(60)
temp2 := id3 * temp1
temp3 := id2 + temp2
id1 := temp3
temp1 := id3 * 60.0
id1 := id2 + temp1
La constante est traduite en réel flottant à la compilation, et non à l'exécutionLa variable temp3 est éliminée
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 registrestemp1 := 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érandesMOV a, R1
ADD 2, R1
MOV R1, b• Chaque processeur a son langage d'assemblage
18
Chapitre 1 : Introduction à la compilationposition = initial + vitesse*60
analyseur lexical
id1 := id2 + id3*60
analyseur syntaxique
Table des symboles
1 position ...2 initial ...3 vitesse ...45...
=
id1 +
*id2
id3 60
analyseur sémantique
id1 +
*id2
id3 inttoreal
60 générateur de code intermédiaire
temp1 := inttoreal(60)
temp2 := id3 * temp1
temp3 := id2 + temp2
id1 := temp3
temp1 := id3 * 60.0
id1 := id2 + temp1
optimiseur de code
générateur de code cible
MOVF id3, R2
MULF #60.0, R2
MOVF id2,R1
ADDF R2, R1
MOVF R1, id1
19
Chapitre 1 : Introduction à la compilation
Outils logiciels :
Outils d’aide à la construction de compilateurs
Générateurs d’analyseurs lexicauxEngendrent un analyseur lexical (scanner, lexer) sous forme d’automate fini à partir d’une
spécification sous forme d’expressions régulièresFlex, Lex
Générateurs d’analyseurs syntaxiquesEngendrent un analyseur syntaxique (parser) à partir d’une grammaireBison, Yacc
Générateurs de traducteursEngendrent un traducteur à partir d’un schéma de traduction (grammaire + règles sémantiques)Bison, Yacc