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