zo iNiTiATiON SPEECHES
S01E94 2024-10-30

S01E94 — 30-10-2024.

L’ingénierie d’un compilateur — Analyzer.

jour 94.

Me voici au chapitre 3, je suis très loin d’avoir fini, mais c’est intéressant de conforter des connaissances acquises et découvrir des concepts nouveaux. L’Analyzer connu comme étant le vérificateur des types (Type Checking) est un sujet assez intéressant. Puisque si ton langage de programmation intègre un système de type et que celui-ci procède à la vérification du langage source durant le temps de compilation, il te garantit une exécution de ton programme sans erreurs de types.

Tu vas devoir conceptualiser ton langage de programmation avec cette possibilité. Par exemple, procéder à la vérification des types durant le temps d’exécution va impacter les performances de ton langage (et oui, il sera moins rapide le coco). Alors que si cela est effectué à la compilation, c’est du ni vu, ni connu. Et tu peux même informer ton utilisateur des différentes erreurs et lui donner des indices pour qu’il puisse les résoudre.

Prenons l’opération suivante :

a + b * c

Ton Analyzer est aveugle. Certes le Parser à vérifié que la forme syntaxique du langage source était correct, mais l’Analyzer quant à lui va devoir déduire ce qui se cache derrière les variables a, b et c. Si je te présente trois verres d’eau, il te sera difficle de savoir si il s’agit de l’eau du robinet, de l’Evian ou encore de la Cristaline. Certes un expert sera faire la différence rien qu’au goût. Mais ton Analyzer n’est pas un expert, il est bête et a besoin d’avoir des règles précises pour déduire un type. On va devoir étiqueter nos verres pour connaitre de façon sûr de quel eau il s’agit.

C’est la mission première de l’Analyzer, aider par quatre composants distincts (que l’on verra plus tard), il va être capable de savoir que les variables a, b et c ont la même étiquette.

Qui a envie de boire un verre d’eau composé de trois eaux différentes ?

Avant de mélanger les verres, j’aimerai m’assurer que j’ai affaire à la même eau. Si j’ai trois verres d’Evian, je dis oui, et ainsi de suite mais si j’ai deux verres d’Evian et un verre de Cristaline. Je ne veux pas mélanger ces verres entre eux. Et bien, c’est la même chose pour un Analyzer tant qu’il ne’est pas capable d’assurer la nature intrinsèque d’une variable. Il génèrera une erreur. Au contraire, si il est sûr (après vérification approfondie) que les variables sont de nature commune — il saura si oui ou non, il peut procéder au calcul requis. Tu peux aussi prendre l’exemple de passagers de trains avec leur billet de train. Compliqué en traversant le wagon de savoir si ils ont tous le bon billet pour ce voyage. Ils vont devoir te présenter un billet et c’est celui qui va te donner les informations dont tu as besoins.

Un langage de programmation généralement, nécessite souvent de déclarer une variable avant de pouvoir l’utiliser. C’est une manière de faire pour permettre à l’Analyzer de faire son job correctement. D’autres pratiques sont possibles pour avoir une liberté de programmation avec un minimum de contrainte comme l’inférence de type. Globalement, il y a toujours un peu d’inférence de type dans un langage de programmation, même si le langage repose sur un typage fort. L’essence propre du vérificateur des types comprend une inférence basique.

Du coup :

        a   +   b   *   c
        |       |       |
        ↓       ↓       ↓
       int     int     int

Chaque variable est un nombre entier. Ton programme est valide.

        a   +   b   *   c
        |       |       |
        ↓       ↓       ↓
       int     int    float

Oups, il y a un intru (un nombre flottant) dans ta maison. Ton programme n’est pas valide.

Tu peux comprendre que tu vas devoir stocker les déclarations de variable dans une table (Hashmap) et l’interroger à chaque fois qu’une variable est invoquée. Simple — Efficlasse.

@invisageable