File:
[local] /
rpl /
src /
analyse_notation_algebrique.c
Revision
1.22:
download - view:
text,
annotated -
select for diffs -
revision graph
Tue Jun 21 15:26:27 2011 UTC (13 years, 10 months ago) by
bertrand
Branches:
MAIN
CVS tags:
HEAD
Correction d'une réinitialisation sauvage de la pile des variables par niveau
dans la copie de la structure de description du processus. Cela corrige
la fonction SPAWN qui échouait sur un segmentation fault car la pile des
variables par niveau était vide alors même que l'arbre des variables contenait
bien les variables. Passage à la prerelease 2.
1: /*
2: ================================================================================
3: RPL/2 (R) version 4.1.0.prerelease.2
4: Copyright (C) 1989-2011 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 = malloc(sizeof(struct_fonction)))
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
CVSweb interface <joel.bertrand@systella.fr>