0% ont trouvé ce document utile (0 vote)
69 vues26 pages

CH01 Introduction-Compilation

Le document décrit les principes de base d'un compilateur, notamment la traduction d'un programme source vers un langage cible, les étapes clés d'un compilateur comme l'analyse lexicale, syntaxique et sémantique, ainsi que les structures de données utilisées comme la table des symboles.

Transféré par

Wiam Beldjaatit
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
69 vues26 pages

CH01 Introduction-Compilation

Le document décrit les principes de base d'un compilateur, notamment la traduction d'un programme source vers un langage cible, les étapes clés d'un compilateur comme l'analyse lexicale, syntaxique et sémantique, ainsi que les structures de données utilisées comme la table des symboles.

Transféré par

Wiam Beldjaatit
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

Chapitre I.

Introduction aux compilateurs (Objectifs)


[email protected]
Qu’est-ce qu’un compilateur ?
 Un compilateur est un traducteur qui permet de
transformer un programme écrit dans un langage L1 en un
autre programme écrit dans un langage L2.
 Le langage L1 dans lequel on écrit le programme original est :
 le langage source ex: C, C++, Pascal …
 Le langage L2 généré à partir du langage L1 est :
 le langage cible (ou langage objet) ex : EXE,…
 En pratique on s’arrête souvent à un langage intermédiaire
(assembleur ou encore un langage d’une machine abstraite)

2 Introduction aux compilateurs


Qu’est-ce qu’un programme?

 Un programme est un ensemble d'opérations qui décrivent


comment produire des résultats à partir des entrées.
 Le compilateur rejette des programmes qui contiennent des erreurs
(erreurs statiques),
 dans le cas contraire, le compilateur construit un nouveau
programme (le programme objet) que la machine pourra
l’exécuter sur différentes entrées.
 L’exécution du code objet sur une entrée particulière peut ne pas
terminer ou échouer à produire un résultat (erreur dynamique).

3 Introduction aux compilateurs


Exemple de compilation
1 int SommeCarre (int a, int b)
Programme source:
2 {
langage C
3 return a*a+b*b;
4 }
Compilateur gcc

1 <SommeCarre>:
2 0: 0f af ff imul %edi, %edi Programme Assembleur
3 3: 0f af f6 imul %esi, %esi généré
4 6: 8d 04 3e lea (%rsi, %rdi,1), %eax
5 9: c3 retq
.
Assembleur

Code machine
généré

4 Introduction aux compilateurs


Compilateur vs Interpréteur
Compilateur

 Un compilateur prend tout le programme et le convertit en


code objet qui est généralement stocké dans un fichier. Le code
objet est également référencé en tant que code binaire et peut être
exécuté directement par la machine après la liaison.
 Exemple: C, C++, Pascal …

5 Introduction aux compilateurs


Compilateur vs Interpréteur
interpréteur

 Un interpréteur exécute directement des instructions écrites

dans un langage de programmation l’une après l’autre sans les

convertir en un code objet ou un code machine.

 Exemple: BASIC, Perl, Python, Ruby, PHP ….

6 Introduction aux compilateurs


Compilateur vs Interpréteur
Avantage et inconvénient

Avantage Inconvénient

Interpréteurs processus de développement processus de traduction peu


simple (en particulier efficace et vitesse d’exécution
débogage) lente

Compilateurs Transmet au processeur Toute modification du code


l’intégralité du code machine nécessite une nouvelle traduction
prêt à l’emploi et exécutable (correction des erreurs,
extension du logiciel, etc.)

7 Introduction aux compilateurs


Compilateur vs Interpréteur
compilateur à la volée

 La compilation à la volée est une solution hybride traduit le code

du programme pendant le fonctionnement, à l’instar d’un


interpréteur. Elle mélange les deux méthodes précédentes pour
bénéficier de leurs avantages. De cette façon, la vitesse
d’exécution élevée (permise par le compilateur) est complétée
par un processus de développement simplifié.

 Exemple: JAVA….

8 Introduction aux compilateurs


Qu’attend-on d’un compilateur ? (1)

 Détection des erreurs: Un compilateur doit pouvoir


détecter les erreurs statiques comme:
• Identificateurs mal formés,
• commentaires non fermés . . .
• Constructions syntaxiques incorrectes,
• Identificateurs non déclarés,
• Expressions mal typées if 3 then "toto" else 4.5,
• Références non instanciées.

9 Introduction aux compilateurs


Qu’attend-on d’un compilateur ? (2)

 Efficacité : Un compilateur doit être si possible rapide.

 Correction : Le programme compilé doit représenter le

même calcul que le programme original.


 Modalité : Utilisation de la compilation séparée lors de
d’un gros développement.

10 Introduction aux compilateurs


Structure d'un compilateur
Programme source

Suite d’unités lexicales

Arbre syntaxique

Arbre syntaxique décoré

Code intermédiaire

Code intermédiaire optimisé

11 Introduction aux compilateurs


Code objet
Analyse lexicale
 L’analyse lexicale consiste à transformer un code sous forme
textuelle en une suite de token (unités lexicales), séparant ainsi
les mots-clés, les variables, les entiers, etc....
 Les commentaires et les blancs séparant les caractères formant
les unités lexicales sont éliminés au cours de cette phase.
 L'analyseur lexical associe à chaque unité lexicale un code qui
spécifie son type et une valeur (un pointeur vers la table des
symboles).

12 Introduction aux compilateurs


Exemple
for i :=1 to vmax do a :=a+i;
On peut dégager la suite de tokens suivante :
for : mot clé
i : identificateur
:= : affectation
1 : entier
to : mot clé
vmax : identificateur
do : mot clé
a : identificateur
:= : affectation
a : identificateur
+: opérateur arithmétique
i : identificateur
;: séparateur

13 Introduction aux compilateurs


Table des symboles
 Une table de symboles est une centralisation des informations
rattachées aux identificateurs d'un programme informatique.
 Dans une table des symboles, on retrouve des informations comme : le
type, l'emplacement mémoire, etc.
 Généralement, la table est créée dynamiquement. Une première
portion est créée au début de la compilation. Puis, de façon
opportuniste, en fonction des besoins, elle est complétée.
 La première fois qu'un symbole est vu (au sens des règles de visibilité
du langage), une entrée est créée dans la table.

14 Introduction aux compilateurs


Table des symboles
N° Unité Lexicale Type de l’unité lexicale
10 for Mot clé
11 to Mot clé
12 do Mot clé
13 ; séparateur
… …… ……
100 := affectation
101 + opérateur arithmétique
… …. ….
1000 i Identificateur
1001 a Identificateur
1002 vmax Identificateur
…. …..
5000 1 entier

Ensuite, l’énoncé précédent peut s’exprimer ainsi : 10, 1000, 100, 5000,
11, 1002, 12, 1001, 100, 1001, 101, 1000, 13
15 Introduction aux compilateurs
Analyse syntaxique
 Cette phase consiste à regrouper les unités lexicales du
programme source en structures grammaticales (i.e. vérifier si
un programme est correctement écrit selon la grammaire qui
spécifie la structure syntaxique du langage).
 En général, cette analyse est représentée par un arbre.

16 Introduction aux compilateurs


Exemple
 Considérons la grammaire suivante pour la boucle for:

 <Instruction> < Affectation > ;| <Instruction for>

 < Affectation >  ident := < Expression>

 <Instruction for>  for < Initialization> to < Expression> do

<Instruction>

 < Initialization>  <Location> := < Expression >|<Location>

 <Location>  ident|const

 < Expression> < Location>|< Location > op < Location >

17 Introduction aux compilateurs


Arbre syntaxique
 Après l'analyse syntaxique on obtient l'arbre suivant

18 Introduction aux compilateurs


Analyse sémantique
 L’analyse sémantique sert à préciser la nature des calculs
représentés par un programme en vérifiant que les opérandes
de chaque opérateur sont conformes aux spécifications du
langage source.
 En général, cette analyse est représentée par un arbre
syntaxique décoré.
Exemple:
 Il faut vérifier que la variable ‘i’ possède bien le type ‘entier’,
et que la variable ‘a’ est bien un nombre. Cette opération
s’effectue en parcourant l’arbre syntaxique et en vérifiant à
chaque niveau que les opérations sont correctes..

19 Introduction aux compilateurs


Génération de code intermédiaire
 Après les phases d’analyse sémantique, certains compilateurs
produisent une représentation intermédiaire, une sorte de code
pour une machine abstraite.
 La forme intermédiaire "code à trois adresses" est largement
utilisée.
 Le passage par le code intermédiaire apporte certains avantages:
• il est relativement facile de changer le code intermédiaire en code
objet;
• la représentation intermédiaire permet d’appliquer des optimisations
indépendantes du langage cible (code objet).
Exemple: JAVA utilise une forme intermédiaire spécifique: Les
bytecode. Le bytecode est exécuté sur n'importe quelle plateforme à
l'aide de la machine virtuelle JAVA (JVM).
20 Introduction aux compilateurs
Optimisation du code intermédiaire (1)
 L'optimisation cherche à améliorer le code intermédiaire afin
d’améliorer ses performances en terme de réduire le temps
d'exécution ou l'occupation mémoire.
 Quelques unes des opérations d'optimisation sont :
 Déplacement de code invariant :
Le but est d'extraire du corps de la boucle des parties du code qui
sont des invariants (nécessitent une seule exécution). Le nombre
total d'instructions exécutées est diminué.

Exemples. Soit le code Après le déplacement du code invariant,


intermédiaire suivant: on obtient:
for (int i = 0; i < n; i++) { x = y + z;
x = y + z; temp1 = x * x;
a[i] = 6 * i + x * x; } for (int i = 0; i < n; i++) {
a[i] = 6 * i + temp1; }
21 Introduction aux compilateurs
Optimisation du code intermédiaire (2)
 Quelques unes des opérations d'optimisation sont :
 Elimination du code mort :
Le compilateur sait reconnaitre les parties du code qui sont morts
(la raison peut être une erreur de programmation).

Exemple . Des instructions qui sont inaccessibles à cause d’instructions de saut sont
considérées comme du code mort et peuvent être éliminées:
if 1 <> 0 goto label
i := a[k]
k := k + 1
label:

22 Introduction aux compilateurs


Optimisation du code intermédiaire (3)
 Quelques unes des opérations d'optimisation sont :
 Elimination des sous-expressions communes
Dans le cas où la valeur d'une expression est calculée en plusieurs
endroits du programme, l'optimiseur gère le résultat de cette
expression et le réutilise plutôt que refaire le calcul.
Exemple . Soit le code Après l’élimination de sous-expressions
intermédiaire suivant: communes (et quelques autres
t6 = 4 * i optimisations), on obtient:
x = a[t6] t6 = 4 * i
t7 = 4 * i x = a[t6]
t8 = 4 * j t8 = 4 * j
t9 = a[t8] t9 = a[t8]
a[t7] = t9 a[t6] = t9
t10 = 4 * j a[t8] = x
a[t10] = x

23 Introduction aux compilateurs


Génération de code objet
 Cette phase produit du code objet en:
 choisissant les emplacements mémoires pour les données ;
 sélectionnant le code machine pour implémenter les
instructions du code intermédiaire ;
 allouant les registres.

Exemple: voici le code Voici le code objet généré en utilisant les


intermédiaire optimisé registres R1 et R2:
suivant: MOVF id3, R2
temp1 := 60.0 * id3 MULF #600, R2
id1 := id2 + temp1 MOVF id2, R1
ADDF R2, R1
MOVF R1, id1

24 Introduction aux compilateurs


Phases
logiques de la
compilation
d’une
instruction

25 Introduction aux compilateurs


Références
 Compilateurs Principes, techniques et outils. Alfred
V.Aho, Ravi Sethi, Jeffrey D.Ullman. Pearson. Paris France.
2007.

26 Introduction aux compilateurs

Vous aimerez peut-être aussi