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