|
@@ -14,12 +14,13 @@
|
14
|
14
|
struct type_t type_courant;
|
15
|
15
|
struct type_t return_type_fonc;
|
16
|
16
|
|
17
|
|
-
|
|
17
|
+// Tableau pour le management des patchs des JMP
|
18
|
18
|
int instructions_ligne_to_patch[10][20];
|
19
|
19
|
int nbs_instructions_to_patch[10];
|
20
|
20
|
|
21
|
21
|
%}
|
22
|
22
|
|
|
23
|
+// Récupération des tokens
|
23
|
24
|
%token tMAIN
|
24
|
25
|
%token tOBRACKET tCBRACKET
|
25
|
26
|
%token<nombre> tOBRACE tCBRACE
|
|
@@ -45,134 +46,411 @@ int nbs_instructions_to_patch[10];
|
45
|
46
|
%left tADD tSUB
|
46
|
47
|
%left tMUL tDIV
|
47
|
48
|
|
48
|
|
-%type<nombre> E DebutAff SuiteAffPointeur DebutAffPointeur EBis Invocation Args ArgSuite Arg SuiteParams Params Get
|
|
49
|
+%type<nombre> E SuiteAffPointeur DebutAffPointeur EBis Invocation Args ArgSuite Arg SuiteParams Params Get
|
49
|
50
|
|
|
51
|
+%%
|
50
|
52
|
|
|
53
|
+/*************************************/
|
|
54
|
+/*************************************/
|
|
55
|
+/*********** Programme C *************/
|
|
56
|
+/*************************************/
|
|
57
|
+/*************************************/
|
51
|
58
|
|
52
|
|
-//%type<nombre> E
|
|
59
|
+// Un programme C correspond a des focntion et un main, une fois que le programme est compilé, on ajoute le STOP et l'on exporte l'assembleur.
|
|
60
|
+C : Fonctions Main {add_operation(STOP,0,0,0);
|
|
61
|
+ create_asm();
|
|
62
|
+ };
|
53
|
63
|
|
54
|
|
-/******************************************** FAIRE LA GENERATION DU CODE ASSEMBLEUR DANS UN TABLEAU AVEC UN FPRINTF *******************/
|
55
|
64
|
|
56
|
|
-%%
|
57
|
65
|
|
58
|
66
|
|
59
|
67
|
|
60
|
|
-C : Fonction Fonctions {add_operation(STOP,0,0,0); create_asm();};
|
61
|
68
|
|
|
69
|
+/*************************************/
|
|
70
|
+/*************************************/
|
|
71
|
+/************ Fonctions **************/
|
|
72
|
+/*************************************/
|
|
73
|
+/*************************************/
|
|
74
|
+
|
|
75
|
+// Des fonctions sont une suite de fonctions (possiblement nulle)
|
62
|
76
|
Fonctions : Fonction Fonctions;
|
63
|
77
|
Fonctions : ;
|
64
|
78
|
|
65
|
|
-Main : tINT {printf("Déclaration du main\n"); create_jump_to_main(get_current_index());} tMAIN tOBRACE Args tCBRACE Body { print(); } ;
|
66
|
79
|
|
67
|
|
-Fonction : Type tID {return_type_fonc = type_courant; printf("Déclaration de la fonction %s\n", $2);} tOBRACE {inc_prof();} Args {decrement_prof(); push_fonction($2,return_type_fonc,get_current_index(), $6);} tCBRACE Body { print_fonctions(); add_operation(RET,0,0,0);} ;
|
68
|
|
-Fonction : Main {print_fonctions();};
|
69
|
80
|
|
70
|
|
-Get : tGET tOBRACE tCBRACE {int addr = push("0_TEMPORARY", 0, integer); add_operation(GET,addr,0,0); $$ = addr;};
|
71
|
81
|
|
72
|
|
-Stop : tSTOP tOBRACE tNB tCBRACE {add_operation(STOP,$3,0,0);};
|
73
|
82
|
|
74
|
|
-Return : tRETURN E tPV {add_operation(COP,0,$2,0); pop(); };
|
|
83
|
+/*************************************/
|
|
84
|
+/*************************************/
|
|
85
|
+/************** Main *****************/
|
|
86
|
+/*************************************/
|
|
87
|
+/*************************************/
|
|
88
|
+
|
|
89
|
+// Le main, renvoi un int, possède le mot clé main, des arguments et un body
|
|
90
|
+// Dès que le main est reconnu (token main) on met en place le JMP
|
|
91
|
+Main : tINT tMAIN {printf("Déclaration du main\n");
|
|
92
|
+ create_jump_to_main(get_current_index());
|
|
93
|
+ }
|
|
94
|
+ tOBRACE Args tCBRACE Body;
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+// Une fonction possède un Type , un identifiant
|
|
98
|
+Fonction : Type tID {return_type_fonc = type_courant; // On récupère le ype de la fonction
|
|
99
|
+ printf("Déclaration de la fonction %s\n", $2);
|
|
100
|
+ }
|
|
101
|
+ tOBRACE {inc_prof(); // On incrémente la profondeur pour les arguments, ils font parti de la fonction
|
|
102
|
+ }
|
|
103
|
+ Args {decrement_prof(); // Quand les arguments sont passés, on peur décrémenter la profondeur (sans effacer les variables)
|
|
104
|
+ push_fonction($2,return_type_fonc,get_current_index(), $6); // On enregistre la fonction dans la table des fonctions
|
|
105
|
+ }
|
|
106
|
+ tCBRACE Body {add_operation(RET,0,0,0); // On ajoute le RET
|
|
107
|
+ };
|
|
108
|
+
|
|
109
|
+// Get, une fonction particulière -> renvoi l'adresse de la valeur getée
|
|
110
|
+Get : tGET tOBRACE tCBRACE {int addr = push("0_TEMPORARY", 0, integer); // On déclare la var temporelle
|
|
111
|
+ add_operation(GET,addr,0,0); // On ajoute le GET
|
|
112
|
+ $$ = addr; // On renvoi l'adresse
|
|
113
|
+ };
|
|
114
|
+
|
|
115
|
+// Print, une fonction particulière
|
|
116
|
+Print : tPRINTF tOBRACE E tCBRACE {add_operation(PRI,$3,0,0); // On ajoute l'instruction PRI
|
|
117
|
+ pop(); // On supprime la variable temporaire
|
|
118
|
+ };
|
|
119
|
+
|
|
120
|
+// Stop, une fonction particulière
|
|
121
|
+Stop : tSTOP tOBRACE tNB tCBRACE {add_operation(STOP,$3,0,0); // On ajoute juste l'instruction stop
|
|
122
|
+ };
|
|
123
|
+
|
|
124
|
+// Return, etape clé d'une fonction
|
|
125
|
+Return : tRETURN E tPV {add_operation(COP,0,$2,0); // On copie la valeur retournée à l'adresse 0 de la frame
|
|
126
|
+ pop(); // On pop la variable temporaire
|
|
127
|
+ };
|
|
128
|
+
|
75
|
129
|
|
76
|
|
-Args : Arg ArgSuite {$$ = $1 + $2; printf("Les arguments de la fonctions vont avoir une taille dans la pile de : %d\n",$$);};
|
77
|
|
-Args : {$$ = 0;};
|
78
|
|
-Arg : Type tID {int addr = push($2,1, type_courant); if (type_courant.pointeur_level > 0){$$ = taille_types[INT];} else{$$ = taille_types[type_courant.base];}};
|
79
|
|
-Arg : Type tID tOCROCH tCCROCH {type_courant.isTab = 2; int addr = push($2,1, type_courant); $$ = taille_types[INT];};
|
80
|
|
-ArgSuite : tCOMA Arg ArgSuite {$$ = $2 + $3;} ;
|
81
|
|
-ArgSuite : {$$ = 0;};
|
82
|
130
|
|
83
|
131
|
|
84
|
|
-Body : tOBRACKET {inc_prof();} Instructions tCBRACKET {print(); reset_prof();};
|
85
|
132
|
|
|
133
|
+/*************************************/
|
|
134
|
+/*************************************/
|
|
135
|
+/************ Arguments **************/
|
|
136
|
+/*************************************/
|
|
137
|
+/*************************************/
|
86
|
138
|
|
|
139
|
+// Les arguments : Args, Arg, ArgSuite renvoient la taille dans la pile des arguments déjà reconnus
|
|
140
|
+// Des argmuments correspondent à : un argument, puis la suite d'arguments
|
|
141
|
+Args : Arg ArgSuite {$$ = $1 + $2; // La taille des arguments est la taille du premier argument plus celle des suivants
|
|
142
|
+ };
|
|
143
|
+Args : {$$ = 0; // Il peut ne pas y avoir d'arguments, alors la taille est 0
|
|
144
|
+ };
|
|
145
|
+// Un argument possède un type et un identifiant (nom)
|
|
146
|
+Arg : Type tID { int addr = push($2,1, type_courant); // On stocke l'argument dans la pile des symboles
|
|
147
|
+ if (type_courant.pointeur_level > 0) {
|
|
148
|
+ $$ = taille_types[ADDR];
|
|
149
|
+ } else {
|
|
150
|
+ $$ = taille_types[type_courant.base];
|
|
151
|
+ }
|
|
152
|
+ };
|
|
153
|
+// Un argument peut aussi être un tableau (argument classique et crochets) il est considéré comme un pointeur
|
|
154
|
+Arg : Type tID tOCROCH tCCROCH {type_courant.pointeur_level++; // Considéré comme un simple pointeur
|
|
155
|
+ int addr = push($2,1, type_courant);
|
|
156
|
+ $$ = taille_types[ADDR];
|
|
157
|
+ };
|
|
158
|
+// La suite d'un argument, une virgule, un argument, et d'autres arguments
|
|
159
|
+ArgSuite : tCOMA Arg ArgSuite {$$ = $2 + $3;
|
|
160
|
+ };
|
|
161
|
+// Cela peut être aucun arguments
|
|
162
|
+ArgSuite : {$$ = 0;
|
|
163
|
+ };
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+/*************************************/
|
|
170
|
+/*************************************/
|
|
171
|
+/*************** Body ****************/
|
|
172
|
+/*************************************/
|
|
173
|
+/*************************************/
|
|
174
|
+
|
|
175
|
+// Un body n'est rien d'autre qu'une suite d'instructions entre deux accolades
|
|
176
|
+Body : tOBRACKET {inc_prof(); // Lors de l'ouverture de l'accolade la profondeur augmente
|
|
177
|
+ }
|
|
178
|
+ Instructions tCBRACKET {reset_prof(); // A la sortie d'un body, on détruit toutes les variables locales de ce body
|
|
179
|
+ };
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+/*************************************/
|
|
187
|
+/*************************************/
|
|
188
|
+/*********** Instructions ************/
|
|
189
|
+/*************************************/
|
|
190
|
+/*************************************/
|
|
191
|
+
|
|
192
|
+// Des instructions sont une instruction suivie d'autres instructions, ou, rien
|
87
|
193
|
Instructions : Instruction Instructions ;
|
88
|
194
|
Instructions : ;
|
89
|
|
-Instruction : Aff {};
|
90
|
|
-Instruction : Decl {};
|
91
|
|
-Instruction : Invocation tPV{pop();};
|
92
|
|
-Instruction : If {};
|
93
|
|
-Instruction : While {};
|
94
|
|
-Instruction : Return {};
|
95
|
|
-Instruction : Stop tPV {};
|
96
|
|
-
|
97
|
|
-
|
98
|
|
-Invocation : tID tOBRACE {struct fonction_t fonc = get_fonction($1);}
|
99
|
|
-Params tCBRACE {struct fonction_t fonc = get_fonction($1); multiple_pop($4);
|
100
|
|
-add_operation(CALL,fonc.first_instruction_line, get_last_addr(),0); if (fonc.return_type.pointeur_level > 0 || fonc.return_type.isTab){
|
101
|
|
- $$ = push("0_TEMPORARY_RETURN", 0, integer);
|
102
|
|
-}
|
103
|
|
-else{
|
104
|
|
-$$ = push("0_TEMPORARY_RETURN", 0, fonc.return_type);
|
105
|
|
-}};
|
106
|
195
|
|
107
|
|
-Invocation : tPRINTF tOBRACE E tCBRACE{add_operation(PRI,$3,0,0);};
|
|
196
|
+// Un instruction peut être : une affectation, une déclaration, une invocation, un if, un while, un return, une fonction particulière
|
|
197
|
+Instruction : Aff;
|
|
198
|
+Instruction : Decl;
|
|
199
|
+Instruction : Invocation tPV {pop();};
|
|
200
|
+Instruction : If;
|
|
201
|
+Instruction : While;
|
|
202
|
+Instruction : Return;
|
|
203
|
+Instruction : Stop tPV;
|
|
204
|
+Instruction : Print tPV;
|
108
|
205
|
|
109
|
|
-Params : {$$ = 0; printf("Sans Params\n"); } ;
|
110
|
|
-Params : Param SuiteParams {$$ = $2 + 1;};
|
111
|
|
-Param : E {printf("Parametre : %d\n", $1);};
|
112
|
|
-SuiteParams : tCOMA Param SuiteParams {$$ = $3 + 1;};
|
113
|
|
-SuiteParams : {$$ = 0;};
|
114
|
206
|
|
115
|
207
|
|
116
|
208
|
|
117
|
|
-//On considère que la première ligne du code en ASM est la ligne 0
|
118
|
|
-If : tIF tOBRACE E tCBRACE {
|
119
|
|
-add_operation(JMF,$3,0,0); $1 = get_current_index() - 1;}
|
120
|
|
-Body {int current = get_current_index();
|
121
|
|
- patch($1,current + 1);
|
122
|
|
- add_operation(JMP,0,0,0);
|
123
|
|
- instructions_ligne_to_patch[get_prof()][nbs_instructions_to_patch[get_prof()]] = current;
|
124
|
|
- nbs_instructions_to_patch[get_prof()]++;
|
125
|
|
- pop();}
|
126
|
|
-Else {printf("If reconnu\n");};
|
127
|
209
|
|
|
210
|
+/*************************************/
|
|
211
|
+/*************************************/
|
|
212
|
+/************ Invocation *************/
|
|
213
|
+/*************************************/
|
|
214
|
+/*************************************/
|
|
215
|
+
|
|
216
|
+Invocation : tID tOBRACE Params tCBRACE {struct fonction_t fonc = get_fonction($1); // On récupère la fonction
|
|
217
|
+ multiple_pop($3); // On pop les paramètres de la table des symboles
|
|
218
|
+ add_operation(CALL,fonc.first_instruction_line, get_last_addr(),0); // On écrit le CALL
|
|
219
|
+ // On renvoi l'adresse de la valeur retour de la fonction
|
|
220
|
+ if (fonc.return_type.pointeur_level > 0 || fonc.return_type.isTab) {
|
|
221
|
+ $$ = push("0_TEMPORARY_RETURN", 0, pointer);
|
|
222
|
+ } else {
|
|
223
|
+ $$ = push("0_TEMPORARY_RETURN", 0, fonc.return_type);
|
|
224
|
+ }
|
|
225
|
+ };
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+/*************************************/
|
|
232
|
+/*************************************/
|
|
233
|
+/************ Paramètres *************/
|
|
234
|
+/*************************************/
|
|
235
|
+/*************************************/
|
|
236
|
+
|
|
237
|
+// Ici aussi, 0, 1 ou plusieurs paramètres avec une suite paramètre pour prendre en compte la virgule, on renvoi le nombre de paramètres
|
|
238
|
+Params : {$$ = 0;
|
|
239
|
+ };
|
|
240
|
+Params : Param SuiteParams {$$ = $2 + 1;
|
|
241
|
+ };
|
|
242
|
+Param : E
|
|
243
|
+SuiteParams : tCOMA Param SuiteParams {$$ = $3 + 1;};
|
|
244
|
+SuiteParams : {$$ = 0;};
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+/*************************************/
|
|
253
|
+/*************************************/
|
|
254
|
+/******** Sauts conditionnels ********/
|
|
255
|
+/*************************************/
|
|
256
|
+/*************************************/
|
|
257
|
+
|
|
258
|
+// Un if : le token, une expression entre parenthèse suivie d'un body et d'un else
|
|
259
|
+If : tIF tOBRACE E tCBRACE {add_operation(JMF,$3,0,0); // On ajoute le JMF sans préciser la ligne du saut
|
|
260
|
+ $1 = get_current_index() - 1; // On stocke le numéro d'instruction à patcher
|
|
261
|
+ }
|
|
262
|
+ Body {int current = get_current_index(); // On récupère le numéro d'instrcution
|
|
263
|
+ patch($1,current + 1); // On patch le Jump en cas d'instruction fausse
|
|
264
|
+ add_operation(JMP,0,0,0); // JMP pour skip le else si on devait faire le body
|
|
265
|
+ instructions_ligne_to_patch[get_prof()][nbs_instructions_to_patch[get_prof()]] = current; // On spécifie que le JMP est a patcher
|
|
266
|
+ nbs_instructions_to_patch[get_prof()]++;
|
|
267
|
+ pop(); // On pop la condition du if
|
|
268
|
+ }
|
|
269
|
+ Else
|
|
270
|
+
|
|
271
|
+// Elsif
|
|
272
|
+Else : tELSE If;
|
|
273
|
+
|
|
274
|
+// Else
|
|
275
|
+Else : tELSE Body {int current = get_current_index();
|
|
276
|
+ for (int i = 0; i< nbs_instructions_to_patch[get_prof()]; i++) {
|
|
277
|
+ patch(instructions_ligne_to_patch[get_prof()][i],current); // On patch après le else
|
|
278
|
+ }
|
|
279
|
+ nbs_instructions_to_patch[get_prof()] = 0;
|
|
280
|
+ };
|
|
281
|
+
|
|
282
|
+// If sans else
|
|
283
|
+Else : {int current = get_current_index();
|
|
284
|
+ for (int i = 0; i< nbs_instructions_to_patch[get_prof()]; i++){
|
|
285
|
+ patch(instructions_ligne_to_patch[get_prof()][i],current); // On patch après le else
|
|
286
|
+ }
|
|
287
|
+ nbs_instructions_to_patch[get_prof()] = 0;
|
|
288
|
+ };
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+/*************************************/
|
|
296
|
+/*************************************/
|
|
297
|
+/************** Boucles **************/
|
|
298
|
+/*************************************/
|
|
299
|
+/*************************************/
|
|
300
|
+
|
|
301
|
+While : tWHILE tOBRACE E tCBRACE {add_operation(JMF,$3,0,0); // Ecriture du JMF
|
|
302
|
+ $1 = get_current_index() - 1; // Enregistrement de la ligne a patch
|
|
303
|
+ pop(); // Pop de la condition
|
|
304
|
+ }
|
|
305
|
+ Body {int current = get_current_index(); // Patch du JMF apres le body
|
|
306
|
+ patch($1,current + 1);
|
|
307
|
+ add_operation(JMP,$1,0,0); // JMP au debut de la boucle
|
|
308
|
+ };
|
|
309
|
+
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+/*************************************/
|
|
316
|
+/*************************************/
|
|
317
|
+/************ Affectations ***********/ // A RETRAVAILLER
|
|
318
|
+/*************************************/
|
|
319
|
+/*************************************/
|
|
320
|
+
|
|
321
|
+// Affectation simple
|
|
322
|
+Aff : tID tEQ E tPV {struct symbole_t * symbole = get_variable($1); // On récupère le symbole
|
|
323
|
+ symbole->initialized = 1; // Le symbole devient initialisé
|
|
324
|
+ add_operation(COP, symbole->adresse, $3,0); // On affecte la valeur
|
|
325
|
+ pop(); // On pop l'expression
|
|
326
|
+ };
|
|
327
|
+
|
|
328
|
+// Debut d'une affectation avec déreférencement de pointeur //////// A RETRAVAILLERRRRRR
|
|
329
|
+DebutAffPointeur : tMUL SuiteAffPointeur {add_operation(READ, $2, $2, 0);
|
|
330
|
+ $$=$2;
|
|
331
|
+ };
|
|
332
|
+
|
|
333
|
+DebutAffPointeur : SuiteAffPointeur {$$=$1;
|
|
334
|
+ };
|
|
335
|
+
|
|
336
|
+SuiteAffPointeur : tMUL tID {struct symbole_t * symbole = get_variable($2);
|
|
337
|
+ int addr = push("0_TEMPORARY", 1, symbole->type);
|
|
338
|
+ add_operation(COP, addr,symbole->adresse,0);
|
|
339
|
+ $$=addr;
|
|
340
|
+ };
|
|
341
|
+
|
|
342
|
+SuiteAffPointeur : tID tOCROCH E tCCROCH {struct symbole_t * symbole = get_variable($1);
|
|
343
|
+ int addr = push("0_TEMPORARY", 1, symbole->type);
|
|
344
|
+ if (symbole->type.isTab == 2) {
|
|
345
|
+ add_operation(COP, addr,symbole->adresse,0);
|
|
346
|
+ } else {
|
|
347
|
+ add_operation(AFCA, addr,symbole->adresse,0);
|
|
348
|
+ }
|
|
349
|
+ int addr2 = push("0_TEMPORARY", 1, integer);
|
|
350
|
+ add_operation(AFC, addr2, taille_types[symbole->type.base],0);
|
|
351
|
+ add_operation(MUL,$3,addr2,$3);
|
|
352
|
+ add_operation(ADD,$3,addr,$3);
|
|
353
|
+ $$=$3;
|
|
354
|
+ pop();
|
|
355
|
+ pop();
|
|
356
|
+ };
|
|
357
|
+
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+// Affectation sur un pointeur
|
|
361
|
+Aff : DebutAffPointeur tEQ E tPV {add_operation(WR,$1,$3,0);
|
|
362
|
+ pop();
|
|
363
|
+ pop();
|
|
364
|
+ };
|
|
365
|
+
|
|
366
|
+
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
|
|
376
|
+
|
|
377
|
+/*************************************/
|
|
378
|
+/*************************************/
|
|
379
|
+/***** Expressions Arithmetiques *****/
|
|
380
|
+/*************************************/
|
|
381
|
+/*************************************/
|
|
382
|
+
|
|
383
|
+// Pour une expression arithmétique, nous renvoyons toujours l'adresse du resultat
|
|
384
|
+
|
|
385
|
+// Un simple nombre
|
|
386
|
+E : tNB {int addr = push("0_TEMPORARY", 1, integer); // On reserve la place de la variable temporaire
|
|
387
|
+ add_operation(AFC, addr,$1,0); // On Affecte la valeur a cette adresse
|
|
388
|
+ $$ = addr; // On renvoi l'adresse
|
|
389
|
+ };
|
|
390
|
+
|
|
391
|
+// Un nombre sous forme XeY, même traitement qu'un nombre classique
|
|
392
|
+E : tNBEXP {int addr = push("0_TEMPORARY", 1, integer);
|
|
393
|
+ add_operation(AFC, addr,$1,0);
|
|
394
|
+ $$ = addr;
|
|
395
|
+ };
|
|
396
|
+
|
|
397
|
+// Une Multiplication
|
|
398
|
+E : E tMUL E {add_operation(MUL,$1,$1,$3); // On Multiplie les valeurs et stockons le résultat dans la première variable temporaire
|
|
399
|
+ $$ = $1; // On renvoi l'adresse du resultat
|
|
400
|
+ pop(); // On libère la seconde variable temporaire
|
|
401
|
+ };
|
|
402
|
+
|
|
403
|
+// Une Division (idem multiplication)
|
|
404
|
+E : E tDIV E {add_operation(DIV, $1,$1,$3);
|
|
405
|
+ $$ = $1;
|
|
406
|
+ pop();
|
|
407
|
+ };
|
|
408
|
+
|
|
409
|
+// Une Soustraction (idem multiplication)
|
|
410
|
+E : E tSUB E {add_operation(SOU,$1,$1,$3);
|
|
411
|
+ $$ = $1;
|
|
412
|
+ pop();
|
|
413
|
+ };
|
|
414
|
+
|
|
415
|
+// Une Addition (idem multiplication)
|
|
416
|
+E : E tADD E {add_operation(ADD,$1,$1,$3);
|
|
417
|
+ $$ = $1;
|
|
418
|
+ pop();
|
|
419
|
+ };
|
|
420
|
+
|
|
421
|
+// Une invocation
|
|
422
|
+E : Invocation {$$ = $1; // Une invocation renvoi déjà l'adresse, cette règle n'est qu'un cast d'Invocation en E
|
|
423
|
+ };
|
|
424
|
+
|
|
425
|
+// Consomation de parenthèses
|
|
426
|
+E : tOBRACE E tCBRACE {$$ = $2; // Cela permet de garantir la prioricité des expressions entre parenthèse
|
|
427
|
+ };
|
|
428
|
+
|
|
429
|
+// Négatif --> -E <=> 0-E
|
|
430
|
+E : tSUB E {int addr = push("0_TEMPORARY", 1, integer); // On réserve la variable temporaire pour le 0
|
|
431
|
+ add_operation(AFC, addr,0,0); // On affecte le 0
|
|
432
|
+ add_operation(SOU, $2, addr, $2); // On applique le 0-E
|
|
433
|
+ $$ = $2; // On renvoi l'adresse
|
|
434
|
+ pop(); // On libère la mémoire temporaire utilisée par 0
|
|
435
|
+ };
|
|
436
|
+
|
|
437
|
+E : E tEQCOND E {add_operation(EQU,$1,$1,$3);
|
|
438
|
+ $$ = $1;
|
|
439
|
+ pop();
|
|
440
|
+ };
|
|
441
|
+
|
|
442
|
+E : E tGT E {add_operation(SUP,$1,$1,$3);
|
|
443
|
+ $$ = $1;
|
|
444
|
+ pop();
|
|
445
|
+ };
|
|
446
|
+
|
|
447
|
+E : E tLT E {add_operation(INF,$1,$1,$3);
|
|
448
|
+ $$ = $1;
|
|
449
|
+ pop();
|
|
450
|
+ };
|
|
451
|
+
|
|
452
|
+E : tNOT E { printf("!\n"); };
|
128
|
453
|
|
129
|
|
-Else : tELSE If { printf("Else if reconnu\n"); };
|
130
|
|
-Else : tELSE Body { printf("Else reconnu\n"); int current = get_current_index();
|
131
|
|
-for (int i = 0; i< nbs_instructions_to_patch[get_prof()]; i++){
|
132
|
|
- patch(instructions_ligne_to_patch[get_prof()][i],current);
|
133
|
|
-}
|
134
|
|
-nbs_instructions_to_patch[get_prof()] = 0;
|
135
|
|
-};
|
136
|
|
-Else : {int current = get_current_index();
|
137
|
|
-for (int i = 0; i< nbs_instructions_to_patch[get_prof()]; i++){
|
138
|
|
- patch(instructions_ligne_to_patch[get_prof()][i],current);
|
139
|
|
-}
|
140
|
|
-nbs_instructions_to_patch[get_prof()] = 0;};
|
141
|
|
-While : tWHILE tOBRACE E tCBRACE {
|
142
|
|
-add_operation(JMF,$3,0,0);
|
143
|
|
-$1 = get_current_index() - 1;
|
144
|
|
-pop();}
|
145
|
|
-
|
146
|
|
-Body { printf("While reconnu\n");
|
147
|
|
-int current = get_current_index();
|
148
|
|
-patch($1,current + 1);
|
149
|
|
-add_operation(JMP,$1,0,0);};
|
150
|
|
-
|
151
|
|
-
|
152
|
|
-Aff : DebutAff tEQ E tPV {add_operation(COP, $1, $3,0); pop();} ;
|
153
|
|
-Aff : DebutAffPointeur tEQ E tPV {add_operation(WR,$1,$3,0); pop(); pop();};
|
154
|
|
-
|
155
|
|
-DebutAff : tID {struct symbole_t * symbole = get_variable($1); symbole->initialized = 1; $$=symbole->adresse; printf("%s prend une valeur\n", $1);};
|
156
|
|
-
|
157
|
|
-DebutAffPointeur : tMUL SuiteAffPointeur {add_operation(READ, $2, $2, 0); $$=$2;};
|
158
|
|
-DebutAffPointeur : SuiteAffPointeur {$$=$1;};
|
159
|
|
-SuiteAffPointeur : tMUL tID {struct symbole_t * symbole = get_variable($2); int addr = push("0_TEMPORARY", 1, symbole->type); add_operation(COP, addr,symbole->adresse,0); $$=addr;};
|
160
|
|
-SuiteAffPointeur : tID tOCROCH E tCCROCH {struct symbole_t * symbole = get_variable($1); int addr = push("0_TEMPORARY", 1, symbole->type); if (symbole->type.isTab == 2){add_operation(COP, addr,symbole->adresse,0);} else{add_operation(AFCA, addr,symbole->adresse,0);} int addr2 = push("0_TEMPORARY", 1, integer); add_operation(AFC, addr2, taille_types[symbole->type.base],0); add_operation(MUL,$3,addr2,$3); add_operation(ADD,$3,addr,$3); $$=$3; pop(); pop();};
|
161
|
|
-
|
162
|
|
-
|
163
|
|
-E : tNB { int addr = push("0_TEMPORARY", 1, integer); add_operation(AFC, addr,$1,0); $$ = addr;};
|
164
|
|
-E : tNBEXP { printf("Nombre exp\n"); int addr = push("0_TEMPORARY", 1, integer); add_operation(AFC, addr,$1,0); $$ = addr;};
|
165
|
|
-E : E tMUL E { printf("Mul\n"); add_operation(MUL,$1,$1,$3); $$ = $1; pop();};
|
166
|
|
-E : E tDIV E { printf("Div\n"); add_operation(DIV, $1,$1,$3); $$ = $1; pop();};
|
167
|
|
-E : E tSUB E { printf("Sub\n"); add_operation(SOU,$1,$1,$3); $$ = $1; pop();};
|
168
|
|
-E : E tADD E { printf("Add\n"); add_operation(ADD,$1,$1,$3); $$ = $1; pop();};
|
169
|
|
-E : Invocation {$$ = $1;};
|
170
|
|
-E : tOBRACE E tCBRACE { printf("Parentheses\n"); $$=$2;};
|
171
|
|
-E : tSUB E { printf("Moins\n"); int addr = push("0_TEMPORARY", 1, integer); add_operation(AFC, addr,0,0); add_operation(SOU, $2,$2,addr); $$ = $2; pop();};
|
172
|
|
-E : E tEQCOND E { printf("==\n"); add_operation(EQU,$1,$1,$3); $$ = $1; pop();};
|
173
|
|
-E : E tGT E { printf(">\n"); add_operation(SUP,$1,$1,$3); $$ = $1; pop();};
|
174
|
|
-E : E tLT E { printf("<\n"); add_operation(INF,$1,$1,$3); $$ = $1; pop();};
|
175
|
|
-E : tNOT E { printf("!\n"); };
|
176
|
454
|
E : E tAND E {add_operation(MUL,$1,$1,$3); $$ = $1; pop();};
|
177
|
455
|
E : E tOR E {add_operation(ADD,$1,$1,$3); $$ = $1; pop();} ;
|
178
|
456
|
E : tMUL E { add_operation(READ, $2, $2, 0); $$=$2;};
|