OpenCores
URL https://opencores.org/ocsvn/minimips_superscalar/minimips_superscalar/trunk

Subversion Repositories minimips_superscalar

[/] [minimips_superscalar/] [trunk/] [gasm_with_mult2_instruction/] [src/] [preparateur.c] - Blame information for rev 6

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 6 mcafruni
/*********************************************************************************************/
2
/* MODULE PREPARATEUR                                                                        */
3
/* ce module a pour but de lire le fichier Syntaxe du programme et de générer l'arbre des    */
4
/* lexèmes qui lui correspond.                                                               */
5
/*                                                                                           */
6
/* Le seul point d'accès de ce module est la fonction init_arbre qui reçoit le nom du        */
7
/* fichier Syntaxe à utiliser.                                                               */
8
/*                                                                                           */
9
/*********************************************************************************************/
10
 
11
#include "preparateur.h"
12
 
13
/* Inclusion des modules de la bibliothèque standard.                                        */
14
#include <stdio.h>
15
#include <string.h>
16
 
17
/* Inclusion des autres modules utilisés du projet.                                          */
18
#include <debogueur.h>
19
#include <parametres.h>
20
#include <dialogue.h>
21
#include <formateur.h>
22
#include <adaptateur.h>
23
 
24
/* Ces macros sont utilisées pour les comparaisons de chaines. Leur valeur détermine la     */
25
/* sensibilité ou non du préparateur à la casse lors de la lecture du fichier Syntaxe.      */
26
#define string_comp     strcasecmp
27
#define lexeme_comp     lexcaseid       
28
 
29
type_noeud *root = NULL;        /* Définition de la racine de l'arbre des lexèmes.           */
30
 
31
/* Numéro de ligne et fichier Syntaxe courant.                                               */
32
static int ligne=1;
33
static char * n_fich;
34
static FILE * f_syn;
35
 
36
/*********************************************************************************************/
37
/*                                                                                           */
38
/* Définition des objets décrivant la syntaxe et l'organisation du fichier Syntaxe. On       */
39
/* trouve :                                                                                  */
40
/*                                                                                           */
41
/*      la table des mots clefs, qui contient les valeurs spécifiant un type de lexème.      */
42
/*      la table des propriétés, regroupant le nom des différentes propriétés.               */
43
/*      la table des fonctions qui peuvent être exécutées à la lecture du fichier Syntaxe.   */
44
/*                                                                                           */
45
/*********************************************************************************************/
46
 
47
 
48
/* TABLES DES MOTS CLEF                                                                      */
49
typedef struct
50
{
51
        char * nom;
52
        type_type_lex code;
53
} type_table;
54
 
55
/* Table statique des mots clefs correspondant aux types de base.                            */
56
#define NUM_KEYWORD     2       /* Nombre de mots clef reconnus par le préparateur.          */
57
static type_table table_clef_base[NUM_KEYWORD] =
58
        { { "alpha"     , ALPHA}
59
        , { "int"       , NUM}
60
        };
61
 
62
/* Table dynamique des mots clefs correspondant aux sous types.                              */
63
static type_table * table_clef_sst=NULL;
64
 
65
 
66
/* TABLE DES PROPRIETES                                                                      */
67
#define NUM_PROP        3
68
static char *prop_table[NUM_PROP] =
69
        {       "TMO"
70
        ,       "MSK"
71
        ,       "FUN"
72
        };
73
enum {TMO, MSK, FUN}; /* Codes symboliques pour les différentes propriétés.                 */
74
 
75
 
76
/* TABLE DES FONCTIONS                                                                      */
77
/* Définition des fonctions de paramétrage du preparateur. Elles seront exécutées à la      */
78
/* demande du fichier Syntaxe lors de la rencontre de l'instruction SET.                    */
79
 
80
/* En cas d'erreur, ces fonctions renvoient 1 et positionnent la variable errcode du module */
81
/* erreur. La fonction appelante se charge de l'affichage de l'erreur.                      */
82
 
83
int casse()
84
{
85
        casse_sens = 1;
86
        DIALOGUE(NULL, 0, B_CASSE);
87
        return 0;
88
}
89
 
90
int nocasse()
91
{
92
        casse_sens = 0;
93
        DIALOGUE(NULL, 0, B_NOCASSE);
94
        return 0;
95
}
96
 
97
int macrofile() /* Cette fonction lit le nom du fichier macro par défaut et l'enregistre.    */
98
{
99
        long pos=ftell(f_syn);
100
        type_lexeme * l;
101
 
102
        DIALOGUE(NULL, 0, B_MAC_DEF);
103
 
104
        l=get_lexeme(f_syn);
105
        if (l==NULL)
106
        {
107
                err_code=S_BAD_ARG;
108
                return 1;
109
        }
110
        if (!TYPE_IS(l, ALPHA) || !LIT_MPV(l->type))
111
        {
112
                FREE_LEX(l);
113
                fseek(f_syn,pos-ftell(f_syn),SEEK_CUR); /* On "remet" le lexème.             */
114
                err_code=S_BAD_ARG;
115
                return 1;
116
        }
117
 
118
        if (fich_macro_def!=NULL) free(fich_macro_def);
119
        fich_macro_def=l->valeur.alpha;
120
        /* On supprime la valeur du lexème pour que la chaine ne soit pas libérée.           */
121
        l->type=RET_MPV(l->type);
122
        FREE_LEX(l);
123
 
124
        err_code = NO_ERR;
125
        return 0;
126
}
127
 
128
int setdefine()
129
{
130
        long pos=ftell(f_syn);
131
        type_lexeme * lex;
132
 
133
        DIALOGUE(NULL, 0, B_INIT_D);
134
 
135
        lex=get_lexeme(f_syn);
136
        if (lex==NULL)
137
        { /* Erreur de lecture de l'argument.                                                */
138
                err_code=S_BAD_ARG;
139
                return 1;
140
        }
141
        if (!TYPE_IS(lex,ALPHA))
142
        { /* L'argument n'a pas le bon type.                                                 */
143
                FREE_LEX(lex);
144
                fseek(f_syn,pos-ftell(f_syn),SEEK_CUR); /* On "remet" le lexème.             */
145
                err_code=S_BAD_ARG;
146
                return 1;
147
        }
148
        if (define_str!=NULL) free(define_str);
149
        define_str=malloc(strlen(lex->valeur.alpha)+1);
150
        strcpy(define_str, lex->valeur.alpha);
151
        FREE_LEX(lex);
152
 
153
        err_code = NO_ERR;
154
        return 0;
155
}
156
 
157
int setundef()
158
{
159
        long pos=ftell(f_syn);
160
        type_lexeme * lex;
161
 
162
        DIALOGUE(NULL, 0, B_INIT_U);
163
 
164
        lex=get_lexeme(f_syn);
165
        if (lex==NULL)
166
        { /* Erreur de lecture de l'argument.                                                */
167
                err_code=S_BAD_ARG;
168
                return 1;
169
        }
170
        if (!TYPE_IS(lex,ALPHA))
171
        { /* L'argument n'a pas le bon type.                                                 */
172
                FREE_LEX(lex);
173
                fseek(f_syn,pos-ftell(f_syn),SEEK_CUR); /* On "remet" le lexème.             */
174
                err_code=S_BAD_ARG;
175
                return 1;
176
        }
177
        if (undef_str!=NULL) free(undef_str);
178
        undef_str=malloc(strlen(lex->valeur.alpha)+1);
179
        strcpy(undef_str, lex->valeur.alpha);
180
        FREE_LEX(lex);
181
 
182
        err_code = NO_ERR;
183
        return 0;
184
}
185
 
186
int setinclude()
187
{
188
        long pos=ftell(f_syn);
189
        type_lexeme * lex;
190
 
191
        DIALOGUE(NULL, 0, B_INIT_I);
192
 
193
        lex=get_lexeme(f_syn);
194
        if (lex==NULL)
195
        {
196
                err_code=S_BAD_ARG;
197
                return 1; /* Erreur de lecture de l'argument.                                */
198
        }
199
        if (!TYPE_IS(lex,ALPHA)) /* L'argument n'a pas le bon type.                          */
200
        {
201
                FREE_LEX(lex);
202
                fseek(f_syn,pos-ftell(f_syn),SEEK_CUR); /* On "remet" le lexème.             */
203
                err_code=S_BAD_ARG;
204
                return 1;
205
        }
206
 
207
        if (include_str!=NULL) free(include_str);
208
        include_str=malloc(strlen(lex->valeur.alpha)+1);
209
        strcpy(include_str, lex->valeur.alpha);
210
        FREE_LEX(lex);
211
 
212
        err_code = NO_ERR;
213
        return 0;
214
}
215
 
216
int setsep()
217
{
218
        type_lexeme * lex;
219
        lex=get_lexeme(f_syn);
220
 
221
        DIALOGUE(NULL, 0, B_INIT_SEP);
222
 
223
        if (lex==NULL)
224
        {
225
                err_code=S_BAD_ARG;
226
                return 1;
227
        }
228
        if (seplex!=NULL) FREE_LEX(seplex);
229
        if (TYPE_IS(lex, OP) && lex->valeur.op==NL) ligne++;
230
        seplex=lex;
231
 
232
        err_code = NO_ERR;
233
        return 0;
234
}
235
 
236
int sst_max=0; /* Nombre maximal de sous-types réservés dans la table.                       */
237
 
238
int setnumsst()
239
{
240
        long pos=ftell(f_syn);
241
        type_lexeme * lex;
242
 
243
        DIALOGUE(NULL, 0, B_PREP_SST);
244
 
245
        if (table_clef_sst!=NULL) /* Réutilisation de SSTNUM.                                */
246
        {
247
                err_code = S_SEC_SST_DEC;
248
                return 1;
249
        }
250
 
251
        lex=get_lexeme(f_syn);
252
        if (lex==NULL)
253
        { /* Erreur de lecture de l'argument.                                                */
254
                err_code=S_BAD_ARG;
255
                return 1;
256
        }
257
        if (!TYPE_IS(lex,NUM))   /* L'argument n'a pas le bon type.                          */
258
        {
259
                FREE_LEX(lex);
260
                fseek(f_syn,pos-ftell(f_syn),SEEK_CUR); /* On "remet" le lexème.             */
261
                err_code=S_BAD_ARG;
262
                return 1;
263
        }
264
        sst_max=lex->valeur.num;
265
 
266
        FREE_LEX(lex);
267
        /* Allocation des tables locales et globale des sous types.                          */
268
        regle_typage = (type_paire *) malloc(sst_max*sizeof(type_paire));
269
        if (regle_typage==NULL) DIALOGUE("preparateur(setnumsst)", 0, F_ERR_MEM);
270
        table_clef_sst = (type_table*) malloc(sst_max*sizeof(type_table));
271
        if (table_clef_sst==NULL) DIALOGUE("preparateur(setnumsst)", 0, F_ERR_MEM);
272
 
273
        err_code = NO_ERR;
274
        return 0;
275
}
276
 
277
int setnewsst()
278
{
279
        long pos=ftell(f_syn);
280
        type_lexeme * lex;
281
        char * nom, *filtre;
282
        type_type_lex code;
283
        int i, bk=0;
284
 
285
        DIALOGUE(NULL, 0, B_ADD_SST);
286
 
287
        /* Vérification que la déclaration du nombre de sous-types est valide.               */
288
        if (regle_typage==NULL || table_clef_sst==NULL || nbr_sous_types>=sst_max)
289
        {
290
                err_code=S_BAD_SST_DEC;
291
                return 1;
292
        }
293
 
294
        /* Lecture du mot clef correspondant au sous-type.                                   */
295
        lex=get_lexeme(f_syn);
296
        if (lex==NULL)
297
        {
298
                err_code=S_BAD_ARG;
299
                return 1; /* Erreur de lecture de l'argument.                                */
300
        }
301
        if (!TYPE_IS(lex,ALPHA)) /* L'argument n'a pas le bon type.                          */
302
        {
303
                FREE_LEX(lex);
304
                fseek(f_syn,pos-ftell(f_syn),SEEK_CUR); /* On "remet" le lexème.             */
305
                err_code=S_BAD_ARG;
306
                return 1;
307
        }
308
        /* Ajout du mot clef.                                                                */
309
        nom = lex->valeur.alpha;
310
        /* On supprime la valeur pour qu'elle ne soit pas libérée par FREE_LEX.              */
311
        lex->type=RET_MPV(lex->type);
312
        FREE_LEX(lex);
313
 
314
 
315
        /* Lecture de la règle de typage correspondant au sous-type.                         */
316
        lex=get_lexeme(f_syn);
317
        if (lex==NULL)
318
        {
319
                err_code=S_BAD_ARG;
320
                return 1; /* Erreur de lecture de l'argument.                                */
321
        }
322
        if (!TYPE_IS(lex,ALPHA)) /* L'argument n'a pas le bon type.                          */
323
        {
324
                FREE_LEX(lex);
325
                free(nom);
326
                fseek(f_syn,pos-ftell(f_syn),SEEK_CUR); /* On "remet" le lexème.             */
327
                err_code=S_BAD_ARG;
328
                return 1;
329
        }
330
        /* Ajout de la règle à la table.                                                     */
331
        filtre=lex->valeur.alpha;
332
         /* On supprime la valeur pour qu'elle ne soit pas libérée par FREE_LEX.             */
333
        lex->type=RET_MPV(lex->type);
334
        FREE_LEX(lex);
335
 
336
        /* Lecture du code correspondant au sous-type.                                       */
337
        lex=get_lexeme(f_syn);
338
        if (lex==NULL)
339
        {
340
                err_code=S_BAD_ARG;
341
                return 1; /* Erreur de lecture de l'argument.                                */
342
        }
343
        if (!TYPE_IS(lex,NUM))   /* L'argument n'a pas le bon type.                          */
344
        {
345
                FREE_LEX(lex);
346
                free(nom);
347
                free(filtre);
348
                fseek(f_syn,pos-ftell(f_syn),SEEK_CUR); /* On "remet" le lexème.             */
349
                err_code=S_BAD_ARG;
350
                return 1;
351
        }
352
        /* Vérification de la valeur du code demandé.                                        */
353
        if (lex->valeur.num<0 || lex->valeur.num>MAX_SOUS_TYPES)
354
        { /* Le nombre de sous-types codables est limité...                                  */
355
                FREE_LEX(lex);
356
                free(nom);
357
                free(filtre);
358
                err_code=S_DEP_SST;
359
                fseek(f_syn,pos-ftell(f_syn),SEEK_CUR); /* On "remet" le lexème.             */
360
                return 1;
361
        }
362
        code=CODE_TYPE(lex->valeur.num);
363
        FREE_LEX(lex);
364
 
365
        for (i=0 ; i<nbr_sous_types ; i++)
366
        { /* Avertissements éventuels si il y a redéfinition du nom ou du type.              */
367
                /* Vérifiction que le code n'est pas déjà attribué à un autre sous-type.     */
368
                if (!bk && table_clef_sst[i].code==code
369
                                && string_comp(table_clef_sst[i].nom, nom))
370
                { /* Avertissement, le même sous-type a deux noms différents.                */
371
                        DIALOGUE(nom, 0, W_REDEF_CODE);
372
                        bk=1; /* On s'assure que le message n'est affiché qu'uns fois.       */
373
                }
374
 
375
                /* Vérification que le nom n'est pas déjà attribué.                          */
376
                if (!bk && table_clef_sst[i].code!=code
377
                                && !string_comp(table_clef_sst[i].nom, nom))
378
                { /* Avertissement, le nom est déjà utilisé.                                 */
379
                        DIALOGUE(nom, 0, W_REDEF_SST);
380
                        bk=1; /* On s'assure que le message n'est affiché qu'uns fois.       */
381
                }
382
        }
383
 
384
        /* Mise à jour des valeurs lues dans les tables locale et globale.                   */
385
        table_clef_sst[nbr_sous_types].nom=nom;
386
        table_clef_sst[nbr_sous_types].code=code;
387
        regle_typage[nbr_sous_types].chaine=filtre;
388
        regle_typage[nbr_sous_types].code=code;
389
 
390
        nbr_sous_types++; /* Incrémentation du nombre de sous types effectivement déclarés.  */
391
 
392
        err_code=NO_ERR;
393
        return 0;
394
}
395
 
396
#define SET             "SET"   /* Nom symbolique de la commande SET.                        */
397
#define NUM_FONC        9
398
 
399
/* Dans cette structure, on stocke les différents couples commande/fonction. On peut ainsi   */
400
/* facilement ajouter de nouvelles commandes de description de la syntaxe sans avoir à       */
401
/* modifier la fonction principale de génération de l'arbre.                                 */
402
struct
403
{
404
        char * nom;
405
        int (*fonction)();
406
} fonc_table[NUM_FONC] =
407
        {       { "CASSE"       , &casse}
408
        ,       { "NOCASSE"     , &nocasse}
409
        ,       { "MACROFILE"   , &macrofile}
410
        ,       { "UNDEFSTR"    , &setundef}
411
        ,       { "DEFINESTR"   , &setdefine}
412
        ,       { "INCLUDESTR"  , &setinclude}
413
        ,       { "SEP"         , &setsep}
414
        ,       { "NUMSST"      , &setnumsst}
415
        ,       { "NEWSST"      , &setnewsst}
416
        };
417
 
418
/* Cette macro réinitialise les variables à positionner par le préparateur. Elle est appelée */
419
/* à chaque initialisation d'arbre de lexèmes (lecture de fichier syntaxe).                  */
420
 
421
#define REINIT  \
422
{\
423
        if (table_clef_sst!=NULL)\
424
        { /* Vidage de la table des sous types.                                             */\
425
                int i;\
426
                for (i=0 ; i<nbr_sous_types ; i++) free(table_clef_sst[i].nom);\
427
                free(table_clef_sst);\
428
        }\
429
        table_clef_sst=NULL;\
430
        if (fich_macro_def!=NULL) free(fich_macro_def);\
431
        fich_macro_def=NULL;\
432
        if (define_str!=NULL) free(define_str);\
433
        define_str=NULL;\
434
        if (undef_str!=NULL) free(undef_str);\
435
        undef_str=NULL;\
436
        if (include_str!=NULL) free(include_str);\
437
        include_str=NULL;\
438
        if (seplex!=NULL) FREE_LEX(seplex);\
439
        seplex=NULL;\
440
        if (regle_typage!=NULL)\
441
        {\
442
                for ( ; nbr_sous_types>0 ; nbr_sous_types--)\
443
                        free(regle_typage[nbr_sous_types-1].chaine);\
444
                free(regle_typage);\
445
                regle_typage=NULL;\
446
        }\
447
        casse_sens=1;\
448
        sst_max=0;\
449
        nbr_sous_types=0;\
450
}
451
 
452
 
453
/*********************************************************************************************/
454
/* FONCTION place_lexeme                                                                     */
455
/*                                                                                           */
456
/* type_noeud * place_lexeme(type_lexeme * l, type_noeud * cur_root)                         */
457
/*                                                                                           */
458
/* Cette fonction reçoit un lexème et un noeud. Elle recherche le lexème dans les fils du    */
459
/* noeud et si elle le trouve, elle renvoie un pointeur sur lui, sinon elle le crée et       */
460
/* renvoie ce nouveau pointeur.                                                              */
461
/*                                                                                           */
462
/*********************************************************************************************/
463
 
464
type_noeud * place_lexeme(type_lexeme * l, type_noeud * cur_root)
465
{
466
        char * msg_orig="préparateur(place_lexeme)";
467
        type_noeud * cur_fils = (cur_root->ptr_fils);
468
 
469
        while (cur_fils != NULL)
470
        {
471
                if (lexeme_comp(l, &(cur_fils->lexeme))) return cur_fils;
472
                cur_fils = cur_fils->ptr_frere;
473
        }
474
        ALLOC_NOEUD(cur_fils);
475
        cur_fils->ptr_frere = cur_root->ptr_fils;
476
        LEX_COPY(l, &(cur_fils->lexeme));
477
        cur_root->ptr_fils = cur_fils;
478
        return cur_fils;
479
}
480
 
481
 
482
/*********************************************************************************************/
483
/* FONCTION lit_feuille                                                                      */
484
/*                                                                                           */
485
/* type_feuille * lit_feuille(FILE * f_syn)                                                  */
486
/*                                                                                           */
487
/* Cette fonction reçoit le fichier Syntaxe ouvert à la bonne position et lit les            */
488
/* différentes propriétés qui s'y trouve. A partir de cette lecture, elle crée une feuille   */
489
/* pour les enregistrer et renvoie un pointeur vers celle-ci. En cas d'erreur, un pointeur   */
490
/* NULL est retourné et le fichier est laissé à la position de l'erreur.                     */
491
/*                                                                                           */
492
/*********************************************************************************************/
493
 
494
#define OPERATEUR       (TYPE_IS(lex, OP))
495
#define VAL_OP          ((lex->valeur).op)
496
#define VAL_ALPHA       ((lex->valeur).alpha)
497
 
498
#define ERR_LF(val)     {\
499
                                if (lex!=NULL) FREE_LEX(lex);\
500
                                if (mask_ptr!=NULL) FREE_MASK(mask_ptr);\
501
                                DIALOGUE(n_fich, ligne, val);\
502
                                return NULL;\
503
                        }
504
/* Comme la lecture d'une feuille n'est pas sensible a la présence de sauts de ligne, la    */
505
/* macro suivante se charge de les éliminer. La terminaison est assurée par EOF.            */
506
/* La macro commence par libérer l'espace du lexème précédent sauf si celui-ci est NULL.    */
507
#define LIT_LEXEME      {\
508
                                do\
509
                                {\
510
                                        if (lex!=NULL) FREE_LEX(lex);\
511
                                        lex=get_lexeme(f_syn);\
512
                                        if (lex==NULL) ERR_LF(err_code)\
513
                                        if (OPERATEUR && VAL_OP==NL) ligne++;\
514
                                }\
515
                                while (OPERATEUR && VAL_OP==NL);\
516
                        }
517
 
518
#define INIT_MASK       {\
519
                                if (mask_ptr==NULL)\
520
                                {\
521
                                        ALLOC_MASK(mask_ptr);\
522
                                        mask_ptr->taille=0;\
523
                                        mask_ptr->valeur=0;\
524
                                }\
525
                                if (mask_ptr==NULL)\
526
                                        DIALOGUE("préparateur(lit_feuille)", 0, F_ERR_MEM);\
527
                        }
528
 
529
type_feuille * lit_feuille()
530
{
531
        char * msg_orig="preparateur(lit_feuille)";
532
        int i, c, tmo_lu=0, i_fun=0;
533
        type_valeur_mask tmp_msk=0;
534
        type_lexeme * lex=NULL;
535
        type_ptr_fgm fun_ptr[MAX_FONCTIONS];
536
        type_mask * mask_ptr=NULL;
537
        type_feuille * tmp_feuille;
538
 
539
        LIT_LEXEME /* Lit le premier lexème différent de NL.                                 */
540
        while (!OPERATEUR || (VAL_OP!=EOF && VAL_OP!=ACO))
541
        {
542
                if (!TYPE_IS(lex, ALPHA)) ERR_LF(S_BAD_PROP);
543
                /* Détermination de la propriété.                                            */
544
                i=-1;
545
                while (++i<NUM_PROP && string_comp(prop_table[i], VAL_ALPHA));
546
                if (i==NUM_PROP) ERR_LF(S_BAD_PROP); /* Propriété inexistante.               */
547
                switch (i)
548
                { /* lecture de la valeur de la propriété.                                   */
549
                        case TMO :      LIT_LEXEME;
550
                                        if (!TYPE_IS(lex,NUM)) ERR_LF(S_BAD_VAL);
551
                                        INIT_MASK;
552
                                        tmo_lu=1;
553
                                        mask_ptr->taille=(lex->valeur).num;
554
                                        break;
555
                        case MSK :      LIT_LEXEME;
556
                                        if (!TYPE_IS(lex,ALPHA)||VAL_ALPHA[0]!='_')
557
                                                ERR_LF(S_BAD_VAL);
558
                                        INIT_MASK;
559
                                        i=1; tmp_msk=0;
560
                                        while ((c=VAL_ALPHA[i++])!='\0')
561
                                        {
562
                                                if (c!='0' && c!='1')
563
                                                {
564
                                                        if (c!='_') ERR_LF(S_BAD_VAL);
565
                                                }
566
                                                else
567
                                                {
568
                                                        tmp_msk<<=1;
569
                                                        tmp_msk+=(c-'0');
570
                                                }
571
                                        }
572
                                        (mask_ptr->valeur)|=tmp_msk;
573
                                        break;
574
                        case FUN :      if (i_fun==MAX_FONCTIONS) ERR_LF(S_DEP_FUNC_NB);
575
                                        LIT_LEXEME;
576
                                        if (!TYPE_IS(lex,ALPHA)) ERR_LF(S_BAD_VAL);
577
                                        fun_ptr[i_fun]=alias(VAL_ALPHA);
578
                                        if (fun_ptr[i_fun]==NULL)
579
                                        { /* Fonction inexistante.                          */
580
                                                ERR_LF(S_BAD_FUN);
581
                                        }
582
                                        i_fun++;
583
                                        break;
584
                        default :       return NULL;
585
                }
586
                LIT_LEXEME;
587
        }
588
 
589
        FREE_LEX(lex);
590
        ALLOC_FEUILLE(tmp_feuille);
591
        if (!tmo_lu && mask_ptr!=NULL)
592
        { /* On ignore le masque si il n'a pas de taille spécifiée.                          */
593
                FREE_MASK(mask_ptr);
594
                mask_ptr=NULL;
595
        }
596
        tmp_feuille->mask_primaire=mask_ptr;
597
 
598
        /* Recopie de la liste des fonctions de génération de masque.                        */
599
        tmp_feuille->nbr_func=i_fun;
600
        if (i_fun)
601
        {
602
                tmp_feuille->ptr_func=(type_ptr_fgm *) (malloc(i_fun*sizeof(type_ptr_fgm)));
603
                if (tmp_feuille->ptr_func==NULL)
604
                        DIALOGUE("préparateur(lit_feuille)", 0, F_ERR_MEM);
605
                while ((i_fun--)>0)
606
                {
607
                        tmp_feuille->ptr_func[i_fun] = fun_ptr[i_fun];
608
                }
609
        }
610
        else    tmp_feuille->ptr_func=NULL;
611
 
612
        return tmp_feuille;
613
}
614
 
615
 
616
/*********************************************************************************************/
617
/* FONCTION init_arbre                                                                       */
618
/*                                                                                           */
619
/* int init_arbre(char * fichier_syntaxe)                                                    */
620
/*                                                                                           */
621
/* Cette fonction reçoit le nom du fichier Syntaxe, l'ouvre et y lit les informations. Elle  */
622
/* les utilise pour mettre à jour l'arbre des lexèmes défini dans le commun (root). Les      */
623
/* erreurs de format sont signalées.                                                         */
624
/* La valeur de retour est le nombre d'erreurs rencontrées.                                  */
625
/*                                                                                           */
626
/*********************************************************************************************/
627
 
628
int init_arbre(char * fichier_syntaxe)
629
 
630
 
631
#define ERREUR(val)     {\
632
                                DIALOGUE(fichier_syntaxe, ligne, val);\
633
                                err=1;\
634
                        }
635
/* Lecture d'un lexème non NULL, au pire EOF, tout en comptant les lignes.                   */
636
/* Le lexème précédent est libéré sauf s'il est NULL.                                        */
637
#define LIT_VALIDE      {\
638
                                if (lex!=NULL) FREE_LEX(lex);\
639
                                while ((lex=get_lexeme(f_syn))==NULL)\
640
                                {\
641
                                        err=1;\
642
                                        ERREUR(err_code);\
643
                                }\
644
                                if (OPERATEUR && VAL_OP==NL) ligne++;\
645
                        }
646
/* Recherche de la prochaine accolade ouvrante (instruction suivante)                        */
647
#define ACO_SUIV        do LIT_VALIDE while (!OPERATEUR || (VAL_OP!=ACO && VAL_OP!=EOF))
648
#define LIGNE_SUIV      do LIT_VALIDE while (!OPERATEUR || (VAL_OP!=NL  && VAL_OP!=EOF))
649
 
650
{
651
        char * msg_orig="preparateur(init_arbre)";
652
        type_lexeme * lex=NULL;
653
        int err=0,gblerr=0; /* err est vrai lors d'une erreur, gblerr s'il y a eu une erreur */
654
        type_noeud * courant;
655
        type_feuille * feuille=NULL;
656
 
657
        /* Réinitialisation des différentes variables locales et globales.                   */
658
        REINIT;
659
        ALLOC_NOEUD(root);
660
 
661
        f_syn=fopen(fichier_syntaxe, "rb"); /* ouverture du fichier Syntaxe.                     */
662
        if (f_syn==NULL)
663
        {
664
                DIALOGUE(NULL, 0, W_NO_SYNTAX);
665
                return 0;
666
        }
667
 
668
        n_fich = fichier_syntaxe; /* Positionne  la variable commune au module.              */
669
        ligne=1; /* Initialisation du numéro de ligne au début du fichier.                   */
670
 
671
        do  /* Lecture du fichier Syntaxe jusqu'à la première accolade ouvrante.             */
672
        {
673
                LIT_VALIDE;
674
                if (TYPE_IS(lex, ALPHA) && !string_comp(VAL_ALPHA, SET))
675
                { /* On a rencontré une commande SET, lecture des arguments.                 */
676
                        int i=-1;
677
                        LIT_VALIDE;
678
                        if (!TYPE_IS(lex, ALPHA))
679
                        {
680
                                ERREUR(S_BAD_ARG);
681
                                gblerr++;
682
                                LIGNE_SUIV;
683
                        }
684
                        else
685
                        {
686
                                while (++i<NUM_FONC && /* Recherche de la fonction.          */
687
                                        string_comp(fonc_table[i].nom, VAL_ALPHA));
688
                                if (i==NUM_FONC)
689
                                { /* La fonction demandée n'existe pas.                      */
690
                                        ERREUR(S_BAD_ARG);
691
                                        gblerr++;
692
                                        LIGNE_SUIV;
693
                                }
694
                                else if (fonc_table[i].fonction())
695
                                { /* Les paramètres de la fonction sont mal spécifiés.       */
696
                                        affiche_message(fichier_syntaxe, ligne);
697
                                        gblerr++;
698
                                        LIGNE_SUIV;
699
                                }
700
                        }
701
                }
702
                else if (!OPERATEUR || (VAL_OP!=ACO && VAL_OP!=EOF && VAL_OP!=NL))
703
                { /* Si on a un lexème interdit (erreur dans le fichier Syntaxe).            */
704
                        gblerr++;
705
                        ERREUR(S_SYN_ERR);
706
                        LIGNE_SUIV; /* On ne tient pas compte de la ligne erronée.           */
707
                }
708
        } while (!OPERATEUR || (VAL_OP!=ACO && VAL_OP!=EOF));
709
 
710
        do /* Lecture des différentes instructions.                                          */
711
        {
712
                courant=root;
713
                err=0;
714
                LIT_VALIDE;
715
                if (OPERATEUR && VAL_OP==EOF) err=2;
716
                if (OPERATEUR && VAL_OP==ACF) ERREUR(S_DCL_VIDE) /* Déclaration vide.        */
717
                else while ((!OPERATEUR || VAL_OP!=ACF) && !err)
718
                { /* Placer les lexèmes dans l'arbre jusqu'à ACF.                            */
719
                        if (LIT_MPV(lex->type) && TYPE_IS(lex, ALPHA))
720
                        { /* Si on a un mot clef, on ajuste le type (on supprime la valeur)  */
721
                                int i, key=0;
722
                                /* Recherche dans les mots clef de base.                     */
723
                                for (i=0 ; i<NUM_KEYWORD && !key ; i++)
724
                                if (!string_comp(table_clef_base[i].nom, VAL_ALPHA))
725
                                {
726
                                        lex->type=table_clef_base[i].code;
727
                                        key=1;
728
                                }
729
                                /* Recherche dans les mots clef des sous-types.              */
730
                                for (i=0 ; i<nbr_sous_types && !key ; i++)
731
                                if (!string_comp(table_clef_sst[i].nom, VAL_ALPHA))
732
                                {
733
                                        lex->type=table_clef_sst[i].code;
734
                                        key=1;
735
                                }
736
                                if (key) free(lex->valeur.alpha);
737
                        }
738
                        courant = place_lexeme(lex, courant);
739
                        LIT_VALIDE;
740
                        if (OPERATEUR && VAL_OP==EOF) ERREUR(S_DCL_NON_TERM);
741
                }
742
 
743
                /* Redéfinition d'une instruction déjà lue.                                  */
744
                if (courant->ptr_feuille!=NULL) ERREUR(S_REDEF_INS);
745
 
746
                if (!err) feuille=lit_feuille(); /* Lecture de la feuille.                   */
747
                if (feuille==NULL) err=1; /* Le message d'erreur est géré à la lecture.      */
748
 
749
                /* Si la lecture est réussie, il faut mémoriser la nouvelle instruction.     */
750
                if (!err) courant->ptr_feuille=feuille;
751
                else ACO_SUIV; /* Erreur de lecture, on passe à l'instruction suivante.      */
752
                gblerr+=(err==1); /* Le code d'erreur est uniquement 1.                      */
753
        }
754
        while (!OPERATEUR ||  VAL_OP!=EOF);
755
        FREE_LEX(lex);
756
        fclose(f_syn);
757
        return gblerr;
758
}
759
 
760
/* Fonction de libération des structures contenues dans un arbre.                            */
761
void free_arbre(type_noeud * courant)
762
{
763
        type_noeud * fils_courant;
764
 
765
        if (courant==NULL) return;
766
        fils_courant=courant->ptr_fils;
767
        while (fils_courant!=NULL)
768
        { /* On efface récursivement tous les sous arbres.                                   */
769
                free_arbre(fils_courant);
770
                fils_courant=fils_courant->ptr_frere;
771
        }
772
        /* On efface le champ valeur des lexèmes ALPHA.                                      */
773
        if (TYPE_IS(&(courant->lexeme), ALPHA) && LIT_MPV(courant->lexeme.type)
774
                && (courant->lexeme.valeur.alpha!=NULL))
775
                free(courant->lexeme.valeur.alpha);
776
        FREE_NOEUD(courant);
777
}
778
 
779
/* Fonction de libération des structures crées par init_arbre.                               */
780
void clear_preparateur()
781
{
782
        free_arbre(root);
783
        root=NULL; /* root a été libéré par la fonction free_arbre.                          */
784
        REINIT;
785
}
786
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.