CS22 - Partie "Traduction" - TP Noté 2 - 1h30

ANALYSE LEXICALE : unités lexicales dans un programme C

L'exercice montre les capacités en reconnaissance de flex seul,
notamment grâce à ses macros-définitions. Il s'agit :
- de reconnaitre les éléments permettrant d'établir les "références croisées"
  d'un programme (table des lignes définissant ou citant chaque symbole)
- ceci en distinguant certaines catégories lexicales

On suppose que le programme analysé :
- est syntaxiquement correct (d'ou pas besoin d'une grammaire complète)
- qu'il contient seulement des définitions :
  de directives (#...), de variables globales, de fonctions
  
Un analyseur lexical suffit : on utilisera flex seul. De plus il suffit
de reconnaitre les catégories visées (pas d'extraction de symbole ici)
 
Chaque question traite d'une seule catégorie, avec un fichier de test spécifique. 
Le barème est indicatif. Des indications générales sont données ici.
Les consignes pour rendre votre travail se trouvent la.
 

I - Reconnaissance des DIRECTIVES #include et #define

(6 points. Fichier è rendre : lex1.flex. Données : test1.txt)

- il faut reconnaitre :
  #include < xxxx>
  #include "xxxxxxx"
  #define XXX
  #define xxxxx yyyyyyyyy
  #define xxxxx ( yyy zzz ... )
 Les autres directives (#ifdef ... ) ne sont pas è traiter
   
- Indications
. on peut prendre comme separateurs espace et tabulation.
. chaque directive est supposée écrite sur une seule ligne
. attention au 2a dans les indications
. pour le 3eme exemple de define, utiliser une regle lexicale specifique


2 - Définitions de VARIABLES GLOBALES DE TYPES SIMPLES

 (7 points. Fichiers :  lex2.flex, test2.txt)

- on ne considère que les variables globales (pas les variables locales)

- on doit reconnaitre les définitions de variables globales :
. de type char, int, long et leurs variantes unsigned
. de type float, double
. ou pointeurs sur ces types simples

- on ne traitera pas ici de types structures, ni de tableaux
  
Indications :
- utiliser des macros, pouvant se citer l'une l'autre (voir Memo flex et man),
- procéder progressivement, par exemple selon cet ordre :
  S :         une suite d'espaces ou tabulations
  S_NL        une suite d'espaces ou tabulations ou "newlines"
  PTR :       une suite d'étoiles (supposées non espacées)
  I_TYP :     un nom de type (char, int, ..), éventuellement unsigned
  R_TYP       un nom de type rationnel (float, double)
  TYP         un nom de type
  SYMB :      un symbole alphanumérique
  VAR :       définition de variable scalaire éventuellement de type pointeur
  VAR_LIST :  liste de noms de variables, séparés par ',', terminée par
              un ';', avec espaces éventuels entre les champs


3 - Définitions de VARIABLES GLOBALES de type TABLEAU

(7 points. Fichiers lex3.flex, test3.txt)

- On suppose que :

. les tableaux sont de types simples, ou pointeurs sur types simples
. les tableaux peuvent comporter plusieurs dimensions
. leur taille selon chaque dimension est un entier, ou bien non spécifiée 
 
- à une definition de type peut être associée une liste de un ou plusieurs
  tableaux, alors séparés par des virgules

- Elaborer progressivement votre analyseur :

. macros pour les notions suivantes : 

  INT_VAL       entier positif
  DIM           dimension de tableau, exemples : [ ] ou [nn]
  DIMS          suite de définitions de dimensions, séparées par des virgules
  ARRAY_DEF     définition (nom + dimensions) d'un tableau, p.ex. a[][2]
  ARR_DEF_LIST  liste de définitions de tableau

. puis traitement des instructions du fichier exemple 

4 - Question subsidiaire : DEFINITIONS DE FONCTIONS

(BONUS - Fichiers lex4.flex, test4.txt)

Ne sont pas à traiter les prototypes de fonction, ni les appels de fonction.
On se contente de reconnaitre le debut et la fin d'une définition de fonction.

a) Reconnaitre d'abord SEPAREMENT :
 
- Type de fonction. Macro F_TYP
  Ne considérer que les types simples, éventuellement pointés, plus le type void
  (ne pas traiter les types struct ou tableau). Réutiliser les macros TYP et PTR
  
- Nom de fonction avec type : macro F_TYPEDNAME, réutilisant F_TYP et SYMB

- Liste de paramètres formels, éventuellement vide, entre '(' et ')' : macros :  
  ARG       un argument, uniquement de type simple, éventuellement pointé
  ARG_LIST  une suite d'ARG séparés par des virgules
  F_ARGTS   une paire '(' ')' contenant éventuellement une ARG_LIST
  
b) Reconnaitre l'en-tête d'une fonction, cad. une succession :
        F_TYPEDNAME F_ARGTS  \{
  . attention, spécifier \{ plutot que '{' qui peut ne pas fonctionner
  . admettre éventuellement des espaces

c) Reconnaitre le bloc d'instructions :
  Après un '{' suivant un en-tête de fonction, il faut reconnaitre
  le '}' de fin correspondant. Pour cela :
  
- utiliser une start-condition (voir memo Flex 2.6) "InFuncBlock"
- utiliser une variable "level, niveau d'imbrication des blocs '{' '}'