SAOUDI Lalia Introduction 2007/2008
I. Introduction
1. Qu’est ce que la compilation ?
Au début de l’informatique, on programmait directement les ordinateurs en langage machine. Cela s’est vite avéré fastidieux, Pour cela il a fallu construire des programmes qui traduisent des énoncés exprimés dans le langage de haut niveau utilisé par les programmeurs, ce qu’on appelle le langage source, en instructions pour la machine cible. Les programmes effectuant ce genre d’opération s’appellent des compilateurs
Un traducteur est un programme qui transforme chaque mot d’un langage L1 en un mot d’un langage L2
Un compilateur est un cas particulier de traducteur qui prend en entrée un mot représentant un programme écrit dans un certain langage et traduit le code source de ce programme en instructions pour la machine cible
Exemples :
D’un langage de haut niveau « Pascal,Fortran,C… » vers un langage d’assembleur.
Du langage d’assembleur vers du code binaire.
D’un langage de haut niveau vers les instructions d’une machine virtuelle (JVM) 2. Interpréteur versus Compilateur
Un interpréteur est un logiciel qui interprète le programme source, c'est-à-dire qu'il analyse les
instructions du programme source, les unes après les autres, et exécute chacune d'elles immédiatement.
Dans ce cas, il n'y a pas de création d'un programme objet équivalent.
L’interpréteur ne connait pas a priori la structure du programme qu’il aura à exécuter et ne peut donc effectuer d’optimisations.
Un compilateur effectue un précalacul sur un programme P pour le transformer en une suite d’instructions P’.
A l’inverse d’un compilateur, il travaille simultanément sur le programme et sur les données.
L’interpréteur doit être présent sur le système à chaque fois que le programme est exécuté, ce qui n’est pas le cas avec le compilateur.
Autre inconvénient, on ne peut pas cacher le code et donc garder des secrets de fabrication.
Les interpréteurs sont généralement plus petits que les compilateurs mais leur principal inconvénient est la lenteur de l’exécution d’un pgm interprété par rapport aux autres.
SAOUDI Lalia Introduction 2007/2008
Exemple de langage interprété: Perl, Scheme, Mathematica, mapple.
3. Dans quel langage écrire un compilateur ?
On peut évidemment écrire les compilateurs en langage machine. Mais les compilateurs sont de gros programmes (le premier compilateur Fortran avait nécessité 18 hommes/années d’effort), qui sont pratiquement impossibles à réaliser en langage machine. De ce fait, on écrit les compilateurs en langage de haut niveau. Comment le fait-on ? Supposons que l’on dispose d’un compilateur PASCAL, et que l’on désire écrire un compilateur C, Pour cela il suffit d’écrire le compilateur sous la forme d’un programme écrit en PASCAL et de le compiler à l’aide du compilateur PASCAL.
Remarque 1: souvent le compilateur transforme le texte source en assembleur, l’assembleur se chargeant ensuite de traduire ce texte en langage machine.
Le processus de compilation peut aussi être décomposé : comme le bytecode java qui est un programme semi-compilé. L’´editeur de liens, reliant le programme compilé avec les librairies précompilées qu’il utilise peut éventuellement faire des optimisations. Le programme peut même être amélioré à l’exécution avant d’être exécuté grâce `à des informations supplémentaires présentes à l’exécution.
4. Qu’attend-on d’un compilateur ?
1- La détection des erreurs : Un compilateur doit pouvoir détecter les erreurs statiques qui ne nécessitent pas l’exécution du pgm et être capable de reporter cette erreur à l’utilisateur.
2- L’efficacité : Un compilateur doit être rapide 3- La correction : Un compilateur doit être correct.
4- La modalité : lorsque l’on construit un gros développement, il est important de pouvoir profiter de la compilation séparée.
5. Les différentes phases de compilation : 5.1 Analyse
La phase d’analyse correspond à reconnaitre qu’une entrée est un programme correct du langage source. Cette analyse doit être la plus rapide possible, c’est pourquoi on la structure en trois parties (analyse lexicale, analyse syntaxique, analyse sémantique)
5.1.1Analyse lexicale :
Consiste à récupérer les mots, que l’on appelle « tokens », à partir d’une suite de caractères. Par exemple déterminer, à partir de l’énoncé suivant :
SAOUDI Lalia Introduction 2007/2008
vmax : identificateur do : mot clé a : identificateur := : affectation
a : identificateur +: opérateur arithmétique i : identificateur ;: séparateur
Et que l’on peut construire la table des symboles suivante :
Numéro de symbole
Token Type de token Type de variable
10 for mot clé
11 to mot clé
12 do mot clé
13 ; séparateur
... ...
100 := affectation
101 +
...
1000 i ident
1001 a ident
1002 vmax ident
...
5001 1 entier
Ensuite, l’énoncé précédent peut s’exprimer ainsi :
10, 1000, 100, 5001, 11, 1002, 12, 1001, 100, 1001, 101, 1000, 13 5.1.2Analyse syntaxique
Lors de l’analyse syntaxique, on vérifie que l’ordre des tokens correspond à l’ordre définit pour le langage. On dit que l’on vérifie la syntaxe du langage à partir de la définition de sa grammaire. Cette phase produit une représentation sous forme d’arbre de la suite des tokens obtenus lors de la phase précédente. Par exemple, l’arbre suivant représente la structure de la phrase :
For i :=1 to vmax do a :=a+i
SAOUDI Lalia Introduction 2007/2008
Instruction
Instruction For
Location Expression
Initialisation Expression Instruction
Affectation for
:=
Cste: 1
to do
Ident: a Ident: i
:= Expression
Location
Ident:
vmax
op: +
Location Location
Ident: a Ident: i
5.1.3Analyse sémantique ou vérification de type
Dans cette phase on vérifie que les variables ont un type correct. Par 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.
5.2 Synthèse
La synthèse correspond à la phase de reconstruction de l’expression du langage cible à partir de l’arbre syntaxique
5.2.1 Allocation mémoire :
Le compilateur peut être amené à réserver de l’espace en mémoire pour des calculs intermédiaires ou le passage des arguments d’une procédure ; Celui-ci doit alors mettre en œuvre des programmes de ramasse miettes (garbage collector) chargés de récupérer l’espace mémoire réutilisable.
5.2.2 Génération de code :
On génère le code pour du langage cible (machine ou un langage d’assemblage.) correspondant aux expressions de l’arbre syntaxique.
5.2.3 Optimisation de code cible :
Il s’agit de détecter des séquences de code cible qui peuvent être optimisées.
5.3 Phase parallèle
Gestion de la table des symboles
On construit pendant toute l’analyse une table des symboles qui associe à chaque identificateur déclaré
SAOUDI Lalia Introduction 2007/2008
Structure d’un compilateur