Skip to content

MOOC NSI - fondamentaux.

Transcription de la vidéo

2.2.2 : Compilateur et interpréteur

Un langage de programmation est donc une notation artificielle, destinée à exprimer des algorithmes et produire des programmes.

D’une manière similaire à une langue naturelle, un langage de programmation est fait d’un alphabet, un vocabulaire, des règles de grammaire (syntaxe), et des significations (sémantique).

Un langage de programmation est mis en oeuvre par un traducteur automatique:

  • compilateur (pour les langages compilés comme C, C++, Fortran, Cobol, Java, OCaml, etc)
  • ou par un interpréteur. (pour les langages interprétés comme Python, Basic, Ruby, PHP, Javascript, etc).

Parlons d'abord de compilateur

Un compilateur est un programme informatique qui transforme un code source écrit dans un langage de programmation (le langage source) en un autre langage informatique (le langage cible).

Pour qu’il puisse être exploité par la machine, le compilateur traduit le code source, écrit dans un langage de haut niveau d’abstraction, facilement compréhensible par l’humain, vers un langage de plus bas niveau, un langage d’assemblage ou langage machine.

La tâche principale d’un compilateur est donc de produire un code objet correct qui s’exécutera sur un ordinateur. La plupart des compilateurs permettent d’optimiser le code, c’est-à-dire qu’ils vont chercher à améliorer la vitesse d’exécution, ou réduire l’occupation mémoire du programme.

Un compilateur fonctionne par analyse-synthèse : au lieu de remplacer chaque construction du langage source par une suite équivalente de constructions du langage cible, il commence par analyser le texte source pour en construire une représentation intermédiaire (appelée image) qu’il traduit à son tour en langage cible.

On sépare le compilateur en au moins deux parties :

  • une partie avant ou frontale (front-end en anglais) qui lit le texte source et produit la représentation intermédiaire (appelée également image);

  • et une partie arrière ou finale -(back-end en anglais), qui parcourt cette représentation pour produire le code cible.

Les phases de la compilation incluent :

Pour la partie analyse :

  • l’analyse lexicale (également appelé scanning en anglais), qui découpe la séquence de caractères du code source en blocs atomiques appelés jetons (tokens en anglais). Chaque jeton appartient à une unité atomique unique du langage appelée unité lexicale ou lexème (par exemple un mot-clé, un identifiant ou un symbole).

  • l’analyse syntaxique (également appelé parsing en anglais) implique l’analyse de la séquence de jetons pour identifier la structure syntaxique du programme.

Cette phase s’appuie généralement sur la construction d’un arbre d’analyse (appelé communément arbre syntaxique) ;

on remplace la séquence linéaire des jetons par une structure en arbre construite selon la grammaire formelle qui définit la syntaxe du langage.

Par exemple, une condition est toujours suivie d’un test logique (égalité, comparaison, ...).

  • l’analyse sémantique, phase durant laquelle le compilateur ajoute des informations sémantiques (donne un « sens ») à l’arbre syntaxique.

Cette phase fait un certain nombre de contrôles:

. vérifie le type des éléments (variables, fonctions, ...) utilisés dans le programme, . leur visibilité, . vérifie que toutes les variables locales utilisées sont initialisées, ....

les trois phases d'analyse construisent et complète la table des symboles qui centralise les informations attachées aux identificateurs du programme. Dans une table des symboles, on retrouve des informations comme : le type, l'emplacement mémoire, la portée, la visibilité, etc.

C’est au cours de ces phases que le compilateur détecte les erreurs éventuelles (par rapport à la définition du langage) et produit les messages d’erreur permettant à l’auteur du programme de poursuivre sa mise au point.

un prétraitement, peut également être effectué avant ou de façon entremêlée aux phases d'analyse. Un tel prétraitement est nécessaire pour certaines langues comme C où il prend en charge la substitution de macro et de la compilation conditionnelle, permettant par exemple de générer des codes différents en fonction de paramètres.

Vient ensuite la génération du code proprement dite, qui inclut trois phases :

  • la transformation du code source en code intermédiaire ;
  • l'optimisation du code intermédiaire : c’est-à-dire rendre le programme plus efficcace, ^par exemple par lasuppression de « code mort » (qui ne pourra jamais être exécuté), la sortie de boucle d’opérations indépendantes de l’itération, la sortie d’alternative des codes communs, etc.
  • viens enfin la génération du code objet final.

Dans le cas des langages interpétés, l'interpréteur est la logiciel utilisé pour analyser et exécuter les codes.

Le cycle d'interprétation consiste en une succession

  • analyse de l'instruction suivante — suivi de l'exécution immédiate de celle-ci.

L’interpréteur est donc à la fois éditeur, compilateur et runtime.