Introduction : Compilation et Traduction Un compilateur est un programme qui prend comme donnée un programme écrit dans un langage source et le traduit dans un langage appelé le langage objet. C etc. objet (bas niveau spécifique à chaque type de machine).
Interpréteurs et preprocesseurs Les interpréteurs sont des programmes qui traduisent directement le programme source en des commandes exécutables immédiatement : LISP, VB, Shell en UNIX. Les préprocesseurs qui effectuent une transformation simple d'un langage évolué dans un autre (ou une version simplifiée du même langage). Le compilateur C est muni d'un préprocesseur pour l'utilisation des commandes include et define.
programme source programme objet Messages d’erreur Compilateur
Les étapes de compilation
Génération du code intermédiaire programme source Analyse lexicale Analyse syntaxique Analyseur sémantique Génération du code intermédiaire Gestion Gestion des tables des erreurs Optimisation du code Génération du code Programme objet
Exemple La traduction de l’instruction : position = initial + rate * 60
Analyse lexicale Il s'agit d'analyser le programme source en y repérant les mots-clés, les identificateurs, d'étiquettes etc… Les caractères lus successivement sont regroupés en lexemes ("token") A certaines unités lexicales sont attachées des valeurs lexicales. Par exemple, quand on rencontre un identificateur, comme initial l’analyseur lexical produit un unité lexicale id et rentre le lexème initial dans la table des symboles, s’il n’y est pas déjà. La valeur lexicale associée à cette occurrence de id pointera vers l’entrée de initial dans la table des symboles. Nous emploierons id1, id2, and id3 pour position, initial, and rate, respectively, de façon à mettre en valeur le fait que la répresentation interne d’un identificateur est différente de la suite des caractères qui le forme. La representation de position = initial + rate * 60 après l’analyse lexicale dévient id1 = id2 + id3 * 60
Traduction de l’instruction position = initial + rate * 60 id1 = id2 + id3 * 60 = id1 + id2 * id3 60 Analyseur lexical Analyseur syntaxique Analyseur sémantique
= id1 + id2 * id3 inttoreal 60 temp1 = inttoreal (60) temp2 = id3 * temp1 temp3 = id2 + temp2 id1 = temp3 Générateur de code intermédiaire
id1 := id2 + temp1 MULF #60.0, R2 MOVF id2, R1 ADDF R2, R1 Optimiseur de code temp1 := id3 * 60.0 id1 := id2 + temp1 Générateur de code MOVF id3, R2 MULF #60.0, R2 MOVF id2, R1 ADDF R2, R1 MOVF R1, id1
Table des symboles position … initial rate La phase finale d’un compilateur est la production du code cible, qui consiste normalement en du code machine translatable ou en code en langage d’assemblage.
Important : L'analyseur lexical a la structure d'un automate fini. Un automate fini qui reconnaît des identificateurs lettre/chiffre lettre délimiteur
Analyseur syntaxique (parser) L'analyseur syntaxique prend comme source le résultat de l'analyseur lexical. Son résultat est l'arbre de dérivation du mot d'entrée (dont les lettres sont les lexèmes) relativement à la grammaire du langage de programmation. Il détecte en même temps les erreurs (par ex. non correspondance des ‘{‘ et des ‘}’).
Si la grammaire contient les règles : Exemple : a * (b + c) expr expr * expr a ( expr ) expr + expr b c Si la grammaire contient les règles : exp exp + exp | ( exp ) | id | exp * exp. Cette grammaire est ambiguë.
Génération du code intermédiaire Le langage intermédiaire est un langage simple du type du "code à trois adresses". Une instruction typique a la forme A := B op C où A, B, C sont des opérandes et op un opérateur binaire
Code optimisation(facultative) The code optimisation phase attempts to improve the intermediate code, so that faster-running machine code will result.
Génération du code La différence principale entre le langage intermédiaire et l'écriture finale en code machine réside dans l'utilisation des registres dans lesquels sont effectués les calculs et dans l'attribution d'adresses physiques en mémoire.
Gestion des erreurs Elle peut se produire à toutes les étapes de la compilation. Par exemple : l'analyseur lexical peut rencontrer des identificateurs mal orthographiés. l'analyseur syntaxique peut détecter une parenthèse manquante. le générateur de code peut détecter une incompatibilité de types entre les opérandes d'un opérateur. la procédure de gestion des tables peut rencontrer un identificateur déclaré plusieurs fois avec des valeurs contradictoires.