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

Subversion Repositories minimips

[/] [minimips/] [trunk/] [gasm/] [src/] [analyseur.c] - Blame information for rev 15

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 13 louismarie
/*********************************************************************************************/
2
/* MODULE ANALYSEUR                                                                          */
3
/* Ce module a pour but de parcourir le fichier assembleur en effectuant la correspondance   */
4
/* du code source avec la syntaxe acceptée par le langage. La lecture se fait lexème par     */
5
/* lexème en utilisant le préprocesseur.                                                     */
6
/* Il se charge de générer la pile de précode qu sera utilisée par le syntéthiseur pour      */
7
/* générer le code final.                                                                    */
8
/*********************************************************************************************/
9
 
10
#include "analyseur.h"
11
 
12
/* Inclusion des autres modules du projet utilisés.                                          */
13
#include <debogueur.h>
14
#include <parametres.h>
15
#include <dialogue.h>
16
#include <formateur.h>
17
#include <preprocesseur.h>
18
#include <adaptateur.h>
19
 
20
type_precode * file_precode=NULL, * fin_file_precode=NULL;
21
 
22
int nprc_alloc=0; /* Compteur du nombre de précodes alloués.                                 */
23
 
24
/* fonctions de filtrage et de comparaison des lexèmes (sensibles ou non à la casse).        */
25
#define filtre(l, filtre)       filtre_lexeme(l, filtre, casse_sens)
26
#define compare_lexeme(l1, l2)  (casse_sens ? lexid(l1, l2) : lexcaseid(l1,l2))
27
 
28
/* Pointeur sur la file de lexèmes composant l'argument courant.                             */
29
static type_file_lexeme * ptr_arg=NULL;
30
 
31
/* ajoute le lexème sur la pile de lexèmes locale (instruction en cours).                    */
32
void push_local(type_lexeme * l)
33
{
34
        type_file_lexeme * nouv;
35
 
36
        nouv = (type_file_lexeme *) malloc(sizeof(type_file_lexeme));
37
        if (nouv==NULL) DIALOGUE("analyseur(push_local)", 0, F_ERR_MEM);
38
 
39
        nouv->suivant=ptr_arg;
40
        nouv->lexeme=l;
41
        ptr_arg=nouv;
42
}
43
 
44
/* Fonction récursive d'analyse du code assembleur.                                          */
45
type_feuille * analyse_rec(type_noeud * n_cour)
46
{
47
        type_lexeme * l_cour;
48
        type_noeud * fils_cour;
49
 
50
        l_cour=pop_lexeme();    /* Lecture d'un lexème par le préprocesseur.                 */
51
        fils_cour=n_cour->ptr_fils;
52
 
53
        while (fils_cour!=NULL && l_cour!=NULL)
54
        {
55
                if (filtre(l_cour, &(fils_cour->lexeme)))
56
                { /* Les lexèmes sont compatibles.                                           */
57
                        type_feuille * rescur;
58
                        rescur=analyse_rec(fils_cour);
59
                        if (rescur!=NULL)
60
                        {  /* Validation de la transition.                                   */
61
                                push_local(l_cour);     /* Ajout dans la file locale.        */
62
                                return rescur;
63
                        }
64
                }
65
                /* La transition n'est pas validée.                                          */
66
                fils_cour=fils_cour->ptr_frere; /* On passe à la transition suivante.        */
67
        }
68
 
69
        push_lexeme(l_cour);            /* Le lexème est rendu au préprocesseur.             */
70
        return (n_cour->ptr_feuille);   /* Si la feuille est valide, l'instruction l'est.    */
71
}
72
 
73
/*********************************************************************************************/
74
/*                                                                                           */
75
/* Point d'entrée principal du module, fonction d'analyse. Les données analysées sont celles */
76
/* fournies par le préprocesseur qui doit être préalablement initialisé.                     */
77
/*                                                                                           */
78
/*********************************************************************************************/
79
 
80
/* Macro d'initialisation d'un nouveau précode.                                              */
81
#define INIT_PRECODE(precode)   \
82
{\
83
        ALLOC_PREC(precode)\
84
        precode->fichier_orig=f_orig;\
85
        precode->ligne_orig=l_orig;\
86
        precode->pco=pco;\
87
}
88
 
89
/* Macro d'ajout d'un précode en queue de la file.                                           */
90
#define EMPILE_PRECODE(precode) \
91
{\
92
        if (file_precode==NULL)\
93
        {\
94
                file_precode=precode;\
95
                fin_file_precode=precode;\
96
        }\
97
        else\
98
        {\
99
                fin_file_precode->suivant=precode;\
100
                fin_file_precode=precode;\
101
        }\
102
}
103
 
104
int analyse()
105
{
106
        int err=0;
107
        char * msg_orig = "analyseur(analyse)";
108
        type_lexeme * lex;
109
 
110
        pco = 0; /* Initialisation du pseudo compteur ordinal.                               */
111
 
112
        if (seplex == NULL)
113
        { /* Utilisation du séparateur par défaut.                                           */
114
                DIALOGUE(NULL, 0, W_SEPLEX_INIT);
115
                seplex=(type_lexeme *) malloc(sizeof(type_lexeme));
116
                if (seplex==NULL) DIALOGUE(msg_orig, 0, F_ERR_MEM);
117
                seplex->type = POS_MPV(OP);
118
                seplex->valeur.op = NL;
119
        }
120
 
121
        while ((lex = pop_lexeme())!=NULL) /* Analyse jusqu'à la fin du fichier.             */
122
        {
123
                int l_orig = ligne_courante();  /* On conserve la ligne de l'instruction.    */
124
                char * f_orig = gen_orig_msg(); /* On conserve le fichier d'origine.         */
125
                type_feuille * feuille;
126
 
127
                push_lexeme(lex);               /* On rend le lexème au prépreocesseur.      */
128
                feuille = analyse_rec(root);    /* Analyse de l'instruction suivante.        */
129
 
130
                if (feuille==NULL)
131
                { /* L'instruction n'a pas été reconnue.                                     */
132
                        type_lexeme * lex_depile;
133
                        type_precode * err_pcd;
134
                        INIT_PRECODE(err_pcd);
135
                        err++;                  /* Détection d'une erreur de syntaxe.        */
136
                        err_pcd->erreur=S_SYN_ERR; /* Mise à jour du code d'erreur.          */
137
                        EMPILE_PRECODE(err_pcd); /* Empilage du lexème erreur.               */
138
 
139
                        DIALOGUE(f_orig, l_orig, S_SYN_ERR);
140
 
141
                        while ((lex_depile=pop_lexeme())!=NULL
142
                                        && !compare_lexeme(lex_depile, seplex))
143
                        { /* On recherche le prochain lexème de séparation.                  */
144
                                FREE_LEX(lex_depile);
145
                        }
146
                        if (lex_depile!=NULL) FREE_LEX(lex_depile); /* Efface le "seplex".   */
147
                }
148
                else
149
                { /* L'instruction a été validée. Génération du précode.                     */
150
                        type_precode * pcd;
151
                        int p2f[MAX_FONCTIONS]; /* tableau des fonctions de seconde passe.   */
152
                        int i;
153
                        INIT_PRECODE(pcd);
154
 
155
                        /* Recopie de la file des lexèmes ayant validé l'instruction.        */
156
                        pcd->param = ptr_arg;
157
 
158
                        /* Recopie du masque de la feuille.                                  */
159
                        if (feuille->mask_primaire==NULL) pcd->mask=NULL;
160
                        else
161
                        {
162
                                ALLOC_MASK(pcd->mask);
163
                                if (pcd->mask==NULL)
164
                                        DIALOGUE(msg_orig, 0, F_ERR_MEM);
165
                                pcd->mask->valeur=feuille->mask_primaire->valeur;
166
                                pcd->mask->taille=feuille->mask_primaire->taille;
167
                        }
168
 
169
                        for (i=0 ; i<feuille->nbr_func ; i++)
170
                        { /* Tentative d'application des fonctions de l'adaptateur.          */
171
                                type_mask *  res = (feuille->ptr_func)[i](ptr_arg);
172
 
173
                                /* Différents cas de réponse de l'adaptateur.                */
174
                                switch (eval_code)
175
                                {
176
                                case EVAL_REUSSIE    :  /* Evalutation réussie.              */
177
                                        if (pcd->mask==NULL)
178
                                        {
179
                                                pcd->mask=res; /* Pas encore de masque.      */
180
                                                res=NULL; /* Evite que le masque soit vidé.  */
181
                                                break;
182
                                        }
183
                                        if (res==NULL) break; /* Rien à faire.               */
184
                                        if (res->taille==pcd->mask->taille)
185
                                        { /* On ajoute le nouveau masque.                    */
186
                                                pcd->mask->valeur|=res->valeur;
187
                                                break;
188
                                        }
189
                                        /* Le masque retourné est incompatible.              */
190
                                        DIALOGUE(f_orig, l_orig, S_FUN_ERR);
191
                                        CLEAR_PRECODE(pcd); /* Le précode est une erreur.    */
192
                                        pcd->erreur=S_FUN_ERR;
193
                                        err++;
194
                                        break;
195
                                case EVAL_IMPOSSIBLE :  /* Fonction de seconde passe.        */
196
                                        p2f[(int)(pcd->nbr_func)++]=i;
197
                                        break;
198
                                case EVAL_ERREUR     :  /* Erreur de l'adaptateur/Syntaxe.   */
199
                                        affiche_message(f_orig, l_orig);
200
                                        err++;
201
                                        CLEAR_PRECODE(pcd); /* Le précode est une erreur.    */
202
                                        pcd->erreur=err_code;
203
                                        break;
204
                                default              :  /* Erreur de l'adaptateur.           */
205
                                        DIALOGUE(f_orig, l_orig, S_ADAP_ERR);
206
                                        CLEAR_PRECODE(pcd);
207
                                        pcd->erreur=S_ADAP_ERR;
208
                                        err++;
209
                                        break;
210
                                }
211
                                if (res!=NULL) FREE_MASK(res); /* Suppression du masque.     */
212
                        }
213
 
214
                        if (pcd->nbr_func!=0) /* Recopie des pointeurs vers les p2f.         */
215
                        { /* Il reste des fonctions de seconde passe.                        */
216
                                pcd->func=(type_ptr_fgm*) /* On crée le tableau.             */
217
                                        malloc((pcd->nbr_func)*sizeof(type_ptr_fgm));
218
                                for (i=0; i<pcd->nbr_func; i++)
219
                                { /* On recopie les fonctions de seconde passe.              */
220
                                        (pcd->func)[i]=(feuille->ptr_func)[p2f[i]];
221
                                }
222
                        }
223
                        else
224
                        { /* Plus de fonctions de seconde passe, effacement des arguments.   */
225
                                pcd->func = NULL;
226
                                FREE_ARGS(pcd->param);
227
                        }
228
 
229
                        if ((pcd->mask==NULL || pcd->mask->taille==0) && pcd->func==NULL
230
                                        && pcd->erreur==NO_ERR)
231
                        { /* On supprime le précode s'il est vide.                           */
232
                                FREE_PRECODE(pcd);
233
                        }
234
                        else
235
                        {
236
                                EMPILE_PRECODE(pcd);
237
                                if (pcd->mask!=NULL) pco+=pcd->mask->taille;
238
                        }
239
 
240
                        ptr_arg=NULL; /* Réinitialisation du pointeur de file de lexèmes.    */
241
                }
242
        }
243
        return err;
244
}
245
 
246
/* Cette fonction libère les structures de précode allouées lors de l'analyse. Les données   */
247
/* non écrites par le synthétiseur seront perdues.                                           */
248
void clear_analyseur()
249
{
250
        while (file_precode!=NULL)
251
        {
252
                type_precode * pcd=file_precode;
253
                file_precode=pcd->suivant;
254
                FREE_PRECODE(pcd);
255
        }
256
        fin_file_precode=NULL;
257
}

powered by: WebSVN 2.1.0

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