Compilateur multi-passes - Multi-pass compiler

Un compilateur multi-passes est un type de compilateur qui traite plusieurs fois le code source ou l'arbre de syntaxe abstraite d'un programme. Cela contraste avec un compilateur en une seule passe , qui ne parcourt le programme qu'une seule fois. Chaque passe prend le résultat de la passe précédente comme entrée et crée une sortie intermédiaire. De cette manière, le code (intermédiaire) est amélioré au passage, jusqu'à ce que le passage final produise le code final.

Les compilateurs multi-passes sont parfois appelés compilateurs larges , en référence à la plus grande portée des passes : ils peuvent "voir" l'intégralité du programme en cours de compilation, au lieu d'une petite partie seulement. La portée plus large ainsi disponible pour ces compilateurs permet une meilleure génération de code (par exemple, une taille de code plus petite, un code plus rapide) par rapport à la sortie des compilateurs à une passe, au prix d'un temps de compilation et d'une consommation de mémoire plus élevés. De plus, certains langages ne peuvent pas être compilés en une seule passe, du fait de leur conception.

Compilateur multi-passes typique

Multi-passcompiler.png

Analyse lexicale

Cette étape d'un compilateur multi-passes consiste à supprimer du programme source les informations non pertinentes que l'analyse syntaxique ne sera pas en mesure d'utiliser ou d'interpréter. Les informations non pertinentes peuvent inclure des éléments tels que des commentaires et des espaces blancs. En plus de supprimer les informations non pertinentes, l'analyse lexicale détermine les tokens lexicaux de la langue. Cette étape signifie que la déclaration directe n'est généralement pas nécessaire si un compilateur multi-passes est utilisé. Cette phase est axée sur la décomposition d'une séquence de caractères en jetons avec des attributs tels que le genre, le type, la valeur et potentiellement d'autres également.

Analyse syntaxique

L'analyse syntaxique est chargée d'examiner les règles de syntaxe du langage (souvent sous forme de grammaire sans contexte ) et de construire une représentation intermédiaire du langage. Un exemple de cette représentation intermédiaire pourrait être quelque chose comme un arbre de syntaxe abstraite ou un graphe acyclique dirigé .

Analyse sémantique

L'analyse sémantique prend la représentation faite à partir de l'analyse syntaxique et applique des règles sémantiques à la représentation pour s'assurer que le programme répond aux exigences des règles sémantiques du langage. Par exemple, dans l'exemple ci-dessous, au stade de l'analyse sémantique, si le langage exigeait que les conditions sur les instructions if soient des expressions booléennes, le type cond serait vérifié pour s'assurer qu'il s'agirait d'une expression booléenne valide.

if(cond) {
 ... 
} else {
 ...
}

En plus d'effectuer une analyse sémantique à ce stade de la compilation, des tables de symboles sont souvent créées afin d'aider à la génération de code.

Génération de code

Cette dernière étape d'un compilateur typique convertit la représentation intermédiaire du programme en un ensemble d'instructions exécutable (souvent assembly ). Cette dernière étape est la seule étape de la compilation qui dépende de la machine. Il peut également y avoir une optimisation à ce stade de la compilation qui rend le programme plus efficace.

D'autres passages du compilateur incluent la phase de génération de code intermédiaire qui a lieu avant la génération de code et la phase d'optimisation de code qui peut avoir lieu lorsque le programme source est écrit, ou après la phase de génération de code intermédiaire, ou après la phase de génération de code.

Avantages des compilateurs multi-passes

Indépendant de la machine : étant donné que les passes multiples incluent une structure modulaire et que la génération de code est découplée des autres étapes du compilateur, les passes peuvent être réutilisées pour différents matériels/machines.

Langages plus expressifs : les passes multiples évitent le besoin de déclarations avancées, permettant à la récursivité mutuelle d'être implémentée avec élégance. Les principaux exemples de langages nécessitant des déclarations avancées en raison de l'exigence d'être compilables en une seule passe incluent C et Pascal , alors que Java n'a pas de déclarations avancées.

Les références

  • Bornat, Richard , Compilation et écriture des compilateurs : un guide à faire soi-même , Éditions Macmillan, 1979. ISBN  0-333-21732-2
  • Bent Thomsen, Langages et compilateurs SProg og Overseattere , Département d'informatique, Université d'Aalborg