Recent Changes - Search:

My Projects

Courses

Writings

Source Code

Social Networks

Live Traffic !

Évolution 6 : Les chaînes de caractères (Partie 1 - Variable et déclaration)

Créer son propre langage de programmation de A à Z

<< Évolution 5 : Les boucles | Évolution 6 : Les chaînes de caractères (Partie 1 - Variable et déclaration) | Évolution 7 : Les chaînes de caractères (Partie 2.1 - Concaténation et ré-allocation dynamique de la mémoire) >>

Grosse évolution : les chaînes de caractères. Le langage Simple ne sait gérer pour le moment que les entiers, les booléens et c'est tout ! Il serait chouette de pouvoir travailler sur du texte. C'est ce que nous allons implémenter. On va créer un nouveau type natif de variable dans Simple, le type texte. Puis nous allons nous dire que les variables de type texte doivent comment par un "t". Ensuite les chaînes de texte écrites en brutes devront être délimitées par des guillemets : "Ceci est un exemple de chaîne en Simple.". On mettra en place une instruction pour supprimer une variable de texte. Ceci dans l'objectif de libérer la mémoire allouée par la variable.

Évolution 6 du langage :

  1. <affectation> ::= <affectation> | variable_texte "=" <expression_texte> ";"
  2.  
  3. <suppression> ::= "supprimer" variable_texte ";"
  4.  
  5. <expression_texte> ::= variable_texte | texte

variable_texte est un terminal au même titre que variable_booleenne et variable_arithmetique. C'est un nom qui doit commencer par un "t" minuscule. texte est aussi un terminal qui est la chaîne entre guillemets. A l'instar des commentaires, la reconnaissance de ce lexème se fera par une condition de démarrage. Mais le contenu ne devra cette fois-ci pas être ignoré par l'analyseur syntaxique. Le token envoyé à ce dernier devra avoir pour valeur la chaîne de caractères. Nous concaténerons les caractères de la chaînes à la variable yylval.texte :

lexique_simple.lex
  1. %{
  2.  
  3. #include "simple.h"
  4. unsigned int lineno=1;
  5. bool error_lexical=false;
  6.  
  7. /* definition de la fonction de concatenation pour les chaines de texte */
  8. void* concat(char*,char*);
  9.  
  10. %}
  11.  
  12. %option noyywrap
  13.  
  14. nombre 0|[1-9][[:digit:]]*
  15. variable_booleenne b(_|[[:alnum:]])*
  16. variable_arithmetique e(_|[[:alnum:]])*
  17. variable_texte t(_|[[:alnum:]])*
  18.  
  19. /* regex de commentaire d'une seule ligne */
  20. commentaire ((\/\/|#).*)
  21.  
  22. /* pour les commentaires de plusieurs lignes, on declare nos deux lexemes en tant que conditions de demarrage exclusives (%x) dans Flex */
  23. %x  commentaire_1
  24. %x  commentaire_2
  25.  
  26. /* chaine de caractere */
  27. %x  chaine
  28.  
  29. %%
  30.  
  31. "/*"    {
  32.             /* un marqueur de debut de commentaire trouve -> on lui dit que le lexeme commentaire_1 commence */
  33.             BEGIN(commentaire_1);
  34.             printf("Commentaire detecte en ligne %i\n",lineno);
  35.         }
  36.  
  37. <commentaire_1>"\n"     {
  38.                             /* si on trouve des retours chariots et que la condition de demarrage est commentaire_1, alors on incremente la variable lineno. sans cela, on serait en decalage pour la suite de l'analyse */
  39.                             lineno++;
  40.                         }
  41.  
  42. <commentaire_1>"*"+"/"      {
  43.                                 /* si on au moins une fois "*" suivi de "/" et que la condition de demarrage est commentaire_1, alors on lui dit que le lexeme commentaire_1 est fini */
  44.                                 BEGIN(INITIAL);
  45.                                 printf("Fin du commentaire en ligne %i\n",lineno);
  46.                                 return TOK_COMMENT;
  47.                             }
  48.  
  49. <commentaire_1>.    {/* les autres caracteres suivants la conditions de demarrage sont absorbes par l'analyse est donc ingores */}
  50.  
  51. "<!--"      {
  52.                 BEGIN(commentaire_2);
  53.                 printf("Commentaire detecte en ligne %i\n",lineno);
  54.             }
  55. <commentaire_2>"\n"         {lineno++;}
  56. <commentaire_2>"-"+"-"+">"  {
  57.                                 BEGIN(INITIAL);
  58.                                 printf("Fin du commentaire en ligne %i\n",lineno);
  59.                                 return TOK_COMMENT;
  60.                             }
  61. <commentaire_2>.            {}
  62.  
  63. "\""         {
  64.                 /* debut de la chaine de texte (premier guillemet) */
  65.                 BEGIN(chaine);
  66.                 yylval.texte=malloc(sizeof(char)*strlen(yytext));
  67.                 if(yylval.texte==NULL){
  68.                     fprintf(stderr,"\tERREUR : Probleme de memoire sur une chaine texte a la ligne %i !\n",lineno);
  69.                     exit(-1);
  70.                 }
  71.                 yylval.texte=strdup(yytext);
  72.                 printf("Chaine de texte detectee en ligne %i\n",lineno);
  73.             }
  74.  
  75. <chaine>"\n"    {
  76.                     /* on prend en compte les sauts de ligne que l'on traduira par "\n" */
  77.                     lineno++;
  78.                     yylval.texte=(char*)concat(yylval.texte,"\\n");
  79.                     if(yylval.texte==NULL){
  80.                         fprintf(stderr,"\tERREUR : Probleme de memoire sur une chaine texte a la ligne %i !\n",lineno);
  81.                         exit(-1);
  82.                     }
  83.                 }
  84.  
  85. <chaine>"\t"    {
  86.                     /* on prend en compte les tabulations que l'on traduira par "\t" */
  87.                     yylval.texte=(char*)concat(yylval.texte,"\\t");
  88.                     if(yylval.texte==NULL){
  89.                         fprintf(stderr,"\tERREUR : Probleme de memoire sur une chaine texte a la ligne %i !\n",lineno);
  90.                         exit(-1);
  91.                     }
  92.                 }
  93.  
  94. <chaine>"\\\""    {
  95.                     /* pour echapper le guillemet dans la chaine \" */
  96.                     yylval.texte=(char*)concat(yylval.texte,yytext);
  97.                     if(yylval.texte==NULL){
  98.                         fprintf(stderr,"\tERREUR : Probleme de memoire sur une chaine texte a la ligne %i !\n",lineno);
  99.                         exit(-1);
  100.                     }
  101.                 }
  102.  
  103. <chaine>"\""     {
  104.                     /* fin de la chaine (deuxieme guillemet non echappe) */
  105.                     BEGIN(INITIAL);
  106.                     yylval.texte=(char*)concat(yylval.texte,yytext);
  107.                     if(yylval.texte==NULL){
  108.                         fprintf(stderr,"\tERREUR : Probleme de memoire sur une chaine texte a la ligne %i !\n",lineno);
  109.                         exit(-1);
  110.                     }
  111.                     printf("Fin de la chaine en ligne %i\n",lineno);
  112.                     return TOK_TEXTE;
  113.                 }
  114.  
  115. <chaine>.  {
  116.                 /* les caracteres de la chaine */
  117.                 yylval.texte=(char*)concat(yylval.texte,yytext);
  118.                 if(yylval.texte==NULL){
  119.                         fprintf(stderr,"\tERREUR : Probleme de memoire sur une chaine texte a la ligne %i !\n",lineno);
  120.                         exit(-1);
  121.                 }
  122.             }
  123.  
  124. {nombre} {
  125.     sscanf(yytext, "%ld", &yylval.nombre);
  126.     return TOK_NOMBRE;
  127. }
  128.  
  129. "si"    {return TOK_SI;}
  130.  
  131. "alors" {return TOK_ALORS;}
  132.  
  133. "sinon" {return TOK_SINON;}
  134.  
  135. "++"    {return TOK_INCREMENTATION;}
  136.  
  137. "--"    {return TOK_DECREMENTATION;}
  138.  
  139. "+="    {return TOK_AFFECT_PLUS;}
  140.  
  141. "-="    {return TOK_AFFECT_MOINS;}
  142.  
  143. "*="    {return TOK_AFFECT_MUL;}
  144.  
  145. "/="    {return TOK_AFFECT_DIV;}
  146.  
  147. "%="    {return TOK_AFFECT_MOD;}
  148.  
  149. "&="    {return TOK_AFFECT_ET;}
  150.  
  151. "|="    {return TOK_AFFECT_OU;}
  152.  
  153. "egal a"|"equivalent a"|"=="        {return TOK_EQU;}
  154.  
  155. "different de"|"!="|"<>"            {return TOK_DIFF;}
  156.  
  157. "superieur a"|"plus grand que"|">"  {return TOK_SUP;}
  158.  
  159. "inferieur a"|"plus petit que"|"<"  {return TOK_INF;}
  160.  
  161. "superieur ou egal a"|">="          {return TOK_SUPEQU;}
  162.  
  163. "inferieur ou egal a"|"<="          {return TOK_INFEQU;}
  164.  
  165. "compris dans"|"dans"               {return TOK_IN;}
  166.  
  167. "afficher"      {return TOK_AFFICHER;}
  168.  
  169. "supprimer"     {return TOK_SUPPR;}
  170.  
  171. "faire"         {return TOK_FAIRE;}
  172.  
  173. "x"             {return TOK_CROIX;}
  174.  
  175. "="             {return TOK_AFFECT;}
  176.  
  177. "+"             {return TOK_PLUS;}
  178.  
  179. "-"             {return TOK_MOINS;}
  180.  
  181. "*"             {return TOK_MUL;}
  182.  
  183. "/"             {return TOK_DIV;}
  184.  
  185. "%"             {return TOK_MOD;}
  186.  
  187. "^"             {return TOK_PUISSANCE;}
  188.  
  189. "("             {return TOK_PARG;}
  190.  
  191. ")"             {return TOK_PARD;}
  192.  
  193. "["             {return TOK_CROG;}
  194.  
  195. "]"             {return TOK_CROD;}
  196.  
  197. "?"             {return TOK_POINT_INTERROGATION;}
  198.  
  199. ":"             {return TOK_DOUBLE_POINT;}
  200.  
  201. "et"            {return TOK_ET;}
  202.  
  203. "ou"            {return TOK_OU;}
  204.  
  205. "non"|"!"           {return TOK_NON;}
  206.  
  207. ";"             {return TOK_FINSTR;}
  208.  
  209. "vrai"          {return TOK_VRAI;}
  210.  
  211. "faux"          {return TOK_FAUX;}
  212.  
  213. "\n"            {lineno++;}
  214.  
  215. {variable_booleenne} {
  216.     yylval.texte = yytext;
  217.     return TOK_VARB;
  218. }
  219.  
  220.  
  221. {variable_arithmetique} {
  222.     yylval.texte = yytext;
  223.     return TOK_VARE;
  224. }
  225.  
  226. {variable_texte} {
  227.     yylval.texte = yytext;
  228.     return TOK_VART;
  229. }
  230.  
  231. {commentaire}   {
  232.     printf("Commentaire detecte en ligne %i\n",lineno);
  233.     printf("Fin du commentaire en ligne %i\n",lineno);
  234.     return TOK_COMMENT;
  235. }
  236.  
  237. " "|"\t" {}
  238.  
  239. . {
  240.     fprintf(stderr,"\tERREUR : Lexeme inconnu a la ligne %d. Il s'agit de %s et comporte %d lettre(s)\n",lineno,yytext,yyleng);
  241.     error_lexical=true;
  242.     return yytext[0];
  243. }
  244.  
  245. %%
  246.  
  247. /* fonction de concatenation - realloue la memoire a la variable texte dimensionne a la taille memoire du tableau de char ajout puis concatene */
  248.  
  249. void* concat(char* texte, char* ajout){
  250.     void* p=NULL;
  251.     /* realloue la memoire -> taille de texte + taille de ajout + 1 (caractere de fin \0) */
  252.     if((p=realloc(texte,sizeof(char)*(strlen(texte)+strlen(ajout)+1)))){
  253.         texte=p;
  254.         return strcat(texte,ajout);
  255.     }else{
  256.         /* appel de la macro FREE pour liberer correctement la memoire */
  257.         FREE(texte);
  258.         return NULL;
  259.     }
  260. }

Le fichier d'entête avec la macro FREE pour libérer correctement la mémoire :

simple.h
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <stdbool.h>
  4. #include <string.h>
  5. #include <glib.h>
  6. #include "syntaxe_simple.tab.h"
  7. int yylex(void);
  8. void yyerror(char*);
  9. extern unsigned int lineno;
  10. extern bool error_lexical;
  11.  
  12. /* MACROS */
  13. #define FREE(x) { if (x) free(x); x = NULL; }
  14.  
  15. /* Le flux de notre fichier de sortie final */
  16. FILE* fichier;
  17.  
  18. /* Definition des methodes de generation de code C */
  19. extern void debut_code(void);
  20. extern void genere_code(GNode*);
  21. extern void fin_code(void);
  22.  
  23. /* Definition des sequences de code possibles pour l'AST (Arbre Syntaxique). Chaque sequence de code est associe a un numerique. Ce sont tout les noeuds possibles de l'AST. */
  24. #define CODE_VIDE       0
  25. #define SEQUENCE        1
  26. #define VARIABLE        2
  27. #define AFFECTATION     3
  28. #define AFFECTATIONE    4
  29. #define AFFECTATIONB    5
  30. #define AFFICHAGEE      6
  31. #define AFFICHAGEB      7
  32. #define ENTIER          8
  33. #define ADDITION        9
  34. #define SOUSTRACTION    10
  35. #define MULTIPLICATION  11
  36. #define DIVISION        12
  37. #define ET              13
  38. #define OU              14
  39. #define NON             15
  40. #define VRAI            16
  41. #define FAUX            17
  42. #define EXPR_PAR        18
  43. #define EGALITE         19
  44. #define DIFFERENT       20
  45. #define SUPERIEUR       21
  46. #define INFERIEUR       22
  47. #define SUPEGAL         23
  48. #define INFEGAL         24
  49. #define DANSII          25      /* inclus-inclus */
  50. #define DANSEI          26      /* exclus-inclus */
  51. #define DANSIE          27      /* inclus-exclus */
  52. #define DANSEE          28      /* exclus-exclus */
  53. #define CONDITION_SI    29
  54. #define CONDITION_SI_SINON 30
  55. #define SI          31
  56. #define SINON       32
  57. #define NEGATIF     33
  58. #define BLOC_CODE   34
  59. #define MODULO      35
  60. #define AFFECTATION_PLUS    36
  61. #define AFFECTATION_MOINS   37
  62. #define AFFECTATION_MUL     38
  63. #define AFFECTATION_DIV     39
  64. #define AFFECTATION_MOD     40
  65. #define AFFECTATION_ET      41
  66. #define AFFECTATION_OU      42
  67. #define INCREMENTATION      43
  68. #define DECREMENTATION      44
  69. #define AFFECTATION_INCR    45
  70. #define AFFECTATION_DECR    46
  71. #define BOUCLE_FOR          47
  72. #define BOUCLE_WHILE        48
  73. #define BOUCLE_DO_WHILE     49
  74. #define AFFECTATIONNT       50
  75. #define AFFECTATIONT        51
  76. #define SUPPRESSIONT        52
  77. #define TEXTE               53
  78. #define AFFICHAGET          54

On met à jour l'analyseur syntaxique :

syntaxe_bison.y
  1. %{
  2.  
  3. #include "simple.h"
  4. bool error_syntaxical=false;
  5. bool error_semantical=false;
  6. /* Notre table de hachage */
  7. GHashTable* table_variable;
  8.  
  9. /* Fonction de suppression des variables declarees a l'interieur d'un arbre syntaxique */
  10. void supprime_variable(GNode*);
  11.  
  12. /* Notre structure Variable qui a comme membre le type et un pointeur generique vers la valeur */
  13. typedef struct Variable Variable;
  14.  
  15. struct Variable{
  16.         char* type;
  17.         GNode* value;
  18. };
  19.  
  20. %}
  21.  
  22. /* L'union dans Bison est utilisee pour typer nos tokens ainsi que nos non terminaux. Ici nous avons declare une union avec trois types : nombre de type int, texte de type pointeur de char (char*) et noeud d'arbre syntaxique (AST) de type (GNode*) */
  23.  
  24. %union {
  25.         long nombre;
  26.         char* texte;
  27.         GNode*  noeud;
  28. }
  29.  
  30. /* Nous avons ici les operateurs, ils sont definis par leur ordre de priorite. Si je definis par exemple la multiplication en premier et l'addition apres, le + l'emportera alors sur le * dans le langage. Les parenthese sont prioritaires avec %right */
  31.  
  32. %left                   TOK_INCREMENTATION      TOK_DECREMENTATION      /* ++ -- */
  33. %left                   TOK_PLUS        TOK_MOINS       /* +- */
  34. %left                   TOK_MUL         TOK_DIV         TOK_MOD         /* /*% */
  35. %left                   TOK_PUISSANCE   /* ^ */
  36. %left                   TOK_ET          TOK_OU          TOK_NON         /* et ou non */
  37. %left                   TOK_EQU         TOK_DIFF        TOK_SUP         TOK_INF         TOK_SUPEQU      TOK_INFEQU      /* comparaisons */
  38. %right                  TOK_PARG        TOK_PARD        /* () */
  39.  
  40. /* Nous avons la liste de nos expressions (les non terminaux). Nous les typons tous en noeud de l'arbre syntaxique (GNode*) */
  41.  
  42. %type<noeud>            code
  43. %type<noeud>            bloc_code
  44. %type<noeud>            commentaire
  45. %type<noeud>            instruction
  46. %type<noeud>        condition
  47. %type<noeud>        condition_si
  48. %type<noeud>        condition_sinon
  49. %type<noeud>        boucle_for
  50. %type<noeud>        boucle_while
  51. %type<noeud>        boucle_do_while
  52. %type<noeud>            variable_arithmetique
  53. %type<noeud>            variable_booleenne
  54. %type<noeud>            variable_texte
  55. %type<noeud>            affectation
  56. %type<noeud>            affichage
  57. %type<noeud>            suppression
  58. %type<noeud>            expression_arithmetique
  59. %type<noeud>            expression_booleenne
  60. %type<noeud>            expression_texte
  61. %type<noeud>            addition
  62. %type<noeud>            soustraction
  63. %type<noeud>            multiplication
  64. %type<noeud>            division
  65. %type<noeud>            modulo
  66.  
  67. /* Nous avons la liste de nos tokens (les terminaux de notre grammaire) */
  68.  
  69. %token<nombre>          TOK_NOMBRE
  70. %token                  TOK_VRAI        /* true */
  71. %token                  TOK_FAUX        /* false */
  72. %token                  TOK_AFFECT      /* = */
  73. %token                  TOK_FINSTR      /* ; */
  74. %token                  TOK_IN          /* dans */
  75. %token                  TOK_CROG    TOK_CROD    /* [] */
  76. %token                  TOK_AFFICHER    /* afficher */
  77. %token<texte>           TOK_VARB        /* variable booleenne */
  78. %token<texte>           TOK_VARE        /* variable arithmetique */
  79. %token<texte>                   TOK_VART
  80. %token                  TOK_SI          /* si */
  81. %token                  TOK_ALORS       /* alors */
  82. %token                  TOK_SINON       /* sinon */
  83. %token                                  TOK_COMMENT             /* commentaire */
  84. %token                                  TOK_AFFECT_PLUS TOK_AFFECT_MOINS        TOK_AFFECT_MUL  TOK_AFFECT_DIV  TOK_AFFECT_MOD  /* += -= *= /= %= */
  85. %token                                  TOK_AFFECT_ET   TOK_AFFECT_OU   /* &= |= */
  86. %token                                  TOK_POINT_INTERROGATION /* ? */
  87. %token                                  TOK_DOUBLE_POINT        /* : */
  88. %token                                  TOK_FAIRE               /* faire */
  89. %token                                  TOK_CROIX               /* x */
  90. %token<texte>                   TOK_TEXTE               /* texte libre */
  91. %token                                  TOK_SUPPR               /* supprimer */
  92.  
  93. %%
  94.  
  95. /* Nous definissons toutes les regles grammaticales de chaque non terminal de notre langage. Par defaut on commence a definir l'axiome, c'est a dire ici le non terminal code. Si nous le definissons pas en premier nous devons le specifier en option dans Bison avec %start */
  96.  
  97. entree:         code{
  98.                                 genere_code($1);
  99.                                 g_node_destroy($1);
  100.                         };
  101.  
  102. bloc_code:      code{
  103.                                 $$=g_node_new((gpointer)BLOC_CODE);
  104.                                 g_node_append($$,$1);
  105.                                 supprime_variable($1);
  106.                         }
  107.  
  108. code:           %empty{$$=g_node_new((gpointer)CODE_VIDE);}
  109.                 |
  110.                 code commentaire{
  111.                         $$=g_node_new((gpointer)SEQUENCE);
  112.                         g_node_append($$,$1);
  113.                         g_node_append($$,$2);
  114.                 }
  115.                 |
  116.                 code instruction{
  117.                         printf("Resultat : C'est une instruction valide !\n\n");
  118.                         $$=g_node_new((gpointer)SEQUENCE);
  119.                         g_node_append($$,$1);
  120.                         g_node_append($$,$2);
  121.                 }
  122.                 |
  123.                 code error{
  124.                         fprintf(stderr,"\tERREUR : Erreur de syntaxe a la ligne %d.\n",lineno);
  125.                         error_syntaxical=true;
  126.                 };
  127.  
  128. commentaire:    TOK_COMMENT{
  129.                                         $$=g_node_new((gpointer)CODE_VIDE);
  130.                                 };
  131.  
  132. instruction:    affectation{
  133.                         printf("\tInstruction type Affectation\n");
  134.                         $$=$1;
  135.                 }
  136.                 |
  137.                 affichage{
  138.                         printf("\tInstruction type Affichage\n");
  139.                         $$=$1;
  140.                 }
  141.                 |
  142.                 condition{
  143.                     printf("Condition si/sinon\n");
  144.                     $$=$1;
  145.                 }
  146.                 |
  147.                 boucle_for{
  148.                         printf("Boucle repetee\n");
  149.                         $$=$1;
  150.                 }
  151.                 |
  152.                 boucle_while{
  153.                         printf("Boucle tant que\n");
  154.                         $$=$1;
  155.                 }
  156.                 |
  157.                 boucle_do_while{
  158.                         printf("Boucle faire tant que\n");
  159.                         $$=$1;
  160.                 }
  161.                 |
  162.                 suppression{
  163.                         printf("\tInstruction type Suppression\n");
  164.                         $$=$1;
  165.                 };
  166.  
  167. variable_arithmetique:  TOK_VARE{
  168.                                 printf("\t\t\tVariable entiere %s\n",$1);
  169.                                 $$=g_node_new((gpointer)VARIABLE);
  170.                                 g_node_append_data($$,strdup($1));
  171.                         };
  172.  
  173. variable_booleenne:     TOK_VARB{
  174.                                 printf("\t\t\tVariable booleenne %s\n",$1);
  175.                                 $$=g_node_new((gpointer)VARIABLE);
  176.                                 g_node_append_data($$,strdup($1));
  177.                         };
  178.  
  179. variable_texte: TOK_VART{
  180.                                 printf("\t\t\tVariable texte %s\n",$1);
  181.                                 $$=g_node_new((gpointer)VARIABLE);
  182.                                 g_node_append_data($$,strdup($1));
  183.                         };
  184.  
  185. condition:      condition_si TOK_FINSTR{
  186.                     printf("\tCondition si\n");
  187.                     $$=g_node_new((gpointer)CONDITION_SI);
  188.                     g_node_append($$,$1);
  189.                 }
  190.                 |
  191.                 condition_si condition_sinon TOK_FINSTR{
  192.                     printf("\tCondition si/sinon\n");
  193.                     $$=g_node_new((gpointer)CONDITION_SI_SINON);
  194.                     g_node_append($$,$1);
  195.                     g_node_append($$,$2);
  196.                 }
  197.                 |
  198.                 TOK_PARG expression_booleenne TOK_PARD TOK_POINT_INTERROGATION bloc_code TOK_DOUBLE_POINT bloc_code TOK_FINSTR{
  199.                         printf("\tCondition si/sinon\n");
  200.                     $$=g_node_new((gpointer)CONDITION_SI_SINON);
  201.                     g_node_append($$,g_node_new((gpointer)SI));
  202.                     g_node_append(g_node_nth_child($$,0),$2);
  203.                     g_node_append(g_node_nth_child($$,0),$5);
  204.                     g_node_append($$,g_node_new((gpointer)SINON));
  205.                     g_node_append(g_node_nth_child($$,1),$7);
  206.  
  207.                 };
  208.  
  209. condition_si:   TOK_SI expression_booleenne TOK_ALORS bloc_code{
  210.                     $$=g_node_new((gpointer)SI);
  211.                     g_node_append($$,$2);
  212.                     g_node_append($$,$4);
  213.                 };
  214.  
  215. condition_sinon:   TOK_SINON bloc_code{
  216.                         $$=g_node_new((gpointer)SINON);
  217.                         g_node_append($$,$2);
  218.                     };
  219.  
  220. boucle_for:             TOK_PARG expression_arithmetique TOK_PARD TOK_CROIX bloc_code TOK_FINSTR{
  221.                                         $$=g_node_new((gpointer)BOUCLE_FOR);
  222.                                         g_node_append($$,$2);
  223.                     g_node_append($$,$5);
  224.                                 };
  225.  
  226. boucle_while:   TOK_PARG expression_booleenne TOK_PARD TOK_POINT_INTERROGATION bloc_code TOK_FINSTR{
  227.                                         $$=g_node_new((gpointer)BOUCLE_WHILE);
  228.                                         g_node_append($$,$2);
  229.                     g_node_append($$,$5);
  230.                                 };
  231.  
  232. boucle_do_while:        TOK_FAIRE bloc_code TOK_POINT_INTERROGATION TOK_PARG expression_booleenne TOK_PARD TOK_FINSTR{
  233.                                                 $$=g_node_new((gpointer)BOUCLE_DO_WHILE);
  234.                                                 g_node_append($$,$2);
  235.                             g_node_append($$,$5);
  236.                                         };
  237.  
  238. affectation:    variable_arithmetique TOK_AFFECT expression_arithmetique TOK_FINSTR{
  239.                         /* $1 est la valeur du premier non terminal. Ici c'est la valeur du non terminal variable. $3 est la valeur du 2nd non terminal. */
  240.                         printf("\t\tAffectation sur la variable\n");
  241.                         Variable* var=g_hash_table_lookup(table_variable,(char*)g_node_nth_child($1,0)->data);
  242.                         if(var==NULL){
  243.                                 /* On cree une Variable et on lui affecte le type que nous connaissons et la valeur */
  244.                                 var=malloc(sizeof(Variable));
  245.                                 if(var!=NULL){
  246.                                         var->type=strdup("entier");
  247.                                         var->value=$3;
  248.                                         /* On l'insere dans la table de hachage (cle: <nom_variable> / valeur: <(type,valeur)>) */
  249.                                         if(g_hash_table_insert(table_variable,g_node_nth_child($1,0)->data,var)){
  250.                                         $$=g_node_new((gpointer)AFFECTATIONE);
  251.                                         g_node_append($$,$1);
  252.                                         g_node_append($$,$3);
  253.                                         }else{
  254.                                             fprintf(stderr,"ERREUR - PROBLEME CREATION VARIABLE !\n");
  255.                                             exit(-1);
  256.                                         }
  257.                                 }else{
  258.                                         fprintf(stderr,"ERREUR - PROBLEME ALLOCATION MEMOIRE VARIABLE !\n");
  259.                                         exit(-1);
  260.                                 }
  261.                         }else{
  262.                                 $$=g_node_new((gpointer)AFFECTATION);
  263.                                 g_node_append($$,$1);
  264.                                 g_node_append($$,$3);
  265.                         }
  266.                 }
  267.                 |
  268.                 variable_arithmetique TOK_AFFECT_PLUS expression_arithmetique TOK_FINSTR{
  269.                         Variable* var=g_hash_table_lookup(table_variable,(char*)g_node_nth_child($1,0)->data);
  270.                         if(var==NULL){
  271.                                 fprintf(stderr,"\tERREUR : Erreur de semantique a la ligne %d. Variable %s jamais declaree !\n",lineno,(char*)g_node_nth_child($1,0)->data);
  272.                                 error_semantical=true;
  273.                         }else{
  274.                                 $$=g_node_new((gpointer)AFFECTATION_PLUS);
  275.                                 g_node_append($$,$1);
  276.                                 g_node_append($$,$3);
  277.                         }
  278.                 }
  279.                 |
  280.                 variable_arithmetique TOK_AFFECT_MOINS expression_arithmetique TOK_FINSTR{
  281.                         Variable* var=g_hash_table_lookup(table_variable,(char*)g_node_nth_child($1,0)->data);
  282.                         if(var==NULL){
  283.                                 fprintf(stderr,"\tERREUR : Erreur de semantique a la ligne %d. Variable %s jamais declaree !\n",lineno,(char*)g_node_nth_child($1,0)->data);
  284.                                 error_semantical=true;
  285.                         }else{
  286.                                 $$=g_node_new((gpointer)AFFECTATION_MOINS);
  287.                                 g_node_append($$,$1);
  288.                                 g_node_append($$,$3);
  289.                         }
  290.                 }
  291.                 |
  292.                 variable_arithmetique TOK_AFFECT_MUL expression_arithmetique TOK_FINSTR{
  293.                         Variable* var=g_hash_table_lookup(table_variable,(char*)g_node_nth_child($1,0)->data);
  294.                         if(var==NULL){
  295.                                 fprintf(stderr,"\tERREUR : Erreur de semantique a la ligne %d. Variable %s jamais declaree !\n",lineno,(char*)g_node_nth_child($1,0)->data);
  296.                                 error_semantical=true;
  297.                         }else{
  298.                                 $$=g_node_new((gpointer)AFFECTATION_MUL);
  299.                                 g_node_append($$,$1);
  300.                                 g_node_append($$,$3);
  301.                         }
  302.                 }
  303.                 |
  304.                 variable_arithmetique TOK_AFFECT_DIV expression_arithmetique TOK_FINSTR{
  305.                         Variable* var=g_hash_table_lookup(table_variable,(char*)g_node_nth_child($1,0)->data);
  306.                         if(var==NULL){
  307.                                 fprintf(stderr,"\tERREUR : Erreur de semantique a la ligne %d. Variable %s jamais declaree !\n",lineno,(char*)g_node_nth_child($1,0)->data);
  308.                                 error_semantical=true;
  309.                         }else{
  310.                                 $$=g_node_new((gpointer)AFFECTATION_DIV);
  311.                                 g_node_append($$,$1);
  312.                                 g_node_append($$,$3);
  313.                         }
  314.                 }
  315.                 |
  316.                 variable_arithmetique TOK_AFFECT_MOD expression_arithmetique TOK_FINSTR{
  317.                         Variable* var=g_hash_table_lookup(table_variable,(char*)g_node_nth_child($1,0)->data);
  318.                         if(var==NULL){
  319.                                 fprintf(stderr,"\tERREUR : Erreur de semantique a la ligne %d. Variable %s jamais declaree !\n",lineno,(char*)g_node_nth_child($1,0)->data);
  320.                                 error_semantical=true;
  321.                         }else{
  322.                                 $$=g_node_new((gpointer)AFFECTATION_MOD);
  323.                                 g_node_append($$,$1);
  324.                                 g_node_append($$,$3);
  325.                         }
  326.                 }
  327.                 |
  328.                 variable_arithmetique TOK_INCREMENTATION TOK_FINSTR{
  329.                         printf("\t\t\tIncrementation de +1 sur la variable\n");
  330.                     $$=g_node_new((gpointer)AFFECTATION_INCR);
  331.                     g_node_append($$,$1);
  332.                 }
  333.                 |
  334.                 variable_arithmetique TOK_DECREMENTATION TOK_FINSTR{
  335.                         printf("\t\t\tDecrementation de -1 sur la variable\n");
  336.                     $$=g_node_new((gpointer)AFFECTATION_DECR);
  337.                     g_node_append($$,$1);
  338.                 }
  339.                 |
  340.                 variable_booleenne TOK_AFFECT expression_booleenne TOK_FINSTR{
  341.                         /* $1 est la valeur du premier non terminal. Ici c'est la valeur du non terminal variable. $3 est la valeur du 2nd non terminal. */
  342.                         printf("\t\tAffectation sur la variable\n");
  343.                         Variable* var=g_hash_table_lookup(table_variable,(char*)g_node_nth_child($1,0)->data);
  344.                         if(var==NULL){
  345.                                 /* On cree une Variable et on lui affecte le type que nous connaissons et la valeur */
  346.                                 var=malloc(sizeof(Variable));
  347.                                 if(var!=NULL){
  348.                                         var->type=strdup("booleen");
  349.                                         var->value=$3;
  350.                                         /* On l'insere dans la table de hachage (cle: <nom_variable> / valeur: <(type,valeur)>) */
  351.                                         if(g_hash_table_insert(table_variable,g_node_nth_child($1,0)->data,var)){
  352.                                         $$=g_node_new((gpointer)AFFECTATIONB);
  353.                                         g_node_append($$,$1);
  354.                                         g_node_append($$,$3);
  355.                                         }else{
  356.                                             fprintf(stderr,"ERREUR - PROBLEME CREATION VARIABLE !\n");
  357.                                             exit(-1);
  358.                                         }
  359.                                 }else{
  360.                                         fprintf(stderr,"ERREUR - PROBLEME ALLOCATION MEMOIRE VARIABLE !\n");
  361.                                         exit(-1);
  362.                                 }
  363.                         }else{
  364.                                 $$=g_node_new((gpointer)AFFECTATION);
  365.                                 g_node_append($$,$1);
  366.                                 g_node_append($$,$3);
  367.                         }
  368.                 }
  369.                 |
  370.                 variable_booleenne TOK_AFFECT_ET expression_booleenne TOK_FINSTR{
  371.                         Variable* var=g_hash_table_lookup(table_variable,(char*)g_node_nth_child($1,0)->data);
  372.                         if(var==NULL){
  373.                                 fprintf(stderr,"\tERREUR : Erreur de semantique a la ligne %d. Variable %s jamais declaree !\n",lineno,(char*)g_node_nth_child($1,0)->data);
  374.                                 error_semantical=true;
  375.                         }else{
  376.                                 $$=g_node_new((gpointer)AFFECTATION_ET);
  377.                                 g_node_append($$,$1);
  378.                                 g_node_append($$,$3);
  379.                         }
  380.                 }
  381.                 |
  382.                 variable_booleenne TOK_AFFECT_OU expression_booleenne TOK_FINSTR{
  383.                         Variable* var=g_hash_table_lookup(table_variable,(char*)g_node_nth_child($1,0)->data);
  384.                         if(var==NULL){
  385.                                 fprintf(stderr,"\tERREUR : Erreur de semantique a la ligne %d. Variable %s jamais declaree !\n",lineno,(char*)g_node_nth_child($1,0)->data);
  386.                                 error_semantical=true;
  387.                         }else{
  388.                                 $$=g_node_new((gpointer)AFFECTATION_OU);
  389.                                 g_node_append($$,$1);
  390.                                 g_node_append($$,$3);
  391.                         }
  392.                 }
  393.                 |
  394.                 variable_texte TOK_AFFECT expression_texte TOK_FINSTR{
  395.                         /* $1 est la valeur du premier non terminal. Ici c'est la valeur du non terminal variable. $3 est la valeur du 2nd non terminal. */
  396.                         printf("\t\tAffectation sur la variable\n");
  397.                         Variable* var=g_hash_table_lookup(table_variable,(char*)g_node_nth_child($1,0)->data);
  398.                         if(var==NULL){
  399.                                 /* On cree une Variable et on lui affecte le type que nous connaissons et la valeur */
  400.                                 var=malloc(sizeof(Variable));
  401.                                 if(var!=NULL){
  402.                                         var->type=strdup("texte");
  403.                                         var->value=$3;
  404.                                         /* On l'insere dans la table de hachage (cle: <nom_variable> / valeur: <(type,valeur)>) */
  405.                                         if(g_hash_table_insert(table_variable,g_node_nth_child($1,0)->data,var)){
  406.                                         $$=g_node_new((gpointer)AFFECTATIONNT);
  407.                                         g_node_append($$,$1);
  408.                                         g_node_append($$,$3);
  409.                                         }else{
  410.                                             fprintf(stderr,"ERREUR - PROBLEME CREATION VARIABLE !\n");
  411.                                             exit(-1);
  412.                                         }
  413.                                 }else{
  414.                                         fprintf(stderr,"ERREUR - PROBLEME ALLOCATION MEMOIRE VARIABLE !\n");
  415.                                         exit(-1);
  416.                                 }
  417.                         }else{
  418.                                 $$=g_node_new((gpointer)AFFECTATIONT);
  419.                                 g_node_append($$,$1);
  420.                                 g_node_append($$,$3);
  421.                         }
  422.                 };
  423.  
  424. affichage:      TOK_AFFICHER expression_arithmetique TOK_FINSTR{
  425.                         printf("\t\tAffichage de la valeur de l'expression arithmetique\n");
  426.                         $$=g_node_new((gpointer)AFFICHAGEE);
  427.                         g_node_append($$,$2);
  428.                 }
  429.                 |
  430.                 TOK_AFFICHER expression_booleenne TOK_FINSTR{
  431.                         printf("\t\tAffichage de la valeur de l'expression booleenne\n");
  432.                         $$=g_node_new((gpointer)AFFICHAGEB);
  433.                         g_node_append($$,$2);
  434.                 }
  435.                 |
  436.                 TOK_AFFICHER expression_texte TOK_FINSTR{
  437.                         printf("\t\tAffichage de la valeur de l'expression textuelle\n");
  438.                         $$=g_node_new((gpointer)AFFICHAGET);
  439.                         g_node_append($$,$2);
  440.                 };
  441.  
  442. suppression:    TOK_SUPPR variable_texte TOK_FINSTR{
  443.                                         /* On recupere un pointeur vers la structure Variable */
  444.                                         Variable* var=g_hash_table_lookup(table_variable,(char*)g_node_nth_child($2,0)->data);
  445.                                         /* Si on a trouve un pointeur valable */
  446.                                         if(var!=NULL){
  447.                                                 /* On verifie que le type est bien un entier - Inutile car impose a l'analyse syntaxique */
  448.                                                 if(strcmp(var->type,"texte")==0){
  449.                                                         printf("\t\t\tSuppression de la variable texte\n");
  450.                                                         $$=g_node_new((gpointer)SUPPRESSIONT);
  451.                                                         g_node_append($$,$2);
  452.                                                         /* suppression de la variable dans la table de hachage */
  453.                                                         printf("suppresion variable %s\n",(char*)g_node_nth_child($2,0)->data);
  454.                                                     if(g_hash_table_remove(table_variable,(char*)g_node_nth_child($2,0)->data)){
  455.                                                         printf("Variable supprimee !\n");
  456.                                                     }else{
  457.                                                         fprintf(stderr,"ERREUR - PROBLEME DE SUPPRESSION VARIABLE !\n");
  458.                                                         exit(-1);
  459.                                                     }
  460.                                                 }else{
  461.                                                         fprintf(stderr,"\tERREUR : Erreur de semantique a la ligne %d. Type incompatible !\n",lineno);
  462.                                                         error_semantical=true;
  463.                                                 }
  464.                                         /* Sinon on conclue que la variable n'a jamais ete declaree car absente de la table */
  465.                                         }else{
  466.                                                 fprintf(stderr,"\tERREUR : Erreur de semantique a la ligne %d. Variable %s jamais declaree !\n",lineno,(char*)g_node_nth_child($2,0)->data);
  467.                                                 error_semantical=true;
  468.                                         }
  469.                                 };
  470.  
  471. expression_arithmetique:        TOK_NOMBRE{
  472.                                         printf("\t\t\tNombre : %ld\n",$1);
  473.                                         /* Comme le token TOK_NOMBRE est de type entier et que on a type expression_arithmetique comme du texte, il nous faut convertir la valeur en texte. */
  474.                                         int length=snprintf(NULL,0,"%ld",$1);
  475.                                         char* str=malloc(length+1);
  476.                                         snprintf(str,length+1,"%ld",$1);
  477.                                         $$=g_node_new((gpointer)ENTIER);
  478.                                         g_node_append_data($$,strdup(str));
  479.                                         free(str);
  480.                                 }
  481.                                 |
  482.                                 variable_arithmetique{
  483.                                         /* On recupere un pointeur vers la structure Variable */
  484.                                         Variable* var=g_hash_table_lookup(table_variable,(char*)g_node_nth_child($1,0)->data);
  485.                                         /* Si on a trouve un pointeur valable */
  486.                                         if(var!=NULL){
  487.                                                 /* On verifie que le type est bien un entier - Inutile car impose a l'analyse syntaxique */
  488.                                                 if(strcmp(var->type,"entier")==0){
  489.                                                         $$=$1;
  490.                                                 }else{
  491.                                                         fprintf(stderr,"\tERREUR : Erreur de semantique a la ligne %d. Type incompatible (entier attendu - valeur : %s) !\n",lineno,(char*)g_node_nth_child($1,0)->data);
  492.                                                         error_semantical=true;
  493.                                                 }
  494.                                         /* Sinon on conclue que la variable n'a jamais ete declaree car absente de la table */
  495.                                         }else{
  496.                                                 fprintf(stderr,"\tERREUR : Erreur de semantique a la ligne %d. Variable %s jamais declaree !\n",lineno,(char*)g_node_nth_child($1,0)->data);
  497.                                                 error_semantical=true;
  498.                                         }
  499.                                 }
  500.                                 |
  501.                                 addition{
  502.                                         $$=$1;
  503.                                 }
  504.                                 |
  505.                                 soustraction{
  506.                                         $$=$1;
  507.                                 }
  508.                                 |
  509.                                 multiplication{
  510.                                         $$=$1;
  511.                                 }
  512.                                 |
  513.                                 division{
  514.                                         $$=$1;
  515.                                 }
  516.                                 |
  517.                                 modulo{
  518.                                         $$=$1;
  519.                                 }
  520.                                 |
  521.                                 TOK_PLUS expression_arithmetique{
  522.                                     $$=$2;
  523.                                 }
  524.                                 |
  525.                                 expression_arithmetique TOK_INCREMENTATION{
  526.                                         printf("\t\t\tIncrementation de +1\n");
  527.                                     $$=g_node_new((gpointer)INCREMENTATION);
  528.                                     g_node_append($$,$1);
  529.                                 }
  530.                                 |
  531.                                 expression_arithmetique TOK_DECREMENTATION{
  532.                                         printf("\t\t\tDecrementation de -1\n");
  533.                                     $$=g_node_new((gpointer)DECREMENTATION);
  534.                                     g_node_append($$,$1);
  535.                                 }
  536.                                 |
  537.                                 TOK_MOINS expression_arithmetique{
  538.                                     printf("\t\t\tOperation unaire negation\n");
  539.                                     $$=g_node_new((gpointer)NEGATIF);
  540.                                         g_node_append($$,$2);
  541.                                 }
  542.                                 |
  543.                                 TOK_PARG expression_arithmetique TOK_PARD{
  544.                                         printf("\t\t\tC'est une expression artihmetique entre parentheses\n");
  545.                                         $$=g_node_new((gpointer)EXPR_PAR);
  546.                                         g_node_append($$,$2);
  547.                                 };
  548.  
  549. expression_booleenne:           TOK_VRAI{
  550.                                         printf("\t\t\tBooleen Vrai\n");
  551.                                         $$=g_node_new((gpointer)VRAI);
  552.                                 }
  553.                                 |
  554.                                 TOK_FAUX{
  555.                                         printf("\t\t\tBooleen Faux\n");
  556.                                         $$=g_node_new((gpointer)FAUX);
  557.                                 }
  558.                                 |
  559.                                 variable_booleenne{
  560.                                         /* On recupere un pointeur vers la structure Variable */
  561.                                         Variable* var=g_hash_table_lookup(table_variable,(char*)g_node_nth_child($1,0)->data);
  562.                                         /* Si on a trouve un pointeur valable */
  563.                                         if(var!=NULL){
  564.                                                 /* On verifie que le type est bien un entier - Inutile car impose a l'analyse syntaxique */
  565.                                                 if(strcmp(var->type,"booleen")==0){
  566.                                                         $$=$1;
  567.                                                 }else{
  568.                                                         fprintf(stderr,"\tERREUR : Erreur de semantique a la ligne %d. Type incompatible (booleen attendu - valeur : %s) !\n",lineno,(char*)g_node_nth_child($1,0)->data);
  569.                                                         error_semantical=true;
  570.                                                 }
  571.                                         /* Sinon on conclue que la variable n'a jamais ete declaree car absente de la table */
  572.                                         }else{
  573.                                                 fprintf(stderr,"\tERREUR : Erreur de semantique a la ligne %d. Variable %s jamais declaree !\n",lineno,(char*)g_node_nth_child($1,0)->data);
  574.                                                 error_semantical=true;
  575.                                         }
  576.                                 }
  577.                                 |
  578.                                 TOK_NON expression_booleenne{
  579.                                         printf("\t\t\tOperation booleenne Non\n");
  580.                                         $$=g_node_new((gpointer)NON);
  581.                                         g_node_append($$,$2);
  582.                                 }
  583.                                 |
  584.                                 expression_booleenne TOK_ET expression_booleenne{
  585.                                         printf("\t\t\tOperation booleenne Et\n");
  586.                                         $$=g_node_new((gpointer)ET);
  587.                                         g_node_append($$,$1);
  588.                                         g_node_append($$,$3);
  589.                                 }
  590.                                 |
  591.                                 expression_booleenne TOK_OU expression_booleenne{
  592.                                         printf("\t\t\tOperation booleenne Ou\n");
  593.                                         $$=g_node_new((gpointer)OU);
  594.                                         g_node_append($$,$1);
  595.                                         g_node_append($$,$3);
  596.                                 }
  597.                                 |
  598.                                 TOK_PARG expression_booleenne TOK_PARD{
  599.                                         printf("\t\t\tC'est une expression booleenne entre parentheses\n");
  600.                                         $$=g_node_new((gpointer)EXPR_PAR);
  601.                                         g_node_append($$,$2);
  602.                                 }
  603.                                 |
  604.                                 expression_booleenne TOK_EQU expression_booleenne{
  605.                                         printf("\t\t\tOperateur d'egalite ==\n");
  606.                                         $$=g_node_new((gpointer)EGALITE);
  607.                                         g_node_append($$,$1);
  608.                                         g_node_append($$,$3);
  609.                                 }
  610.                                 |
  611.                                 expression_booleenne TOK_DIFF expression_booleenne{
  612.                                         printf("\t\t\tOperateur d'inegalite !=\n");
  613.                                         $$=g_node_new((gpointer)DIFFERENT);
  614.                                         g_node_append($$,$1);
  615.                                         g_node_append($$,$3);
  616.                                 }
  617.                                 |
  618.                                 expression_arithmetique TOK_EQU expression_arithmetique{
  619.                                         printf("\t\t\tOperateur d'egalite ==\n");
  620.                                         $$=g_node_new((gpointer)EGALITE);
  621.                                         g_node_append($$,$1);
  622.                                         g_node_append($$,$3);
  623.                                 }
  624.                                 |
  625.                                 expression_arithmetique TOK_DIFF expression_arithmetique{
  626.                                         printf("\t\t\tOperateur d'inegalite !=\n");
  627.                                         $$=g_node_new((gpointer)DIFFERENT);
  628.                                         g_node_append($$,$1);
  629.                                         g_node_append($$,$3);
  630.                                 }
  631.                                 |
  632.                                 expression_arithmetique TOK_SUP expression_arithmetique{
  633.                                         printf("\t\t\tOperateur de superiorite >\n");
  634.                                         $$=g_node_new((gpointer)SUPERIEUR);
  635.                                         g_node_append($$,$1);
  636.                                         g_node_append($$,$3);
  637.                                 }
  638.                                 |
  639.                                 expression_arithmetique TOK_INF expression_arithmetique{
  640.                                         printf("\t\t\tOperateur d'inferiorite <\n");
  641.                                         $$=g_node_new((gpointer)INFERIEUR);
  642.                                         g_node_append($$,$1);
  643.                                         g_node_append($$,$3);
  644.                                 }
  645.                                 |
  646.                                 expression_arithmetique TOK_SUPEQU expression_arithmetique{
  647.                                         printf("\t\t\tOperateur >=\n");
  648.                                         $$=g_node_new((gpointer)SUPEGAL);
  649.                                         g_node_append($$,$1);
  650.                                         g_node_append($$,$3);
  651.                                 }
  652.                                 |
  653.                                 expression_arithmetique TOK_INFEQU expression_arithmetique{
  654.                                         printf("\t\t\tOperateur <=\n");
  655.                                         $$=g_node_new((gpointer)INFEGAL);
  656.                                         g_node_append($$,$1);
  657.                                         g_node_append($$,$3);
  658.                                 }
  659.                                 |
  660.                 expression_arithmetique TOK_IN TOK_CROG expression_arithmetique TOK_FINSTR expression_arithmetique TOK_CROD{
  661.                                         printf("\t\t\tOperateur dans\n");
  662.                                         $$=g_node_new((gpointer)DANSII);
  663.                                         g_node_append($$,$1);
  664.                                         g_node_append($$,$4);
  665.                                         g_node_append($$,$6);
  666.                                 }
  667.                                 |
  668.                 expression_arithmetique TOK_IN TOK_CROD expression_arithmetique TOK_FINSTR expression_arithmetique TOK_CROD{
  669.                                         printf("\t\t\tOperateur dans\n");
  670.                                         $$=g_node_new((gpointer)DANSEI);
  671.                                         g_node_append($$,$1);
  672.                                         g_node_append($$,$4);
  673.                                         g_node_append($$,$6);
  674.                                 }
  675.                                 |
  676.                 expression_arithmetique TOK_IN TOK_CROG expression_arithmetique TOK_FINSTR expression_arithmetique TOK_CROG{
  677.                                         printf("\t\t\tOperateur dans\n");
  678.                                         $$=g_node_new((gpointer)DANSIE);
  679.                                         g_node_append($$,$1);
  680.                                         g_node_append($$,$4);
  681.                                         g_node_append($$,$6);
  682.                                 }
  683.                                 |
  684.                 expression_arithmetique TOK_IN TOK_CROD expression_arithmetique TOK_FINSTR expression_arithmetique TOK_CROG{
  685.                                         printf("\t\t\tOperateur dans\n");
  686.                                         $$=g_node_new((gpointer)DANSEE);
  687.                                         g_node_append($$,$1);
  688.                                         g_node_append($$,$4);
  689.                                         g_node_append($$,$6);
  690.                                 };
  691.  
  692. expression_texte:       TOK_TEXTE{
  693.                                                 printf("\t\t\tTexte %s\n",$1);
  694.                                                 $$=g_node_new((gpointer)TEXTE);
  695.                                                 g_node_append_data($$,strdup($1));
  696.                                         }
  697.                                         |
  698.                                         variable_texte{
  699.                                                 /* On recupere un pointeur vers la structure Variable */
  700.                                                 Variable* var=g_hash_table_lookup(table_variable,(char*)g_node_nth_child($1,0)->data);
  701.                                                 /* Si on a trouve un pointeur valable */
  702.                                                 if(var!=NULL){
  703.                                                         /* On verifie que le type est bien un entier - Inutile car impose a l'analyse syntaxique */
  704.                                                         if(strcmp(var->type,"texte")==0){
  705.                                                                 $$=$1;
  706.                                                         }else{
  707.                                                                 fprintf(stderr,"\tERREUR : Erreur de semantique a la ligne %d. Type incompatible (texte attendu - valeur : %s) !\n",lineno,(char*)g_node_nth_child($1,0)->data);
  708.                                                                 error_semantical=true;
  709.                                                         }
  710.                                                 /* Sinon on conclue que la variable n'a jamais ete declaree car absente de la table */
  711.                                                 }else{
  712.                                                         fprintf(stderr,"\tERREUR : Erreur de semantique a la ligne %d. Variable %s jamais declaree !\n",lineno,(char*)g_node_nth_child($1,0)->data);
  713.                                                         error_semantical=true;
  714.                                                 }
  715.                                         };
  716.  
  717. addition:       expression_arithmetique TOK_PLUS expression_arithmetique{
  718.                         printf("\t\t\tAddition\n");
  719.                         $$=g_node_new((gpointer)ADDITION);
  720.                         g_node_append($$,$1);
  721.                         g_node_append($$,$3);
  722.                 };
  723.  
  724. soustraction:   expression_arithmetique TOK_MOINS expression_arithmetique{
  725.                                 printf("\t\t\tSoustraction\n");
  726.                                 $$=g_node_new((gpointer)SOUSTRACTION);
  727.                                 g_node_append($$,$1);
  728.                                 g_node_append($$,$3);
  729.                         };
  730.  
  731. multiplication: expression_arithmetique TOK_MUL expression_arithmetique{
  732.                         printf("\t\t\tMultiplication\n");
  733.                         $$=g_node_new((gpointer)MULTIPLICATION);
  734.                         g_node_append($$,$1);
  735.                         g_node_append($$,$3);
  736.                 };
  737.  
  738. division:       expression_arithmetique TOK_DIV expression_arithmetique{
  739.                                 printf("\t\t\tDivision\n");
  740.                                 $$=g_node_new((gpointer)DIVISION);
  741.                                 g_node_append($$,$1);
  742.                                 g_node_append($$,$3);
  743.                         };
  744.  
  745. modulo:         expression_arithmetique TOK_MOD expression_arithmetique{
  746.                                 printf("\t\t\tModulo\n");
  747.                                 $$=g_node_new((gpointer)MODULO);
  748.                                 g_node_append($$,$1);
  749.                                 g_node_append($$,$3);
  750.                         };
  751.  
  752. %%
  753.  
  754. /* Dans la fonction main on appelle bien la routine yyparse() qui sera genere par Bison. Cette routine appellera yylex() de notre analyseur lexical. */
  755.  
  756. int main(int argc, char** argv){
  757.         /* recuperation du nom de fichier d'entree (langage Simple) donne en parametre */
  758.         char* fichier_entree=strdup(argv[1]);
  759.         /* ouverture du fichier en lecture dans le flux d'entree stdin */
  760.         stdin=fopen(fichier_entree,"r");
  761.         /* creation fichier de sortie (langage C) */
  762.         char* fichier_sortie=strdup(argv[1]);
  763.         /* remplace l'extension par .c */
  764.         strcpy(rindex(fichier_sortie, '.'), ".c");
  765.         /* ouvre le fichier cree en ecriture */
  766.         fichier=fopen(fichier_sortie, "w");
  767.         /* Creation de la table de hachage */
  768.         table_variable=g_hash_table_new_full(g_str_hash,g_str_equal,NULL,free);
  769.         printf("Debut de l'analyse syntaxique :\n");
  770.         debut_code();
  771.         yyparse();
  772.         fin_code();
  773.         printf("Fin de l'analyse !\n");
  774.         printf("Resultat :\n");
  775.         if(error_lexical){
  776.                 printf("\t-- Echec : Certains lexemes ne font pas partie du lexique du langage ! --\n");
  777.                 printf("\t-- Echec a l'analyse lexicale --\n");
  778.         }
  779.         else{
  780.                 printf("\t-- Succes a l'analyse lexicale ! --\n");
  781.         }
  782.         if(error_syntaxical){
  783.                 printf("\t-- Echec : Certaines phrases sont syntaxiquement incorrectes ! --\n");
  784.                 printf("\t-- Echec a l'analyse syntaxique --\n");
  785.         }
  786.         else{
  787.                 printf("\t-- Succes a l'analyse syntaxique ! --\n");
  788.                 if(error_semantical){
  789.                         printf("\t-- Echec : Certaines phrases sont semantiquement incorrectes ! --\n");
  790.                         printf("\t-- Echec a l'analyse semantique --\n");
  791.                 }
  792.                 else{
  793.                         printf("\t-- Succes a l'analyse semantique ! --\n");
  794.                 }
  795.         }
  796.         /* Suppression du fichier genere si erreurs analyse */
  797.         if(error_lexical||error_syntaxical||error_semantical){
  798.                 remove(fichier_sortie);
  799.                 printf("ECHEC GENERATION CODE !\n");
  800.         }
  801.         else{
  802.                 printf("Le fichier \"%s\" a ete genere !\n",fichier_sortie);
  803.         }
  804.         /* Fermeture des flux */
  805.         fclose(fichier);
  806.         fclose(stdin);
  807.         /* Liberation memoire */
  808.         free(fichier_entree);
  809.         free(fichier_sortie);
  810.         g_hash_table_destroy(table_variable);
  811.         return EXIT_SUCCESS;
  812. }
  813.  
  814. void yyerror(char *s) {
  815.         fprintf(stderr, "Erreur de syntaxe a la ligne %d: %s\n", lineno, s);
  816. }
  817.  
  818. /* Cette fonction supprime dans la table de hachage toutes les variables declarees pour la premiere fois dans l'arbre syntaxique donne en parametre */
  819.  
  820. void supprime_variable(GNode* ast){
  821.     /* si l'element est n'est pas NULL et que ce n'est pas une feuille et que ce n'est pas un type bloc code (pour eviter de supprimer une variable deja suprimee) */
  822.     if(ast&&!G_NODE_IS_LEAF(ast)&&(long)ast->data!=BLOC_CODE){
  823.         /* si le noeud est de type declaration */
  824.         if((long)ast->data==AFFECTATIONB||(long)ast->data==AFFECTATIONE||(long)ast->data==AFFECTATIONT){
  825.             /* suppression de la variable dans la table de hachage */
  826.             if(g_hash_table_remove(table_variable,(char*)g_node_nth_child(g_node_nth_child(ast,0),0)->data)){
  827.                 printf("Variable supprimee !\n");
  828.             }else{
  829.                 fprintf(stderr,"ERREUR - PROBLEME DE SUPPRESSION VARIABLE !\n");
  830.                 exit(-1);
  831.             }
  832.         /* sinon on continue de parcourir l'arbre */
  833.         }else{
  834.             int nb_enfant;
  835.             for(nb_enfant=0;nb_enfant<=g_node_n_children(ast);nb_enfant++){
  836.                 supprime_variable(g_node_nth_child(ast,nb_enfant));
  837.             }
  838.         }
  839.     }
  840. }

Et pour finir ? Le générateur de code :

generation_code.c
  1. #include "simple.h"
  2.  
  3. unsigned int nb_boucle=0;
  4.  
  5. void debut_code(){
  6.         fprintf(fichier, "/* FICHIER GENERE PAR LE COMPILATEUR SIMPLE */\n\n");
  7.         fprintf(fichier, "#include<stdlib.h>\n#include<stdbool.h>\n#include<stdio.h>\n#include<string.h>\n\n");
  8.         fprintf(fichier, "int main(void){\n");
  9. }
  10.  
  11. void fin_code(){
  12.         fprintf(fichier, "\treturn EXIT_SUCCESS;\n");
  13.         fprintf(fichier, "}\n");
  14. }
  15.  
  16. void genere_code(GNode* ast){
  17.         if(ast){
  18.                 switch((long)ast->data){
  19.                         case SEQUENCE:
  20.                                 genere_code(g_node_nth_child(ast,0));
  21.                                 genere_code(g_node_nth_child(ast,1));
  22.                                 break;
  23.                         case VARIABLE:
  24.                                 fprintf(fichier,"%s",(char*)g_node_nth_child(ast,0)->data);
  25.                                 break;
  26.                         case AFFECTATIONE:
  27.                                 fprintf(fichier,"\tlong ");
  28.                                 genere_code(g_node_nth_child(ast,0));
  29.                                 fprintf(fichier,"=");
  30.                                 genere_code(g_node_nth_child(ast,1));
  31.                                 fprintf(fichier,";\n");
  32.                                 break;
  33.                         case AFFECTATIONB:
  34.                                 fprintf(fichier,"\tbool ");
  35.                                 genere_code(g_node_nth_child(ast,0));
  36.                                 fprintf(fichier,"=");
  37.                                 genere_code(g_node_nth_child(ast,1));
  38.                                 fprintf(fichier,";\n");
  39.                                 break;
  40.                         case AFFECTATION:
  41.                                 fprintf(fichier,"\t");
  42.                                 genere_code(g_node_nth_child(ast,0));
  43.                                 fprintf(fichier,"=");
  44.                                 genere_code(g_node_nth_child(ast,1));
  45.                                 fprintf(fichier,";\n");
  46.                                 break;
  47.                         case AFFECTATION_PLUS:
  48.                                 fprintf(fichier,"\t");
  49.                                 genere_code(g_node_nth_child(ast,0));
  50.                                 fprintf(fichier,"+=");
  51.                                 genere_code(g_node_nth_child(ast,1));
  52.                                 fprintf(fichier,";\n");
  53.                                 break;
  54.                         case AFFECTATION_MOINS:
  55.                                 fprintf(fichier,"\t");
  56.                                 genere_code(g_node_nth_child(ast,0));
  57.                                 fprintf(fichier,"-=");
  58.                                 genere_code(g_node_nth_child(ast,1));
  59.                                 fprintf(fichier,";\n");
  60.                                 break;
  61.                         case AFFECTATION_MUL:
  62.                                 fprintf(fichier,"\t");
  63.                                 genere_code(g_node_nth_child(ast,0));
  64.                                 fprintf(fichier,"*=");
  65.                                 genere_code(g_node_nth_child(ast,1));
  66.                                 fprintf(fichier,";\n");
  67.                                 break;
  68.                         case AFFECTATION_DIV:
  69.                                 fprintf(fichier,"\t");
  70.                                 genere_code(g_node_nth_child(ast,0));
  71.                                 fprintf(fichier,"/=");
  72.                                 genere_code(g_node_nth_child(ast,1));
  73.                                 fprintf(fichier,";\n");
  74.                                 break;
  75.                         case AFFECTATION_MOD:
  76.                                 fprintf(fichier,"\t");
  77.                                 genere_code(g_node_nth_child(ast,0));
  78.                                 fprintf(fichier,"%%=");
  79.                                 genere_code(g_node_nth_child(ast,1));
  80.                                 fprintf(fichier,";\n");
  81.                                 break;
  82.                         case AFFECTATION_ET:
  83.                                 fprintf(fichier,"\t");
  84.                                 genere_code(g_node_nth_child(ast,0));
  85.                                 fprintf(fichier,"&=");
  86.                                 genere_code(g_node_nth_child(ast,1));
  87.                                 fprintf(fichier,";\n");
  88.                                 break;
  89.                         case AFFECTATION_OU:
  90.                                 fprintf(fichier,"\t");
  91.                                 genere_code(g_node_nth_child(ast,0));
  92.                                 fprintf(fichier,"|=");
  93.                                 genere_code(g_node_nth_child(ast,1));
  94.                                 fprintf(fichier,";\n");
  95.                                 break;
  96.                         case AFFECTATION_INCR:
  97.                                 fprintf(fichier,"\t");
  98.                                 genere_code(g_node_nth_child(ast,0));
  99.                                 fprintf(fichier,"++;\n");
  100.                                 break;
  101.                         case AFFECTATION_DECR:
  102.                                 fprintf(fichier,"\t");
  103.                                 genere_code(g_node_nth_child(ast,0));
  104.                                 fprintf(fichier,"--;\n");
  105.                                 break;
  106.                         case AFFICHAGEE:
  107.                                 fprintf(fichier,"\tprintf(\"%%ld\",");
  108.                                 genere_code(g_node_nth_child(ast,0));
  109.                                 fprintf(fichier,");\n");
  110.                                 break;
  111.                         case AFFICHAGEB:
  112.                                 fprintf(fichier,"\tprintf(\"%%s\",");
  113.                                 genere_code(g_node_nth_child(ast,0));
  114.                                 fprintf(fichier,"?\"vrai\":\"faux\");\n");
  115.                                 break;
  116.                         case ENTIER:
  117.                                 fprintf(fichier,"%s",(char*)g_node_nth_child(ast,0)->data);
  118.                                 break;
  119.                         case ADDITION:
  120.                                 genere_code(g_node_nth_child(ast,0));
  121.                                 fprintf(fichier,"+");
  122.                                 genere_code(g_node_nth_child(ast,1));
  123.                                 break;
  124.                         case SOUSTRACTION:
  125.                                 genere_code(g_node_nth_child(ast,0));
  126.                                 fprintf(fichier,"-");
  127.                                 genere_code(g_node_nth_child(ast,1));
  128.                                 break;
  129.                         case MULTIPLICATION:
  130.                                 genere_code(g_node_nth_child(ast,0));
  131.                                 fprintf(fichier,"*");
  132.                                 genere_code(g_node_nth_child(ast,1));
  133.                                 break;
  134.                         case DIVISION:
  135.                                 genere_code(g_node_nth_child(ast,0));
  136.                                 fprintf(fichier,"/");
  137.                                 genere_code(g_node_nth_child(ast,1));
  138.                                 break;
  139.                         case MODULO:
  140.                                 genere_code(g_node_nth_child(ast,0));
  141.                                 fprintf(fichier,"%%");
  142.                                 genere_code(g_node_nth_child(ast,1));
  143.                                 break;
  144.                         case INCREMENTATION:
  145.                                 genere_code(g_node_nth_child(ast,0));
  146.                                 fprintf(fichier,"+1");
  147.                                 break;
  148.                         case DECREMENTATION:
  149.                                 genere_code(g_node_nth_child(ast,0));
  150.                                 fprintf(fichier,"-1");
  151.                                 break;
  152.                         case VRAI:
  153.                                 fprintf(fichier,"true");
  154.                                 break;
  155.                         case FAUX:
  156.                                 fprintf(fichier,"false");
  157.                                 break;
  158.                         case ET:
  159.                                 genere_code(g_node_nth_child(ast,0));
  160.                                 fprintf(fichier,"&&");
  161.                                 genere_code(g_node_nth_child(ast,1));
  162.                                 break;
  163.                         case OU:
  164.                                 genere_code(g_node_nth_child(ast,0));
  165.                                 fprintf(fichier,"||");
  166.                                 genere_code(g_node_nth_child(ast,1));
  167.                                 break;
  168.                         case NON:
  169.                                 fprintf(fichier,"!");
  170.                                 genere_code(g_node_nth_child(ast,0));
  171.                                 break;
  172.                         case EXPR_PAR:
  173.                                 fprintf(fichier,"(");
  174.                                 genere_code(g_node_nth_child(ast,0));
  175.                                 fprintf(fichier,")");
  176.                                 break;
  177.                         case EGALITE:
  178.                                 genere_code(g_node_nth_child(ast,0));
  179.                                 fprintf(fichier,"==");
  180.                                 genere_code(g_node_nth_child(ast,1));
  181.                                 break;
  182.                         case DIFFERENT:
  183.                                 genere_code(g_node_nth_child(ast,0));
  184.                                 fprintf(fichier,"!=");
  185.                                 genere_code(g_node_nth_child(ast,1));
  186.                                 break;
  187.                         case INFERIEUR:
  188.                                 genere_code(g_node_nth_child(ast,0));
  189.                                 fprintf(fichier,"<");
  190.                                 genere_code(g_node_nth_child(ast,1));
  191.                                 break;
  192.                         case SUPERIEUR:
  193.                                 genere_code(g_node_nth_child(ast,0));
  194.                                 fprintf(fichier,">");
  195.                                 genere_code(g_node_nth_child(ast,1));
  196.                                 break;
  197.                         case INFEGAL:
  198.                                 genere_code(g_node_nth_child(ast,0));
  199.                                 fprintf(fichier,"<=");
  200.                                 genere_code(g_node_nth_child(ast,1));
  201.                                 break;
  202.                         case SUPEGAL:
  203.                                 genere_code(g_node_nth_child(ast,0));
  204.                                 fprintf(fichier,">=");
  205.                                 genere_code(g_node_nth_child(ast,1));
  206.                                 break;
  207.                         case DANSII:
  208.                                 genere_code(g_node_nth_child(ast,0));
  209.                                 fprintf(fichier,">=");
  210.                                 genere_code(g_node_nth_child(ast,1));
  211.                                 fprintf(fichier,"&&");
  212.                                 genere_code(g_node_nth_child(ast,0));
  213.                                 fprintf(fichier,"<=");
  214.                                 genere_code(g_node_nth_child(ast,2));
  215.                                 break;
  216.                         case DANSEI:
  217.                                 genere_code(g_node_nth_child(ast,0));
  218.                                 fprintf(fichier,">");
  219.                                 genere_code(g_node_nth_child(ast,1));
  220.                                 fprintf(fichier,"&&");
  221.                                 genere_code(g_node_nth_child(ast,0));
  222.                                 fprintf(fichier,"<=");
  223.                                 genere_code(g_node_nth_child(ast,2));
  224.                                 break;
  225.                         case DANSIE:
  226.                                 genere_code(g_node_nth_child(ast,0));
  227.                                 fprintf(fichier,">=");
  228.                                 genere_code(g_node_nth_child(ast,1));
  229.                                 fprintf(fichier,"&&");
  230.                                 genere_code(g_node_nth_child(ast,0));
  231.                                 fprintf(fichier,"<");
  232.                                 genere_code(g_node_nth_child(ast,2));
  233.                                 break;
  234.                         case DANSEE:
  235.                                 genere_code(g_node_nth_child(ast,0));
  236.                                 fprintf(fichier,">");
  237.                                 genere_code(g_node_nth_child(ast,1));
  238.                                 fprintf(fichier,"&&");
  239.                                 genere_code(g_node_nth_child(ast,0));
  240.                                 fprintf(fichier,"<");
  241.                                 genere_code(g_node_nth_child(ast,2));
  242.                                 break;
  243.                         case NEGATIF:
  244.                                 fprintf(fichier,"-");
  245.                                 genere_code(g_node_nth_child(ast,0));
  246.                                 break;
  247.                         case CONDITION_SI:
  248.                                 genere_code(g_node_nth_child(ast,0));
  249.                                 fprintf(fichier,"\n");
  250.                                 break;
  251.                         case CONDITION_SI_SINON:
  252.                                 genere_code(g_node_nth_child(ast,0));
  253.                                 genere_code(g_node_nth_child(ast,1));
  254.                                 break;
  255.                         case SI:
  256.                                 fprintf(fichier,"\tif(");
  257.                                 genere_code(g_node_nth_child(ast,0));
  258.                                 fprintf(fichier,"){\n");
  259.                                 genere_code(g_node_nth_child(ast,1));
  260.                                 fprintf(fichier,"\t}");
  261.                                 break;
  262.                         case SINON:
  263.                                 fprintf(fichier,"else{\n");
  264.                                 genere_code(g_node_nth_child(ast,0));
  265.                                 fprintf(fichier,"\t}\n");
  266.                                 break;
  267.                         case BOUCLE_FOR:
  268.                                 fprintf(fichier,"\tint i%i;\n\tfor(i%i=0;i%i<",nb_boucle,nb_boucle,nb_boucle);
  269.                                 genere_code(g_node_nth_child(ast,0));
  270.                                 fprintf(fichier,";i%i++){\n",nb_boucle);
  271.                                 nb_boucle++;
  272.                                 genere_code(g_node_nth_child(ast,1));
  273.                                 fprintf(fichier,"\t}\n");
  274.                                 break;
  275.                         case BOUCLE_WHILE:
  276.                                 fprintf(fichier,"\twhile(");
  277.                                 genere_code(g_node_nth_child(ast,0));
  278.                                 fprintf(fichier,"){\n");
  279.                                 genere_code(g_node_nth_child(ast,1));
  280.                                 fprintf(fichier,"\t}\n");
  281.                                 break;
  282.                         case BOUCLE_DO_WHILE:
  283.                                 fprintf(fichier,"\tdo{\n");
  284.                                 genere_code(g_node_nth_child(ast,0));
  285.                                 fprintf(fichier,"\t}while(");
  286.                                 genere_code(g_node_nth_child(ast,1));
  287.                                 fprintf(fichier,");\n");
  288.                                 break;
  289.                         case BLOC_CODE:
  290.                                 genere_code(g_node_nth_child(ast,0));
  291.                                 break;
  292.                         case AFFICHAGET:
  293.                                 fprintf(fichier,"\tprintf(\"%%s\",");
  294.                                 genere_code(g_node_nth_child(ast,0));
  295.                                 fprintf(fichier,");\n");
  296.                                 break;
  297.                         case TEXTE:
  298.                                 fprintf(fichier,"%s",(char*)g_node_nth_child(ast,0)->data);
  299.                                 break;
  300.                         case AFFECTATIONNT:
  301.                                 fprintf(fichier,"\tchar* ");
  302.                                 genere_code(g_node_nth_child(ast,0));
  303.                                 fprintf(fichier,"=malloc(sizeof(char)*(strlen(");
  304.                                 genere_code(g_node_nth_child(ast,1));
  305.                                 fprintf(fichier,")+1));\n");
  306.                                 fprintf(fichier,"\tif(");
  307.                                 genere_code(g_node_nth_child(ast,0));
  308.                                 fprintf(fichier,"==NULL){\n");
  309.                                 fprintf(fichier,"\tprintf(\"Erreur d'allocation memoire sur la variable ");
  310.                                 genere_code(g_node_nth_child(ast,0));
  311.                                 fprintf(fichier," !\");\n\texit(-1);\n\t}\n\tstrcpy(");
  312.                                 genere_code(g_node_nth_child(ast,0));
  313.                                 fprintf(fichier,",");
  314.                                 genere_code(g_node_nth_child(ast,1));
  315.                                 fprintf(fichier,");\n");
  316.                                 break;
  317.                         case AFFECTATIONT:
  318.                                 fprintf(fichier,"\t");
  319.                                 genere_code(g_node_nth_child(ast,0));
  320.                                 fprintf(fichier,"=realloc(");
  321.                                 genere_code(g_node_nth_child(ast,0));
  322.                                 fprintf(fichier,",sizeof(char)*(strlen(");
  323.                                 genere_code(g_node_nth_child(ast,1));
  324.                                 fprintf(fichier,")+1));\n");
  325.                                 fprintf(fichier,"\tif(");
  326.                                 genere_code(g_node_nth_child(ast,0));
  327.                                 fprintf(fichier,"==NULL){\n");
  328.                                 fprintf(fichier,"\tprintf(\"Erreur de reallocation memoire sur la variable ");
  329.                                 genere_code(g_node_nth_child(ast,0));
  330.                                 fprintf(fichier," !\");\n\texit(-1);\n\t}\n\tstrcpy(");
  331.                                 genere_code(g_node_nth_child(ast,0));
  332.                                 fprintf(fichier,",");
  333.                                 genere_code(g_node_nth_child(ast,1));
  334.                                 fprintf(fichier,");\n");
  335.                                 break;
  336.                         case SUPPRESSIONT:
  337.                                 fprintf(fichier,"\tfree(");
  338.                                 genere_code(g_node_nth_child(ast,0));
  339.                                 fprintf(fichier,");\n");
  340.                                 break;
  341.                 }
  342.         }
  343. }

On compile et on teste avec ce joli programme :

programme.simple
  1. //affichage d'une chaine de texte
  2. afficher "Bonjour le monde ! (oui on est en France ici, pas de Hallo Welt !!)\n";
  3.  
  4. //affectation de la variable texte
  5. tphrase_de_thomas="Thomas a dit :
  6.  
  7. \"J'aime bien la science-fiction et les dessins animés Disney !\".
  8.  
  9. Mais voilà on s'en fiche un peu...
  10.  
  11. ";
  12.  
  13. //affiche la variable texte
  14. afficher tphrase_de_thomas;
  15.  
  16. //supprime la variable texte (libere la memoire) - la variable est desormais inutilisable en l'etat
  17. supprimer tphrase_de_thomas;
  18.  
  19. <!--
  20.  
  21. AFFICHAGE DE LA TABLE DE MULTIPLICATION DE 1 A 10
  22.  
  23. -->
  24.  
  25. afficher "---------------------------------TABLE DE MULTIPLICATION---------------------------------\n";
  26. afficher "|X\t1\t2\t3\t4\t5\t6\t7\t8\t9\t10\t|\n";
  27. e_i=0;
  28. (10)x
  29.     e_j=0;
  30.     e_i++;
  31.     afficher "|";
  32.     afficher e_i;
  33.     (10)x
  34.         e_j++;
  35.         afficher "\t";
  36.         afficher e_i*e_j;
  37.     ;
  38.     afficher "\t|\n";
  39. ;
  40. afficher "-----------------------------------------------------------------------------------------\n";

Cela devrait vous afficher sur la console :

Bonjour le monde ! (oui on est en France ici, pas de Hallo Welt !!)
Thomas a dit :

"J'aime bien la science-fiction et les dessins animés Disney !".

Mais voilà on s'en fiche un peu...

---------------------------------TABLE DE MULTIPLICATION---------------------------------
|X      1       2       3       4       5       6       7       8       9       10      |
|1      1       2       3       4       5       6       7       8       9       10      |
|2      2       4       6       8       10      12      14      16      18      20      |
|3      3       6       9       12      15      18      21      24      27      30      |
|4      4       8       12      16      20      24      28      32      36      40      |
|5      5       10      15      20      25      30      35      40      45      50      |
|6      6       12      18      24      30      36      42      48      54      60      |
|7      7       14      21      28      35      42      49      56      63      70      |
|8      8       16      24      32      40      48      56      64      72      80      |
|9      9       18      27      36      45      54      63      72      81      90      |
|10     10      20      30      40      50      60      70      80      90      100     |
-----------------------------------------------------------------------------------------

On va continuer sur les chaînes de caractères. On implémentera dans la prochaine évolution la concaténation (sous forme d'affectation) de deux expressions texte.

<< Évolution 5 : Les boucles | Évolution 6 : Les chaînes de caractères (Partie 1 - Variable et déclaration) | Évolution 7 : Les chaînes de caractères (Partie 2.1 - Concaténation et ré-allocation dynamique de la mémoire) >>

Thomas - (CC BY-NC-SA 3.0 FR)

Page last modified on July 12, 2018, at 11:09 AM EST

This page has been requested 2483 times (Today : 2) - Total number of requests : 256316

Edit - History - Statistics - Print - Recent Changes - Search

Clin d'oeil aux victimes des attentats survenus dans la soirée du 13 novembre 2015. La nouvelle version du site a été installée quelques heures avant.