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