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