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