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