Recent Changes - Search:

My Projects

Writings

Source Code

Social Networks

Histoires

Live Traffic !


My Servers

Hosted and administered websites

My Friends

Old Website

Évolution 7 : Les chaînes de caractères (Partie 2.1 - Concaténation et ré-allocation dynamique de la mémoire)

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

<< É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)

Cette évolution est bien plus légère que la précédente. On va juste concaténer une variable avec une autre chaîne sous la forme d'affectation avec le lexème "+=". Ce lexème existe déjà (Voir évolution 4 sur les raccourcis syntaxiques), on a donc nul besoin de toucher à l'analyseur lexical.

Évolution 7 du langage :

  1. <affectation> ::= <affectation>
  2.                 | variable_texte "+=" <expression_texte> ";"

Vous voyez que c'est vraiment une petite évolution. On ajoute un numéro pour l'arbre abstrait syntaxique dans le fichier d'entête :

simple.h
  1. #define AFFECTATIONT_CONCAT 55

On met à jour le non terminal affectation dans l'analyseur syntaxique :

syntaxe_simple.y
  1. affectation:    variable_arithmetique TOK_AFFECT expression_arithmetique TOK_FINSTR{
  2.                         /* $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. */
  3.                         printf("\t\tAffectation sur la variable\n");
  4.                         Variable* var=g_hash_table_lookup(table_variable,(char*)g_node_nth_child($1,0)->data);
  5.                         if(var==NULL){
  6.                                 /* On cree une Variable et on lui affecte le type que nous connaissons et la valeur */
  7.                                 var=malloc(sizeof(Variable));
  8.                                 if(var!=NULL){
  9.                                         var->type=strdup("entier");
  10.                                         var->value=$3;
  11.                                         /* On l'insere dans la table de hachage (cle: <nom_variable> / valeur: <(type,valeur)>) */
  12.                                         if(g_hash_table_insert(table_variable,g_node_nth_child($1,0)->data,var)){
  13.                                         $$=g_node_new((gpointer)AFFECTATIONE);
  14.                                         g_node_append($$,$1);
  15.                                         g_node_append($$,$3);
  16.                                         }else{
  17.                                             fprintf(stderr,"ERREUR - PROBLEME CREATION VARIABLE !\n");
  18.                                             exit(-1);
  19.                                         }
  20.                                 }else{
  21.                                         fprintf(stderr,"ERREUR - PROBLEME ALLOCATION MEMOIRE VARIABLE !\n");
  22.                                         exit(-1);
  23.                                 }
  24.                         }else{
  25.                                 $$=g_node_new((gpointer)AFFECTATION);
  26.                                 g_node_append($$,$1);
  27.                                 g_node_append($$,$3);
  28.                         }
  29.                 }
  30.                 |
  31.                 variable_arithmetique TOK_AFFECT_PLUS expression_arithmetique TOK_FINSTR{
  32.                         Variable* var=g_hash_table_lookup(table_variable,(char*)g_node_nth_child($1,0)->data);
  33.                         if(var==NULL){
  34.                                 fprintf(stderr,"\tERREUR : Erreur de semantique a la ligne %d. Variable %s jamais declaree !\n",lineno,(char*)g_node_nth_child($1,0)->data);
  35.                                 error_semantical=true;
  36.                         }else{
  37.                                 $$=g_node_new((gpointer)AFFECTATION_PLUS);
  38.                                 g_node_append($$,$1);
  39.                                 g_node_append($$,$3);
  40.                         }
  41.                 }
  42.                 |
  43.                 variable_arithmetique TOK_AFFECT_MOINS expression_arithmetique TOK_FINSTR{
  44.                         Variable* var=g_hash_table_lookup(table_variable,(char*)g_node_nth_child($1,0)->data);
  45.                         if(var==NULL){
  46.                                 fprintf(stderr,"\tERREUR : Erreur de semantique a la ligne %d. Variable %s jamais declaree !\n",lineno,(char*)g_node_nth_child($1,0)->data);
  47.                                 error_semantical=true;
  48.                         }else{
  49.                                 $$=g_node_new((gpointer)AFFECTATION_MOINS);
  50.                                 g_node_append($$,$1);
  51.                                 g_node_append($$,$3);
  52.                         }
  53.                 }
  54.                 |
  55.                 variable_arithmetique TOK_AFFECT_MUL expression_arithmetique TOK_FINSTR{
  56.                         Variable* var=g_hash_table_lookup(table_variable,(char*)g_node_nth_child($1,0)->data);
  57.                         if(var==NULL){
  58.                                 fprintf(stderr,"\tERREUR : Erreur de semantique a la ligne %d. Variable %s jamais declaree !\n",lineno,(char*)g_node_nth_child($1,0)->data);
  59.                                 error_semantical=true;
  60.                         }else{
  61.                                 $$=g_node_new((gpointer)AFFECTATION_MUL);
  62.                                 g_node_append($$,$1);
  63.                                 g_node_append($$,$3);
  64.                         }
  65.                 }
  66.                 |
  67.                 variable_arithmetique TOK_AFFECT_DIV expression_arithmetique TOK_FINSTR{
  68.                         Variable* var=g_hash_table_lookup(table_variable,(char*)g_node_nth_child($1,0)->data);
  69.                         if(var==NULL){
  70.                                 fprintf(stderr,"\tERREUR : Erreur de semantique a la ligne %d. Variable %s jamais declaree !\n",lineno,(char*)g_node_nth_child($1,0)->data);
  71.                                 error_semantical=true;
  72.                         }else{
  73.                                 $$=g_node_new((gpointer)AFFECTATION_DIV);
  74.                                 g_node_append($$,$1);
  75.                                 g_node_append($$,$3);
  76.                         }
  77.                 }
  78.                 |
  79.                 variable_arithmetique TOK_AFFECT_MOD expression_arithmetique TOK_FINSTR{
  80.                         Variable* var=g_hash_table_lookup(table_variable,(char*)g_node_nth_child($1,0)->data);
  81.                         if(var==NULL){
  82.                                 fprintf(stderr,"\tERREUR : Erreur de semantique a la ligne %d. Variable %s jamais declaree !\n",lineno,(char*)g_node_nth_child($1,0)->data);
  83.                                 error_semantical=true;
  84.                         }else{
  85.                                 $$=g_node_new((gpointer)AFFECTATION_MOD);
  86.                                 g_node_append($$,$1);
  87.                                 g_node_append($$,$3);
  88.                         }
  89.                 }
  90.                 |
  91.                 variable_arithmetique TOK_INCREMENTATION TOK_FINSTR{
  92.                         printf("\t\t\tIncrementation de +1 sur la variable\n");
  93.                     $$=g_node_new((gpointer)AFFECTATION_INCR);
  94.                     g_node_append($$,$1);
  95.                 }
  96.                 |
  97.                 variable_arithmetique TOK_DECREMENTATION TOK_FINSTR{
  98.                         printf("\t\t\tDecrementation de -1 sur la variable\n");
  99.                     $$=g_node_new((gpointer)AFFECTATION_DECR);
  100.                     g_node_append($$,$1);
  101.                 }
  102.                 |
  103.                 variable_booleenne TOK_AFFECT expression_booleenne TOK_FINSTR{
  104.                         /* $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. */
  105.                         printf("\t\tAffectation sur la variable\n");
  106.                         Variable* var=g_hash_table_lookup(table_variable,(char*)g_node_nth_child($1,0)->data);
  107.                         if(var==NULL){
  108.                                 /* On cree une Variable et on lui affecte le type que nous connaissons et la valeur */
  109.                                 var=malloc(sizeof(Variable));
  110.                                 if(var!=NULL){
  111.                                         var->type=strdup("booleen");
  112.                                         var->value=$3;
  113.                                         /* On l'insere dans la table de hachage (cle: <nom_variable> / valeur: <(type,valeur)>) */
  114.                                         if(g_hash_table_insert(table_variable,g_node_nth_child($1,0)->data,var)){
  115.                                         $$=g_node_new((gpointer)AFFECTATIONB);
  116.                                         g_node_append($$,$1);
  117.                                         g_node_append($$,$3);
  118.                                         }else{
  119.                                             fprintf(stderr,"ERREUR - PROBLEME CREATION VARIABLE !\n");
  120.                                             exit(-1);
  121.                                         }
  122.                                 }else{
  123.                                         fprintf(stderr,"ERREUR - PROBLEME ALLOCATION MEMOIRE VARIABLE !\n");
  124.                                         exit(-1);
  125.                                 }
  126.                         }else{
  127.                                 $$=g_node_new((gpointer)AFFECTATION);
  128.                                 g_node_append($$,$1);
  129.                                 g_node_append($$,$3);
  130.                         }
  131.                 }
  132.                 |
  133.                 variable_booleenne TOK_AFFECT_ET expression_booleenne TOK_FINSTR{
  134.                         Variable* var=g_hash_table_lookup(table_variable,(char*)g_node_nth_child($1,0)->data);
  135.                         if(var==NULL){
  136.                                 fprintf(stderr,"\tERREUR : Erreur de semantique a la ligne %d. Variable %s jamais declaree !\n",lineno,(char*)g_node_nth_child($1,0)->data);
  137.                                 error_semantical=true;
  138.                         }else{
  139.                                 $$=g_node_new((gpointer)AFFECTATION_ET);
  140.                                 g_node_append($$,$1);
  141.                                 g_node_append($$,$3);
  142.                         }
  143.                 }
  144.                 |
  145.                 variable_booleenne TOK_AFFECT_OU expression_booleenne TOK_FINSTR{
  146.                         Variable* var=g_hash_table_lookup(table_variable,(char*)g_node_nth_child($1,0)->data);
  147.                         if(var==NULL){
  148.                                 fprintf(stderr,"\tERREUR : Erreur de semantique a la ligne %d. Variable %s jamais declaree !\n",lineno,(char*)g_node_nth_child($1,0)->data);
  149.                                 error_semantical=true;
  150.                         }else{
  151.                                 $$=g_node_new((gpointer)AFFECTATION_OU);
  152.                                 g_node_append($$,$1);
  153.                                 g_node_append($$,$3);
  154.                         }
  155.                 }
  156.                 |
  157.                 variable_texte TOK_AFFECT expression_texte TOK_FINSTR{
  158.                         /* $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. */
  159.                         printf("\t\tAffectation sur la variable\n");
  160.                         Variable* var=g_hash_table_lookup(table_variable,(char*)g_node_nth_child($1,0)->data);
  161.                         if(var==NULL){
  162.                                 /* On cree une Variable et on lui affecte le type que nous connaissons et la valeur */
  163.                                 var=malloc(sizeof(Variable));
  164.                                 if(var!=NULL){
  165.                                         var->type=strdup("texte");
  166.                                         var->value=$3;
  167.                                         /* On l'insere dans la table de hachage (cle: <nom_variable> / valeur: <(type,valeur)>) */
  168.                                         if(g_hash_table_insert(table_variable,g_node_nth_child($1,0)->data,var)){
  169.                                         $$=g_node_new((gpointer)AFFECTATIONNT);
  170.                                         g_node_append($$,$1);
  171.                                         g_node_append($$,$3);
  172.                                         }else{
  173.                                             fprintf(stderr,"ERREUR - PROBLEME CREATION VARIABLE !\n");
  174.                                             exit(-1);
  175.                                         }
  176.                                 }else{
  177.                                         fprintf(stderr,"ERREUR - PROBLEME ALLOCATION MEMOIRE VARIABLE !\n");
  178.                                         exit(-1);
  179.                                 }
  180.                         }else{
  181.                                 $$=g_node_new((gpointer)AFFECTATIONT);
  182.                                 g_node_append($$,$1);
  183.                                 g_node_append($$,$3);
  184.                         }
  185.                 }
  186.                 |
  187.                 variable_texte TOK_AFFECT_PLUS expression_texte TOK_FINSTR{
  188.                         Variable* var=g_hash_table_lookup(table_variable,(char*)g_node_nth_child($1,0)->data);
  189.                         if(var==NULL){
  190.                                 fprintf(stderr,"\tERREUR : Erreur de semantique a la ligne %d. Variable %s jamais declaree !\n",lineno,(char*)g_node_nth_child($1,0)->data);
  191.                                 error_semantical=true;
  192.                         }else{
  193.                                 $$=g_node_new((gpointer)AFFECTATIONT_CONCAT);
  194.                                 g_node_append($$,$1);
  195.                                 g_node_append($$,$3);
  196.                         }
  197.                 };

Puis ??? Le générateur de code pardi !

generation_code.c
  1. case AFFECTATIONT_CONCAT:
  2.                                 fprintf(fichier,"\tif((");
  3.                                 genere_code(g_node_nth_child(ast,0));
  4.                                 fprintf(fichier,"=realloc(");
  5.                                 genere_code(g_node_nth_child(ast,0));
  6.                                 fprintf(fichier,",sizeof(char)*(strlen(");
  7.                                 genere_code(g_node_nth_child(ast,0));
  8.                                 fprintf(fichier,")+strlen(");
  9.                                 genere_code(g_node_nth_child(ast,1));
  10.                                 fprintf(fichier,")+1)))==NULL){\n");
  11.                                 fprintf(fichier,"\tprintf(\"Erreur de reallocation memoire sur la variable ");
  12.                                 genere_code(g_node_nth_child(ast,0));
  13.                                 fprintf(fichier," !\");\n\texit(-1);\n\t}\n\tstrcat(");
  14.                                 genere_code(g_node_nth_child(ast,0));
  15.                                 fprintf(fichier,",");
  16.                                 genere_code(g_node_nth_child(ast,1));
  17.                                 fprintf(fichier,");\n");
  18.                                 break;

Et on a fini. On compile et on teste :

programme.simple
  1. t_CONVERSATION = "Thomas Tributsch :
  2. ";
  3.  
  4. t_THOMAS = "\"Bon je dois me forcer à écrire un truc.";
  5.  
  6. t_THOMAS += " Ceci dans le simple but de tester si la concaténation fonctionne.";
  7.  
  8. t_THOMAS += "\nAu fait, je vous l'ai dit que j'aime bien l'univers Disney ?\"";
  9.  
  10. t_CONVERSATION += t_THOMAS;
  11.  
  12. t_CONVERSATION += "\n\nMickey Mouse :
  13. ";
  14.  
  15. t_MICKEY = "\"Salut Thomas ! On ne t'a pas déjà dit que tout le monde s'en moque un peu ?\"";
  16.  
  17. t_CONVERSATION += t_MICKEY;
  18.  
  19. t_CONVERSATION += "\n\nThomas Tributsch :
  20. ";
  21.  
  22. t_THOMAS = "\"Je rêve ou Mickey est vraiment en train de me parler là ??\"";
  23.  
  24. t_CONVERSATION += t_THOMAS;
  25.  
  26. t_CONVERSATION += "\n\nMickey Mouse :
  27. ";
  28.  
  29. t_MICKEY = "\"Oui et je suis même en train d'écouter du Coldplay avec Pluto ou Dingo. (Je sais plus lequel des 2 est mon ami ou mon chien)\"";
  30.  
  31. t_CONVERSATION += t_MICKEY;
  32.  
  33. t_CONVERSATION += "\n\nThomas Tributsch:
  34. ";
  35.  
  36. t_THOMAS = "\"Pluto c'est ton chien ! Faudrait que j'arrête de faire du Bison moi...\"";
  37.  
  38. t_CONVERSATION += t_THOMAS;
  39.  
  40. t_CONVERSATION += "\n\nMickey Mouse :
  41. ";
  42.  
  43. t_MICKEY = "\"Ah oui toi aussi tu t'y es mis ! Dur de décrocher à ça, c'est vraiment trop fort ! Chez Disney, tout nos sites (go.com) ont été conçu avec une technologie Java qui a été développé par la Walt Disney Internet Group. Il s'agit de Tea Trove, une alternative à JSP qui répond efficacement à nos attentes. Cela va presque faire 16 ans qu'on le maintient. Puis on est aussi en partie à l'origine de Squeak, un dialecte de Smalltalk utilisé entre autre pour faire des applications interactives et ludiques destinées aux enfants.\"";
  44.  
  45. t_CONVERSATION += t_MICKEY;
  46.  
  47. t_CONVERSATION += "\n\nThomas Tributsch:
  48. ";
  49.  
  50. t_THOMAS = "\"Ok donc comme ça Mickey fait du développement informatique... Bon il est temps que je m'arrête sur ce programme test, ça part pas mal en live là. J'ai suffisamment écrit pour tester si oui ou non la concaténation fonctionne.\"\n";
  51.  
  52. t_CONVERSATION += t_THOMAS;
  53.  
  54. afficher t_CONVERSATION;
  55.  
  56. supprimer t_THOMAS;
  57. supprimer t_MICKEY;
  58. supprimer t_CONVERSATION;

Cela devrait vous sortir ceci :

Thomas Tributsch :
"Bon je dois me forcer à écrire un truc. Ceci dans le simple but de tester si la concaténation fonctionne.
Au fait, je vous l'ai dit que j'aime bien l'univers Disney ?"

Mickey Mouse :
"Salut Thomas ! On ne t'a pas déjà dit que tout le monde s'en moque un peu ?"

Thomas Tributsch :
"Je rêve ou Mickey est vraiment en train de me parler là ??"

Mickey Mouse :
"Oui et je suis même en train d'écouter du Coldplay avec Pluto ou Dingo. (Je sais plus lequel des 2 est mon ami ou mon chien)"

Thomas Tributsch:
"Pluto c'est ton chien ! Faudrait que j'arrête de faire du Bison moi..."

Mickey Mouse :
"Ah oui toi aussi tu t'y es mis ! Dur de décrocher à ça, c'est vraiment trop fort ! Chez Disney, tout nos sites (go.com) ont été conçu avec une technologie Java qui a été développé par la Walt Disney Internet Group. Il s'agit de Tea Trove, une alternative à JSP qui répond efficacement à nos attentes. Cela va presque faire 16 ans qu'on le maintient. Puis on est aussi en partie à l'origine de Squeak, un dialecte de Smalltalk utilisé entre autre pour faire des applications interactives et ludiques destinées aux enfants."

Thomas Tributsch:
"Ok donc comme ça Mickey fait du développement informatique... Bon il est temps que je m'arrête sur ce programme test, ça part pas mal en live là. J'ai suffisamment écrit pour tester si oui ou non la concaténation fonctionne."

La prochaine évolution sera courte aussi. On reviendra sur la boucle for (voir évolution 5) et ajouter de nouvelles règles syntaxiques bien pratiques pour le développeur.

<< É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 Tributsch - (CC BY-NC-SA 3.0 FR)

Page last modified on April 10, 2017, at 11:00 PM EST

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

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.