Réaliser un interpréteur en Pascal

Avec Free Pascal sous Lazarus

Auteur

Gilles Vasseur

Ce tutoriel vous permet d'apprendre les bases de la programmation avec un dérivé de LOGO ou de vous perfectionner en bâtissant l'interpréteur de A à Z…

Commentez

- Titre : Réaliser un interpréteur en Pascal

- Auteur : Gilles Vasseur

- Parution : 15 mars 2015

- Public visé :

- Licence : Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright ® 2015 Gilles Vasseur. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- I. Le projet

- II. Les objets de GVLOGO

- III. Récréation : EasyTurtle (logiciel de dessin)

- IV. Les outils de programmation

- V. Les composants du langage

- VI. L'interpréteur

- VII. Le programme final

- VII-A. Aperçu de l'organisation du logiciel

- VII-A-1. La coloration syntaxique

- VII-A-2. L'interface utilisateur

- VII-B. Ce qu'il reste à faire

- VII-B-1. L'urgent

- VII-B-2. Le possible et le souhaitable

I - Le projet

II - Les objets de GVLOGO

III - Récréation : EasyTurtle (logiciel de dessin)

IV - Les outils de programmation

V - Les composants du langage

VI - L'interpréteur

VII - Le programme final

Cette partie décrit de manière succincte le logiciel final GVLOGO. Il ne s'agit plus de tests d'unités, mais de la mise en œuvre de tout le travail précédent.

VII-A - Aperçu de l'organisation du logiciel

On reconnaît les différentes unités créées dans les chapitres précédents : elles sont toutes contenues dans le répertoire units.

Les nouvelles unités sont presque toutes des fiches préfixées par frm. Leur nom devrait éclairer sur leur rôle qui est rappelé par les commentaires au sein du code lui-même.

L'unité principale se nomme main.pas. L'unité GVLOGOConsts contient les constantes propres au programme final.

Une unité originale étudiée plus loin gère la coloration syntaxique de l'éditeur : il s'agit de GVHighlighter. L'unité frmeditor est la plus intéressante puisqu'elle contient à la fois les méthodes pour la coloration syntaxique et celles pour l'interprétation du contenu de l'éditeur.

Les dépendances nouvelles sont Printer4Lazarus, CodeTools, SynEdit et richmemopackage. Seul ce dernier paquet n'est pas fourni avec Lazarus : il figure dans le dossier « 3rdparty » avec BGRABitmap et doit être installé pour faire fonctionner l'ensemble.

VII-A-1 - La coloration syntaxique

Pour son propre fonctionnement, Lazarus utilise une version du paquet SynEdit qui permet entre autres la coloration syntaxique d'un éditeur. Comme ce paquet est utilisé de manière interne, il est inutile de l'installer. Il suffit de l'inclure dans les paquets requis pour qu'il soit accessible.

Livré avec des unités de coloration pour de nombreux langages, il fournit aussi des outils pour mettre au point un éditeur adapté aux besoins d'un projet particulier. C'est pourquoi il en est fait usage dans GVLOGO.

Afin de faciliter la compréhension des problèmes à résoudre et des solutions apportées, un dossier spécifique contient le test de l'unité GVHighlighter. Son développement s'appuie pour une large part sur le tutoriel fourni dans le sous-dossier SynEdit du dossier « examples » de Lazarus.

Le travail de coloration s'appuie sur les mêmes critères que l'interpréteur, à savoir le premier caractère de chaque unité lexicale. La difficulté supplémentaire ne concerne que les commentaires à repérer puisqu'ils conditionnent toute la ligne et non une unité particulière.

C'est la méthode Next qui s'occupe de ces difficultés :

procedure TGVHighlighter.Next;
// *** caractère suivant ***
var
Li: Integer;
LB: Boolean;
begin
fTokenPos := fTokenEnd; // position en cours
Li := Length(FLineText); // longueur de la ligne en cours
if fTokenPos > Li then // fin de ligne ?
Exit // on sort
else
// une chaîne ?
if fLineText[fTokenEnd] = CQuote then
begin
LB := True; // drapeau de caractère d'échappement
while (fTokenEnd <= Li) and (not (fLineText[fTokenEnd]
in [CTab, CBlank]) or LB) do
begin
LB := fLineText[fTokenEnd] = '$';
Inc(fTokenEnd); // on compte jusqu'à la fin de l'élément
end;
end
else
// un symbole ?
if fLineText[fTokenEnd] in CBraces then
Inc(fTokenEnd)
else
// un commentaire ? (seulement si commence la ligne)
if (Length(TrimLeft(fLineText)) > 1) and (TrimLeft(fLineText)[1] = CSlash)
and (TrimLeft(fLineText)[2] = CSlash) then
fTokenEnd := Length(fLineText) + 1
else
// un espace ?
if fLineText[fTokenEnd] in CBlanks then
while (fTokenEnd <= Li) and (fLineText[fTokenEnd] in CNonPrintable) do
Inc(fTokenEnd) // on saute les espaces
else
// autres cas
while (fTokenEnd <= Li) and not(fLineText[fTokenEnd]
in CSeparators) do
Inc(fTokenEnd); // on compte jusqu'à la fin de l'élément
// POUR ou FIN ? => pliage possible
if SameText(TrimLeft(Copy(fLineText, 1, fTokenEnd - 1)), P_To) then
StartCodeFoldBlock(nil)
else
if SameText(TrimLeft(Copy(fLineText, 1, fTokenEnd - 1)), P_End) then
EndCodeFoldBlock;
end;

Le programme de test se présente sous cette forme :

Un simple clic sur le bouton « Colorer » activera la coloration syntaxique :

On pourra de même plier et déplier le code des procédures.

VII-A-2 - L'interface utilisateur

Sans vouloir se substituer à un véritable mode d'emploi, une présentation rapide du logiciel final est sans doute nécessaire.

Pour l'installation, il suffit de partir du dossier fourni en téléchargement qui contient au minimum le programme GVLOGO, le fichier GVPrimDefs.txt et le dossier « samples » des exemples. Le dossier global est à placer dans l'emplacement désiré.

Les habitués de Windows savent que depuis Windows 7, il n'est plus accepté de modifications des fichiers placés dans les zones protégées qui abritent les exécutables. GVLOGO crée les dossiers adéquats dans lesquels il est conseillé de sauvegarder son travail. Dans l'attente d'un véritable programme d'installation, il est souhaitable de transférer les fichiers d'exemples dans ce dossier créé et sélectionné par défaut.

Généralement, il se présente comme suit :

En cliquant sur l'exécutable, on obtient l'écran suivant :

La fenêtre ouverte permet d'accéder à toutes les fonctionnalités du logiciel dès lors qu'elles sont opérationnelles, ce qui dépend du contexte. Le composant non visuel TActionList est le fondement de tout ce travail d'activation et de désactivation des fonctionnalités.

Afin de démarrer, il est conseillé d'ouvrir un des fichiers d'exemples comme Tout.GVL :

Le fichier est chargé en utilisant la commande « Ouvrir… » du menu « Fichier ». Dès qu'il a été chargé, l'éditeur s'ouvre. L'utilisateur a alors accès à toutes les procédures préenregistrées du projet.

Il suffit de choisir dans le menu « Exécuter », la fonction « Interpréter » pour lancer l'enregistrement des procédures présentes dans l'éditeur, mais aussi l'exécution des commandes du même éditeur.

L'observation de l'éditeur montre que des lignes de commandes seront ainsi exécutées en cas d'interprétation :

Juste après la définition d'un triangle, on a en effet une série de commandes qui demandent d'effacer l'écran, de dessiner une spirale composée d'octogones et d'écrire des messages sur l'écran de texte.

Dès que GVLOGO repère qu'il faut agir sur un des écrans (tortue ou texte), les deux apparaissent en avant-plan. On obtient donc :

La ligne de commandes affichée au-dessus des deux fenêtres de sortie, permet de donner des ordres à l'interpréteur sans intervenir dans l'éditeur. Par exemple, après ce premier dessin, il est suggéré de taper sur cette ligne les commandes suivantes :

VIDE.ECRAN TETRAEDRE 100 4

Un simple appui sur la touche « Entrée » lancera l'exécution de la procédure enregistrée, après effacement de l'écran de la tortue :

En remplaçant TETRAEDRE par NIMPORTEQUOI, on déclenche une erreur :

On pourra ainsi tester les différentes options et fonctionnalités du logiciel : les plus intéressantes sont certainement celles de débogage qui affichent en temps réel l'état des variables locales et globales, ou encore les paquets. L'activation de la trace depuis le menu « Exécuter » sera l'occasion de consulter la fenêtre de suivi. De même, une procédure est modifiable depuis le menu « Voir » dans sa partie « Débogage ». Dans le menu « Voir », l'état de la tortue et celui de l'écran de texte peuvent être modifiés directement. Enfin, les amateurs d'éditeurs analyseront avec profit le fonctionnement des menus « Éditer » et Chercher ».

VII-B - Ce qu'il reste à faire

L'objectif était de réaliser un interpréteur LOGO grâce à Lazarus. De ce point de vue, le travail est terminé ! Mais il est toujours possible d'aller plus loin…

VII-B-1 - L'urgent

Il est indispensable de rédiger un mode d'emploi de GVLOGO, ainsi qu'un guide pour l'utilisation du programme (programmation et activités pédagogiques).

VII-B-2 - Le possible et le souhaitable

Les éléments suivants sont faciles à implémenter et peuvent faire l'objet d'exercices de prolongation de cette brochure :

- implémentation des méthodes de la tortue dessinant des formes prédéfinies (comme prévu dans le présent document au chapitre sur la tortue) ;

- implémentation de méthodes complémentaires pour le texte sur l'écran de la tortue ;

- ajout de primitives concernant les dates et les heures ;

- implémentation des queues et des piles (comme prévu par le présent document au chapitre sur les piles) ;

- gestion élémentaire de la souris.

Des améliorations de détails sont sans doute souhaitables :

- utilisation de VRAI et FAUX au lieu de 0 et -1 pour les retours et les paramètres de type booléen ;

- HASARD devrait différencier HASARD "123 et HASARD 123, le premier renvoyant un élément du mot (1, 2, ou 3) et le second un nombre de 1 à 123 ; mise en place d'un système de bulles d'aide dans l'éditeur dès qu'une primitive est sous le curseur ou le pointeur de la souris ;

- un menu d'options permettant de personnaliser l'éditeur, surtout pour les couleurs employées ;

- le remplacement global dans l'éditeur avec un questionnement préalable à chaque occurrence.

Des fonctionnalités un peu plus délicates sont aussi envisageables :

- impression avec différenciation syntaxique ;

- chargement et enregistrement de fichiers de procédures sans passer par l'éditeur ;

- mise en place d'un système de points de suivi/d'arrêt lors de l'exécution d'un programme ;

- acceptation des caractères accentués dans les identificateurs ;

- les primitives ont des structures redondantes pour les nommer, donc sources d'erreurs : pourquoi ne pas tout fonder sur le fichier chargé au démarrage, ce qui permettrait par ailleurs de pouvoir modifier l'intitulé des primitives ?

La liste est loin d'être exhaustive… Alors, pour qui se dit qu'il a glané ici ou là des idées à partager avec la communauté des programmeurs en Pascal, il ne reste qu'à retrousser les manches et à livrer ses trouvailles !