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 '{' '}'