|
@@ -1,10 +1,20 @@
|
|
1
|
+%code requires {
|
|
2
|
+ #include "../Tables/Symboles/table_symboles.h"
|
|
3
|
+
|
|
4
|
+ struct while_t {
|
|
5
|
+ int n_ins_cond;
|
|
6
|
+ int n_ins_jmf;
|
|
7
|
+ };
|
|
8
|
+}
|
|
9
|
+
|
1
|
10
|
%union {
|
2
|
11
|
int nombre;
|
3
|
|
- char id[30];
|
|
12
|
+ struct symbole_t symbole;
|
|
13
|
+ char id[30];
|
|
14
|
+ struct while_t my_while;
|
4
|
15
|
}
|
5
|
16
|
%{
|
6
|
17
|
#include "../Tables/Fonctions/tab_fonctions.h"
|
7
|
|
-#include "../Tables/Symboles/table_symboles.h"
|
8
|
18
|
#include <stdio.h>
|
9
|
19
|
#include <string.h>
|
10
|
20
|
#include <stdlib.h>
|
|
@@ -18,6 +28,9 @@ struct type_t return_type_fonc;
|
18
|
28
|
int instructions_ligne_to_patch[10][20];
|
19
|
29
|
int nbs_instructions_to_patch[10];
|
20
|
30
|
|
|
31
|
+// Utile a l'affectation avec des pointeurs
|
|
32
|
+int first_etoile = 1;
|
|
33
|
+
|
21
|
34
|
%}
|
22
|
35
|
|
23
|
36
|
// Récupération des tokens
|
|
@@ -32,8 +45,8 @@ int nbs_instructions_to_patch[10];
|
32
|
45
|
%token<nombre> tNB tNBEXP
|
33
|
46
|
%token<id> tID
|
34
|
47
|
%token tPRINTF tGET tSTOP
|
35
|
|
-%token tERROR
|
36
|
|
-%token<nombre> tIF tWHILE tELSE
|
|
48
|
+%token<nombre> tIF tELSE
|
|
49
|
+%token<my_while> tWHILE
|
37
|
50
|
%token tRETURN
|
38
|
51
|
%token tLT tGT tEQCOND
|
39
|
52
|
%token tAND tOR
|
|
@@ -46,7 +59,10 @@ int nbs_instructions_to_patch[10];
|
46
|
59
|
%left tADD tSUB
|
47
|
60
|
%left tMUL tDIV
|
48
|
61
|
|
49
|
|
-%type<nombre> E SuiteAffPointeur DebutAffPointeur EBis Invocation Args ArgSuite Arg SuiteParams Params Get
|
|
62
|
+%right tINT tMAIN
|
|
63
|
+
|
|
64
|
+%type<symbole> SymboleAffectation
|
|
65
|
+%type<nombre> E EBis Invocation Args ArgSuite Arg SuiteParams Params Get InitTab SuiteInitTab
|
50
|
66
|
|
51
|
67
|
%%
|
52
|
68
|
|
|
@@ -57,10 +73,15 @@ int nbs_instructions_to_patch[10];
|
57
|
73
|
/*************************************/
|
58
|
74
|
|
59
|
75
|
// 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);
|
|
76
|
+C : Fonctions {add_operation(STOP,0,0,0);
|
61
|
77
|
create_asm();
|
62
|
78
|
};
|
63
|
79
|
|
|
80
|
+// Le main, renvoi un int, possède le mot clé main, des arguments et un body
|
|
81
|
+// Dès que le main est reconnu (token main) on met en place le JMP
|
|
82
|
+Main : tINT tMAIN {create_jump_to_main(get_current_index()); printf("DANS LE MAIN \n");
|
|
83
|
+ }
|
|
84
|
+ tOBRACE Args tCBRACE Body {print();};
|
64
|
85
|
|
65
|
86
|
|
66
|
87
|
|
|
@@ -73,30 +94,11 @@ C : Fonctions Main {add_operation(STOP,0,0,0);
|
73
|
94
|
/*************************************/
|
74
|
95
|
|
75
|
96
|
// Des fonctions sont une suite de fonctions (possiblement nulle)
|
76
|
|
-Fonctions : Fonction Fonctions;
|
77
|
|
-Fonctions : ;
|
78
|
|
-
|
79
|
|
-
|
80
|
|
-
|
81
|
|
-
|
82
|
|
-
|
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
|
|
-
|
|
97
|
+Fonctions : Main ;
|
|
98
|
+Fonctions : Fonction Fonctions ;
|
96
|
99
|
|
97
|
100
|
// 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);
|
|
101
|
+Fonction : Type tID {return_type_fonc = type_courant; // On récupère le ype de la fonction
|
100
|
102
|
}
|
101
|
103
|
tOBRACE {inc_prof(); // On incrémente la profondeur pour les arguments, ils font parti de la fonction
|
102
|
104
|
}
|
|
@@ -143,15 +145,17 @@ Args : Arg ArgSuite {$$ = $1 + $2;
|
143
|
145
|
Args : {$$ = 0; // Il peut ne pas y avoir d'arguments, alors la taille est 0
|
144
|
146
|
};
|
145
|
147
|
// 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
|
|
- }
|
|
148
|
+Arg : Type tID {type_courant.nb_blocs = 1;
|
|
149
|
+ int addr = push($2,1, type_courant); // On stocke l'argument dans la pile des symboles
|
|
150
|
+ if (type_courant.pointeur_level > 0) {
|
|
151
|
+ $$ = taille_types[ADDR];
|
|
152
|
+ } else {
|
|
153
|
+ $$ = taille_types[type_courant.base];
|
|
154
|
+ }
|
152
|
155
|
};
|
153
|
156
|
// 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
|
|
157
|
+Arg : Type tID tOCROCH tCCROCH {type_courant.nb_blocs = 1;
|
|
158
|
+ type_courant.pointeur_level++; // Considéré comme un simple pointeur
|
155
|
159
|
int addr = push($2,1, type_courant);
|
156
|
160
|
$$ = taille_types[ADDR];
|
157
|
161
|
};
|
|
@@ -298,13 +302,16 @@ Else : {int current = get_current_index();
|
298
|
302
|
/*************************************/
|
299
|
303
|
/*************************************/
|
300
|
304
|
|
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
|
|
305
|
+While : tWHILE {$1.n_ins_cond = get_current_index(); // On enregistre l'endroit de la condition (pour le JMP en fin de while)
|
|
306
|
+ }
|
|
307
|
+
|
|
308
|
+ tOBRACE E tCBRACE {add_operation(JMF,$4,0,0); // Ecriture du JMF
|
|
309
|
+ $1.n_ins_jmf = get_current_index() - 1; // Enregistrement du numero d'instruction du jmf à patch
|
303
|
310
|
pop(); // Pop de la condition
|
304
|
311
|
}
|
305
|
312
|
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
|
|
313
|
+ patch($1.n_ins_jmf,current + 1);
|
|
314
|
+ add_operation(JMP,$1.n_ins_cond,0,0); // JMP au debut de la boucle
|
308
|
315
|
};
|
309
|
316
|
|
310
|
317
|
|
|
@@ -314,55 +321,80 @@ While : tWHILE tOBRACE E tCBRACE {add_operation(JMF,$3,0,0);
|
314
|
321
|
|
315
|
322
|
/*************************************/
|
316
|
323
|
/*************************************/
|
317
|
|
-/************ Affectations ***********/ // A RETRAVAILLER
|
|
324
|
+/************ Affectations ***********/
|
318
|
325
|
/*************************************/
|
319
|
326
|
/*************************************/
|
320
|
327
|
|
321
|
328
|
// 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
|
|
329
|
+Aff : tID tEQ E tPV {struct symbole_t * symbole = get_variable($1);
|
|
330
|
+ symbole->initialized = 1;
|
|
331
|
+ if (symbole->type.isConst == 1 && symbole->type.pointeur_level == 0 || symbole->type.isTab) {
|
|
332
|
+ printf("\033[31;01m ERROR : \033[00m %s est READ-ONLY\n", symbole->nom);
|
|
333
|
+ exit(2);
|
|
334
|
+ } else {
|
|
335
|
+ add_operation(COP,symbole->adresse,$3,0); // On affecte la valeur
|
|
336
|
+ pop(); // On pop l'expression
|
|
337
|
+ first_etoile = 1; // On reinitialise first_etoile
|
|
338
|
+ }
|
326
|
339
|
};
|
327
|
340
|
|
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
|
|
-
|
|
341
|
+// Affectation sur un pointeur
|
|
342
|
+Aff : SymboleAffectation tEQ E tPV {if ($1.type.isConst == 1 && $1.type.pointeur_level == 0 || $1.type.isTab) {
|
|
343
|
+ printf("\033[31;01m ERROR : \033[00m %s ou un de ses déréférencement est READ-ONLY\n", $1.nom);
|
|
344
|
+ exit(2);
|
|
345
|
+ } else {
|
|
346
|
+ add_operation(WR,$1.adresse,$3,0); // On affecte la valeur
|
|
347
|
+ pop(); // On pop l'expression
|
|
348
|
+ pop(); // On pop la variable temporaire de l'adresse
|
|
349
|
+ }
|
|
350
|
+ };
|
358
|
351
|
|
|
352
|
+// Debut d'une affectation avec déreférencement de pointeur
|
|
353
|
+SymboleAffectation : tID {struct symbole_t * symbole = get_variable($1);
|
|
354
|
+ symbole->initialized = 1;
|
|
355
|
+ int addr = push("0_TEMPORARY", 1, pointer);
|
|
356
|
+ if (symbole->type.isTab) {
|
|
357
|
+ add_operation(AFCA, addr, symbole->adresse,0); // Si tableau AFCA
|
|
358
|
+ } else {
|
|
359
|
+ add_operation(COP, addr, symbole->adresse,0); // Si pointeur COP
|
|
360
|
+ }
|
|
361
|
+ struct symbole_t symbolebis = *symbole;
|
|
362
|
+ symbolebis.adresse = addr;
|
|
363
|
+ $$ = symbolebis; // On renvoi un symbole pointant sur la copie de l'adresse
|
|
364
|
+ };
|
359
|
365
|
|
360
|
|
-// Affectation sur un pointeur
|
361
|
|
-Aff : DebutAffPointeur tEQ E tPV {add_operation(WR,$1,$3,0);
|
362
|
|
- pop();
|
363
|
|
- pop();
|
364
|
|
- };
|
|
366
|
+SymboleAffectation : SymboleAffectation tOCROCH E tCCROCH {if ($1.type.pointeur_level == 0) { // Check déréférençable
|
|
367
|
+ printf("\033[35;01m WARNING : \033[00m déréférencement exessif\n");
|
|
368
|
+ } else {
|
|
369
|
+ $1.type.pointeur_level--; // On baisse le niveau de pointeur
|
|
370
|
+ int addr = push("0_TEMPORARY", 1, integer); // On alloue la place pour stocker la taille du type pointé
|
|
371
|
+ if ($1.type.pointeur_level > 0) {
|
|
372
|
+ add_operation(AFC, addr, taille_types[ADDR],0); // Si on est encore un pointeur, la taille d'un adresse
|
|
373
|
+ } else {
|
|
374
|
+ add_operation(AFC, addr, taille_types[$1.type.base],0); // Sinon le type de base
|
|
375
|
+ }
|
|
376
|
+ add_operation(MUL,$3,addr,$3); // On multiple le nombre de décalage par la taille du type
|
|
377
|
+ add_operation(ADD,$3,$1.adresse,$3); // On l'ajoute a l'adresse de base
|
|
378
|
+ $1.type.isTab = 0;
|
|
379
|
+ $$=$1;
|
|
380
|
+ pop();
|
|
381
|
+ pop();
|
|
382
|
+ }
|
|
383
|
+ };
|
365
|
384
|
|
|
385
|
+SymboleAffectation : tMUL SymboleAffectation {if ($2.type.pointeur_level == 0) { // Check déréférençable
|
|
386
|
+ printf("\033[35;01m WARNING : \033[00m déréférencement exessif\n");
|
|
387
|
+ } else {
|
|
388
|
+ $2.type.pointeur_level--; // On baisse le niveau de pointeur
|
|
389
|
+ $2.type.isTab = 0;
|
|
390
|
+ if (first_etoile) {
|
|
391
|
+ first_etoile = 0; // Le premier déréférencement doit être skip a cause du WR
|
|
392
|
+ } else {
|
|
393
|
+ add_operation(READ, $2.adresse, $2.adresse,0); //
|
|
394
|
+ $$=$2;
|
|
395
|
+ }
|
|
396
|
+ }
|
|
397
|
+ };
|
366
|
398
|
|
367
|
399
|
|
368
|
400
|
|
|
@@ -386,6 +418,7 @@ Aff : DebutAffPointeur tEQ E tPV {add_operation(WR,$1,$3,0);
|
386
|
418
|
E : tNB {int addr = push("0_TEMPORARY", 1, integer); // On reserve la place de la variable temporaire
|
387
|
419
|
add_operation(AFC, addr,$1,0); // On Affecte la valeur a cette adresse
|
388
|
420
|
$$ = addr; // On renvoi l'adresse
|
|
421
|
+ printf("Nombre %d@%d\n", $1, addr);
|
389
|
422
|
};
|
390
|
423
|
|
391
|
424
|
// Un nombre sous forme XeY, même traitement qu'un nombre classique
|
|
@@ -394,6 +427,10 @@ E : tNBEXP {int addr = push("0_TEMPORARY", 1, inte
|
394
|
427
|
$$ = addr;
|
395
|
428
|
};
|
396
|
429
|
|
|
430
|
+
|
|
431
|
+
|
|
432
|
+
|
|
433
|
+
|
397
|
434
|
// Une Multiplication
|
398
|
435
|
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
|
436
|
$$ = $1; // On renvoi l'adresse du resultat
|
|
@@ -418,6 +455,11 @@ E : E tADD E {add_operation(ADD,$1,$1,$3);
|
418
|
455
|
pop();
|
419
|
456
|
};
|
420
|
457
|
|
|
458
|
+
|
|
459
|
+
|
|
460
|
+
|
|
461
|
+
|
|
462
|
+
|
421
|
463
|
// Une invocation
|
422
|
464
|
E : Invocation {$$ = $1; // Une invocation renvoi déjà l'adresse, cette règle n'est qu'un cast d'Invocation en E
|
423
|
465
|
};
|
|
@@ -434,68 +476,217 @@ E : tSUB E {int addr = push("0_TEMPORARY", 1, inte
|
434
|
476
|
pop(); // On libère la mémoire temporaire utilisée par 0
|
435
|
477
|
};
|
436
|
478
|
|
|
479
|
+
|
|
480
|
+
|
|
481
|
+
|
|
482
|
+// Opérateur == (idem multiplication)
|
437
|
483
|
E : E tEQCOND E {add_operation(EQU,$1,$1,$3);
|
438
|
484
|
$$ = $1;
|
439
|
485
|
pop();
|
440
|
486
|
};
|
441
|
|
-
|
|
487
|
+// Opérateur > (idem multiplication)
|
442
|
488
|
E : E tGT E {add_operation(SUP,$1,$1,$3);
|
443
|
489
|
$$ = $1;
|
444
|
490
|
pop();
|
445
|
491
|
};
|
446
|
492
|
|
|
493
|
+// Opérateur < (idem multiplication)
|
447
|
494
|
E : E tLT E {add_operation(INF,$1,$1,$3);
|
|
495
|
+ printf("INF %d %d %d\n", $1, $1, $3);
|
|
496
|
+ print();
|
448
|
497
|
$$ = $1;
|
449
|
498
|
pop();
|
450
|
499
|
};
|
|
500
|
+// Opérateur !E <=> E==0
|
|
501
|
+E : tNOT E {int addr = push("0_TEMPORARY", 1, integer); // On réserve la variable temporaire pour le 0
|
|
502
|
+ add_operation(AFC, addr,0,0); // On affecte le 0
|
|
503
|
+ add_operation(EQU, $2, addr, $2); // On applique le 0==E
|
|
504
|
+ $$ = $2; // On renvoi l'adresse
|
|
505
|
+ pop();
|
|
506
|
+ };
|
|
507
|
+
|
|
508
|
+// Opérateur E && E' <=> E*E' (idem multiplication)
|
|
509
|
+E : E tAND E {add_operation(MUL,$1,$1,$3);
|
|
510
|
+ $$ = $1;
|
|
511
|
+ pop();
|
|
512
|
+ };
|
|
513
|
+
|
|
514
|
+// Opérateur E || E' <=> E+E' (idem multiplication)
|
|
515
|
+E : E tOR E {add_operation(ADD,$1,$1,$3);
|
|
516
|
+ $$ = $1;
|
|
517
|
+ pop();
|
|
518
|
+ };
|
|
519
|
+
|
|
520
|
+
|
|
521
|
+
|
|
522
|
+
|
|
523
|
+
|
|
524
|
+// Déréférencement de pointeur
|
|
525
|
+E : tMUL E {add_operation(READ, $2, $2, 0); // Extraction en mémoire
|
|
526
|
+ $$=$2;
|
|
527
|
+ };
|
451
|
528
|
|
452
|
|
-E : tNOT E { printf("!\n"); };
|
453
|
529
|
|
454
|
|
-E : E tAND E {add_operation(MUL,$1,$1,$3); $$ = $1; pop();};
|
455
|
|
-E : E tOR E {add_operation(ADD,$1,$1,$3); $$ = $1; pop();} ;
|
456
|
|
-E : tMUL E { add_operation(READ, $2, $2, 0); $$=$2;};
|
457
|
|
-E : tID { printf("Id\n"); struct symbole_t * symbole = get_variable($1); struct type_t type = symbole->type; type.nb_blocs = 1; int addr = push("0_TEMPORARY", 1, type); if (symbole->type.isTab == 1){add_operation(AFCA, addr,symbole->adresse,0);} else{add_operation(COP, addr,symbole->adresse,0);} $$=addr;};
|
458
|
530
|
|
|
531
|
+// Une variable
|
|
532
|
+E : tID {struct symbole_t * symbole = get_variable($1); // On cherche la variable dans la table des symboles
|
|
533
|
+ struct type_t type = symbole->type; // On récupère le type
|
|
534
|
+ type.nb_blocs = 1;
|
|
535
|
+ int addr = push("0_TEMPORARY", 1, type); // On créé la variable temporaire
|
|
536
|
+ if (symbole->type.isTab == 1) {
|
|
537
|
+ add_operation(AFCA, addr,symbole->adresse,0); // Si c'est un tableau on affecte l'adresse du début
|
|
538
|
+ } else {
|
|
539
|
+ add_operation(COP, addr,symbole->adresse,0); // Si c'est autre chose, on copie la valeur
|
|
540
|
+ }
|
|
541
|
+ $$ = addr;
|
|
542
|
+ printf("variable stoquée a l'adresse %d \n", addr);
|
|
543
|
+ };
|
|
544
|
+
|
|
545
|
+// Une variable sous forme de tableau
|
|
546
|
+E : tID tOCROCH E tCCROCH {struct symbole_t * symbole = get_variable($1); // On récupère le symbole
|
|
547
|
+ struct type_t type = symbole->type; // On récupère le type
|
|
548
|
+ type.nb_blocs = 1;
|
|
549
|
+ int addr = push("0_TEMPORARY", 1, type); // On créé la variable temporaire
|
|
550
|
+ if (type.isTab == 2) {
|
|
551
|
+ add_operation(COP, addr,symbole->adresse,0);
|
|
552
|
+ } else {
|
|
553
|
+ add_operation(AFCA, addr,symbole->adresse,0);
|
|
554
|
+ }
|
|
555
|
+ int addr2 = push("0_TEMPORARY", 1, integer);
|
|
556
|
+ add_operation(AFC, addr2, taille_types[symbole->type.base],0);
|
|
557
|
+ add_operation(MUL,$3,addr2,$3);
|
|
558
|
+ add_operation(ADD,$3,addr,$3);
|
|
559
|
+ add_operation(READ,$3,$3,0);
|
|
560
|
+ $$=$3;
|
|
561
|
+ pop();
|
|
562
|
+ pop();
|
|
563
|
+ };
|
459
|
564
|
|
460
|
|
-E : tID tOCROCH E tCCROCH {struct symbole_t * symbole = get_variable($1); struct type_t type = symbole->type; type.nb_blocs = 1; int addr = push("0_TEMPORARY", 1, type); if(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);
|
461
|
|
-add_operation(ADD,$3,addr,$3); add_operation(READ,$3,$3,0); $$=$3; pop(); pop();};
|
462
|
565
|
E : tADDR EBis {$$=$2;};
|
463
|
566
|
E : Get {$$ = $1;};
|
464
|
567
|
|
465
|
|
-EBis : tID tOCROCH E tCCROCH {struct symbole_t * symbole = get_variable($1);
|
466
|
|
-struct type_t type = symbole->type; type.nb_blocs = 1;
|
467
|
|
-int addr = push("0_TEMPORARY", 1, type);
|
468
|
|
-if(type.isTab == 2) {
|
469
|
|
-add_operation(COP, addr,symbole->adresse,0);
|
470
|
|
-}
|
471
|
|
- else{
|
472
|
|
-add_operation(AFCA, addr,symbole->adresse,0);
|
473
|
|
-}
|
474
|
|
-int addr2 = push("0_TEMPORARY", 1, integer);
|
475
|
|
-add_operation(AFC, addr2, taille_types[symbole->type.base],0);
|
476
|
|
-add_operation(MUL,$3,addr2,$3);
|
477
|
|
-add_operation(ADD,$3,addr,$3); $$=$3;
|
478
|
|
-pop(); pop();};
|
479
|
|
-EBis : tID { printf("Id\n"); struct symbole_t * symbole = get_variable($1); struct type_t type = symbole->type; type.nb_blocs = 1; int addr = push("0_TEMPORARY", 1, type); add_operation(AFCA, addr,symbole->adresse,0); $$=addr;};
|
|
568
|
+EBis : tID tOCROCH E tCCROCH {struct symbole_t * symbole = get_variable($1);
|
|
569
|
+ struct type_t type = symbole->type;
|
|
570
|
+ type.nb_blocs = 1;
|
|
571
|
+ int addr = push("0_TEMPORARY", 1, type);
|
|
572
|
+ if(type.isTab == 2) {
|
|
573
|
+ add_operation(COP, addr,symbole->adresse,0);
|
|
574
|
+ } else {
|
|
575
|
+ add_operation(AFCA, addr,symbole->adresse,0);
|
|
576
|
+ }
|
|
577
|
+ int addr2 = push("0_TEMPORARY", 1, integer);
|
|
578
|
+ add_operation(AFC, addr2, taille_types[symbole->type.base],0);
|
|
579
|
+ add_operation(MUL,$3,addr2,$3);
|
|
580
|
+ add_operation(ADD,$3,addr,$3);
|
|
581
|
+ $$=$3;
|
|
582
|
+ pop();
|
|
583
|
+ pop();
|
|
584
|
+ };
|
|
585
|
+
|
|
586
|
+
|
|
587
|
+EBis : tID { struct symbole_t * symbole = get_variable($1); struct type_t type = symbole->type; type.nb_blocs = 1; int addr = push("0_TEMPORARY", 1, type); add_operation(AFCA, addr,symbole->adresse,0); $$=addr;};
|
|
588
|
+
|
|
589
|
+
|
480
|
590
|
|
481
|
591
|
|
482
|
592
|
|
483
|
|
-//Créer un champ isConst dans la table des symboles
|
484
|
|
-Type : tINT {type_courant.base = INT; type_courant.pointeur_level = 0; type_courant.isTab = 0; type_courant.nb_blocs = 1; printf("Type int\n");} ;
|
485
|
|
-Type : Type tMUL {type_courant.pointeur_level++; printf("Type int *\n");};
|
486
|
593
|
|
487
|
|
-Decl : Type SuiteDecl FinDecl ;
|
488
|
|
-Decl : tCONST Type SuiteDeclConst FinDeclConst;
|
489
|
594
|
|
490
|
|
-SuiteDecl : tID {push($1, 0, type_courant); printf("Suite Decl\n");};
|
491
|
|
-SuiteDecl : tID tEQ E {pop(); int addr = push($1,1, type_courant);};
|
492
|
|
-SuiteDecl : tID tOCROCH tNB tCCROCH {type_courant.isTab = 1; type_courant.nb_blocs = $3; push($1, 0, type_courant);} ;
|
493
|
|
-FinDecl : tPV { printf("Fin Decl\n");};
|
494
|
|
-FinDecl : tCOMA SuiteDecl FinDecl ;
|
495
|
595
|
|
496
|
|
-SuiteDeclConst : tID tEQ E {pop(); int addr = push($1,1, type_courant);};
|
497
|
|
-FinDeclConst : tPV;
|
498
|
|
-FinDeclConst : tCOMA SuiteDeclConst FinDeclConst;
|
|
596
|
+
|
|
597
|
+
|
|
598
|
+/*************************************/
|
|
599
|
+/*************************************/
|
|
600
|
+/*************** Types ***************/
|
|
601
|
+/*************************************/
|
|
602
|
+/*************************************/
|
|
603
|
+
|
|
604
|
+// Type INT
|
|
605
|
+Type : tINT {type_courant.base = INT;
|
|
606
|
+ type_courant.pointeur_level = 0;
|
|
607
|
+ type_courant.isConst = 0;
|
|
608
|
+ };
|
|
609
|
+
|
|
610
|
+// Type pointeur
|
|
611
|
+Type : Type tMUL {type_courant.pointeur_level++; // On ajoute un niveau de pointeur
|
|
612
|
+ };
|
|
613
|
+
|
|
614
|
+// Constante
|
|
615
|
+Type : tCONST Type {type_courant.isConst = 1;
|
|
616
|
+ };
|
|
617
|
+
|
|
618
|
+
|
|
619
|
+
|
|
620
|
+
|
|
621
|
+/*
|
|
622
|
+Type : tINT TypeNext
|
|
623
|
+Type : tCONST tINT TypeNext
|
|
624
|
+
|
|
625
|
+TypeNext :
|
|
626
|
+| tMUL TypeNext
|
|
627
|
+*/
|
|
628
|
+
|
|
629
|
+
|
|
630
|
+
|
|
631
|
+/*************************************/
|
|
632
|
+/*************************************/
|
|
633
|
+/************ Déclaration ************/
|
|
634
|
+/*************************************/
|
|
635
|
+/*************************************/
|
|
636
|
+
|
|
637
|
+// Une déclaration est un type, un identifiant eventuellement initialisé, et fin de déclaration (une autre ou un ;);
|
|
638
|
+Decl : Type UneDecl FinDecl ;
|
|
639
|
+
|
|
640
|
+// Une déclaration d'une simple variable sans initialisation
|
|
641
|
+UneDecl : tID {type_courant.isTab = 0; // On est pas un tableau
|
|
642
|
+ type_courant.nb_blocs = 1; // On fixe le nombre de blocs
|
|
643
|
+ push($1, 0, type_courant);
|
|
644
|
+ };
|
|
645
|
+
|
|
646
|
+// Une déclaration d'une simple variable avec initialisation
|
|
647
|
+UneDecl : tID tEQ E {pop(); // On pop l'expression
|
|
648
|
+ type_courant.isTab = 0; // On est pas un tableau
|
|
649
|
+ type_courant.nb_blocs = 1; // On fixe le nombre de blocs
|
|
650
|
+ int addr = push($1,1, type_courant); // On déclare la variable qui a la même adresse que la variable temporaire, et, a donc déjà la valeur
|
|
651
|
+ };
|
|
652
|
+
|
|
653
|
+// Une déclaration d'un tableau sans initialisation
|
|
654
|
+UneDecl : tID tOCROCH tNB tCCROCH {type_courant.isTab = 1; // On est un tableau
|
|
655
|
+ type_courant.pointeur_level++; // On augmente le niveau de pointeur (un tableau est un pointeur)
|
|
656
|
+ type_courant.nb_blocs = $3; // On fixe le nombre de blocs
|
|
657
|
+ push($1, 0, type_courant);
|
|
658
|
+ };
|
|
659
|
+
|
|
660
|
+// Une déclaration d'un tableau avec initialisation
|
|
661
|
+UneDecl : tID tOCROCH tNB tCCROCH tEQ tOBRACKET InitTab tCBRACKET {if ($3 != $7) {
|
|
662
|
+ printf("\033[31;01m ERROR : \033[00m Initialisation de %s : %d éléments donnés, %d éléments requis\n", $1, $7, $3);
|
|
663
|
+ exit(2);
|
|
664
|
+ } else {
|
|
665
|
+ type_courant.isTab = 1;
|
|
666
|
+ type_courant.pointeur_level++; // On augmente le niveau de pointeur (un tableau est un pointeur)
|
|
667
|
+ type_courant.nb_blocs = $3;
|
|
668
|
+ int i;
|
|
669
|
+ for (i=0;i<$3;i++) {
|
|
670
|
+ pop();
|
|
671
|
+ }
|
|
672
|
+ push($1, 1, type_courant);
|
|
673
|
+ }
|
|
674
|
+ };
|
|
675
|
+
|
|
676
|
+// Un ; ou une autre déclaration
|
|
677
|
+FinDecl : tPV;
|
|
678
|
+FinDecl : tCOMA UneDecl FinDecl ;
|
|
679
|
+
|
|
680
|
+// Initialisation des tableau
|
|
681
|
+InitTab : E SuiteInitTab {$$ = $2 + 1;
|
|
682
|
+ };
|
|
683
|
+SuiteInitTab : tCOMA E SuiteInitTab {$$ = $3 + 1;
|
|
684
|
+ };
|
|
685
|
+SuiteInitTab : {$$ = 0;
|
|
686
|
+ };
|
|
687
|
+
|
|
688
|
+
|
|
689
|
+
|
499
|
690
|
%%
|
500
|
691
|
void main(void) {
|
501
|
692
|
init();
|