No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

as.y 34KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694
  1. %code requires {
  2. #include "../Tables/Symboles/table_symboles.h"
  3. struct while_t {
  4. int n_ins_cond;
  5. int n_ins_jmf;
  6. };
  7. }
  8. %union {
  9. int nombre;
  10. struct symbole_t symbole;
  11. char id[30];
  12. struct while_t my_while;
  13. }
  14. %{
  15. #include "../Tables/Fonctions/tab_fonctions.h"
  16. #include <stdio.h>
  17. #include <string.h>
  18. #include <stdlib.h>
  19. #include "../Tables/Instructions/tab_instruc.h"
  20. #define TAILLE 1024
  21. struct type_t type_courant;
  22. struct type_t return_type_fonc;
  23. // Tableau pour le management des patchs des JMP
  24. int instructions_ligne_to_patch[10][20];
  25. int nbs_instructions_to_patch[10];
  26. // Utile a l'affectation avec des pointeurs
  27. int first_etoile = 1;
  28. %}
  29. // Récupération des tokens
  30. %token tMAIN
  31. %token tOBRACKET tCBRACKET
  32. %token<nombre> tOBRACE tCBRACE
  33. %token tOCROCH tCCROCH
  34. %token tINT
  35. %token tCONST
  36. %token tPV tCOMA
  37. %token tMUL tDIV tADD tSUB tEQ
  38. %token<nombre> tNB tNBEXP
  39. %token<id> tID
  40. %token tPRINTF tGET tSTOP
  41. %token<nombre> tIF tELSE
  42. %token<my_while> tWHILE
  43. %token tRETURN
  44. %token tLT tGT tEQCOND
  45. %token tAND tOR
  46. %token tADDR
  47. %left tLT tGT
  48. %left tEQCOND
  49. %left tAND tOR
  50. %left tNOT
  51. %left tADD tSUB
  52. %left tMUL tDIV
  53. %right tINT tMAIN
  54. %type<symbole> SymboleAffectation
  55. %type<nombre> E EBis Invocation Args ArgSuite Arg SuiteParams Params Get InitTab SuiteInitTab
  56. %%
  57. /*************************************/
  58. /*************************************/
  59. /*********** Programme C *************/
  60. /*************************************/
  61. /*************************************/
  62. // 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.
  63. C : Fonctions {add_operation(STOP,0,0,0);
  64. create_asm();
  65. };
  66. // Le main, renvoi un int, possède le mot clé main, des arguments et un body
  67. // Dès que le main est reconnu (token main) on met en place le JMP
  68. Main : tINT tMAIN {create_jump_to_main(get_current_index()); printf("DANS LE MAIN \n");
  69. }
  70. tOBRACE Args tCBRACE Body {print();};
  71. /*************************************/
  72. /*************************************/
  73. /************ Fonctions **************/
  74. /*************************************/
  75. /*************************************/
  76. // Des fonctions sont une suite de fonctions (possiblement nulle)
  77. Fonctions : Main ;
  78. Fonctions : Fonction Fonctions ;
  79. // Une fonction possède un Type , un identifiant
  80. Fonction : Type tID {return_type_fonc = type_courant; // On récupère le ype de la fonction
  81. }
  82. tOBRACE {inc_prof(); // On incrémente la profondeur pour les arguments, ils font parti de la fonction
  83. }
  84. Args {decrement_prof(); // Quand les arguments sont passés, on peur décrémenter la profondeur (sans effacer les variables)
  85. push_fonction($2,return_type_fonc,get_current_index(), $6); // On enregistre la fonction dans la table des fonctions
  86. }
  87. tCBRACE Body {add_operation(RET,0,0,0); // On ajoute le RET
  88. };
  89. // Get, une fonction particulière -> renvoi l'adresse de la valeur getée
  90. Get : tGET tOBRACE tCBRACE {int addr = push("0_TEMPORARY", 0, integer); // On déclare la var temporelle
  91. add_operation(GET,addr,0,0); // On ajoute le GET
  92. $$ = addr; // On renvoi l'adresse
  93. };
  94. // Print, une fonction particulière
  95. Print : tPRINTF tOBRACE E tCBRACE {add_operation(PRI,$3,0,0); // On ajoute l'instruction PRI
  96. pop(); // On supprime la variable temporaire
  97. };
  98. // Stop, une fonction particulière
  99. Stop : tSTOP tOBRACE tNB tCBRACE {add_operation(STOP,$3,0,0); // On ajoute juste l'instruction stop
  100. };
  101. // Return, etape clé d'une fonction
  102. Return : tRETURN E tPV {add_operation(COP,0,$2,0); // On copie la valeur retournée à l'adresse 0 de la frame
  103. pop(); // On pop la variable temporaire
  104. };
  105. /*************************************/
  106. /*************************************/
  107. /************ Arguments **************/
  108. /*************************************/
  109. /*************************************/
  110. // Les arguments : Args, Arg, ArgSuite renvoient la taille dans la pile des arguments déjà reconnus
  111. // Des argmuments correspondent à : un argument, puis la suite d'arguments
  112. Args : Arg ArgSuite {$$ = $1 + $2; // La taille des arguments est la taille du premier argument plus celle des suivants
  113. };
  114. Args : {$$ = 0; // Il peut ne pas y avoir d'arguments, alors la taille est 0
  115. };
  116. // Un argument possède un type et un identifiant (nom)
  117. Arg : Type tID {type_courant.nb_blocs = 1;
  118. int addr = push($2,1, type_courant); // On stocke l'argument dans la pile des symboles
  119. if (type_courant.pointeur_level > 0) {
  120. $$ = taille_types[ADDR];
  121. } else {
  122. $$ = taille_types[type_courant.base];
  123. }
  124. };
  125. // Un argument peut aussi être un tableau (argument classique et crochets) il est considéré comme un pointeur
  126. Arg : Type tID tOCROCH tCCROCH {type_courant.nb_blocs = 1;
  127. type_courant.pointeur_level++; // Considéré comme un simple pointeur
  128. int addr = push($2,1, type_courant);
  129. $$ = taille_types[ADDR];
  130. };
  131. // La suite d'un argument, une virgule, un argument, et d'autres arguments
  132. ArgSuite : tCOMA Arg ArgSuite {$$ = $2 + $3;
  133. };
  134. // Cela peut être aucun arguments
  135. ArgSuite : {$$ = 0;
  136. };
  137. /*************************************/
  138. /*************************************/
  139. /*************** Body ****************/
  140. /*************************************/
  141. /*************************************/
  142. // Un body n'est rien d'autre qu'une suite d'instructions entre deux accolades
  143. Body : tOBRACKET {inc_prof(); // Lors de l'ouverture de l'accolade la profondeur augmente
  144. }
  145. Instructions tCBRACKET {reset_prof(); // A la sortie d'un body, on détruit toutes les variables locales de ce body
  146. };
  147. /*************************************/
  148. /*************************************/
  149. /*********** Instructions ************/
  150. /*************************************/
  151. /*************************************/
  152. // Des instructions sont une instruction suivie d'autres instructions, ou, rien
  153. Instructions : Instruction Instructions ;
  154. Instructions : ;
  155. // Un instruction peut être : une affectation, une déclaration, une invocation, un if, un while, un return, une fonction particulière
  156. Instruction : Aff;
  157. Instruction : Decl;
  158. Instruction : Invocation tPV {pop();};
  159. Instruction : If;
  160. Instruction : While;
  161. Instruction : Return;
  162. Instruction : Stop tPV;
  163. Instruction : Print tPV;
  164. /*************************************/
  165. /*************************************/
  166. /************ Invocation *************/
  167. /*************************************/
  168. /*************************************/
  169. Invocation : tID tOBRACE Params tCBRACE {struct fonction_t fonc = get_fonction($1); // On récupère la fonction
  170. multiple_pop($3); // On pop les paramètres de la table des symboles
  171. add_operation(CALL,fonc.first_instruction_line, get_last_addr(),0); // On écrit le CALL
  172. // On renvoi l'adresse de la valeur retour de la fonction
  173. if (fonc.return_type.pointeur_level > 0 || fonc.return_type.isTab) {
  174. $$ = push("0_TEMPORARY_RETURN", 0, pointer);
  175. } else {
  176. $$ = push("0_TEMPORARY_RETURN", 0, fonc.return_type);
  177. }
  178. };
  179. /*************************************/
  180. /*************************************/
  181. /************ Paramètres *************/
  182. /*************************************/
  183. /*************************************/
  184. // 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
  185. Params : {$$ = 0;
  186. };
  187. Params : Param SuiteParams {$$ = $2 + 1;
  188. };
  189. Param : E
  190. SuiteParams : tCOMA Param SuiteParams {$$ = $3 + 1;};
  191. SuiteParams : {$$ = 0;};
  192. /*************************************/
  193. /*************************************/
  194. /******** Sauts conditionnels ********/
  195. /*************************************/
  196. /*************************************/
  197. // Un if : le token, une expression entre parenthèse suivie d'un body et d'un else
  198. If : tIF tOBRACE E tCBRACE {add_operation(JMF,$3,0,0); // On ajoute le JMF sans préciser la ligne du saut
  199. $1 = get_current_index() - 1; // On stocke le numéro d'instruction à patcher
  200. }
  201. Body {int current = get_current_index(); // On récupère le numéro d'instrcution
  202. patch($1,current + 1); // On patch le Jump en cas d'instruction fausse
  203. add_operation(JMP,0,0,0); // JMP pour skip le else si on devait faire le body
  204. instructions_ligne_to_patch[get_prof()][nbs_instructions_to_patch[get_prof()]] = current; // On spécifie que le JMP est a patcher
  205. nbs_instructions_to_patch[get_prof()]++;
  206. pop(); // On pop la condition du if
  207. }
  208. Else
  209. // Elsif
  210. Else : tELSE If;
  211. // Else
  212. Else : tELSE Body {int current = get_current_index();
  213. for (int i = 0; i< nbs_instructions_to_patch[get_prof()]; i++) {
  214. patch(instructions_ligne_to_patch[get_prof()][i],current); // On patch après le else
  215. }
  216. nbs_instructions_to_patch[get_prof()] = 0;
  217. };
  218. // If sans else
  219. Else : {int current = get_current_index();
  220. for (int i = 0; i< nbs_instructions_to_patch[get_prof()]; i++){
  221. patch(instructions_ligne_to_patch[get_prof()][i],current); // On patch après le else
  222. }
  223. nbs_instructions_to_patch[get_prof()] = 0;
  224. };
  225. /*************************************/
  226. /*************************************/
  227. /************** Boucles **************/
  228. /*************************************/
  229. /*************************************/
  230. While : tWHILE {$1.n_ins_cond = get_current_index(); // On enregistre l'endroit de la condition (pour le JMP en fin de while)
  231. }
  232. tOBRACE E tCBRACE {add_operation(JMF,$4,0,0); // Ecriture du JMF
  233. $1.n_ins_jmf = get_current_index() - 1; // Enregistrement du numero d'instruction du jmf à patch
  234. pop(); // Pop de la condition
  235. }
  236. Body {int current = get_current_index(); // Patch du JMF apres le body
  237. patch($1.n_ins_jmf,current + 1);
  238. add_operation(JMP,$1.n_ins_cond,0,0); // JMP au debut de la boucle
  239. };
  240. /*************************************/
  241. /*************************************/
  242. /************ Affectations ***********/
  243. /*************************************/
  244. /*************************************/
  245. // Affectation simple
  246. Aff : tID tEQ E tPV {struct symbole_t * symbole = get_variable($1);
  247. symbole->initialized = 1;
  248. if (symbole->type.isConst == 1 && symbole->type.pointeur_level == 0 || symbole->type.isTab) {
  249. printf("\033[31;01m ERROR : \033[00m %s est READ-ONLY\n", symbole->nom);
  250. exit(2);
  251. } else {
  252. add_operation(COP,symbole->adresse,$3,0); // On affecte la valeur
  253. pop(); // On pop l'expression
  254. first_etoile = 1; // On reinitialise first_etoile
  255. }
  256. };
  257. // Affectation sur un pointeur
  258. Aff : SymboleAffectation tEQ E tPV {if ($1.type.isConst == 1 && $1.type.pointeur_level == 0 || $1.type.isTab) {
  259. printf("\033[31;01m ERROR : \033[00m %s ou un de ses déréférencement est READ-ONLY\n", $1.nom);
  260. exit(2);
  261. } else {
  262. add_operation(WR,$1.adresse,$3,0); // On affecte la valeur
  263. pop(); // On pop l'expression
  264. pop(); // On pop la variable temporaire de l'adresse
  265. }
  266. };
  267. // Debut d'une affectation avec déreférencement de pointeur
  268. SymboleAffectation : tID {struct symbole_t * symbole = get_variable($1);
  269. symbole->initialized = 1;
  270. int addr = push("0_TEMPORARY", 1, pointer);
  271. if (symbole->type.isTab) {
  272. add_operation(AFCA, addr, symbole->adresse,0); // Si tableau AFCA
  273. } else {
  274. add_operation(COP, addr, symbole->adresse,0); // Si pointeur COP
  275. }
  276. struct symbole_t symbolebis = *symbole;
  277. symbolebis.adresse = addr;
  278. $$ = symbolebis; // On renvoi un symbole pointant sur la copie de l'adresse
  279. };
  280. SymboleAffectation : SymboleAffectation tOCROCH E tCCROCH {if ($1.type.pointeur_level == 0) { // Check déréférençable
  281. printf("\033[35;01m WARNING : \033[00m déréférencement exessif\n");
  282. } else {
  283. $1.type.pointeur_level--; // On baisse le niveau de pointeur
  284. int addr = push("0_TEMPORARY", 1, integer); // On alloue la place pour stocker la taille du type pointé
  285. if ($1.type.pointeur_level > 0) {
  286. add_operation(AFC, addr, taille_types[ADDR],0); // Si on est encore un pointeur, la taille d'un adresse
  287. } else {
  288. add_operation(AFC, addr, taille_types[$1.type.base],0); // Sinon le type de base
  289. }
  290. add_operation(MUL,$3,addr,$3); // On multiple le nombre de décalage par la taille du type
  291. add_operation(ADD,$3,$1.adresse,$3); // On l'ajoute a l'adresse de base
  292. $1.type.isTab = 0;
  293. $$=$1;
  294. pop();
  295. pop();
  296. }
  297. };
  298. SymboleAffectation : tMUL SymboleAffectation {if ($2.type.pointeur_level == 0) { // Check déréférençable
  299. printf("\033[35;01m WARNING : \033[00m déréférencement exessif\n");
  300. } else {
  301. $2.type.pointeur_level--; // On baisse le niveau de pointeur
  302. $2.type.isTab = 0;
  303. if (first_etoile) {
  304. first_etoile = 0; // Le premier déréférencement doit être skip a cause du WR
  305. } else {
  306. add_operation(READ, $2.adresse, $2.adresse,0); //
  307. $$=$2;
  308. }
  309. }
  310. };
  311. /*************************************/
  312. /*************************************/
  313. /***** Expressions Arithmetiques *****/
  314. /*************************************/
  315. /*************************************/
  316. // Pour une expression arithmétique, nous renvoyons toujours l'adresse du resultat
  317. // Un simple nombre
  318. E : tNB {int addr = push("0_TEMPORARY", 1, integer); // On reserve la place de la variable temporaire
  319. add_operation(AFC, addr,$1,0); // On Affecte la valeur a cette adresse
  320. $$ = addr; // On renvoi l'adresse
  321. printf("Nombre %d@%d\n", $1, addr);
  322. };
  323. // Un nombre sous forme XeY, même traitement qu'un nombre classique
  324. E : tNBEXP {int addr = push("0_TEMPORARY", 1, integer);
  325. add_operation(AFC, addr,$1,0);
  326. $$ = addr;
  327. };
  328. // Une Multiplication
  329. 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
  330. $$ = $1; // On renvoi l'adresse du resultat
  331. pop(); // On libère la seconde variable temporaire
  332. };
  333. // Une Division (idem multiplication)
  334. E : E tDIV E {add_operation(DIV, $1,$1,$3);
  335. $$ = $1;
  336. pop();
  337. };
  338. // Une Soustraction (idem multiplication)
  339. E : E tSUB E {add_operation(SOU,$1,$1,$3);
  340. $$ = $1;
  341. pop();
  342. };
  343. // Une Addition (idem multiplication)
  344. E : E tADD E {add_operation(ADD,$1,$1,$3);
  345. $$ = $1;
  346. pop();
  347. };
  348. // Une invocation
  349. E : Invocation {$$ = $1; // Une invocation renvoi déjà l'adresse, cette règle n'est qu'un cast d'Invocation en E
  350. };
  351. // Consomation de parenthèses
  352. E : tOBRACE E tCBRACE {$$ = $2; // Cela permet de garantir la prioricité des expressions entre parenthèse
  353. };
  354. // Négatif --> -E <=> 0-E
  355. E : tSUB E {int addr = push("0_TEMPORARY", 1, integer); // On réserve la variable temporaire pour le 0
  356. add_operation(AFC, addr,0,0); // On affecte le 0
  357. add_operation(SOU, $2, addr, $2); // On applique le 0-E
  358. $$ = $2; // On renvoi l'adresse
  359. pop(); // On libère la mémoire temporaire utilisée par 0
  360. };
  361. // Opérateur == (idem multiplication)
  362. E : E tEQCOND E {add_operation(EQU,$1,$1,$3);
  363. $$ = $1;
  364. pop();
  365. };
  366. // Opérateur > (idem multiplication)
  367. E : E tGT E {add_operation(SUP,$1,$1,$3);
  368. $$ = $1;
  369. pop();
  370. };
  371. // Opérateur < (idem multiplication)
  372. E : E tLT E {add_operation(INF,$1,$1,$3);
  373. printf("INF %d %d %d\n", $1, $1, $3);
  374. print();
  375. $$ = $1;
  376. pop();
  377. };
  378. // Opérateur !E <=> E==0
  379. E : tNOT E {int addr = push("0_TEMPORARY", 1, integer); // On réserve la variable temporaire pour le 0
  380. add_operation(AFC, addr,0,0); // On affecte le 0
  381. add_operation(EQU, $2, addr, $2); // On applique le 0==E
  382. $$ = $2; // On renvoi l'adresse
  383. pop();
  384. };
  385. // Opérateur E && E' <=> E*E' (idem multiplication)
  386. E : E tAND E {add_operation(MUL,$1,$1,$3);
  387. $$ = $1;
  388. pop();
  389. };
  390. // Opérateur E || E' <=> E+E' (idem multiplication)
  391. E : E tOR E {add_operation(ADD,$1,$1,$3);
  392. $$ = $1;
  393. pop();
  394. };
  395. // Déréférencement de pointeur
  396. E : tMUL E {add_operation(READ, $2, $2, 0); // Extraction en mémoire
  397. $$=$2;
  398. };
  399. // Une variable
  400. E : tID {struct symbole_t * symbole = get_variable($1); // On cherche la variable dans la table des symboles
  401. struct type_t type = symbole->type; // On récupère le type
  402. type.nb_blocs = 1;
  403. int addr = push("0_TEMPORARY", 1, type); // On créé la variable temporaire
  404. if (symbole->type.isTab == 1) {
  405. add_operation(AFCA, addr,symbole->adresse,0); // Si c'est un tableau on affecte l'adresse du début
  406. } else {
  407. add_operation(COP, addr,symbole->adresse,0); // Si c'est autre chose, on copie la valeur
  408. }
  409. $$ = addr;
  410. printf("variable stoquée a l'adresse %d \n", addr);
  411. };
  412. // Une variable sous forme de tableau
  413. E : tID tOCROCH E tCCROCH {struct symbole_t * symbole = get_variable($1); // On récupère le symbole
  414. struct type_t type = symbole->type; // On récupère le type
  415. type.nb_blocs = 1;
  416. int addr = push("0_TEMPORARY", 1, type); // On créé la variable temporaire
  417. if (type.isTab == 2) {
  418. add_operation(COP, addr,symbole->adresse,0);
  419. } else {
  420. add_operation(AFCA, addr,symbole->adresse,0);
  421. }
  422. int addr2 = push("0_TEMPORARY", 1, integer);
  423. add_operation(AFC, addr2, taille_types[symbole->type.base],0);
  424. add_operation(MUL,$3,addr2,$3);
  425. add_operation(ADD,$3,addr,$3);
  426. add_operation(READ,$3,$3,0);
  427. $$=$3;
  428. pop();
  429. pop();
  430. };
  431. E : tADDR EBis {$$=$2;};
  432. E : Get {$$ = $1;};
  433. EBis : tID tOCROCH E tCCROCH {struct symbole_t * symbole = get_variable($1);
  434. struct type_t type = symbole->type;
  435. type.nb_blocs = 1;
  436. int addr = push("0_TEMPORARY", 1, type);
  437. if(type.isTab == 2) {
  438. add_operation(COP, addr,symbole->adresse,0);
  439. } else {
  440. add_operation(AFCA, addr,symbole->adresse,0);
  441. }
  442. int addr2 = push("0_TEMPORARY", 1, integer);
  443. add_operation(AFC, addr2, taille_types[symbole->type.base],0);
  444. add_operation(MUL,$3,addr2,$3);
  445. add_operation(ADD,$3,addr,$3);
  446. $$=$3;
  447. pop();
  448. pop();
  449. };
  450. 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;};
  451. /*************************************/
  452. /*************************************/
  453. /*************** Types ***************/
  454. /*************************************/
  455. /*************************************/
  456. // Type INT
  457. Type : tINT {type_courant.base = INT;
  458. type_courant.pointeur_level = 0;
  459. type_courant.isConst = 0;
  460. };
  461. // Type pointeur
  462. Type : Type tMUL {type_courant.pointeur_level++; // On ajoute un niveau de pointeur
  463. };
  464. // Constante
  465. Type : tCONST Type {type_courant.isConst = 1;
  466. };
  467. /*
  468. Type : tINT TypeNext
  469. Type : tCONST tINT TypeNext
  470. TypeNext :
  471. | tMUL TypeNext
  472. */
  473. /*************************************/
  474. /*************************************/
  475. /************ Déclaration ************/
  476. /*************************************/
  477. /*************************************/
  478. // Une déclaration est un type, un identifiant eventuellement initialisé, et fin de déclaration (une autre ou un ;);
  479. Decl : Type UneDecl FinDecl ;
  480. // Une déclaration d'une simple variable sans initialisation
  481. UneDecl : tID {type_courant.isTab = 0; // On est pas un tableau
  482. type_courant.nb_blocs = 1; // On fixe le nombre de blocs
  483. push($1, 0, type_courant);
  484. };
  485. // Une déclaration d'une simple variable avec initialisation
  486. UneDecl : tID tEQ E {pop(); // On pop l'expression
  487. type_courant.isTab = 0; // On est pas un tableau
  488. type_courant.nb_blocs = 1; // On fixe le nombre de blocs
  489. 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
  490. };
  491. // Une déclaration d'un tableau sans initialisation
  492. UneDecl : tID tOCROCH tNB tCCROCH {type_courant.isTab = 1; // On est un tableau
  493. type_courant.pointeur_level++; // On augmente le niveau de pointeur (un tableau est un pointeur)
  494. type_courant.nb_blocs = $3; // On fixe le nombre de blocs
  495. push($1, 0, type_courant);
  496. };
  497. // Une déclaration d'un tableau avec initialisation
  498. UneDecl : tID tOCROCH tNB tCCROCH tEQ tOBRACKET InitTab tCBRACKET {if ($3 != $7) {
  499. printf("\033[31;01m ERROR : \033[00m Initialisation de %s : %d éléments donnés, %d éléments requis\n", $1, $7, $3);
  500. exit(2);
  501. } else {
  502. type_courant.isTab = 1;
  503. type_courant.pointeur_level++; // On augmente le niveau de pointeur (un tableau est un pointeur)
  504. type_courant.nb_blocs = $3;
  505. int i;
  506. for (i=0;i<$3;i++) {
  507. pop();
  508. }
  509. push($1, 1, type_courant);
  510. }
  511. };
  512. // Un ; ou une autre déclaration
  513. FinDecl : tPV;
  514. FinDecl : tCOMA UneDecl FinDecl ;
  515. // Initialisation des tableau
  516. InitTab : E SuiteInitTab {$$ = $2 + 1;
  517. };
  518. SuiteInitTab : tCOMA E SuiteInitTab {$$ = $3 + 1;
  519. };
  520. SuiteInitTab : {$$ = 0;
  521. };
  522. %%
  523. void main(void) {
  524. init();
  525. yyparse();
  526. }