Compilateur

Un compilateur réalisé en C

Un compilateur pour le langage L


Durant les cours de compilation, en licence 3 Informatique à l'université, il nous a été demandé de réaliser un compilateur avec le langage C destiné à lire et à interpréter un langage inventé pour le projet : le langage L.

Le compilateur en lui-même

Un compilateur est un programme informatique qui lit un autre programme écrit dans un langage source (ici le langage L) et qui le traduit en un langage cible, afin de pouvoir exécuter le programme ou l'algorithme qui en résulte. Il signale également les éventuelles erreurs du langage source.

Un langage, en programmation informatique, est constitué avant tout de mots-clés spécifiques et de règles syntaxiques à respecter. Il faut donc évidemment que le compilateur connaisse le lexique complet du langage L et la syntaxe d'écriture du code.

Les analyseurs

C'est pour cela que notre compilateur est équipé de deux analyseurs : un analyseur lexical et un analyseur syntaxique. L'analyseur lexical va lire des séquences de caractères appelés lexèmes. C'est-à-dire que pour chaque groupe de caractères lu, l'analyseur va lui associer un type de données (via des identificateurs comme "nombre", "identificateur de variable", "identificateur de fonction"...) et récupérer ensuite ces caractères lus (donc le mot lu). L'analyseur lexical ne regarde pas si le code est écrit correctement ou non. Il faut simplement que les mots lus par l'analyseur soient présents dans le lexique du langage. L'analyseur syntaxique est plus complexe et va traiter l'ordre des éléments du langage source pour vérifier si la syntaxe du langage est respectée (par exemple, si le mot lu est une parenthèse ouvrante, il faut s'assurer qu'il y a bien une parenthèse fermante qui la suit).

La grammaire

Pour permettre à l'analyseur de connaître la syntaxe du langage, et donc de l'exploiter, on utilise une grammaire propre au langage L. En informatique, une grammaire est un ensemble de contraintes syntaxiques. Ces contraintes sont illustrées par des règles de réécriture (ou règles de production) sous la forme suivante : A -> BC | DE (dans ce cas, cela signifie : "A engendre B suivi de C OU engendre D suivi de E"). La grammaire du langage L possède plus de 60 règles de réécriture. Et ce sont ces règles que l'analyseur syntaxique doit connaître pour fonctionner correctement. Ainsi, pour que l'analyseur soit en possession de ces règles, il faut les programmer dans l'analyseur lui même (sans évidemment faire d'erreurs). Et pour cela, il faut respecter une certaine structure récurrente pour chaque règle.
Voici un exemple de code vérifiant la grammaire de la structure de la boucle "TANT QUE" :


void instructionTantque() {
    affiche_balise_ouvrante("instructionTantque", 1);
    if (uniteCourante == TANTQUE) {
        afficher_element(uniteCourante);
        uniteCourante = yylex();
        expression();
        if (uniteCourante == FAIRE) {
            afficher_element(uniteCourante);
            uniteCourante = yylex();
            instructionBloc();
        } else {
            erreur("erreur de syntaxe -> \'FAIRE\' attendu.");
        }
    } else {
        erreur("erreur de syntaxe -> \'TANTQUE\' attendu.");
    }
        affiche_balise_fermante("instructionTantque", 1);
}


L'"unité courante" est une variable qui contient le dernier caractère ou le dernier mot-clé lu. C'est pour cela qu'on teste plusieurs conditions avec celle-ci. Si elle est égale au mot-clé "TANTQUE" alors on lui fait lire le mot suivant et ainsi de suite. Il en découle ainsi un ordre de mots-clés correspondant à la syntaxe du langage (et donc à la grammaire). Si l'ordre et donc la syntaxe des mots-clés sont respectés, l'instruction est correcte (et une autre structure se chargera de la faire fonctionner). Autrement, on se trouve dans le cas "erreur" indiquant qu'une erreur de syntaxe a été trouvée.

Les explications s'arrêtent ici pour éviter toute complexité. Toutefois, le code de notre compilateur est disponible via GitHub (lien ci-dessous).

Caractéristiques du projet


Titre Compilateur
Description Compilateur en C pour le langage inventé L.
Langage utilisé C
Année de réalisation 2016
Accès au code Lien