source: trunk/etc/src/Ydf1.cc @ 1

Last change on this file since 1 was 1, checked in by lnalod, 15 years ago

Initial import of YAO sources

File size: 45.4 KB
Line 
1//g++ Ydf1.cc -Wall -o Ydf1
2
3#include <stdio.h>
4#include <string.h>
5#include <stdlib.h>
6#include <ctype.h>
7
8#define BUFSIZE           2048
9#define LG_MAX_NAME         24
10#define NB_MAX_VARIAB    10000
11#define LG_MAX_BIGVAR      128
12#define NB_MAX_EXPRESYM  10000
13#define NB_MAX_DIFFVAR   10000
14//#define NB_MAX_CPLX     1000
15
16/*=============================================================================*/
17struct st_diff {
18        char            vardiff[LG_MAX_NAME*2 + 1];
19        int             deblockportee;
20};
21
22/*=============================================================================*/
23short   trace=0;
24FILE    *fpmodul, *fpginac;
25//char    modul_file_name[LG_MAX_NAME+1];
26int     i, j=0, k;
27char      buffer[BUFSIZE+1];
28char    delim[] =" \t(),\n";
29//char    *pstr1, *pstr3, *pstrw;
30//char    *pstr2=NULL;
31short   Phase=0;
32int     NbIn, NbOut;
33int     indicYS=0;
34int     indic=0;
35char      instruct[BUFSIZE+1];
36short   indicBLOCK=0;
37short   indicCROUV=0;
38short   indicTAB=0;
39char    TabVar[NB_MAX_VARIAB][LG_MAX_BIGVAR+1];
40int     NbVar=0;
41short   indicDECLAR=0;
42short   indicAFFECT=0;
43short   prodlevel=0;
44char    Ysubstit[LG_MAX_NAME+1];
45int     iexp;
46
47char    TabExpreSym[NB_MAX_EXPRESYM][LG_MAX_NAME + 1];
48short   TabFlagIn[NB_MAX_EXPRESYM];
49int     NbExpreSym = 0;
50//char    affectsv[BUFSIZE+1];
51struct  st_diff TabDiff[NB_MAX_DIFFVAR];
52int     NbDiff = 0;
53
54int     CurBlockLev = 0; //semaphore de decompte des accolades pour gerer le niveau d'imbrication des block
55
56char    ModulName[LG_MAX_NAME+1];
57//int     lenModulName;
58
59char    TabDejaDiff[NB_MAX_DIFFVAR][LG_MAX_NAME+1]; //!!! tableau en global a usage local : initialement, et
60int     NbDejaDiff;                                 //    localement, mettre NbDejaDiff a ZERO !
61
62short   flagCPLX=0;
63int     NbInCplx=0;
64//char    TabCplx[NB_MAX_CPLX][LG_MAX_NAME + 1];
65//int     NbCplx=0;
66
67//principaux mots du langage C/C++ (liste non exhaustive ... )
68#define NB_CWORD  109
69char    TabCword [NB_CWORD][LG_MAX_NAME] =
70{       "abs",      "acos",     "asin",     "atan",    "atan2",    "atoi",
71        "atof",     "atol",     "break",    "case",    "char",     "close",  "complex",
72        "const",    "continue", "cos",      "cosh",    "default",  "delete",
73        "div",      "do",       "double",   "enum",    "else",     "exp",
74        "exit",     "extern",   "fabs",     "float",   "fclose"    "feof",
75        "fgetc",    "fgets",    "fopen",    "for",     "fprintf",  "fputc",
76        "fputs",    "free",     "getc",     "getchar", "getenv",   "gets",
77        "goto",     "if",       "int",      "isalnum", "isdigit",  "islower",
78        "isupper",  "log",      "log10",    "long",    "memchr",   "memcmp",
79        "memcpy",   "memove",   "new",      "NULL",    "open",     "pow",
80        "putenv",   "puts",     "rand",     "read",    "return",   "scanf",
81        "setenv",   "sprintf",  "short",    "sin",     "sinh",     "sizeof",
82        "sqrt",     "srand",    "sscanf",   "static",  "stdin",    "stdout",
83        "strcat",   "strchr",   "strcmp",   "strcpy",  "strlen",   "strncat",
84        "strncmp",  "strncpy",  "strpbrk",  "strrchr", "strspn",   "strstr",
85        "strtok",   "strtol",   "struct",   "switch",  "tan",      "tanh",
86        "tolower",  "toupper",  "typedef",  "union",   "unsigned", "void",
87        "volatile", "vfprintf", "vsprintf", "while",   "write",    "YREAL",
88};
89
90/*=============================================================================*/
91
92//*---------------------------------------------------------------------------*/
93int c_word(char *word)
94{   int wi;
95    for (wi=0; wi<NB_CWORD; ++wi)
96    {     if (!strcmp(word, TabCword[wi]))
97                 return (1);
98    }
99    return(0);
100}
101//*---------------------------------------------------------------------------*/
102char *str_affect(char *str)
103{    char *pstr;
104
105     pstr = strstr(str, "+=");  if (pstr != NULL) return pstr;
106     pstr = strstr(str, "-=");  if (pstr != NULL) return pstr;
107     pstr = strstr(str, "*=");  if (pstr != NULL) return pstr;
108     pstr = strstr(str, "/=");  if (pstr != NULL) return pstr;
109
110     pstr = strstr(str, "==");
111     if (pstr != NULL)  return (str_affect(pstr+2));
112     pstr = strstr(str, ">=");
113     if (pstr != NULL)  return (str_affect(pstr+2));
114     pstr = strstr(str, "<=");
115     if (pstr != NULL)  return (str_affect(pstr+2));
116     pstr = strstr(str, "!=");
117     if (pstr != NULL)  return (str_affect(pstr+2));
118     //autres cas non traited plm : <<=, >>=, &=, ^=, |=
119
120     //et enfin le cas d'une simple affectation
121     pstr = strstr(str, "=");  if (pstr != NULL) return pstr;
122
123     return(NULL);
124}
125/*---------------------------------------------------------------------------*/
126void str_lesschr(char *str, char car)
127{ int lg, i,j;
128  lg = strlen(str);
129  i=j=0;
130  for (i=0; i<lg; ++i)
131  {   if (str[i]==car) continue;
132      str[j]=str[i];
133      ++j;
134  }
135  str[j]='\0';
136}
137/*---------------------------------------------------------------------------*/
138int str_qalphanum(char *str)
139{   int lgstr = strlen(str);
140    int i=0;
141    short alphok=0;
142    while (i<lgstr)
143    {  if ( !isalnum(str[i]) && str[i]!='_') return(0);
144       if ( isalpha(str[i]) || str[i]=='_') alphok = 1;
145       ++i;
146    }
147    if (alphok) return(1);
148    return(0);
149}
150/*---------------------------------------------------------------------------*/
151int str_qdigit(char *str)
152{   int lgstr = strlen(str);
153    int i;
154    for (i=0; i<lgstr; ++i)
155    {  if (!isdigit(str[i])) return(0);
156    }
157    return(1);
158}
159/*---------------------------------------------------------------------------*/
160char *str_tok(char *str, char *delim, char *svdelim, char *pmax)
161{    char *p1, *p2;
162
163     if (str>=pmax) return (NULL);
164
165     p1 = str;
166     //se positionner sur le 1er caratere non delimiteur
167     while (p1[0]!='\0' && strchr(delim, p1[0])!=NULL) ++p1;
168     //avancer tant qu'on ne retombe pas sur un caratere delimiteur
169     p2=p1;
170     while (p2[0]!='\0' && strchr(delim, p2[0])==NULL) ++p2;
171     //on informe du delimiteur trouved avant de l'ecraser par '\0'
172     *svdelim=p2[0];
173     p2[0]='\0';
174     return(p1);
175}
176
177/*---------------------------------------------------------------------------*/
178void BackwardOut(char *instruct)
179{    char   *pstr1, *pstr2;
180     char    bufwrk[BUFSIZE+1];
181
182     if (trace) printf("\n/*BO:%s:*/\n", instruct);
183
184     strcpy(bufwrk, instruct);
185     pstr1 = bufwrk;
186                 fprintf(fpginac, "  cout ");
187     while (1)
188     {  pstr2 = strpbrk(pstr1, "\n\"");
189        if (pstr2!=NULL)
190        {
191           if (pstr2[0]=='\n')
192           {  pstr2[0]='\0';
193              fprintf(fpginac," <<\"%s\" <<endl ",pstr1);
194              pstr1=pstr2+1;
195           }
196           else
197           {  pstr2[0]='\0';
198              fprintf(fpginac,"<<\"%s\\\"\" ", pstr1);
199              pstr1=pstr2+1;
200           }
201        }
202        else
203        { fprintf(fpginac," <<\"%s\"",pstr1);
204          break;
205        }
206     }
207     fprintf(fpginac, " ;\n");
208}
209
210/*---------------------------------------------------------------------------*/
211int add_var(char *strvar)
212{
213    if (NbVar>=NB_MAX_VARIAB)
214    {  printf("Ydf1: too much variables in that modul (%s)\n", ModulName);
215       exit(-9);
216    }
217    strcpy(TabVar[NbVar], strvar);
218    ++NbVar;
219    return(NbVar-1);
220}
221
222/*---------------------------------------------------------------------------*/
223short is_yadvar(char *str)
224{   char bufstr[7];
225    strncpy(bufstr, str, 6);  //strcpy(bufstr, str);
226    bufstr[6]='\0';
227    return (!strcmp(bufstr, "Yadvar"));
228}
229
230/*---------------------------------------------------------------------------*/
231int exist_expresym(char *expresym)
232{
233    int wi;
234    for (wi=0; wi<NbExpreSym; ++wi)
235    {   if (!strcmp(expresym, TabExpreSym[wi]))
236           return (1);
237    }
238    return(0);
239}
240
241/*---------------------------------------------------------------------------*/
242int id_diff(char *diff)
243{
244    int wi;
245    for (wi=0; wi<NbDiff; ++wi)
246    {   if (!strcmp(diff, TabDiff[wi].vardiff))
247               return (wi);
248    }
249    return(-1);
250}
251/*---------------------------------------------------------------------------*/
252void decrem_diff_blocklev()
253{
254    int wi;
255    for (wi=0; wi<NbDiff; ++wi)
256    {     if (TabDiff[wi].deblockportee  == CurBlockLev)
257           TabDiff[wi].deblockportee = 0;
258    }
259    --CurBlockLev;
260}
261
262/*---------------------------------------------------------------------------*/
263/*int is_input(char *str)
264{
265    int wi;
266    for (wi=0; wi<NbIn; ++wi)
267    {     if (!strcmp(str, TabExpreSym[wi]))
268                 return (1);
269    }
270    return(0);
271}
272int is_input(char *str)
273{
274    int wi, nballin;
275                nballin = NbIn+NbInCplx;
276    for (wi=0; wi<nballin; ++wi)
277    {     if (!strcmp(str, TabExpreSym[wi]))
278                 return (1);
279    }
280    return(0);
281}
282*/
283int id_input(char *input)
284{
285    int wi, nballin;
286                nballin = NbIn+NbInCplx;
287    for (wi=0; wi<nballin; ++wi)
288    {   if (!strcmp(input, TabExpreSym[wi]))
289               return (wi);
290    }
291    return(-1);
292}
293
294/*---------------------------------------------------------------------------*/
295int id_YSi(char *tok)
296{   int num;
297    if (tok[0]!='Y' || tok[1]!='S') return(0);
298                if (tok[2]=='0') return(0);
299                if (!str_qdigit(&tok[2])) return (0);
300                num = atoi(&tok[2]);
301                if (num<=NbOut) return(num);
302    return(0);
303}
304
305/*---------------------------------------------------------------------------*/
306void transfo_affect(char *instruct, char *pstr2)
307{//   ...VAR {+,-,*,/}= EXPR ;   a tranformer en :--->    VAR = VAR {+,-,*,/} ( EXPR ) ;
308 //   ( avec pstr2 qui pointera sur le = et non plus le {+,-,*,/}= )
309
310     char    bufwrk[BUFSIZE+1];
311     char    *p3;
312
313     //printf("befor|%s|%c|\n", instruct, pstr2[0]);
314
315                 memset(bufwrk, '\0', BUFSIZE+1);
316                 bufwrk[0]=pstr2[-1];
317                 pstr2[-1] = '\0'; //on termine la variable affectee par un '\0'
318
319                 //il faut retrouver la variable affectee (ie se positionner dessus)
320                 p3 = pstr2-2;
321     while ((p3[0]==' ' || p3[0]=='\t') && p3>instruct) --p3; //on remonte les espaces et \t
322     while (p3[0]!=' ' && p3[0]!='\t' && p3>instruct) --p3; //on remonte les autres caractères
323                 if (p3<instruct) p3=instruct; //en faisant attention de rester sur l'instruction
324
325                 //
326                 strcat(bufwrk, "= ");                                                                  //'= '
327                 strcat(bufwrk, p3);                                                                            //VAR
328                 strcat(bufwrk, " ");                                                                           //' '
329                 bufwrk[strlen(bufwrk)] = pstr2[0];               //{'+','-','*','/'}
330                 strcat(bufwrk, " (");                                                                  //' ('
331                 strcat(bufwrk, pstr2+2);                                                               //EXPR ;
332                 bufwrk[strlen(bufwrk)-1] = '\0';               //pour enlever le ';' de fin
333                 strcat(bufwrk, " ) ;");                                                                //et le remplacer par ' ) ;"
334
335                 //
336                 strcat(instruct, bufwrk);
337
338     //printf("after|%s|%c|\n", instruct, pstr2[0]);
339}
340
341/*---------------------------------------------------------------------------*/
342void substitut_by_symbol(char *str)
343{    char    *pstr1, *pmax;
344     char    bufwrk[BUFSIZE+1];
345     char    delim;
346     char    *p1;
347     strcpy(bufwrk, str);
348     memset(str, '\0', strlen(str)); //raz de la string qu'on va
349     //reconstruire en substituant les QAN par leur equivalent symbol
350     pstr1 = bufwrk;
351     pmax = pstr1+strlen(pstr1);
352     while ((p1=str_tok(pstr1, " \n\t", &delim, pmax))!=NULL)
353     {
354               if (str_qalphanum (p1))
355            if (!c_word(p1) && !is_yadvar(p1))
356               if (exist_expresym(p1))
357         {
358                  strcat(str, "Ygs_");
359         }
360         strcat(str, p1);
361         sprintf(str, "%s%c", str, delim);
362               pstr1 = pstr1+strlen(pstr1)+1;
363     }
364}
365
366/*---------------------------------------------------------------------------*/
367void substitut_produce_tab(char *instruct)
368{    //on a detected qu'il y avait 1 (ou plusieurs) tableau dans instruct
369     //on va les substituer, ..., mais avant, il faut les trouver ...
370     char   *pstr1, *pstr2, *pstr3;
371     char    bufwrk[BUFSIZE+1];
372     char    strtab[LG_MAX_BIGVAR+1];
373     int     idvar;
374     int     semcro;
375     char    yadvari[LG_MAX_NAME+1];
376                 //printf("TAB(S) FOUND IN |%s|\n", instruct);
377
378     strcpy(bufwrk, instruct);
379     memset(instruct, '\0', strlen(instruct)); //raz d'instruct qu'on va
380     //reconstruire en substituant les tableaux s'il y en a (risqued!?)
381
382     fprintf(fpginac,"  cout<<endl;\n");
383
384     pstr1 = bufwrk;
385     while (1)
386     {
387        pstr2 = strchr(pstr1, '[');
388        semcro=1;
389        if (pstr2!=NULL)
390        {  //pstr2 pointe sur le debut de tableau, il faut en trouver la fin
391           pstr3=pstr2+1;
392           while (1)
393           {   pstr3=strpbrk(pstr3, "][");
394               if (pstr3!=NULL)
395               {
396                              if (pstr3[0]=='[') ++semcro; else --semcro; //
397                              ++pstr3;
398                  if (pstr3[0]!='['  && semcro==0) break;
399               }
400               else break; //?
401           }
402           //rendu ici, pstr3 est sensed pointer sur l'octet qui suit le
403           //crochet de fin du tableau
404
405           //maintenant, on remonte pstr2 en arriere pour se mettre au debut
406           //de la variable tableau
407           while (pstr2[0]!=' ' && pstr2[0]!='\t' && pstr2[0]!='\n') --pstr2;
408
409           //on met des /0 pour delimiter et creer la string tableau
410           pstr2[0]='\0'; ++pstr2; //debut de la string tableau
411           pstr3[0]='\0';          //fin de la string tableau
412                                         //printf ("->|%s|%s|%s|<-\n", pstr1, pstr2, pstr3+1); //pour verif du decoupage
413
414                 strcpy(strtab, pstr2);
415           str_lesschr(strtab, ' ');
416                                         //printf ("->|%s|<-\n", strtab);
417
418           //ajout de ce tableau comme variable dans un tableaux de variable
419           idvar = add_var(strtab);
420           sprintf (yadvari, "Yadvar%i", idvar); //
421           //creation du symbol pour le tableau
422           fprintf(fpginac,"  symbol %s(\"%s\");\n", yadvari, yadvari);
423
424           //declaration de la variable intermediaire pour backward
425           fprintf(fpginac,"  cout<<\"double %s = %s;\"<<endl;\n", yadvari, strtab);
426
427           //substitution : on reconstruit instruct (qu'on a razeder au debut)
428           strcat(instruct, pstr1);
429           strcat(instruct, " ");
430           strcat(instruct, yadvari);
431
432           //on repositionne pstr1 pour la suite, y'a peut etre encore d'autres tableaux?
433           pstr1 = pstr3+1;
434        }
435        else
436        {  strcat(instruct, pstr1);   //fin de reconstruction de instruct
437           break;
438        }
439     }
440}
441
442/*---------------------------------------------------------------------------*/
443void BackProduce_DAdx(char *instruct)
444{    char   *pstr, *pmax;
445     char   bufwrk[BUFSIZE+1];
446     char   delim;
447     char   *p1;
448     char   DA_dx[LG_MAX_NAME*2+1];
449     int    wi, idiff;
450int nballin, startin;
451nballin = NbIn+NbInCplx;
452if (flagCPLX) startin=NbIn; else startin=0;
453
454     strcpy(bufwrk, instruct);
455     pstr = bufwrk;
456     pmax = pstr+strlen(pstr);
457     while ((p1=str_tok(pstr, " \n\t", &delim, pmax))!=NULL)
458     {
459               if (str_qalphanum(p1))
460            if (!c_word(p1) && !is_yadvar(p1))
461                                 {
462//            for (wi=0; wi<NbIn; ++wi)
463for (wi=startin; wi<nballin; ++wi)
464            {
465                sprintf(DA_dx, "YD%s_d%s", p1, TabExpreSym[wi]);
466                      idiff = id_diff(DA_dx);
467                      if (idiff<0) //ce qui veut dire qu'on rencontre DA_dx pour la 1ere fois
468                {
469                   if (NbDiff>=NB_MAX_DIFFVAR)
470                   {  printf(" Ydf1: Automatic derivativ stopped for modul %s\n", ModulName);
471                      printf("       because :=> too much derivative in that modul\n");
472                      exit(-9);
473                   }
474                               strcpy(TabDiff[NbDiff].vardiff, DA_dx);
475                               TabDiff[NbDiff].deblockportee = CurBlockLev;
476                   ++NbDiff;
477                   fprintf(fpginac,"  cout<<\"double %s; \"<<endl;\n", DA_dx);
478                }
479                else //DA_dx existe deja, mais pour backward il faut eventuellement
480                {    //produire de nouveau la declaration en tenant compte de l'imbrication des blocks !
481                   if (TabDiff[idiff].deblockportee == 0)
482                   {  TabDiff[idiff].deblockportee = CurBlockLev;
483                                  fprintf(fpginac,"  cout<<\"double %s; \"<<endl;\n", DA_dx);
484                   }
485                }
486            }
487                                 }
488         pstr = pstr+strlen(pstr)+1;
489     }
490}
491
492/*---------------------------------------------------------------------------*/
493void Sto_GinProduce_ExpreSym(char *str)
494{    char    *pstr, *pmax;
495     char    bufwrk[BUFSIZE+1];
496     char    delim;
497     char    *p1;
498     strcpy(bufwrk, str);
499     pstr = bufwrk;
500     pmax = pstr+strlen(pstr);
501/*
502short  vuegal=0;
503printf("SGPESI: |%s|\n", instruct);
504*/
505     while ((p1=str_tok(pstr, " \n\t", &delim, pmax))!=NULL)
506     {
507/*
508if (p1[0]=='=') vuegal=1;
509*/
510               if (str_qalphanum(p1))
511            if (!c_word(p1) && !is_yadvar(p1))
512               if (!exist_expresym(p1))
513               {
514                  if (NbExpreSym>=NB_MAX_EXPRESYM)
515                  {  printf(" Ydf1: Automatic derivativ stopped for modul %s\n", ModulName);
516                     printf("       because :=> too much token in that modul\n");
517                     exit(-9);
518                  }
519/*nb: on est dans cette fct que si queaffect,
520CELA N'EST SANS DOUTE PLUS VRAI
521donc la variable n'a pas du faire l'objet
522//    d'une declaration ce qui laisse penser qu'il s'agit d'une variable externe.
523//    Si on est sur le token qui precede le '=', alors cela voudrait dire qu'on est en
524//    train de de modifier cette variable externe, ce qui du coup modifie la fonction
525//    elle meme, ce qui not fair et rend les testdf KO, --> WARNING
526if (!vuegal)
527{  printf("WARNING: you may be are modifying a extenal variable (%s) ...\n", p1);
528   printf("         this is not fair and may make failed the validation functions test\n");
529}
530*/
531                  strcpy(TabExpreSym[NbExpreSym], p1);
532                  ++NbExpreSym;
533                              fprintf(fpginac,"  ex %s;\n", p1);
534                              fprintf(fpginac,"  symbol Ygs_%s(\"Ygs_%s\");\n", p1, p1);
535               }
536               pstr = pstr+strlen(pstr)+1;
537     }
538}
539
540/*---------------------------------------------------------------------------*/
541short dejadiff(char *var2diff)
542{   //char   TabDejaDiff[NB_MAX_DIFFVAR][LG_MAX_NAME+1];
543    //!!! tableau en global a usage local : initialement, et
544                //    localement, mettre NbDejaDiff a ZERO !
545    int wi;
546    for (wi=0; wi<NbDejaDiff; ++wi)
547    {   if (!strcmp(var2diff, TabDejaDiff[wi]))
548               return (1);
549    }
550    return(0);
551}
552
553/*---------------------------------------------------------------------------*/
554void GinBackProduce_dfDf(char *A, char *straffect) //A = straffect
555{                //maintenant, il faut produire les derivees.
556     //1) il faut  produire dans ginac les derivee de tous les QAN de droite pour celui de gauche :
557     //   ex avec : A = f(sB, sB, sC, ...)
558     //   on doit obtenir : da_DB = A.diff(sB,1);  UNE SEULE FOIS
559     //                                                                                 da_DC = A.diff(sC,1);    ...
560     //algo:
561     // pour chaque variable (V) de straffect (en considerant qu'un token QAN !c_word et !yadvare est une variable (quid des constantes?)
562     // construire da_DV
563     // si dA_DV n'existe pas dans Tabdiff alors l'y ajouter et creer "ex da_DV;" pour ginac
564     // produire pour ginac : "da_DV = A.diff(Ygs_V, 1);" une seule fois pour chaque variable
565     char   *pstr, *pmax;
566     char    bufwrk[BUFSIZE+1];
567     char    delim;
568     char    dA_DV[LG_MAX_NAME*2+1];
569     int     idiff;
570     char    *p1;
571
572                 NbDejaDiff=0; //usage du tableau TabDejaDiff pour s'assurer qu'on ne derive qu'une seule fois une variable
573                               //et meme si, lorsqu'en particulier elle apparait plusieurs fois en partie droite
574
575     strcpy(bufwrk, straffect);
576                 pstr = bufwrk;
577     pmax = pstr+strlen(pstr);
578     while ((p1=str_tok(pstr, " \n\t", &delim, pmax))!=NULL)
579     {
580               if (str_qalphanum(p1))
581            if (!c_word(p1) && !is_yadvar(p1))
582         {
583               sprintf(dA_DV, "Yd%s_D%s", A, p1);
584                     idiff = id_diff(dA_DV);
585                     if (idiff<0) //ce qui veut dire qu'on rencontre dA_DV pour la 1ere fois
586               {
587                  if (NbDiff>=NB_MAX_DIFFVAR)
588                  {  printf(" Ydf1: Automatic derivativ stopped for modul %s\n", ModulName);
589                     printf("       because :=> too much derivative in that modul\n");
590                     exit(-9);
591                  }
592                              strcpy(TabDiff[NbDiff].vardiff, dA_DV);
593                              TabDiff[NbDiff].deblockportee = CurBlockLev;
594                  ++NbDiff;
595                              fprintf(fpginac,"  ex %s;\n", dA_DV);
596                  fprintf(fpginac,"  cout<<\"double %s; \"<<endl;\n", dA_DV);
597               }
598               else //dA_DV existe deja, mais pour backward il faut eventuellement
599               {    //produire de nouveau la declaration en tenant compte de l'imbrication des blocks !
600                  if (TabDiff[idiff].deblockportee == 0)
601                  {  TabDiff[idiff].deblockportee = CurBlockLev;
602                                 fprintf(fpginac,"  cout<<\"double %s; \"<<endl;\n", dA_DV);
603                  }
604               }
605
606                                                         //pour ne produire la derivee qu'une seule fois
607                                                         if (!dejadiff(dA_DV))
608               {  if (NbDejaDiff>=NB_MAX_DIFFVAR)
609                  {  printf(" Ydf1: Automatic derivativ stopped for modul %s\n", ModulName);
610                     printf("       because :=> too much derivative in that modul\n");
611                     exit(-9);
612                  }
613                                                                  strcpy(TabDejaDiff[NbDejaDiff], dA_DV);
614                                                                        ++NbDejaDiff;
615                                                            fprintf(fpginac,"  %s = %s.diff(Ygs_%s, 1);\n", dA_DV, A, p1);
616                  fprintf(fpginac,"  cout<<\"%s = \" <<csrc<< %s <<\";\"<<endl;\n", dA_DV, dA_DV);
617               }
618         }
619               pstr = pstr+strlen(pstr)+1;
620     }
621}
622
623/*---------------------------------------------------------------------------*/
624void BackProduce_Dfdx(char *A, char *straffect)
625{    //2) puis il faut produire la derivee du terme de gauche par rapport aux entrees.
626     //   il s'agit de faire, directement dans le backward, la somme pour chaque entree xi :
627     //             DA_dxi = dA_DV1.DV1_dxi + ... + dA_DVn.DVn_dxi
628     char   *pstr, *pmax;
629     char    bufwrk[BUFSIZE+1];
630     char    delim;
631     char    DA_dx[LG_MAX_NAME*2+1];
632     int     wi;
633     char    dA_DV[LG_MAX_NAME*2+1];
634     int     idiff;
635     char    *p1;
636     char    DV_dx[LG_MAX_NAME*2+1];
637int nballin, startin;
638nballin = NbIn+NbInCplx;
639if (flagCPLX) startin=NbIn; else startin=0;
640     //pmax = straffect+strlen(straffect);
641//---
642//     for (wi=0; wi<NbIn; ++wi)
643//for (wi=startin; wi<nballin; ++wi)
644for (wi=0; wi<nballin; ++wi)
645     {
646if (TabFlagIn[wi]==-1) continue; //entree reelle comprise dans une entree complexe
647
648         if (indicYS<=0) //(!isYSi)
649         {
650            sprintf(DA_dx, "YD%s_d%s", A, TabExpreSym[wi]);
651                  idiff = id_diff(DA_dx);
652                  if (idiff<0) //ce qui veut dire qu'on rencontre DA_dx pour la 1ere fois
653            {
654               if (NbDiff>=NB_MAX_DIFFVAR)
655               {  printf(" Ydf1: Automatic derivativ stopped for modul %s\n", ModulName);
656                  printf("       because :=> too much derivative in that modul\n");
657                  exit(-9);
658               }
659                           strcpy(TabDiff[NbDiff].vardiff, DA_dx);
660                           TabDiff[NbDiff].deblockportee = CurBlockLev;
661               ++NbDiff;
662               fprintf(fpginac,"  cout<<\"double %s; \"<<endl;\n", DA_dx); //+pB
663            }
664            else //DA_dx existe deja, mais pour backward il faut eventuellement
665            {    //produire de nouveau la declaration en tenant compte de l'imbrication des blocks !
666               if (TabDiff[idiff].deblockportee == 0)
667               {  TabDiff[idiff].deblockportee = CurBlockLev;
668                              fprintf(fpginac,"  cout<<\"double %s; \"<<endl;\n", DA_dx);
669               }
670            }
671         }
672         else
673            sprintf(DA_dx, "YJ%iI%i", indicYS, wi+1);
674//---
675         fprintf(fpginac,"  cout<<\"%s = \";", DA_dx);
676
677                                 NbDejaDiff=0;
678
679             strcpy(bufwrk, straffect);
680         pmax = bufwrk+strlen(bufwrk);
681         pstr = bufwrk;
682               while ((p1=str_tok(pstr, " \n\t", &delim, pmax))!=NULL)
683           {
684                   if (str_qalphanum(p1))
685                 if (!c_word(p1) && !is_yadvar(p1))
686             {
687                                                                  sprintf(dA_DV, "Yd%s_D%s", A, p1);
688                                                                  sprintf(DV_dx, "YD%s_d%s", p1, TabExpreSym[wi]); //.
689
690                                                            //pour ne produire la derivee qu'une seule fois
691                                                                        if (!dejadiff(dA_DV))
692                                                                        {  if (NbDejaDiff>=NB_MAX_DIFFVAR)
693                                                                                 {  printf(" Ydf1: Automatic derivativ stopped for modul %s\n", ModulName);
694                                                                                          printf("       because :=> too much derivative in that modul\n");
695                                                                                                 exit(-9);
696                                                                                        }
697                                                                                        strcpy(TabDejaDiff[NbDejaDiff], dA_DV);
698                                                                                        ++NbDejaDiff;
699                      if (!strcmp(p1, TabExpreSym[wi]))
700                      {  //fprintf(fpginac,"  cout<<\"Yd%s_D%s + \";", A, p1);
701                                                                               fprintf(fpginac,"  cout<<\"%s + \";", dA_DV);
702                      }
703                      else if (id_input(p1)==-1) //(!is_input(p1))
704                      {  //fprintf(fpginac,"  cout<<\"Yd%s_D%s*YD%s_d%s + \";", A, p1, p1, TabExpreSym[wi]);
705                         if (id_diff(DV_dx)>=0) //on s'assure que DV_dx existe bien ...
706                                                                                            fprintf(fpginac,"  cout<<\"%s*%s + \";", dA_DV, DV_dx);
707                      }
708                                                                        }
709             }
710                   pstr = pstr+strlen(pstr)+1;
711         }
712               fprintf(fpginac,"  cout <<\"0;\"<<endl;\n");
713     }
714}
715
716/*----------------------------------------------------------------------------*/
717/*============================================================================*/
718void quedeclar (char *instruct, char *pstr2)
719{  if (trace) printf("\n/*indicDECLAR & !indicAFFECT:|%s|%s|*/\n", instruct, pstr2);
720   //un token de Type (double, float, ...) a ete rencontred et pstr2 pointe dessus
721   //exemple soil_CG:         "} else { double ZFROZEN2;"
722   //on va decouper l'instruction en 2 morceaux : Debut (instruct), et la declaration proprement dite (pstr2)
723   pstr2[-1]='\0'; //nb: le token est en principe preceded d'au moins un ' ' ou '\t'
724   //on produit le debut
725   if (instruct<pstr2)
726      BackwardOut(instruct); //d'abord le debut de l'instruction
727
728   //on produit DAdx pour backward
729   BackProduce_DAdx(pstr2);
730         //on stocke et produit pour ginac les QAN d'instruct dans TabExp si ils n'existe pas deja (ni en symbol)
731   Sto_GinProduce_ExpreSym(pstr2);
732
733   //on reconduit la suite (declaration proprement dite) tel quel pour backward
734   BackwardOut(pstr2);
735}
736
737/*---------------------------------------------------------------------------*/
738void quedeclar_cplx(char *instruct, char *pstr2)
739{    char    *pstr, *pmax;
740     char    bufwrk[BUFSIZE+1];
741     char    delim;
742     char    *p1;
743     char    varcplx[LG_MAX_NAME+1];
744                 short   flagvarcplx=0;
745                 //short flagisinput=0;
746                 short   idin1=-1,idin2=-1;
747
748//exemple1:         "} else { complex < double > beta ( betr , beti ) ;"
749//                            ^
750//exemple2:         "} else { complex < double > beta ( betr , beti ), alpha ( ar , ai ), gamma;"
751//                            ^
752     pstr2[-1]='\0'; //nb: le token est en principe preceded d'au moins un ' ' ou '\t'
753     //on produit le debut
754     if (instruct<pstr2)
755        BackwardOut(instruct); //d'abord le debut de l'instruction
756
757     strcpy(bufwrk, pstr2);
758     pstr = bufwrk;
759     pmax = pstr+strlen(pstr);
760     while ((p1=str_tok(pstr, " \t", &delim, pmax))!=NULL)
761     {
762                     if ((p1[0]==')' || p1[0]==';') && flagvarcplx==1)          // fin de la variable complexe precedente
763                                 {
764                                                //a la fin, si flagisinput vaut 2 alors il s'agit une variable complexe d'entree
765                                                //if (flagisinput==2)
766                                                //Si idin1 et idin2 on une valeur d'indice alors (...) : variable complexe (d'entree?)
767                                                if (idin1>=0 && idin2>=0)
768                                                {  TabFlagIn[idin1] = TabFlagIn[idin2] = -1; //on neutralise ces entrees car c'est le complexe
769                                                                ++NbInCplx;                               //associed qui devient la variable d'entree
770                                                                //idin1 = idin2 = -1;
771                                                                //flagvarcplx=0;
772                                                }
773                                                else    //sinon, il s'agit d'une variable intermediaire, on produit DAdx pour backward
774                                                {  BackProduce_DAdx(varcplx);
775                                                }
776
777                                    //re-init et passage a l'eventuelle variable suivante
778                                    flagvarcplx=0;
779                                                idin1 = idin2 = -1;
780            pstr = pstr+strlen(pstr)+1; //pour avancer sur la chaine de carateres
781                                    continue;
782                                 }
783
784               if (str_qalphanum(p1))
785            if (!c_word(p1) && !is_yadvar(p1))
786                                 {
787            if (!flagvarcplx)
788                                                {  //on est sur le 1er token apres "double",  donc c'est sense etre le
789                                                   //nom de la variable complexe beta
790
791/*xxxxxxxxx
792                                                         if (!exist_expresym(p1))
793                                                         {  if (NbExpreSym>=NB_MAX_EXPRESYM)
794                                                                        {  printf(" Ydf1: Automatic derivativ stopped for modul %s\n", ModulName);
795                                                                                        printf("       because :=> too much token in that modul\n");
796                                                                                        exit(-9);
797                                                            }
798                                                            strcpy(TabExpreSym[NbExpreSym], p1);
799                                                            ++NbExpreSym;
800                                                            fprintf(fpginac,"  ex %s;\n", p1);
801                                                            fprintf(fpginac,"  symbol Ygs_%s(\"Ygs_%s\");\n", p1, p1);
802                                                         }
803*/
804                                                         Sto_GinProduce_ExpreSym(p1);
805/*xxxxxxxxx
806//             if (!exist_cplx(p1))
807                                                   {  if (NbCplx>=NB_MAX_CPLX)
808                  {  printf(" Ydf1: Automatic derivativ stopped for modul %s\n", ModulName);
809                     printf("       because :=> too much complex token in that modul\n");
810                     exit(-9);
811                  }
812                  strcpy(TabCplx[NbCplx], p1);
813                  ++NbCplx;
814                                                         }
815*/
816                                                         strcpy(varcplx, p1); //="beta"
817                                                   flagvarcplx=1;
818                                                }
819                                                else
820                                                {  //on est sur une des variables d'entree (betr ou beti) qui forme le complexe
821                                                   //if (is_input(p1)) ++flagisinput;
822                                                         if (idin1==-1) idin1=id_input(p1);
823                                                         else idin2=id_input(p1);
824                                                }
825
826                                 }
827         pstr = pstr+strlen(pstr)+1;
828     }
829
830                 //on reconduit la suite (declaration proprement dite) tel quel pour backward
831     BackwardOut(pstr2);
832}
833
834
835/*---------------------------------------------------------------------------*/
836/*=============================================================================*/
837void queaffect(char *instruct, char *pstr2)
838{  char   *pstr3;
839   char   affectsv[BUFSIZE+1];
840
841         if (trace) printf("\n/*indicAFFECT:|%s|%s|*/\n", instruct, pstr2);
842   //des tokens d'affectation ('=', '+=', '-=', '*=', '/=')
843   //on ete detected ... et pstr2 pointe dessus printf ("|%s|\n|%s|\n", instruct, pstr2);
844         //exemple:  "} else { double ZFROZEN2 = x1 ;"
845
846   //si on a VAR {+,-,*,/}= EXPR; on va transformer en VAR = VAR {+,-,*,/} ( EXPR );
847         if (pstr2[0]=='+' || pstr2[0]=='-' || pstr2[0]=='*' || pstr2[0]=='/')
848         {  //printf("avant:|%s|%p|%c|\n", instruct, pstr2, pstr2[0]);
849            transfo_affect(instruct, pstr2); //(! modifie la chaine passed mais pstr2 doit pointer sur '=')
850      //printf("apres:|%s|%p|%c|\n", instruct, pstr2, pstr2[0]);
851         }
852
853         //si les variables sont externes au module (une variable globale par exemple)
854         //il faut quand meme la declarer pour ginac
855         Sto_GinProduce_ExpreSym(instruct);
856
857         //ensuite, on va decouper l'instruction en 3 morceaux : Debut (instruct)  Variable(pstr3) Suite(pstr2)
858   --pstr2;
859   while ((pstr2[0]==' ' || pstr2[0]=='\t') && pstr2>instruct) --pstr2; //on remonte les espaces et \t
860   pstr3=pstr2; //pstr3 va servire a pointer sur le debut de la variable affectee
861   while (pstr3[0]!=' ' && pstr3[0]!='\t' && pstr3>instruct) --pstr3; //on remonte les autres caractères
862         if (pstr3>=instruct)  //si on est pas au debut de instruct
863   {  pstr3[0]='\0'; //on met un '\0' avant la variable affected
864      ++pstr3;
865   }
866   ++pstr2; pstr2[0]='\0'; //on met un '\0' apres la variable
867   ++pstr2; //pour ne pas perdre la partie affectation de la suite de 'instruction
868   //on devrait etre dans la situation suivante: ex:  "   if ( C1 ) " "A"    " = pow ( x , 2 ) , B ; "
869         //                                                  ^instruct       ^pstr3 ^pstr2
870
871   //au passage, on interdit l'affectation des variables d'input ...!
872   if (id_input(pstr3)!=-1) //(is_input(pstr3))
873   {  printf (" Ydf1: Automatic derivative failed for modul %s\n", ModulName);
874      printf ("       because :=> input values must not be changed !\n");
875                        exit (-9);
876   }
877
878   //positionnenemt d'un flag pour savoir s'il s'agit d'un YSi
879   indicYS = id_YSi(pstr3);
880
881   //puis on produit pour backward
882         if (instruct<pstr3) BackwardOut(instruct); //d'abord le debut de l'instruction (si different de pstr3)
883   if ((indicBLOCK-indicCROUV)>0) //if (indicBLOCK && !indicCROUV)
884   {  fprintf(fpginac,"  cout << \"{\"<<endl;\n"); //et eventuellement, on rajoute un crochet ouvrant ('{')
885      ++CurBlockLev; //printf("+CurBlockLev=%i\n", CurBlockLev);
886   }
887
888   //si on a detecter un tableau on passe et on le remplace par une variable intermediaire
889         if (indicTAB) substitut_produce_tab(pstr2); // puis les tableaux s'il y a lieu (! modifie la chaine passed)
890
891         //pour ginac il faut reconduire l'affectation en remplacant les variables de la partie droite par des symbols
892   //on sauvegarde donc cette partie droite car on devra la reproduire pour backward mais seulement apres les derivee
893   strcpy(affectsv, pstr2);    //sauvegarde pour backward
894         substitut_by_symbol(pstr2); //on remplace les QAN par leur equivalent symbol(! modifie la chaine passed)
895   fprintf(fpginac,"  %s %s\n", pstr3, pstr2); //et on produit pour ginac
896
897         //maintenant, il faut calculer les derivees.
898   //1) il faut  produire dans ginac les derivee de tous les QAN de droite pour celui de gauche :
899   //   ex avec : A = f(sB, sB, sC, ...)
900   //   on doit obtenir :  da_DB = A.diff(sB,1);  UNE SEULE FOIS
901   //                                                                            da_DC = A.diff(sC,1);                  ...
902         GinBackProduce_dfDf(pstr3, affectsv);
903
904   //2) puis il faut produire dans le backward directement, la derivee du terme de gauche par rapport aux entrees.
905   //   il s'agit de faire, la somme pour chaque entree xi :
906   //             DA_dxi = dA_DV1.DV1_dxi + ... + dA_DVn.DVn_dxi
907         BackProduce_Dfdx(pstr3, affectsv);
908
909   //on termine par l'affectation pour backward (sauf pour YSi a moins que level>=9 !?)
910   if (indicYS<=0 || (indicYS>0 && prodlevel>=9))
911   {
912                        BackwardOut(pstr3);          //la variable
913      fprintf(fpginac,"  cout <<\" \";\n"); //(un espace separateur?)
914                        BackwardOut(affectsv);       //puis la suite (partie affectation prealablement sauvegarded)
915   }
916
917         //eventuellement, il faut terminer par une accolade fermante ('}')
918   if ((indicBLOCK-indicCROUV)>0) //if (indicBLOCK && !indicCROUV)
919   {  fprintf(fpginac,"  cout <<endl<< \"}\"<<endl;\n");
920      decrem_diff_blocklev(); //--CurBlockLev; //printf("+CurBlockLev=%i\n", CurBlockLev);
921   }
922}
923/*----------------------------------------------------------------------------*/
924/*============================================================================*/
925void declaretaffect (char *instruct, char *pstr2)
926{  //declaration et affectation: ex : if (... double A=vglob1, B=pow(A,2), C, D=A*vglob2;
927   //pstr2 pointe sur le type
928         char   *p3;
929         char   *paffect;
930         char   winst[BUFSIZE +1];
931         int    entre;
932         int    wi, last;
933         int    blockindic=0;
934
935   if (trace) printf("\n/*indicDECLAR & indicAFFECT:|%s|%s|*/\n", instruct, pstr2);
936
937   //on produit le debut
938         pstr2[-1]='\0'; //nb: le token est en principe preceded d'au moins un ' ' ou '\t'
939   if (instruct<pstr2) BackwardOut(instruct); //d'abord le debut de l'instruction (si different de pstr2)
940
941   //puis ici, y'a peut etre bien des crochet ....
942   if ((indicBLOCK-indicCROUV)>0) //if (indicBLOCK && !indicCROUV)
943   {  fprintf(fpginac,"  cout << \"{\"<<endl;\n"); //et eventuellement, on rajoute une accolade ouvrante ('{')
944      ++CurBlockLev; //printf("+CurBlockLev=%i\n", CurBlockLev);
945                        //et on neutralise le flag indicBLOCK pour pas avoir des accolades en double par la fct queaffect()
946            //blockindic=1; indicBLOCK=0;
947                        blockindic=indicBLOCK;  indicBLOCK=indicCROUV;
948   }
949
950         //on se positionne a la fin du type pour l'isoler
951         p3 = pstr2;
952         while (p3[0]!=' ' && p3[0]!='\t') ++p3;
953         p3[0]='\0';
954         ++p3;
955
956         //puis, on remplace toutes les ',' qui ne sont pas entre ({[]}) par ';'
957         //a partir de p3
958         entre = 0;
959         wi=0; last=0;
960         while (!last)
961         {   if (p3[wi]==';') last=1;
962
963             if (p3[wi]=='(' || p3[wi]=='{' || p3[wi]=='[') ++entre;
964             if (p3[wi]==')' || p3[wi]=='}' || p3[wi]==']') --entre;
965                         if (p3[wi]==',' && entre==0) p3[wi]=';';
966
967                         if (p3[wi]==';') //il faut traiter le cas   icicicicici
968                         {  if (!last) p3[wi+1]='\0';
969                            if ((paffect = str_affect(p3)) != NULL)
970                                        {  //on traite l'aspect declaration
971                                           paffect[-1] = '\0'; //ca isole la variable
972                                                 sprintf(winst, " %s %s ;\n", pstr2, p3); //on formate la declaration
973                                                 quedeclar(winst, winst);                                                     //et on la traite
974
975                                                 //on traite l'aspect affectation
976                                                 sprintf(winst, " %s %s \n", p3, paffect);
977                                                 paffect = str_affect(winst);
978                                                 queaffect(winst, paffect);
979                                        }
980          else // il ne s'agit que d'une declarartion
981                                        {   sprintf(winst, " %s %s \n", pstr2, p3); //on formate la declaration
982                                                  quedeclar(winst, winst);                                                   //et on la traite
983                                        }
984
985                                        p3 = &p3[wi+2]; //equiv: p3 = p3+wi+2;
986                                        wi = 0;
987                         }
988                         else
989                            ++wi;
990         }
991
992   //eventuellement, on ajoute une accolade fermante ('}') et on restaure le flag indicBLOCK
993   if (blockindic) //(blockindic>0)
994   {  fprintf(fpginac,"  cout <<endl<< \"}\"<<endl;\n");
995      decrem_diff_blocklev(); //--CurBlockLev; //printf("+CurBlockLev=%i\n", CurBlockLev);
996      indicBLOCK=blockindic; //indicBLOCK=1;
997   }
998
999         //printf("\n/*indicDECLAR & indicAFFECT:|%s|%s|*/\n", instruct, pstr2);
1000}
1001
1002/*=============================================================================*/
1003/* en entree : un nom de module.h qui est sensee contenir une fonction forward */
1004/* en sortie : un programme qui saura generer une fonction backward            */
1005/*=============================================================================*/
1006/*---------------------------------------------------------------------------*/
1007int main (int argc, char *argv[])
1008{  //syntaxe: Ydf1 wrk_modul_in_file_name  module  nbin  nbout  [prodlevel]
1009        int     nbinfound=0;
1010  char    *paffect;
1011        char      *pstr1;
1012  char    *pstr2=NULL;
1013        char      modul_file_name[LG_MAX_NAME+1];
1014        int     lenmodulname;
1015  printf("Ydf1:id:3\n");
1016
1017   /* debut : verif arg, ouverture fichier ... :::::::::::::::::::::::::::::::*/
1018  if (argc < 5 || argc > 6)
1019        {  printf (" Ydf1: Syntaxe error: Ydf1 modul_file_name module_name nbin nbout [prodlevel]}\n");
1020           exit(-9);
1021        }
1022
1023        strcpy(modul_file_name, argv[1]);
1024        if ((fpmodul = fopen(modul_file_name, "r")) <= 0)
1025        {  printf (" Ydf1: In file (%s) not found \n", argv[1]);
1026           exit(-9);
1027        }
1028
1029  if (argc==6)
1030  {  prodlevel=atoi(argv[5]);
1031  }
1032
1033  NbIn  = atoi(argv[3]);
1034  NbOut = atoi(argv[4]);
1035
1036  /*-----*/
1037        if ((fpginac = fopen("Y37wrk.cc", "w")) <= 0)
1038        {  printf (" Ydf1: Pb when opening out file (Y37wrk.cc)\n");
1039           exit(-9);
1040        }
1041  /*-----*/
1042
1043        //on recupere le nom du module (pour apres)
1044        strcpy(ModulName, argv[2]);                                     //en enlevant
1045        lenmodulname = strlen(ModulName);   //eventuellement .h
1046        if (ModulName[lenmodulname-1]=='h' && ModulName[lenmodulname-2]=='.')
1047           ModulName[lenmodulname-2]='\0';
1048
1049  /* entête */
1050  fprintf (fpginac, "#include <iostream>\n");
1051  fprintf (fpginac, "#include <ginac/ginac.h>\n");
1052  fprintf (fpginac, "using namespace std;\n");
1053  fprintf (fpginac, "using namespace GiNaC;\n");
1054  fprintf (fpginac, "int main()\n");
1055  fprintf (fpginac, "{\n");
1056
1057  memset(instruct, '\0', BUFSIZE+1); //instruct[0]='\0';
1058
1059  /* boucle de lecture du module */
1060  while (  (fgets(buffer, BUFSIZE+1, fpmodul)) != NULL)
1061  {   //printf("lu|%s|\n", buffer);
1062
1063                  pstr1 = strtok(buffer, delim);
1064      while (pstr1!=NULL)
1065      {   //printf("pstr1=|%s|\n", pstr1);
1066
1067          if (!strcmp(pstr1, "{")) ++CurBlockLev;
1068          if (!strcmp(pstr1, "}")) decrem_diff_blocklev(); //--CurBlockLev; //printf("CurBlockLev=%i\n", CurBlockLev);
1069          //----------------------------------------------------------
1070          //traitement ligne forward
1071                                        //----------------------------------------------------------
1072          if (Phase==0 && !strcmp(pstr1, "forward"))
1073          {  Phase=1;
1074          }
1075          else if (Phase==1)
1076          {  if (!strcmp(pstr1, "{")) //if (pstr1[0]=='{')
1077             {
1078                if (nbinfound != NbIn)
1079                {  printf (" Ydf1: Automatic derivative failed for modul %s\n", ModulName);
1080                   printf ("       because :=> Desagree on input: found %i expected %i\n", nbinfound, NbIn);
1081                                                                         exit (-9);
1082                }
1083                fprintf(fpginac, "  cout << \"void %s::backward (", ModulName);
1084                for (k=0; k<NbIn-1; ++k)
1085                    fprintf(fpginac, "YREAL  %s, ", TabExpreSym[k] );
1086                fprintf(fpginac, "YREAL  %s ", TabExpreSym[k] );
1087                fprintf(fpginac, ")\"<<endl<<\"{\";\n");
1088
1089                Phase=2;
1090                                                                strcpy(delim," \t");  //delimiteur pour la PHASE 2
1091             }
1092             else
1093             {  //traitement ligne forward : symbole d'input
1094                if (strcmp(pstr1, "YREAL"))
1095                {  //chouette voici un symbole d'input //printf ("symbol=%s\n", pstr1);
1096                                                                         Sto_GinProduce_ExpreSym(pstr1);
1097                   ++nbinfound;
1098               }
1099             }
1100          }
1101                                        //----------------------------------------------------------
1102          // fin ligne forward, maintenant il s'agit de traiter le corps
1103                                        //----------------------------------------------------------
1104          //algo : on stock les tokens dans une chaine jusqu'a un ';'
1105                                  else if (Phase==2)
1106          {
1107                                                        //stockage (par concatenation) des tokens dans la chaine instruct
1108                                                  sprintf (instruct, "%s %s", instruct, pstr1);
1109
1110              //indicateurs ...
1111              if      (!strcmp(pstr1, "complex"))
1112              {  flagCPLX=1;
1113                                                           //ne pas casser pstr2 si deja positionned
1114                                                                 if (pstr2==NULL) //if (!indicAFFECT) //sinon il doit s'agir d'un cast
1115                                                           {  pstr2=instruct+strlen(instruct)-strlen(pstr1);
1116                                                                    indicDECLAR = 1;
1117                                                                 }
1118              }
1119              else if (!strcmp(pstr1, "if"))      ++indicBLOCK; //indicBLOCK  = 1;
1120              else if (!strcmp(pstr1, "else"))    ++indicBLOCK; //indicBLOCK  = 1;
1121              else if (!strcmp(pstr1, "while"))   ++indicBLOCK; //indicBLOCK  = 1;
1122              else if (!strcmp(pstr1, "for"))     ++indicBLOCK; //indicBLOCK  = 1;
1123              else if (!strcmp(pstr1, "{"))       ++indicCROUV; //indicCROUV  = 1;
1124              else if (strchr(pstr1, '[')!=NULL)  indicTAB    = 1;
1125              else if ( !strcmp(pstr1, "YREAL") || !strcmp(pstr1, "double")  || !strcmp(pstr1, "int")
1126              ||        !strcmp(pstr1, "long")  || !strcmp(pstr1, "float")
1127                      )
1128              {  //ne pas casser pstr2 si deja positionned
1129                                                           if (pstr2==NULL) //if (!indicAFFECT) //sinon il doit s'agir d'un cast
1130                                                           {  pstr2=instruct+strlen(instruct)-strlen(pstr1);
1131                                                                    indicDECLAR = 1;
1132                                                                 }
1133              }
1134
1135                                                        paffect = str_affect(pstr1);
1136                                                        if (paffect != NULL)
1137                                                        {  //if (!indicAFFECT && !indicDECLAR) //... ne pas casser pstr2 si deja positionned
1138                                                           if (pstr2==NULL) //... ne pas casser pstr2 si deja positionned
1139                                                           {  //pstr2 = paffect;
1140                                                                    pstr2 = instruct+strlen(instruct)-strlen(paffect);
1141                                                                 }
1142                                                           indicAFFECT = 1;
1143                                                        }
1144
1145              //au passage, on s'assurer qu'YS* n'apparait pas en partie droite
1146              //because c'est pas pratique a gerer, mais ce peut etre une source d'erreur !!!??? ...
1147              if  (indicAFFECT || indicDECLAR) //on est donc soit deja en partie droite d'une affectation,
1148              {                                //soit sur une declaration et la aussi YSi ne doit pas apparaitre
1149                                  if (id_YSi(pstr1)>0)
1150                  {  printf (" Ydf1: Automatic derivative failed for modul %s\n", ModulName);
1151                     printf ("       because :=> YSi must not appears neither on declaration or on right side of an affectation !\n");
1152                                                                           exit (-9);
1153                  }
1154              }
1155
1156                    //fin de constitution de la chaine; il faut traiter
1157              if  (!strcmp(pstr1, ";"))
1158              {
1159                  if (indicDECLAR && !indicAFFECT)  //=> SI QUE DECLAR
1160                                                                        {        if (flagCPLX)                                                                                   //ex:  " if ( C1 ) complex < double > A ( rA , iA ) ; "
1161                                                                              quedeclar_cplx(instruct, pstr2); //                           ^
1162                                                                           else //cas 'normal'
1163                                                                                    quedeclar(instruct, pstr2);   //ex:  " if ( C1 ) double A ; "
1164                                                                                                                                                                                                                  //      ^instruct  ^pstr2
1165                                                                        }
1166                  else if (indicDECLAR) //=> SI DECLAR ET AFFECT
1167                  {  declaretaffect(instruct, pstr2); //ex:  "if ( C1 )  double A = pow ( x , 2 ) , B ; "
1168                                                                        }                                   //      ^instruct  ^pstr2
1169                                                                        else if (indicAFFECT) //=> SI QUE AFFECT
1170                  {   queaffect(instruct, pstr2);     //ex:  "   if ( C1 )  A = pow ( x , 2 ) , B ; "
1171                                                                        }                                   //      ^instruct       ^pstr2
1172                  else
1173                  {  // ???!!!! reconduit-on ou pas tel quel !!!???
1174                     if (prodlevel==1 || prodlevel>2)
1175                     {  //on reproduite tel quel, QUE pour BACKWARD et donc RIEN pour GINAC.
1176                        //il doit s'agir de ce genre d'instruction dont on ne sait que faire
1177                        //pour la derivation comme *printf*, *str*, *get*, *scan*, io, ...
1178
1179                        //j'ai un pb avec les " exemple :  strcpy ( toto , "toto" ) ; ...
1180                        //ca devrait etre regled
1181                        //printf("  cout << \"%s\";\n", instruct);
1182                                                                                                BackwardOut(instruct); //par contre c'est ok pour par exemple:  strcpy(toto,titi);
1183                     }
1184                  }
1185
1186                  //re-init pour instruction suivante
1187                  indicBLOCK=indicCROUV=indicTAB=indicAFFECT=indicDECLAR=indicYS=0; //re-init des indicateurs
1188                                                                        pstr2=NULL;
1189                  memset(instruct, '\0', BUFSIZE+1); //reinit de instruct
1190              }//fin de if ';'
1191                                        }//fin du if Phase 2
1192                            //passer au token suivant
1193          pstr1 = strtok(NULL, delim);
1194     }
1195  }
1196  BackwardOut(instruct); //pour reconduire la fin du code pour backward qui peut (et
1197                         //devrait) consister des carateres de terminaison de block ('}')
1198
1199        //fprintf(fpginac, "  } \n\n", pstr2); // fin pour ginac
1200        fprintf(fpginac, "  } \n\n"); // fin pour ginac
1201  exit(0);
1202}
Note: See TracBrowser for help on using the repository browser.