Ce cours aborde toutes les étapes de la compilation, de l'analyse d'un langage source jusqu'à la génération d'un langage cible, en passant par l'analyse lexicale, l'analyse syntaxique, la représentation intermédiaire, la génération de code et l'interface avec le système d'exploitation et les ressources. Il s'agit d'un cours à la fois pratique, avec l'implémentation d'un compilateur de A à Z sous la forme d'un projet, mais aussi théorique, fondé sur des notions formelles et nécessitant beaucoup de rigueur pour manipuler des structures complexes. Forts d'une compréhension profonde de ce processus essentiel à l'informatique, les étudiants apprennent à mieux se servir d'un compilateur, à ne pas le considérer comme une boîte noire et, ainsi, à mieux programmer. De plus, les techniques décrites dans le cadre de la compilation peuvent être utilisées pour tout processus de traduction non trivial entre deux types de structures. Finalement, ce cours permet la mise en pratique de concepts de gestion de projet, afin d'organiser le développement d'un projet logiciel important.
-
introduction (10%) : architecture d'un compilateur, étapes d'analyse, étapes de génération, notions élémentaires (langage source, langage cible, représentation intermédiaire, table des symboles, etc.)
-
analyse lexicale (10%) : rappel expressions régulières, rappel automates finis, unités lexicales, identificateurs, écriture d'analyseurs lexicaux avec (f)lex
-
analyse syntaxique (20%) : rappel grammaires hors contexte, arbre de dérivation, ambiguïté, récursivité gauche/droite, factorisation, écriture de grammaires, rappel automates à pile, algorithmes d'analyse syntaxique (LL, LR, etc.)
-
analyse sémantique (10%) : table des symboles, typage, vérifications de types, conversion/coercition de types
-
grammaires attribuées (20%) : actions sémantiques, système d'attributs synthétisés/hérités, construction de l'arbre abstrait
-
langage machine (10%) : rappel architecture des ordinateurs (processeur, registres, mémoire, etc.), jeu d'instructions assembler (transfert de données, opérations arithmétiques/logiques, instructions de contrôle, etc.), interface avec système d'exploitation, pile du système
-
génération de code (20%) : allocation de ressources (mémoire, registres, etc.), génération d'instructions, appels de fonction, trame de pile, allocation et portée de variables, passage d'arguments par valeur/référence