[Next] [Previous] [Top]

Metteur en page de sources Ada


3. Analyses et conceptions de base

Dans les deux premières applications, on a besoin de traiter spécialement certains éléments lexicaux du langage Ada : identificateurs et mots réservés dans l'application de changement d'apparence, et mots réservés et commentaires dans l'application de génération de fichiers d'impression.

En plus, les autres éléments lexicaux du langage doivent être traités également, même si on ne va pas les modifier mais les récrire tels quels dans le fichier de sortie.

Une analyse lexicale des sources se montre donc nécessaire.

Les composants de base pour les deux premières applications doivent donc permettre d'une part la lecture du fichier à analyser, et d'autre part son analyse lexicale.

On veut pouvoir accepter des arguments sur la ligne de commandes pour toutes les applications. Pour ceci, on va se servir du composant Command_Line, qui permet d'analyser les arguments passés en paramètre.

Dans toutes les applications, on veut aussi pouvoir travailler, en absence des arguments indiquant les fichiers d'entrée et de sortie, avec les canaux standards d'E/S.

Dans le cas où les fichiers d'entrée et de sortie soient indiqués, il faudra donc les ouvrir en lecture et en écriture respectivement, et les positionner comme canaux standards d'E/S (à l'aide des instructions Set_Input et Set_Output de Text_IO), pour après faire appel aux services de lecture et d'analyse lexical.

Si, par contre, on utilise les mécanismes de redirection offerts par Unix (<, >), cette procédure d'assignation des canaux standards d'E/S est automatiquement faite par le système d'exploitation.


3.1. Services de lecture

Il s'agit du composant Character_Input_G, qui offre des services de lecture de caractères du fichier d'entrée courant.

Du point de vue de l'implémentation, c'est un paquetage générique, dont le paramètre générique fixe la longueur maximale des lignes lues :

generic

  Max_Line_Length : in Positive := 512;

Les primitives fournies par ce composant sont :

- Constructeurs :

procedure Get_Line;       : permet de lire une ligne.

procedure Get_Next;       : permet d'avancer d'un caractère dans la ligne
                            courante.

procedure Backtrack
  (N : in Positive := 1); : permet de reculer dans la ligne courante.

- Sélecteurs :

function Current_Line
  return Natural;         : permet de consulter la valeur du numéro de
                            ligne courante.

function Current_Column
  return Natural;         : permet de consulter la valeur du numéro de
                            colonne courante.

function Has_Char
  return Boolean;         : permet de vérifier l'existence de caractères.

function Current_Char
  return Character;       : permet de consulter le caractère courant.

function Line_Slice
  (First,
   Last : Positive)
  return String;          : permet d'obtenir une tranche de la ligne
                            courante.


3.2. Analyseur lexical

Il s'agit du composant Ada_To_Foo_G, qui, en se servant du composant précédent, parcourt le fichier d'entrée courant en réalisant son analyse lexical.

Les éléments lexicaux du langage Ada reconnus sont [LRM87] :

- les séparateurs,
- les délimiteurs,
- les identificateurs,
- les mots réservés,
- les littéraux numériques,
- les littéraux caractères,
- les littéraux chaînes,
- les commentaires.

Les mots réservés étant à priori considérés comme des identificateurs du langage, leur reconnaissance se fait à l'aide d'une table contenant tous les mots réservés du langage Ada [LRM87]. Cette table est triée par ordre alphabétique, de façon à pouvoir effectuer une recherche par dichotomie.

Du point de vue de l'implémentation, c'est un paquetage générique, dont les paramètres génériques définissent le traitement qu'on va effectuer sur chacun des éléments du langage :

generic

  procedure Put_Page;       : invoquée lorsqu'on retrouve une nouvelle
                              page.

  procedure Put_Empty;      : invoquée lorsqu'on retrouve une ligne vide.

  procedure Put_Newline;    : invoquée lorsqu'on retrouve une nouvelle
                              ligne.

  procedure Put_Line_Number
    (Number : in Positive); : invoquée au début de chaque nouvelle
                              ligne, pour la numéroter si nécessaire.

  procedure Put_Blank
    (S : in String);        : invoquée lorsqu'on retrouve une suite de
                              espaces ou de caractères de tabulation.

  procedure Put_Reserved
    (Word : in String);     : invoquée lorsqu'on retrouve un mot réservé.

  procedure Put_Identifier
    (Id : in String);       : invoquée lorsqu'on retrouve un
                              identificateur.

  procedure Put_Numeric
    (Num : in String);      : invoquée lorsqu'on retrouve un littéral
                              numérique.

  procedure Put_String
    (S : in String);        : invoquée lorsqu'on retrouve un littéral
                              chaîne.

  procedure Put_Comment
    (S : in String);        : invoquée lorsqu'on retrouve un
                              commentaire.

  procedure Put_Character
    (C : in Character);     : invoquée lorsqu'on retrouve un littéral
                              caractère.

  procedure Put_Delimiter
    (Compound : in String); : invoquée lorsqu'on retrouve un délimiteur.

  procedure Put_Substitute
    (C : in Character);     : permet, lors de l'écriture, de traiter les
                              caractères spéciaux dans la lexicographie
                              du langage, en les substituant si nécessaire.



Figure 1. Architecture de l'analyse lexicale.

Lors de l'analyse lexicale du fichier source, on ne fait que "reconnaître" les différents éléments lexicaux du langage, qui sont donc passés tels quels aux services de traitement correspondantes. De cette façon, l'analyseur reste indépendant du traitement spécifique réalisé, et c'est dans l'application qui l'utilise qu'on décide les différents traitements à faire.

A ce propos :

- les mots réservés et les identificateurs sont passés tels quels à l'application, sans les transformer (majuscules / minuscules);

- les commentaires sont passés sans le début du commentaire (--), qu'on ajoute dans l'application. On peut même penser à décorer nos commentaires avec un motif différent.

Certaines de ces procédures, qu'on pourrait croire ne pas avoir besoin (par exemple, la génération de code PostScript n'a pas besoin de Put_Empty), sont pourtant conservées pour que le composant reste général, en fournissant une "base", qui sera objet d'un usage spécifique par chaque application.

Des applications qui génèrent des fichiers d'impression dans d'autres formats, notamment html, LaTeX et roff (applications ada2html, ada2latex et ada2roff respectivement) vont ainsi être facilement réalisables à l'aide de ce composant, en ne modifiant à chaque fois que le corps des procédures constituant les paramètres génériques du composant, qui reste donc inchangé.

Les primitives fournies par ce composant sont :

- Constructeurs :

procedure Translate;     : invoquée pour lancer l'analyse lexicale du
                           fichier d'entrée courant.

- Sélecteurs (invoqés depuis les opérations passées en paramètres effectifs génériques, pour contrôler la sortie) :

function Current_Line
  return Natural;        : permet de consulter la valeur du numéro de
                           ligne courante.

function Current_Column
  return Natural;        : permet de consulter la valeur du numéro de
                           colonne courante.


Metteur en page de sources Ada - 29 MAR 95
[Next] [Previous] [Top]

Generated with CERN WebMaker