Annotation of rpl/src/analyse_notation_algebrique.c, revision 1.45
1.14 bertrand 1: /*
2: ================================================================================
1.42 bertrand 3: RPL/2 (R) version 4.1.13
1.41 bertrand 4: Copyright (C) 1989-2013 Dr. BERTRAND Joël
1.14 bertrand 5:
6: This file is part of RPL/2.
7:
8: RPL/2 is free software; you can redistribute it and/or modify it
9: under the terms of the CeCILL V2 License as published by the french
10: CEA, CNRS and INRIA.
11:
12: RPL/2 is distributed in the hope that it will be useful, but WITHOUT
13: ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14: FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL V2 License
15: for more details.
16:
17: You should have received a copy of the CeCILL License
18: along with RPL/2. If not, write to info@cecill.info.
19: ================================================================================
20: */
21:
22:
1.23 bertrand 23: #include "rpl-conv.h"
24:
25:
26: /*
27: ================================================================================
28: Analyseur syntaxique d'une expression algébrique
29: ================================================================================
30: Entrées : chaîne de caractères comprenant l'expression algébrique
31: --------------------------------------------------------------------------------
32: Sorties : chaîne de caractères contenant l'expression convertie en
33: notation polonaise inverse et liste chaînée contenant les diverses
34: fonctions.
35: --------------------------------------------------------------------------------
36: Effets de bord : néant
37: ================================================================================
38: */
39:
40: unsigned char *
41: analyse_algebrique(struct_processus *s_etat_processus,
42: unsigned char *chaine_algebrique, struct_liste_chainee **l_base_liste)
43: {
44: struct_fonction *s_fonction;
45:
46: struct_liste_chainee *l_element_courant;
47:
48: logical1 chaine_invalide;
49: logical1 drapeau_debut_zone_valide;
50: logical1 drapeau_elimination_parentheses;
51: logical1 drapeau_fin_boucle;
52: logical1 drapeau_fin_zone_valide;
53: logical1 drapeau_modification;
54: logical1 drapeau_priorite_entierement_traitee;
55: logical1 fin_boucle_extraction;
56: logical1 presence_chaine;
57: logical1 presence_fonction;
58: logical1 presence_liste;
59:
60: unsigned char *chaine_arguments;
61: unsigned char *chaine_centrale;
62: unsigned char *chaine_droite;
63: unsigned char *chaine_fonction;
64: unsigned char *chaine_gauche;
65: unsigned char *chaine_travail;
66: unsigned char *epilogue;
67: unsigned char instruction_test[6];
68: unsigned char *instruction_majuscule;
69: unsigned char *prologue;
70: unsigned char *ptr1;
71: unsigned char *ptr2;
72: unsigned char *registre_instruction_courante;
73: unsigned char registre_instruction_valide;
74: unsigned char registre_test;
75: unsigned char *sous_chaine_droite;
76: unsigned char *sous_chaine_gauche;
77: unsigned char *tampon;
78:
1.43 bertrand 79: int t0;
80: int t1;
81: int t2;
82: int t3;
83: int t4;
84:
85: integer8 debut_zone_algebrique;
86: integer8 fin_zone_algebrique;
87: integer8 i;
88: integer8 j;
1.44 bertrand 89: integer8 k;
1.43 bertrand 90: integer8 longueur_chaine;
91: integer8 longueur_tampon;
92: integer8 niveau;
93: integer8 niveau_liste;
94: integer8 nombre_apostrophes;
95: integer8 nombre_arguments;
96: integer8 priorite;
1.23 bertrand 97:
98: (*l_base_liste) = NULL;
99:
100: /*
101: * Vérification de la chaîne. Celle-ci doit comporter au moins un
102: * caractère entre les délimiteurs ''.
103: */
104:
105: presence_chaine = d_faux;
106: presence_liste = d_faux;
107: niveau_liste = 0;
108:
1.43 bertrand 109: for(i = 1, chaine_invalide = d_vrai; i < ((integer8)
110: strlen(chaine_algebrique)) - 1; i++)
1.23 bertrand 111: {
112: if (chaine_algebrique[i] != ' ')
113: {
114: chaine_invalide = d_faux;
115: }
116:
117: if (chaine_algebrique[i] == '"')
118: {
119: presence_chaine = (presence_chaine == d_faux) ? d_vrai : d_faux;
120: }
121: else if (presence_chaine == d_faux)
122: {
123: if (chaine_algebrique[i] == '{')
124: {
125: presence_liste = d_vrai;
126: niveau_liste++;
127: }
128: else if (chaine_algebrique[i] == '}')
129: {
130: presence_liste = d_vrai;
131: niveau_liste--;
132: }
133: }
134: }
135:
136: if ((chaine_invalide == d_vrai) || (presence_chaine == d_vrai) ||
137: (niveau_liste != 0) || (presence_liste == d_vrai))
138: {
139: (*s_etat_processus).erreur_execution = d_ex_expression_invalide;
140: return(NULL);
141: }
142:
143: /*
144: * Transformation des "**" en "^ "
145: */
146:
1.43 bertrand 147: for(i = 1; i < ((integer8) strlen(chaine_algebrique)) - 1; i++)
1.23 bertrand 148: {
149: if (chaine_algebrique[i] == '*')
150: {
151: if (chaine_algebrique[i + 1] == '*')
152: {
153: chaine_algebrique[i++] = '^';
154: chaine_algebrique[i] = ' ';
155: }
156: }
157: }
158:
159: if ((chaine_travail = (unsigned char *) malloc((strlen(chaine_algebrique) +
160: 1) * sizeof(unsigned char))) == NULL)
161: {
162: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
163: return(NULL);
164: }
165:
166: strcpy(chaine_travail, chaine_algebrique);
167:
168: /*
169: * Retrait des espaces dans l'expression algébrique
170: */
171:
172: ptr1 = chaine_travail;
173: ptr2 = chaine_travail;
174: presence_chaine = d_faux;
175:
176: while((*ptr1) != d_code_fin_chaine)
177: {
178: if ((*ptr1) == '"')
179: {
1.45 ! bertrand 180: if (ptr1 != chaine_travail)
! 181: { // Il existe un caractère précédent.
! 182: if ((*(ptr1 - 1)) != '\\')
! 183: {
! 184: if (presence_chaine == d_faux)
! 185: {
! 186: presence_chaine = d_vrai;
! 187: }
! 188: else
! 189: {
! 190: presence_chaine = d_faux;
! 191: }
! 192: }
1.23 bertrand 193: }
194: else
1.45 ! bertrand 195: { // Il n'existe pas de caractère précédent.
! 196: if (presence_chaine == d_faux)
! 197: {
! 198: presence_chaine = d_vrai;
! 199: }
! 200: else
! 201: {
! 202: presence_chaine = d_faux;
! 203: }
1.23 bertrand 204: }
205: }
206:
207: if (presence_chaine == d_faux)
208: {
209: if ((*ptr1) != ' ')
210: {
211: (*(ptr2++)) = (*ptr1);
212: }
213: else
214: {
215: instruction_test[5] = d_code_fin_chaine;
216:
217: instruction_majuscule = conversion_majuscule(strncpy(
218: instruction_test, ptr1, 5));
219:
220: if (instruction_majuscule == NULL)
221: {
222: (*s_etat_processus).erreur_systeme =
223: d_es_allocation_memoire;
224: return(NULL);
225: }
226:
227: /*
228: * Repérer le premier espace ou la fin de la chaîne.
229: */
230:
231: if (strcmp(instruction_majuscule, " AND ") == 0)
232: {
233: for(i = 0; i < 4; (*(ptr2++)) = (*(ptr1++)), i++);
234: (*(ptr2++)) = (*ptr1);
235: }
236: else if (strcmp(instruction_majuscule, " XOR ") == 0)
237: {
238: for(i = 0; i < 4; (*(ptr2++)) = (*(ptr1++)), i++);
239: (*(ptr2++)) = (*ptr1);
240: }
241: else if ((strncmp(instruction_majuscule, " OR ", 4) == 0) &&
242: (strlen(instruction_majuscule) == 4))
243: {
244: for(i = 0; i < 3; (*(ptr2++)) = (*(ptr1++)), i++);
245: (*(ptr2++)) = (*ptr1);
246: }
247:
248: free(instruction_majuscule);
249: }
250:
251: ptr1++;
252: }
253: else
254: {
255: (*(ptr2++)) = (*(ptr1++));
256: }
257: }
258:
259: (*ptr2) = d_code_fin_chaine;
260:
261: do
262: {
263: i = 0;
264: drapeau_modification = d_faux;
265:
266: do
267: {
268: presence_chaine = d_faux;
269: drapeau_debut_zone_valide = d_faux;
270: debut_zone_algebrique = 0;
271: drapeau_fin_boucle = d_faux;
272:
273: do
274: {
275: if (chaine_travail[i] == d_code_fin_chaine)
276: {
277: drapeau_fin_boucle = d_vrai;
278: }
279: else if ((chaine_travail[i] == '\'') &&
280: (presence_chaine == d_faux))
281: {
282: drapeau_fin_boucle = d_vrai;
283: debut_zone_algebrique = i;
284: drapeau_debut_zone_valide = d_vrai;
285: }
286: else if (chaine_travail[i] == '"')
287: {
288: presence_chaine = (presence_chaine == d_vrai)
289: ? d_faux : d_vrai;
290: }
291:
292: i++;
293: } while(drapeau_fin_boucle == d_faux);
294:
295: presence_chaine = 0;
296: drapeau_fin_zone_valide = d_faux;
297:
298: if (drapeau_debut_zone_valide == d_vrai)
299: {
300: j = debut_zone_algebrique + 1;
301: }
302: else
303: {
304: j = 0;
305: }
306:
307: fin_zone_algebrique = 0;
308: drapeau_fin_boucle = d_faux;
309:
310: do
311: {
312: if (chaine_travail[j] == 0)
313: {
314: drapeau_fin_boucle = d_vrai;
315: }
316:
317: if ((chaine_travail[j] == '\'') && (presence_chaine == d_faux))
318: {
319: drapeau_fin_boucle = d_vrai;
320: fin_zone_algebrique = j;
321: drapeau_fin_zone_valide = d_vrai;
322: }
323:
324: if (chaine_travail[j] == '"')
325: {
326: presence_chaine = (presence_chaine == d_vrai)
327: ? d_faux : d_vrai;
328: }
329:
330: j++;
331: } while(drapeau_fin_boucle == d_faux);
332:
333: if ((drapeau_debut_zone_valide == d_vrai) &&
334: (drapeau_fin_zone_valide == d_vrai))
335: {
336: chaine_gauche = purification_chaine(
337: extraction_chaine(chaine_travail,
338: 1, debut_zone_algebrique));
339: chaine_centrale = purification_chaine(
340: extraction_chaine(chaine_travail,
341: debut_zone_algebrique + 1, fin_zone_algebrique + 1));
342: chaine_droite = purification_chaine(
343: extraction_chaine(chaine_travail,
1.43 bertrand 344: fin_zone_algebrique + 2,
345: (integer8) strlen(chaine_travail)));
1.23 bertrand 346:
347: free(chaine_travail);
348:
349: if ((chaine_gauche == NULL) || (chaine_centrale == NULL) ||
350: (chaine_droite == NULL))
351: {
352: (*s_etat_processus).erreur_systeme =
353: d_es_allocation_memoire;
354: return(NULL);
355: }
356:
357: if ((strcmp(chaine_centrale, "''") == 0) ||
358: (strcmp(chaine_centrale, "'()'") == 0))
359: {
360: free(chaine_gauche);
361: free(chaine_centrale);
362: free(chaine_droite);
363:
364: (*s_etat_processus).erreur_execution =
365: d_ex_expression_invalide;
366: return(NULL);
367: }
368:
369: i = 1;
370: niveau = 0;
371: drapeau_elimination_parentheses = d_vrai;
372: presence_chaine = d_faux;
373:
1.43 bertrand 374: while(i < ((integer8) strlen(chaine_centrale)) - 1)
1.23 bertrand 375: {
376: if (chaine_centrale[i] == '"')
377: {
378: presence_chaine = (presence_chaine == d_faux)
379: ? d_vrai : d_faux;
380:
381: if (i == 1)
382: {
383: drapeau_elimination_parentheses = d_faux;
384: }
385: }
386: else if (presence_chaine == d_faux)
387: {
388: if (chaine_centrale[i] == '(')
389: {
390: niveau++;
391: }
392:
393: if ((niveau == 0) || ((((test_cfsf(s_etat_processus,
394: 48) == d_vrai) && (chaine_centrale[i] ==
395: '.')) || ((test_cfsf(s_etat_processus, 48)
396: == d_faux) && (chaine_centrale[i] == ',')))
397: && (niveau == 1)))
398: {
399: drapeau_elimination_parentheses = d_faux;
400: }
401:
402: if (chaine_centrale[i] == ')')
403: {
404: niveau--;
405: }
406: }
407:
408: i++;
409: }
410:
411: if (drapeau_elimination_parentheses == d_vrai)
412: {
413: tampon = chaine_centrale;
414:
415: if ((chaine_centrale = (unsigned char *) malloc(
416: (strlen(tampon) - 1) * sizeof(unsigned char)))
417: == NULL)
418: {
419: (*s_etat_processus).erreur_systeme =
420: d_es_allocation_memoire;
421: return(NULL);
422: }
423:
424: tampon[strlen(tampon) - 2] = d_code_fin_chaine;
425:
426: sprintf(chaine_centrale, "'%s'", &(tampon[2]));
427: free(tampon);
428:
429: fin_zone_algebrique -= 2;
430: drapeau_modification = d_vrai;
431: }
432:
433: if ((test_expression_rpn(chaine_centrale) == d_vrai) &&
434: (fin_zone_algebrique - debut_zone_algebrique > 0))
435: {
436: if ((tampon = purification_chaine(
437: extraction_chaine(chaine_centrale, 2,
1.43 bertrand 438: ((integer8) strlen(chaine_centrale)) - 1))) == NULL)
1.23 bertrand 439: {
440: (*s_etat_processus).erreur_systeme =
441: d_es_allocation_memoire;
442: return(NULL);
443: }
444:
445: /*
446: * Si on tombe sur une fonction intrinsèque ou
447: * extrinsèque, il doit y avoir des arguments passés
448: * entre parenthèses et on ne doit pas passer par ici !
449: */
450:
451: registre_instruction_courante = (*s_etat_processus)
452: .instruction_courante;
453: registre_test = (*s_etat_processus).test_instruction;
454: registre_instruction_valide = (*s_etat_processus)
455: .instruction_valide;
456:
457: (*s_etat_processus).test_instruction = 'Y';
458: (*s_etat_processus).instruction_courante = tampon;
459:
460: analyse(s_etat_processus, NULL);
461:
462: (*s_etat_processus).test_instruction = registre_test;
463: (*s_etat_processus).instruction_courante =
464: registre_instruction_courante;
465:
466: if (((*s_etat_processus).instruction_valide == 'Y') &&
467: ((*s_etat_processus).constante_symbolique == 'N'))
468: {
469: free(chaine_gauche);
470: free(chaine_centrale);
471: free(chaine_droite);
472: free(tampon);
473:
474: (*s_etat_processus).instruction_valide =
475: registre_instruction_valide;
476:
477: (*s_etat_processus).erreur_execution =
478: d_ex_expression_invalide;
479: return(NULL);
480: }
481:
482: (*s_etat_processus).instruction_valide =
483: registre_instruction_valide;
484:
485: free(chaine_centrale);
486: chaine_centrale = tampon;
487:
488: fin_zone_algebrique--;
489: drapeau_modification = d_vrai;
490: }
491: else if ((test_fonction(chaine_centrale) == d_vrai) &&
492: (fin_zone_algebrique - debut_zone_algebrique > 0))
493: {
494: i = 1;
1.43 bertrand 495: while((i < ((integer8) strlen(chaine_centrale)) - 1) &&
1.23 bertrand 496: (chaine_centrale[i] != '('))
497: {
498: i++;
499: }
500:
1.43 bertrand 501: j = ((integer8) strlen(chaine_centrale)) - 1;
1.23 bertrand 502: while(chaine_centrale[j] != ')')
503: {
504: j--;
505: }
506:
507: chaine_fonction = purification_chaine(
508: extraction_chaine(chaine_centrale, 2, i));
509: chaine_arguments = purification_chaine(
510: extraction_chaine(chaine_centrale, i + 2, j));
511:
512: i = 0;
513: niveau = 0;
514: nombre_arguments = 1;
515:
516: while(chaine_arguments[i] != d_code_fin_chaine)
517: {
518: if (chaine_arguments[i] == '(')
519: {
520: niveau++;
521: }
522:
523: if (chaine_arguments[i] == ')')
524: {
525: niveau--;
526: }
527:
528: if ((chaine_arguments[i] == ',') && (niveau == 0))
529: {
530: sous_chaine_gauche = purification_chaine(
531: extraction_chaine(chaine_arguments, 1, i));
532: sous_chaine_droite = purification_chaine(
533: extraction_chaine(chaine_arguments, i + 2,
1.43 bertrand 534: ((integer8) strlen(chaine_arguments))));
1.23 bertrand 535:
536: free(chaine_arguments);
537:
538: if ((chaine_arguments = (unsigned char *) malloc(
539: (strlen(sous_chaine_gauche) + strlen(
540: sous_chaine_droite) + 3 + 1) * sizeof(
541: unsigned char))) == NULL)
542: {
543: (*s_etat_processus).erreur_systeme =
544: d_es_allocation_memoire;
545: return(NULL);
546: }
547:
548: sprintf(chaine_arguments, "%s' '%s",
549: sous_chaine_gauche, sous_chaine_droite);
550: i += 2;
551:
552: free(sous_chaine_gauche);
553: free(sous_chaine_droite);
554:
555: nombre_arguments++;
556: }
557:
558: i++;
559: }
560:
561: free(chaine_centrale);
562:
563: l_element_courant = (*l_base_liste);
564: presence_fonction = d_faux;
565:
566: while((l_element_courant != NULL) &&
567: (presence_fonction == d_faux))
568: {
569: if (strcmp((*((struct_fonction *) ((*l_element_courant)
570: .donnee))).nom_fonction, chaine_fonction) == 0)
571: {
572: presence_fonction = d_vrai;
573: }
574: else
575: {
576: l_element_courant = (*l_element_courant).suivant;
577: }
578: }
579:
580: if (presence_fonction == d_vrai)
581: {
582: if ((*((struct_fonction *)
583: ((*l_element_courant).donnee)))
584: .nombre_arguments != nombre_arguments)
585: {
586: (*s_etat_processus).erreur_execution =
587: d_ex_nombre_arguments;
588:
589: free(chaine_arguments);
590: free(chaine_fonction);
591: free(chaine_gauche);
592: free(chaine_droite);
593:
594: return(NULL);
595: }
596: }
597: else
598: {
599: registre_instruction_courante = (*s_etat_processus)
600: .instruction_courante;
601: registre_test = (*s_etat_processus).test_instruction;
602: registre_instruction_valide = (*s_etat_processus)
603: .instruction_valide;
604:
605: (*s_etat_processus).test_instruction = 'Y';
606: (*s_etat_processus).instruction_courante =
607: chaine_fonction;
608:
609: analyse(s_etat_processus, NULL);
610:
611: (*s_etat_processus).test_instruction = registre_test;
612: (*s_etat_processus).instruction_courante =
613: registre_instruction_courante;
614: (*s_etat_processus).instruction_valide =
615: registre_instruction_valide;
616:
1.43 bertrand 617: if (((*s_etat_processus).nombre_arguments !=
618: nombre_arguments) &&
1.23 bertrand 619: ((*s_etat_processus).nombre_arguments != -2))
620: {
621: (*s_etat_processus).erreur_execution =
622: d_ex_nombre_arguments_fonction;
623:
624: free(chaine_arguments);
625: free(chaine_fonction);
626: free(chaine_gauche);
627: free(chaine_droite);
628:
629: return(NULL);
630: }
631:
632: if ((l_element_courant = (struct_liste_chainee *)
633: malloc(sizeof(struct_liste_chainee))) == NULL)
634: {
635: (*s_etat_processus).erreur_systeme =
636: d_es_allocation_memoire;
637: return(NULL);
638: }
639:
640: (*l_element_courant).suivant = (*l_base_liste);
641: (*l_base_liste) = l_element_courant;
642:
643: if ((s_fonction = malloc(sizeof(struct_fonction)))
644: == NULL)
645: {
646: (*s_etat_processus).erreur_systeme =
647: d_es_allocation_memoire;
648: return(NULL);
649: }
650:
651: if (((*s_fonction).nom_fonction = (unsigned char *)
652: malloc((strlen(chaine_fonction) + 1) *
653: sizeof(unsigned char))) == NULL)
654: {
655: (*s_etat_processus).erreur_systeme =
656: d_es_allocation_memoire;
657: return(NULL);
658: }
659:
660: strcpy((*s_fonction).nom_fonction, chaine_fonction);
661: (*s_fonction).nombre_arguments = nombre_arguments;
662:
663: (*(*l_base_liste)).donnee = (void *) s_fonction;
664: }
665:
666: if ((chaine_centrale = (unsigned char *) malloc((strlen(
667: chaine_arguments) + 1 + strlen(chaine_fonction)
668: + 1 + 2) * sizeof(unsigned char))) == NULL)
669: {
670: (*s_etat_processus).erreur_systeme =
671: d_es_allocation_memoire;
672: return(NULL);
673: }
674:
675: sprintf(chaine_centrale, "'%s' %s", chaine_arguments,
676: chaine_fonction);
677: drapeau_modification = d_vrai;
678:
679: free(chaine_arguments);
680: free(chaine_fonction);
681: }
682: else if ((chaine_centrale[1] == '+') ||
683: (chaine_centrale[1] == '-'))
684: {
685: if (chaine_centrale[1] == '-')
686: {
687: tampon = chaine_centrale;
688:
689: if ((chaine_centrale = (unsigned char *) malloc(
690: (strlen(tampon) + 5) * sizeof(unsigned char)))
691: == NULL)
692: {
693: (*s_etat_processus).erreur_systeme =
694: d_es_allocation_memoire;
695: return(NULL);
696: }
697:
698: tampon[strlen(tampon) - 1] = d_code_fin_chaine;
699: sprintf(chaine_centrale, "'NEG(%s)'", &(tampon[2]));
700: fin_zone_algebrique += 5;
701: drapeau_modification = d_vrai;
702:
703: free(tampon);
704: }
705: else
706: {
707: tampon = chaine_centrale;
708:
709: if ((chaine_centrale = (unsigned char *) malloc(
710: (strlen(tampon) + 7) * sizeof(unsigned char)))
711: == NULL)
712: {
713: (*s_etat_processus).erreur_systeme =
714: d_es_allocation_memoire;
715: return(NULL);
716: }
717:
718: tampon[strlen(tampon) - 1] = d_code_fin_chaine;
719: sprintf(chaine_centrale, "'RELAX(%s)'", &(tampon[2]));
720: fin_zone_algebrique += 7;
721: drapeau_modification = d_vrai;
722:
723: free(tampon);
724: }
725: }
726:
727: if ((chaine_travail = (unsigned char *) malloc(
728: (strlen(chaine_gauche) + strlen(chaine_centrale) +
729: strlen(chaine_droite) + 1 + 2) * sizeof(unsigned char)))
730: == NULL)
731: {
732: (*s_etat_processus).erreur_systeme =
733: d_es_allocation_memoire;
734: return(NULL);
735: }
736:
737: sprintf(chaine_travail, "%s %s %s", chaine_gauche,
738: chaine_centrale, chaine_droite);
739:
740: free(chaine_gauche);
741: free(chaine_centrale);
742: free(chaine_droite);
743: }
744:
745: i = fin_zone_algebrique + 1;
746: } while((drapeau_debut_zone_valide == d_vrai)
747: && (drapeau_fin_zone_valide == d_vrai));
748:
1.43 bertrand 749: for(longueur_chaine = (integer8) strlen(chaine_travail),
1.23 bertrand 750: i = nombre_apostrophes = 0; i < longueur_chaine;
751: nombre_apostrophes += (chaine_travail[i++] == '\'') ? 1 : 0);
752:
753: if (nombre_apostrophes != 0)
754: {
755: priorite = 1;
756:
757: do
758: {
759: drapeau_priorite_entierement_traitee = d_vrai;
760:
761: i = 0;
762: while((chaine_travail[i] != '\'') && (chaine_travail[i] != 0))
763: {
764: i++;
765: }
766:
767: if (chaine_travail[i] == 0)
768: {
769: i = 0;
770: }
771:
772: j = i + 1;
773: while((chaine_travail[j] != '\'') && (chaine_travail[j] != 0))
774: {
775: j++;
776: }
777:
778: if (chaine_travail[j] == 0)
779: {
780: j = 0;
781: }
782:
783: if ((chaine_travail[i] != 0) && (j != 0))
784: {
785: chaine_gauche = purification_chaine(
786: extraction_chaine(chaine_travail, 1, i));
787: chaine_centrale = purification_chaine(
788: extraction_chaine(chaine_travail,
789: i + 1, j + 1));
790: chaine_droite = purification_chaine(
791: extraction_chaine(chaine_travail, j + 2,
1.43 bertrand 792: ((integer8) strlen(chaine_travail))));
1.23 bertrand 793:
794: if ((chaine_gauche == NULL) || (chaine_centrale == NULL) ||
795: (chaine_droite == NULL))
796: {
797: (*s_etat_processus).erreur_systeme =
798: d_es_allocation_memoire;
799: return(NULL);
800: }
801:
802: drapeau_elimination_parentheses = d_vrai;
803:
1.43 bertrand 804: if ((longueur_tampon = ((integer8) strlen(chaine_centrale)))
805: != 0)
1.23 bertrand 806: {
807: niveau = 0;
808:
809: for(i = 1; i < longueur_tampon - 1; i++)
810: {
811: if (chaine_centrale[i] == '(')
812: {
813: niveau++;
814: }
815:
816: if ((niveau == 0) || ((((test_cfsf(s_etat_processus,
817: 48) == d_vrai) && (chaine_centrale[i] ==
818: '.')) || ((test_cfsf(s_etat_processus, 48)
819: == d_faux) && (chaine_centrale[i] == ',')))
820: && (niveau == 1)))
821: {
822: drapeau_elimination_parentheses = d_faux;
823: }
824:
825: if (chaine_centrale[i] == ')')
826: {
827: niveau--;
828: }
829: }
830:
831: if (drapeau_elimination_parentheses == d_vrai)
832: {
1.43 bertrand 833: if ((tampon = (unsigned char *) malloc(((size_t)
834: ((longueur_tampon = (integer8) strlen(
835: chaine_centrale)) + 1)) * sizeof(
1.23 bertrand 836: unsigned char))) == NULL)
837: {
838: (*s_etat_processus).erreur_systeme =
839: d_es_allocation_memoire;
840: return(NULL);
841: }
842:
843: chaine_centrale[longueur_tampon - 2] =
844: d_code_fin_chaine;
845: sprintf(tampon, "'%s'", &(chaine_centrale[2]));
846: free(chaine_centrale);
847: chaine_centrale = tampon;
848: drapeau_modification = d_vrai;
849: }
850: }
851:
852: if ((tampon = (unsigned char *) malloc(sizeof(
853: unsigned char))) == NULL)
854: {
855: (*s_etat_processus).erreur_systeme =
856: d_es_allocation_memoire;
857: return(NULL);
858: }
859:
860: tampon[0] = d_code_fin_chaine;
1.43 bertrand 861: longueur_chaine = (integer8) strlen(chaine_centrale);
862: k = ((integer8) strlen(chaine_centrale)) - 1;
1.23 bertrand 863: niveau = 0;
864: fin_boucle_extraction = d_faux;
865:
1.43 bertrand 866: while((k >= 0) && (fin_boucle_extraction == d_faux))
1.23 bertrand 867: {
1.43 bertrand 868: t0 = (k < ((integer8) strlen(chaine_centrale)))
1.23 bertrand 869: ? chaine_centrale[k + 1] : ' ';
870: t1 = chaine_centrale[k];
871: t2 = (k < 1) ? ' ' : chaine_centrale[k - 1];
872: t3 = (k < 2) ? ' ' : chaine_centrale[k - 2];
873: t4 = (k < 3) ? ' ' : chaine_centrale[k - 3];
874:
875: if ((t0 >= 'a') && (t0 <= 'z'))
876: {
877: t0 = t0 + ('A' - 'a');
878: }
879:
880: if ((t1 >= 'a') && (t1 <= 'z'))
881: {
882: t1 = t1 + ('A' - 'a');
883: }
884:
885: if ((t2 >= 'a') && (t2 <= 'z'))
886: {
887: t2 = t2 + ('A' - 'a');
888: }
889:
890: if ((t3 >= 'a') && (t3 <= 'z'))
891: {
892: t3 = t3 + ('A' - 'a');
893: }
894:
895: if ((t4 >= 'a') && (t4 <= 'z'))
896: {
897: t4 = t4 + ('A' - 'a');
898: }
899:
900: if (t1 == '(')
901: {
902: niveau++;
903: }
904:
905: if (niveau == 0)
906: {
907: prologue = purification_chaine(
908: extraction_chaine(chaine_centrale, 1, k));
909: epilogue = purification_chaine(
910: extraction_chaine(chaine_centrale,
911: k + 2, longueur_chaine));
912:
913: if ((prologue == NULL) || (epilogue == NULL))
914: {
915: (*s_etat_processus).erreur_systeme =
916: d_es_allocation_memoire;
917: return(NULL);
918: }
919:
920: /*
921: * Priorité = 1 : traitement des fonctions les plus prioritaires
922: */
923:
924: if (((priorite == 4) && (((t1 == '<') && (t0 != '=')
925: && (t2 != '=')) || ((t1 == '>') &&
926: (t0 != '=') && (t2 != '=')) ||
927: ((t1 == '=') && (t0 != '=') && (t0 != '<')
928: && (t0 != '>') && (t2 != '<') && (t2 != '>')
929: && (t2 != '=')))) ||
930: ((t1 == '+') && (priorite == 5) &&
931: (t2 != '\'') && (!(((t2 == '(')
932: || (t2 == '\'') || (t2 == 'e')
933: || (t2 == 'E')) && (((t3 >= '0')
934: && (t3 <= '9')) || (t3 == '.'))))) ||
935: ((t1 == '-') && (priorite == 6) &&
936: (t2 != '\'') && (!(((t2 == '(')
937: || (t2 == '\'') || (t2 == 'e')
938: || (t2 == 'E')) && (((t3 >= '0')
939: && (t3 <= '9')) || (t3 == '.')))))
940: || ((t1 == '*') && (priorite == 7))
941: || ((t1 == '/') && (priorite == 8)) ||
942: ((t1 == '^') && (priorite == 9)))
943: {
944: drapeau_priorite_entierement_traitee = d_faux;
945: fin_boucle_extraction = d_vrai;
946:
947: free(tampon);
948:
949: if ((tampon = (unsigned char *)
950: malloc((strlen(prologue) +
951: strlen(epilogue) + 6) *
952: sizeof(unsigned char))) == NULL)
953: {
954: (*s_etat_processus).erreur_systeme =
955: d_es_allocation_memoire;
956: return(NULL);
957: }
958:
959: sprintf(tampon, "%s' '%s %c",
960: prologue, epilogue, t1);
961: drapeau_modification = d_vrai;
962: }
963: else if (((priorite == 4) && (((t1 == '<') &&
964: (t2 == '=')) || ((t1 == '=') &&
965: (t2 == '<')) || ((t1 == '>') &&
966: (t2 == '<')) || (((t1 == '>') &&
967: (t2 == '=')) || ((t1 == '=') &&
968: (t2 == '>')) || ((t1 == '=') &&
969: (t2 == '='))))) || ((priorite == 1) &&
970: (t1 == 'R') && (t2 == 'O') && (t3 == ' ')
971: && (t0 == ' ')))
972: {
973: drapeau_priorite_entierement_traitee = d_faux;
974: fin_boucle_extraction = d_vrai;
975:
976: free(tampon);
977:
978: if ((tampon = (unsigned char *)
979: malloc((strlen(prologue) +
980: strlen(epilogue) + 6) *
981: sizeof(unsigned char))) == NULL)
982: {
983: (*s_etat_processus).erreur_systeme =
984: d_es_allocation_memoire;
985: return(NULL);
986: }
987:
988: prologue[strlen(prologue) - 1] =
989: d_code_fin_chaine;
990:
991: sprintf(tampon, "%s' '%s %c%c", prologue,
992: epilogue, t2, t1);
993: drapeau_modification = d_vrai;
994: }
995: else if (((priorite == 1) && (t4 == ' ') &&
996: (t3 == 'X') && (t2 == 'O') && (t1 == 'R')
997: && (t0 == ' ')) || ((priorite == 2) &&
998: (t4 == ' ') && (t3 == 'A') && (t2 == 'N')
999: && (t1 == 'D') && (t0 == ' ')))
1000: {
1001: drapeau_priorite_entierement_traitee = d_faux;
1002: fin_boucle_extraction = d_vrai;
1003:
1004: free(tampon);
1005:
1006: if ((tampon = (unsigned char *)
1007: malloc((strlen(prologue) +
1008: strlen(epilogue) + 5) *
1009: sizeof(unsigned char))) == NULL)
1010: {
1011: (*s_etat_processus).erreur_systeme =
1012: d_es_allocation_memoire;
1013: return(NULL);
1014: }
1015:
1016: prologue[strlen(prologue) - 3] =
1017: d_code_fin_chaine;
1018:
1019: sprintf(tampon, "%s' '%s %c%c%c", prologue,
1020: epilogue, t3, t2, t1);
1021: drapeau_modification = d_vrai;
1022: }
1023:
1024: free(prologue);
1025: free(epilogue);
1026: }
1027:
1028: if (t1 == ')')
1029: {
1030: niveau--;
1031: }
1032:
1033: k--;
1034: }
1035:
1036: if (drapeau_priorite_entierement_traitee == d_vrai)
1037: {
1038: free(tampon);
1039:
1040: if ((tampon = (unsigned char *) malloc(
1041: (strlen(chaine_centrale) + 1) *
1042: sizeof(unsigned char))) == NULL)
1043: {
1044: (*s_etat_processus).erreur_systeme =
1045: d_es_allocation_memoire;
1046: return(NULL);
1047: }
1048:
1049: strcpy(tampon, chaine_centrale);
1050: }
1051:
1052: free(chaine_centrale);
1053: free(chaine_travail);
1054:
1055: if ((chaine_travail = (unsigned char *) malloc(
1056: (strlen(chaine_gauche) + strlen(tampon)
1057: + strlen(chaine_droite) + 1 + 2)
1058: * sizeof(unsigned char))) == NULL)
1059: {
1060: (*s_etat_processus).erreur_systeme =
1061: d_es_allocation_memoire;
1062: return(NULL);
1063: }
1064:
1065: sprintf(chaine_travail, "%s %s %s", chaine_gauche,
1066: tampon, chaine_droite);
1067:
1068: free(chaine_gauche);
1069: free(tampon);
1070: free(chaine_droite);
1071: }
1072:
1073: if (drapeau_priorite_entierement_traitee == d_vrai)
1074: {
1075: priorite++;
1076: }
1077: else
1078: {
1079: priorite = 1;
1080: }
1081: } while(priorite < 10);
1082:
1083: /*
1084: * Aucune modification n'a pu être faite sur l'expression
1085: * algébrique.
1086: */
1087:
1088: if (drapeau_modification == d_faux)
1089: {
1090: free(chaine_travail);
1091:
1092: (*s_etat_processus).erreur_execution = d_ex_syntaxe;
1093: return(NULL);
1094: }
1095: }
1096: } while(nombre_apostrophes != 0);
1097:
1098: tampon = chaine_travail;
1099:
1100: if ((chaine_travail = (unsigned char *) malloc((strlen(tampon) + 1 + 6) *
1101: sizeof(unsigned char))) == NULL)
1102: {
1103: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
1104: return(NULL);
1105: }
1106:
1107: sprintf(chaine_travail, "<< %s >>", tampon);
1108: free(tampon);
1109:
1110: return(chaine_travail);
1111: }
1112:
1113:
1114: unsigned char *
1115: purification_chaine(unsigned char *chaine)
1116: {
1.44 bertrand 1117: integer8 i;
1118: integer8 j;
1.23 bertrand 1119:
1120: unsigned char *chaine_purifiee;
1121:
1122: i = 0;
1.43 bertrand 1123: j = ((integer8) strlen(chaine)) - 1;
1.23 bertrand 1124:
1125: while(chaine[i] == ' ')
1126: {
1127: if ((i++) > j)
1128: {
1129: i = j;
1130: break;
1131: }
1132: }
1133:
1134: if (j >= 0)
1135: {
1136: while(chaine[j] == ' ')
1137: {
1138: if ((--j) < 0)
1139: {
1140: j = 0;
1141: break;
1142: }
1143: }
1144: }
1145:
1146: chaine_purifiee = extraction_chaine(chaine, i + 1, j + 1);
1147: free(chaine);
1148:
1149: return(chaine_purifiee);
1150: }
1151:
1152:
1153: logical1
1154: test_expression_rpn(unsigned char *chaine)
1155: {
1.43 bertrand 1156: int t;
1157: int t0;
1158: int t1;
1159: int t2;
1160: int t3;
1161: int t4;
1162:
1163: integer8 compteur;
1164: integer8 longueur_chaine;
1165: integer8 i;
1.44 bertrand 1166: integer8 j;
1.43 bertrand 1167: integer8 niveau;
1.23 bertrand 1168:
1169: /*
1170: * On teste d'abord la chaîne pour vérifier qu'il n'y a pas de fonction
1171: * utilisant la notation infixe.
1172: */
1173:
1174: compteur = 0;
1175:
1.43 bertrand 1176: for(longueur_chaine = ((integer8) strlen(chaine)), i = 1;
1177: i < longueur_chaine; i++)
1.23 bertrand 1178: {
1179: /*
1180: * On saute les chaînes de caractères
1181: */
1182:
1183: if (chaine[i - 1] == '"')
1184: {
1185: i++;
1186: while(chaine[i - 1] != '"')
1187: {
1188: i++;
1189: }
1190: }
1191:
1.43 bertrand 1192: j = i - 2;
1.23 bertrand 1193: t0 = (i >= 2) ? chaine[i - 2] : '?';
1194: t1 = chaine[i - 1];
1195: t2 = chaine[i];
1.43 bertrand 1196: t3 = ((i + 1) < ((integer8) strlen(chaine))) ? chaine[i + 1] : '?';
1197: t4 = ((i + 2) < ((integer8) strlen(chaine))) ? chaine[i + 2] : '?';
1.23 bertrand 1198:
1199: /*
1200: * Ouverture d'une parenthèse signalant une fonction
1201: */
1202:
1203: if ((t1 != '+') && (t1 != '-') && (t1 != '*') && (t1 != '/')
1204: && (t1 != '\'') && (t2 == '('))
1205: {
1206: niveau = 0;
1207:
1208: do
1209: {
1210: if ((t = chaine[i++]) == '(')
1211: {
1212: niveau++;
1213: }
1214: else if (t == ')')
1215: {
1216: niveau--;
1217: }
1218: } while(((niveau != 0) || (t != ')')) && (i < longueur_chaine));
1219:
1220: if (i < longueur_chaine)
1221: {
1222: t2 = chaine[i];
1223: }
1224: else
1225: {
1226: t2 = ' ';
1227: }
1228: }
1229:
1230: /*
1231: * Signalement de l'une des quatre opérations et des fonctions
1232: * infixes traditionnelles
1233: */
1234:
1235: if ((t2 == '+') || (t2 == '-') || (t2 == '*') || (t2 == '/')
1236: || (t2 == '^') || (t2 == '<') || (t2 == '>') || (t2 == '=')
1237: || ((t0 == ' ') && ((t1 == 'A') || (t1 == 'a')) &&
1238: ((t2 == 'N') || (t2 == 'n')) && ((t3 == 'D') || (t3 == 'd'))
1239: && (t4 == ' ')) ||
1240: ((t0 == ' ') && ((t1 == 'O') || (t1 == 'o')) &&
1241: ((t2 == 'R') || (t2 == 'r')) && (t3 == ' ')) ||
1242: ((t0 == ' ') && ((t1 == 'X') || (t1 == 'x')) &&
1243: ((t2 == 'O') || (t2 == 'o')) && ((t3 == 'R') || (t3 == 'r'))
1244: && (t4 == ' ')))
1245: {
1246: compteur++;
1247: }
1248:
1249: /*
1250: * Signalement d'un nombre
1251: */
1252:
1253: if (((t2 == '+') || (t2 == '-')) && ((t1 == '(')
1254: || ((t1 == 'e') || (t1 == 'E') || (t1 == '\'')))
1255: && (((t0 >= '0') && (t0 <= '9')) || (t0 == '.')))
1256: {
1257: compteur--;
1258: }
1259: else if (((t2 == '+') || (t2 == '-')) && (t1 == '\'') && (j < 0)
1260: && (((t3 >= '0') && (t3 <= '9')) || (t3 == '.')))
1261: {
1262: compteur--;
1263: }
1264: }
1265:
1266: return(((compteur == 0) && (test_fonction(chaine) == d_faux))
1267: ? d_vrai : d_faux);
1268: }
1269:
1270:
1271: logical1
1272: test_fonction(unsigned char *chaine)
1273: {
1274: logical1 drapeau_fonction;
1275:
1.43 bertrand 1276: int t;
1.23 bertrand 1277:
1.43 bertrand 1278: integer8 compteur;
1279: integer8 i;
1280: integer8 longueur_chaine;
1.23 bertrand 1281:
1.43 bertrand 1282: longueur_chaine = (integer8) strlen(chaine);
1.23 bertrand 1283: i = 1;
1284:
1285: while(((t = chaine[i]) != '(') && (i < (longueur_chaine - 1)))
1286: {
1287: if ((t == '+') || (t == '-') || (t == '*') ||
1288: (t == '/') || (t == '^') || (t == '>') || (t == '<') ||
1289: (t == '='))
1290: {
1291: i = longueur_chaine - 1;
1292: }
1293: else
1294: {
1295: i++;
1296: }
1297: }
1298:
1299: compteur = 1;
1300: drapeau_fonction = ((i < (longueur_chaine - 1)) && (i != 1))
1301: ? d_vrai : d_faux;
1302:
1303: for(i++; i < (longueur_chaine - 2); i++)
1304: {
1305: if ((t = chaine[i]) == '(')
1306: {
1307: compteur++;
1308: }
1309: else if (t == ')')
1310: {
1311: compteur--;
1312: }
1313:
1314: if (compteur == 0)
1315: {
1316: drapeau_fonction = d_faux;
1317: }
1318: }
1319:
1320: return drapeau_fonction;
1321: }
1322:
1323:
1324: unsigned char *
1.43 bertrand 1325: extraction_chaine(unsigned char *chaine, integer8 position_1,
1326: integer8 position_2)
1.23 bertrand 1327: {
1.43 bertrand 1328: integer8 i;
1.23 bertrand 1329:
1330: unsigned char *pointeur_ecriture;
1331: unsigned char *pointeur_lecture;
1332: unsigned char *sous_chaine;
1333:
1334: if ((position_1 < 1) || (position_2 < position_1) ||
1.45 ! bertrand 1335: (position_2 > ((integer8) strlen(chaine))))
1.23 bertrand 1336: {
1337: if ((sous_chaine = (unsigned char *) malloc(sizeof(unsigned char)))
1338: == NULL)
1339: {
1340: return(NULL);
1341: }
1342:
1343: (*sous_chaine) = d_code_fin_chaine;
1344: return(sous_chaine);
1345: }
1346:
1347: if ((sous_chaine = (unsigned char *)
1.43 bertrand 1348: malloc(((size_t) (position_2 - position_1 + 2)) *
1349: sizeof(unsigned char))) == NULL)
1.23 bertrand 1350: {
1351: return(NULL);
1352: }
1353:
1354: pointeur_lecture = &(chaine[position_1 - 1]);
1355: pointeur_ecriture = sous_chaine;
1356:
1357: for(sous_chaine[i = position_2 - position_1 + 1] = 0; (--i) >= 0;
1358: *(pointeur_ecriture++) = *(pointeur_lecture++));
1359:
1360: return(sous_chaine);
1361: }
1362:
1363: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>