Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/matc/src/parser.c
3196 views
1
/*****************************************************************************
2
*
3
* Elmer, A Finite Element Software for Multiphysical Problems
4
*
5
* Copyright 1st April 1995 - , CSC - IT Center for Science Ltd., Finland
6
*
7
* This library is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU Lesser General Public
9
* License as published by the Free Software Foundation; either
10
* version 2.1 of the License, or (at your option) any later version.
11
*
12
* This library is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Lesser General Public License for more details.
16
*
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with this library (in file ../LGPL-2.1); if not, write
19
* to the Free Software Foundation, Inc., 51 Franklin Street,
20
* Fifth Floor, Boston, MA 02110-1301 USA
21
*
22
*****************************************************************************/
23
24
/*******************************************************************************
25
*
26
* MATC language/expression parser.
27
*
28
*******************************************************************************
29
*
30
* Author: Juha Ruokolainen
31
*
32
* Address: CSC - IT Center for Science Ltd.
33
* Keilaranta 14, P.O. BOX 405
34
* 02101 Espoo, Finland
35
* Tel. +358 0 457 2723
36
* Telefax: +358 0 457 2302
37
* EMail: [email protected]
38
*
39
* Date: 30 May 1996
40
*
41
* Modified by:
42
*
43
* Date of modification:
44
*
45
******************************************************************************/
46
/***********************************************************************
47
|
48
| PARSER.C - Last Edited 8. 8. 1988
49
|
50
***********************************************************************/
51
52
/*======================================================================
53
|Syntax of the manual pages:
54
|
55
|FUNCTION NAME(...) params ...
56
|
57
$ usage of the function and type of the parameters
58
? explain the effects of the function
59
= return value and the type of value if not of type int
60
@ globals effected directly by this routine
61
! current known bugs or limitations
62
& functions called by this function
63
~ these functions may interest you as an alternative function or
64
| because they control this function somehow
65
^=====================================================================*/
66
67
68
/*
69
* $Id: parser.c,v 1.5 2006/11/22 10:57:14 jpr Exp $
70
*
71
* $Log: parser.c,v $
72
* Revision 1.5 2006/11/22 10:57:14 jpr
73
* *** empty log message ***
74
*
75
* Revision 1.4 2006/02/02 06:54:44 jpr
76
* small formatting changes.
77
*
78
* Revision 1.2 2005/05/27 12:26:21 vierinen
79
* changed header install location
80
*
81
* Revision 1.1.1.1 2005/04/14 13:29:14 vierinen
82
* initial matc automake package
83
*
84
* Revision 1.2 1998/08/01 12:34:54 jpr
85
*
86
* Added Id, started Log.
87
*
88
*
89
*/
90
91
#include "elmer/matc.h"
92
93
static SYMTYPE symbol, bendsym;
94
static char *str, csymbol[4096], buf[4096];
95
#pragma omp threadprivate (symbol, bendsym, str, csymbol, buf)
96
97
int char_in_list(int ch, char *list)
98
{
99
char *p;
100
101
for(p = list; *p != '\0'; p++)
102
if (*p == ch) return TRUE;
103
104
return FALSE;
105
}
106
107
void scan(void)
108
{
109
char *p, ch;
110
int i;
111
112
symbol = nullsym;
113
if ( *str == '\0' ) return;
114
115
while( isspace(*str) ) str++;
116
if (*str == '\0') return;
117
118
p = str;
119
120
if (isdigit(*str) || (*str == '.' && isdigit(*(str+1))))
121
{
122
str++; while(isdigit(*str)) str++;
123
124
if (*str == '.')
125
{
126
str++;
127
if (isdigit(*str))
128
{
129
while(isdigit(*str)) str++;
130
}
131
else if ( *str != '\0' && *str != 'e' && *str != 'E' && *str != 'd' && *str != 'D' )
132
{
133
error("Badly formed number.\n");
134
}
135
}
136
137
if ( *str == 'd' || *str == 'D' ) *str = 'e';
138
139
if (*str == 'e' || *str=='E' )
140
{
141
str++;
142
if (isdigit(*str))
143
{
144
while(isdigit(*str)) str++;
145
}
146
else if (char_in_list(*str,"+-"))
147
{
148
str++;
149
if (isdigit(*str))
150
{
151
while(isdigit(*str)) str++;
152
}
153
else
154
{
155
error("Badly formed number.\n");
156
}
157
}
158
else
159
{
160
error("Badly formed number.\n");
161
}
162
}
163
symbol = number;
164
}
165
166
else if (isalpha(*str) || char_in_list(*str, symchars))
167
{
168
while(isalnum(*str) || char_in_list(*str, symchars)) str++;
169
ch = *str; *str = '\0';
170
171
for(i = 0; reswords[i] != NULL; i++)
172
if (strcmp(p, reswords[i]) == 0)
173
{
174
symbol = rsymbols[i]; break;
175
}
176
if (reswords[i] == NULL) symbol = name;
177
178
*str = ch;
179
}
180
181
else if (*str == '"')
182
{
183
str++;
184
while(*str != '"' && *str != '\0')
185
{
186
if (*str++ == '\\') str++;
187
}
188
189
if (*str == '\0')
190
{
191
error("String not terminated.\n");
192
}
193
str++; symbol = string;
194
}
195
196
else if (char_in_list(*str, csymbols))
197
{
198
for(i = 0; *str != csymbols[i]; i++);
199
symbol = ssymbols[i];
200
201
str++;
202
203
if (*str == '=')
204
switch(symbol)
205
{
206
case assignsym:
207
symbol = eq; str++; break;
208
209
case lt:
210
symbol = le; str++; break;
211
212
case gt:
213
symbol = ge; str++; break;
214
215
case indclose: case rightpar:
216
break;
217
218
default:
219
error("Syntax error.\n");
220
}
221
222
if (*str == '>')
223
if (symbol == lt)
224
{
225
symbol = neq; str++;
226
}
227
}
228
229
else
230
{
231
error("Syntax error.\n");
232
}
233
234
ch = *str;
235
*str = '\0';
236
237
strcpy( csymbol, p );
238
*str = ch;
239
240
return;
241
}
242
243
TREE *newtree(void)
244
{
245
return (TREE *)ALLOCMEM(sizeof(TREE));
246
}
247
248
TREE *args(int minp, int maxp)
249
{
250
TREE *treeptr, *root;
251
int numgot = 0;
252
253
root = treeptr = equation();
254
numgot++;
255
256
while(symbol == argsep)
257
{
258
scan();
259
NEXT(treeptr) = equation();
260
treeptr = NEXT(treeptr);
261
numgot++;
262
if (numgot > maxp) error("Too many parameters.\n");
263
}
264
265
if (numgot < minp) error("Too few parameters.\n");
266
267
return root;
268
}
269
270
271
TREE *nameorvar(void)
272
{
273
TREE *root, *treeptr, *prevtree, *tp;
274
275
SYMTYPE sym = nullsym;
276
277
int i, slen;
278
279
char *tstr;
280
281
root = treeptr = prevtree = newtree();
282
283
if (symbol == minus && !isspace(*str) &&
284
(str-2<buf || isspace(*(str-2)) || char_in_list(*(str-2),"{};=[(\\<>&|+-*/^,")))
285
{
286
sym = minus; scan();
287
}
288
289
if (symbol != name && symbol != number &&
290
symbol != string && symbol != leftpar)
291
{
292
error("Expecting identifier, constant or leftpar.\n");
293
}
294
295
while(symbol == name || symbol == number ||
296
symbol == string || symbol == leftpar)
297
{
298
299
switch(symbol)
300
{
301
case name:
302
SDATA(treeptr) = STRCOPY(csymbol);
303
ETYPE(treeptr) = ETYPE_NAME;
304
if (*str == '(' || *str == '[')
305
{
306
scan(); scan(); ARGS(treeptr) = args(0, 10000);
307
if (symbol != rightpar && symbol != indclose)
308
{
309
error("Expecting closing parenthesis.\n");
310
}
311
}
312
break;
313
314
case string:
315
tstr = csymbol + 1;
316
tstr[strlen(tstr)-1] = '\0';
317
slen = strlen(tstr);
318
for(i = 0; i < strlen(tstr); i++)
319
if (tstr[i] == '\\')
320
switch(tstr[++i])
321
{
322
case 'n': break;
323
default: slen--;
324
break;
325
}
326
SDATA(treeptr) = (char *)ALLOCMEM(slen+1);
327
for(i = 0; *tstr != '\0'; i++, tstr++)
328
if (*tstr == '\\')
329
switch(*++tstr)
330
{
331
case 'n':
332
SDATA(treeptr)[i++] = '\r';
333
SDATA(treeptr)[i] = '\n';
334
break;
335
336
case 't':
337
SDATA(treeptr)[i] = '\t';
338
break;
339
340
case 'v':
341
SDATA(treeptr)[i] = '\v';
342
break;
343
344
case 'b':
345
SDATA(treeptr)[i] = '\b';
346
break;
347
348
case 'r':
349
SDATA(treeptr)[i] = '\r';
350
break;
351
352
case 'f':
353
SDATA(treeptr)[i] = '\f';
354
break;
355
356
case 'e':
357
SDATA(treeptr)[i] = 27;
358
break;
359
360
default:
361
SDATA(treeptr)[i] = *tstr;
362
break;
363
}
364
else
365
SDATA(treeptr)[i] = *tstr;
366
ETYPE(treeptr) = ETYPE_STRING;
367
break;
368
369
case number:
370
DDATA(treeptr) = atof(csymbol);
371
ETYPE(treeptr) = ETYPE_NUMBER;
372
break;
373
374
case leftpar:
375
scan(); LEFT(treeptr) = equation();
376
if (symbol != rightpar)
377
{
378
error("Right parenthesis missing.\n");
379
}
380
ETYPE(treeptr) = ETYPE_EQUAT;
381
break;
382
}
383
384
if (*str == '[')
385
{
386
scan(); scan(); SUBS(treeptr) = args(1,2);
387
if (symbol != rightpar && symbol != indclose)
388
{
389
error("Expecting closing parenthesis.\n");
390
}
391
}
392
393
if (sym == minus)
394
{
395
tp = newtree();
396
VDATA(tp) = opr_minus;
397
ETYPE(tp) = ETYPE_OPER;
398
LEFT(tp) = treeptr;
399
if (root == treeptr)
400
root = treeptr = tp;
401
else
402
LINK(prevtree) = treeptr = tp;
403
}
404
405
sym = symbol;
406
scan();
407
408
if (symbol == minus && !isspace(*str) &&
409
(str-2<buf || isspace(*(str-2)) || char_in_list(*(str-2),"{};=([\\<>&|+-*/^,")))
410
{
411
sym = minus;
412
413
if (*str == '-' && !isspace(*(str + 1)))
414
{
415
break;
416
}
417
else if (*str == '-')
418
error("Syntax error.\n");
419
420
scan();
421
422
if (symbol != name && symbol != number &&
423
symbol != string && symbol != leftpar)
424
{
425
error("Expecting identifier, constant or leftpar.\n");
426
}
427
}
428
429
if (symbol == name || symbol == number ||
430
symbol == string || symbol == leftpar)
431
{
432
prevtree = treeptr; LINK(treeptr) = newtree(); treeptr = LINK(treeptr);
433
}
434
}
435
436
return root;
437
}
438
439
TREE *par_apply(TREE *root)
440
{
441
TREE *newroot;
442
443
newroot = newtree();
444
445
switch(symbol)
446
{
447
case apply:
448
VDATA(newroot) = opr_apply;
449
break;
450
451
case not:
452
VDATA(newroot) = opr_not;
453
break;
454
}
455
456
ETYPE(newroot) = ETYPE_OPER;
457
scan();
458
459
if (symbol == apply || symbol == not)
460
LEFT(newroot) = par_apply(newroot);
461
else
462
LEFT(newroot) = nameorvar();
463
464
return newroot;
465
}
466
467
468
TREE *par_trans(TREE *root)
469
{
470
TREE *newroot;
471
472
while(symbol == transpose)
473
{
474
newroot = newtree();
475
LEFT(newroot) = root;
476
VDATA(newroot) = opr_trans;
477
ETYPE(newroot) = ETYPE_OPER;
478
root = newroot;
479
scan();
480
}
481
482
return newroot;
483
}
484
485
TREE *par_pow(TREE *root)
486
{
487
TREE *newroot;
488
489
while(symbol == power)
490
{
491
newroot = newtree();
492
LEFT(newroot) = root;
493
VDATA(newroot) = opr_pow;
494
ETYPE(newroot) = ETYPE_OPER;
495
root = newroot;
496
497
scan(); RIGHT(newroot) = nameorvar();
498
499
switch(symbol)
500
{
501
case transpose:
502
RIGHT(newroot) = par_trans(RIGHT(newroot));
503
break;
504
505
case apply: case not:
506
RIGHT(newroot) = par_apply(RIGHT(newroot));
507
break;
508
}
509
}
510
511
return newroot;
512
}
513
514
TREE *par_timesdivide(TREE *root)
515
{
516
TREE *newroot;
517
518
while(symbol == times || symbol == ptimes || symbol == divide)
519
{
520
newroot = newtree();
521
LEFT(newroot) = root;
522
switch(symbol)
523
{
524
case times:
525
VDATA(newroot) = opr_mul;
526
break;
527
528
case ptimes:
529
VDATA(newroot) = opr_pmul;
530
break;
531
532
case divide:
533
VDATA(newroot) = opr_div;
534
break;
535
}
536
ETYPE(newroot) = ETYPE_OPER;
537
root = newroot;
538
539
scan(); RIGHT(newroot) = nameorvar();
540
541
switch(symbol)
542
{
543
case power:
544
RIGHT(newroot) = par_pow(RIGHT(newroot));
545
break;
546
547
case transpose:
548
RIGHT(newroot) = par_trans(RIGHT(newroot));
549
break;
550
551
case apply: case not:
552
RIGHT(newroot) = par_apply(RIGHT(newroot));
553
break;
554
}
555
}
556
557
return newroot;
558
}
559
560
561
TREE *par_plusminus(TREE *root)
562
{
563
TREE *newroot;
564
565
while(symbol == plus || symbol == minus)
566
{
567
newroot = newtree();
568
LEFT(newroot) = root;
569
570
switch(symbol)
571
{
572
case plus:
573
VDATA(newroot) = opr_add;
574
break;
575
576
case minus:
577
VDATA(newroot) = opr_subs;
578
break;
579
}
580
ETYPE(newroot) = ETYPE_OPER;
581
root = newroot;
582
583
scan(); RIGHT(newroot) = nameorvar();
584
585
switch(symbol)
586
{
587
case times: case ptimes: case divide:
588
RIGHT(newroot) = par_timesdivide(RIGHT(newroot));
589
break;
590
591
case power:
592
RIGHT(newroot) = par_pow(RIGHT(newroot));
593
break;
594
595
case transpose:
596
RIGHT(newroot) = par_trans(RIGHT(newroot));
597
break;
598
599
case apply: case not:
600
RIGHT(newroot) = par_apply(RIGHT(newroot));
601
break;
602
}
603
}
604
605
return newroot;
606
}
607
608
TREE *par_compare(TREE *root)
609
{
610
TREE *newroot;
611
612
while(symbol == eq || symbol == neq || symbol == lt ||
613
symbol == gt || symbol == le || symbol == ge)
614
{
615
616
newroot = newtree();
617
LEFT(newroot) = root;
618
switch(symbol)
619
{
620
case eq:
621
VDATA(newroot) = opr_eq;
622
break;
623
624
case lt:
625
VDATA(newroot) = opr_lt;
626
break;
627
628
case gt:
629
VDATA(newroot) = opr_gt;
630
break;
631
632
case neq:
633
VDATA(newroot) = opr_neq;
634
break;
635
636
case le:
637
VDATA(newroot) = opr_le;
638
break;
639
640
case ge:
641
VDATA(newroot) = opr_ge;
642
break;
643
}
644
ETYPE(newroot) = ETYPE_OPER;
645
root = newroot;
646
647
scan(); RIGHT(newroot) = nameorvar();
648
649
switch(symbol)
650
{
651
case plus: case minus:
652
RIGHT(newroot) = par_plusminus(RIGHT(newroot));
653
break;
654
655
case times: case ptimes: case divide:
656
RIGHT(newroot) = par_timesdivide(RIGHT(newroot));
657
break;
658
659
case power:
660
RIGHT(newroot) = par_pow(RIGHT(newroot));
661
break;
662
663
case transpose:
664
RIGHT(newroot) = par_trans(RIGHT(newroot));
665
break;
666
667
case apply: case not:
668
RIGHT(newroot) = par_apply(RIGHT(newroot));
669
break;
670
}
671
}
672
673
return newroot;
674
}
675
676
TREE *par_vector(TREE *root)
677
{
678
TREE *newroot;
679
680
while(symbol == vector)
681
{
682
newroot = newtree();
683
LEFT(newroot) = root;
684
VDATA(newroot) = opr_vector;
685
ETYPE(newroot) = ETYPE_OPER;
686
root = newroot;
687
scan();
688
RIGHT(newroot) = nameorvar();
689
690
switch(symbol)
691
{
692
case eq: case neq: case lt: case gt: case le: case ge:
693
RIGHT(newroot) = par_compare(RIGHT(newroot));
694
break;
695
696
case plus: case minus:
697
RIGHT(newroot) = par_plusminus(RIGHT(newroot));
698
break;
699
700
case times: case ptimes: case divide:
701
RIGHT(newroot) = par_timesdivide(RIGHT(newroot));
702
break;
703
704
case power:
705
RIGHT(newroot) = par_pow(RIGHT(newroot));
706
break;
707
708
case transpose:
709
RIGHT(newroot) = par_trans(RIGHT(newroot));
710
break;
711
712
case apply: case not:
713
RIGHT(newroot) = par_apply(RIGHT(newroot));
714
break;
715
}
716
}
717
718
return newroot;
719
}
720
721
TREE *par_logical(TREE *root)
722
{
723
TREE *newroot;
724
725
while(symbol == and || symbol == or)
726
{
727
728
newroot = newtree();
729
LEFT(newroot) = root;
730
switch(symbol)
731
{
732
case and:
733
VDATA(newroot) = opr_and;
734
break;
735
736
case or:
737
VDATA(newroot) = opr_or;
738
break;
739
}
740
ETYPE(newroot) = ETYPE_OPER;
741
root = newroot;
742
scan(); RIGHT(newroot) = nameorvar();
743
744
switch(symbol)
745
{
746
case vector:
747
RIGHT(newroot) = par_vector(RIGHT(newroot));
748
break;
749
750
case eq: case neq: case lt: case gt: case le: case ge:
751
RIGHT(newroot) = par_compare(RIGHT(newroot));
752
break;
753
754
case plus: case minus:
755
RIGHT(newroot) = par_plusminus(RIGHT(newroot));
756
break;
757
758
case times: case ptimes: case divide:
759
RIGHT(newroot) = par_timesdivide(RIGHT(newroot));
760
break;
761
762
case power:
763
RIGHT(newroot) = par_pow(RIGHT(newroot));
764
break;
765
766
case transpose:
767
RIGHT(newroot) = par_trans(RIGHT(newroot));
768
break;
769
770
case apply: case not:
771
RIGHT(newroot) = par_apply(RIGHT(newroot));
772
break;
773
}
774
}
775
776
return newroot;
777
}
778
779
TREE *par_reduction(TREE *root)
780
{
781
TREE *newroot;
782
783
while(symbol == reduction)
784
{
785
newroot = newtree();
786
VDATA(newroot) = opr_reduction;
787
ETYPE(newroot) = ETYPE_OPER;
788
scan(); RIGHT(newroot) = nameorvar();
789
LEFT(newroot) = root;
790
root = newroot;
791
792
switch(symbol)
793
{
794
case and: case or:
795
RIGHT(newroot) = par_logical(RIGHT(newroot));
796
break;
797
798
case vector:
799
RIGHT(newroot) = par_vector(RIGHT(newroot));
800
break;
801
802
case eq: case neq: case lt: case gt: case le: case ge:
803
RIGHT(newroot) = par_compare(RIGHT(newroot));
804
break;
805
806
case plus: case minus:
807
RIGHT(newroot) = par_plusminus(RIGHT(newroot));
808
break;
809
810
case times: case ptimes: case divide:
811
RIGHT(newroot) = par_timesdivide(RIGHT(newroot));
812
break;
813
814
case power:
815
RIGHT(newroot) = par_pow(RIGHT(newroot));
816
break;
817
818
case transpose:
819
RIGHT(newroot) = par_trans(RIGHT(newroot));
820
break;
821
822
case apply: case not:
823
RIGHT(newroot) = par_apply(RIGHT(newroot));
824
break;
825
}
826
}
827
828
return newroot;
829
}
830
831
TREE *par_resize(TREE *root)
832
{
833
TREE *newroot;
834
835
while(symbol == resize)
836
{
837
newroot = newtree();
838
VDATA(newroot) = opr_resize;
839
ETYPE(newroot) = ETYPE_OPER;
840
scan(); LEFT(newroot) = nameorvar();
841
RIGHT(newroot) = root;
842
root = newroot;
843
844
switch(symbol)
845
{
846
case reduction:
847
LEFT(newroot) = par_reduction(LEFT(newroot));
848
break;
849
850
case and: case or:
851
LEFT(newroot) = par_logical(LEFT(newroot));
852
break;
853
854
case vector:
855
LEFT(newroot) = par_vector(LEFT(newroot));
856
break;
857
858
case eq: case neq: case lt: case gt: case le: case ge:
859
LEFT(newroot) = par_compare(LEFT(newroot));
860
break;
861
862
case plus: case minus:
863
LEFT(newroot) = par_plusminus(LEFT(newroot));
864
break;
865
866
case times: case ptimes: case divide:
867
LEFT(newroot) = par_timesdivide(LEFT(newroot));
868
break;
869
870
case power:
871
LEFT(newroot) = par_pow(LEFT(newroot)); break;
872
873
case transpose:
874
LEFT(newroot) = par_trans(LEFT(newroot));
875
break;
876
877
case apply: case not:
878
LEFT(newroot) = par_apply(LEFT(newroot));
879
break;
880
}
881
}
882
883
return newroot;
884
}
885
886
TREE *equation(void)
887
{
888
TREE *treeptr;
889
890
switch(symbol)
891
{
892
case apply: case not:
893
break;
894
895
default:
896
treeptr = nameorvar();
897
break;
898
}
899
900
while(TRUE)
901
{
902
switch(symbol)
903
{
904
case resize:
905
treeptr = par_resize(treeptr);
906
break;
907
908
case reduction:
909
treeptr = par_reduction(treeptr);
910
break;
911
912
case and: case or:
913
treeptr = par_logical(treeptr);
914
break;
915
916
case vector:
917
treeptr = par_vector(treeptr);
918
break;
919
920
case eq: case neq: case lt: case gt: case le: case ge:
921
treeptr = par_compare(treeptr);
922
break;
923
924
case plus: case minus:
925
treeptr = par_plusminus(treeptr);
926
break;
927
928
case times: case ptimes: case divide:
929
treeptr = par_timesdivide(treeptr);
930
break;
931
932
case power:
933
treeptr = par_pow(treeptr);
934
break;
935
936
case transpose:
937
treeptr = par_trans(treeptr);
938
break;
939
940
case apply: case not:
941
treeptr = par_apply(treeptr);
942
break;
943
944
default:
945
return treeptr;
946
}
947
}
948
}
949
950
CLAUSE *commentparse(void)
951
{
952
char *p = str;
953
954
CLAUSE *root = NULL;
955
956
while( *str!='\n' && *str!='\0' ) str++;
957
scan();
958
959
return root;
960
}
961
962
CLAUSE *scallparse()
963
{
964
char *p = str;
965
966
CLAUSE *root = NULL;
967
968
while( *str!='\n' && *str != ';' && *str!='\0' ) str++;
969
if ( *str ) *str++ = '\0';
970
971
if ( *p )
972
{
973
root = (CLAUSE *)ALLOCMEM(sizeof(CLAUSE));
974
root->data = systemcall;
975
976
root->this = newtree();
977
SDATA(root->this) = STRCOPY( p );
978
ETYPE(root->this) = ETYPE_STRING;
979
}
980
981
scan();
982
983
return root;
984
}
985
986
CLAUSE *statement(void)
987
{
988
char *csymbcopy, *p;
989
990
CLAUSE *root = (CLAUSE *)ALLOCMEM(sizeof(CLAUSE));
991
992
if (symbol == name)
993
{
994
p = str;
995
csymbcopy = STRCOPY(csymbol);
996
997
do
998
{
999
scan();
1000
} while( symbol != assignsym && symbol != nullsym && symbol != statemend );
1001
1002
strcpy(csymbol, csymbcopy);
1003
FREEMEM(csymbcopy);
1004
str = p;
1005
1006
if (symbol == assignsym)
1007
{
1008
symbol = name; root -> this = nameorvar(); scan();
1009
}
1010
else
1011
symbol = name;
1012
}
1013
1014
LINK(root) = (CLAUSE *)ALLOCMEM(sizeof(CLAUSE));
1015
LINK(root) -> this = equation();
1016
1017
root->data = assignsym;
1018
1019
return root;
1020
}
1021
1022
CLAUSE *blockparse(void)
1023
{
1024
CLAUSE *root, *ptr;
1025
1026
root = (CLAUSE *)NULL;
1027
1028
if (symbol != beginsym)
1029
error("if|while|function: missing block open symbol.\n");
1030
1031
scan();
1032
1033
if (symbol == nullsym)
1034
{
1035
dogets(str, PMODE_BLOCK);
1036
scan();
1037
}
1038
1039
if (symbol != endsym)
1040
{
1041
root = ptr = parse();
1042
while(LINK(ptr) != NULL)
1043
{
1044
ptr = LINK(ptr);
1045
}
1046
}
1047
1048
while(symbol != endsym && symbol != elsesym)
1049
{
1050
if (symbol == nullsym)
1051
{
1052
dogets(str, PMODE_BLOCK); scan();
1053
}
1054
if (symbol != endsym && symbol != elsesym)
1055
{
1056
LINK(ptr) = parse();
1057
while(LINK(ptr) != NULL)
1058
{
1059
ptr = LINK(ptr);
1060
}
1061
}
1062
}
1063
1064
bendsym = symbol;
1065
scan();
1066
1067
return root;
1068
}
1069
1070
CLAUSE *funcparse(void)
1071
{
1072
CLAUSE *root, *ptr;
1073
SYMTYPE sym;
1074
TREE *lptr, *rptr,*help;
1075
1076
int ch,n;
1077
1078
char *p = str;
1079
1080
root = ptr = (CLAUSE *)ALLOCMEM(sizeof(CLAUSE));
1081
ptr->data = funcsym;
1082
1083
scan();
1084
ptr->this = nameorvar();
1085
1086
help = SUBS(root->this) = newtree();
1087
SDATA( help ) = STRCOPY( p );
1088
p = str;
1089
1090
while ( symbol == nullsym || symbol == comment )
1091
{
1092
dogets( str, PMODE_CONT );
1093
scan();
1094
1095
if ( symbol == comment )
1096
{
1097
NEXT(help) = newtree();
1098
help = NEXT(help);
1099
1100
while( *str != '\n' && *str != '\0' ) str++;
1101
ch = *str;
1102
if ( *str ) *++str = '\0';
1103
*str = ch;
1104
SDATA(help) = STRCOPY( p );
1105
1106
p = str;
1107
}
1108
}
1109
1110
while(symbol == import || symbol == export)
1111
{
1112
if (symbol == import)
1113
lptr = LEFT(root->this);
1114
else
1115
lptr = RIGHT(root->this);
1116
1117
sym = symbol;
1118
scan();
1119
rptr = args(1,1000);
1120
1121
if (lptr == NULL)
1122
{
1123
if (sym == import)
1124
LEFT(root->this) = rptr;
1125
else
1126
RIGHT(root->this) = rptr;
1127
}
1128
else
1129
{
1130
while(NEXT(lptr)) lptr=NEXT(lptr);
1131
NEXT(lptr) = rptr;
1132
}
1133
1134
if (symbol == nullsym)
1135
{
1136
dogets(str, PMODE_CONT);
1137
scan();
1138
}
1139
}
1140
1141
if (symbol == beginsym)
1142
{
1143
LINK(ptr) = blockparse();
1144
if (bendsym != endsym)
1145
error("function: missing end.\n");
1146
}
1147
else
1148
LINK(ptr) = parse();
1149
1150
return root;
1151
}
1152
1153
CLAUSE *ifparse(void)
1154
{
1155
CLAUSE *root, *ptr, *parse();
1156
int block = FALSE;
1157
1158
scan();
1159
if (symbol != leftpar)
1160
{
1161
error("Missing leftpar.\n");
1162
}
1163
1164
root = ptr = (CLAUSE *)ALLOCMEM(sizeof(CLAUSE));
1165
ptr->data = ifsym;
1166
1167
scan();
1168
ptr -> this = equation();
1169
1170
if (symbol != rightpar)
1171
{
1172
error("Missing rightpar.\n");
1173
}
1174
scan();
1175
1176
if (symbol == thensym) scan();
1177
1178
if (symbol == nullsym)
1179
{
1180
dogets(str, PMODE_CONT);
1181
scan();
1182
}
1183
1184
if (symbol == beginsym)
1185
{
1186
block = TRUE;
1187
LINK(ptr) = blockparse();
1188
}
1189
else
1190
LINK(ptr) = parse();
1191
1192
while(LINK(ptr) != NULL)
1193
{
1194
ptr = LINK(ptr);
1195
}
1196
1197
root->jmp = LINK(ptr) = (CLAUSE *)ALLOCMEM(sizeof(CLAUSE));
1198
ptr = LINK(ptr); ptr->data = endsym;
1199
1200
if (symbol == elsesym || bendsym == elsesym)
1201
{
1202
root -> jmp = LINK(ptr) = (CLAUSE *)ALLOCMEM(sizeof(CLAUSE));
1203
ptr = LINK(ptr); ptr->data = elsesym;
1204
1205
if (symbol == elsesym) scan();
1206
1207
if (symbol == nullsym)
1208
{
1209
dogets(str, PMODE_CONT);
1210
scan();
1211
}
1212
1213
if (symbol == beginsym)
1214
{
1215
LINK(ptr) = blockparse();
1216
if (block && bendsym != endsym)
1217
error("else: missing end.\n");
1218
}
1219
else
1220
LINK(ptr) = parse();
1221
1222
while(LINK(ptr) != NULL)
1223
{
1224
ptr = LINK(ptr);
1225
}
1226
root->jmp->jmp = LINK(ptr) = (CLAUSE *)ALLOCMEM(sizeof(CLAUSE));
1227
LINK(ptr)->data = endsym;
1228
}
1229
1230
return root;
1231
}
1232
1233
CLAUSE *whileparse(void)
1234
{
1235
CLAUSE *root, *ptr;
1236
1237
scan();
1238
1239
if (symbol != leftpar)
1240
{
1241
error("Missing leftpar.\n");
1242
}
1243
1244
root = ptr = (CLAUSE *)ALLOCMEM(sizeof(CLAUSE));
1245
ptr->data = whilesym;
1246
1247
scan();
1248
ptr->this = equation();
1249
1250
if (symbol != rightpar)
1251
{
1252
error("Missing rightpar.\n");
1253
}
1254
scan();
1255
1256
if (symbol == nullsym)
1257
{
1258
dogets(str, PMODE_CONT);
1259
scan();
1260
}
1261
1262
if (symbol == beginsym)
1263
{
1264
LINK(ptr) = blockparse();
1265
if (bendsym != endsym)
1266
error("while: missing end.\n");
1267
}
1268
else
1269
LINK(ptr) = parse();
1270
1271
while(LINK(ptr) != NULL)
1272
{
1273
ptr = LINK(ptr);
1274
}
1275
1276
root -> jmp = LINK(ptr) = (CLAUSE *)ALLOCMEM(sizeof(CLAUSE));
1277
LINK(ptr)->data = endsym;
1278
1279
return root;
1280
}
1281
1282
CLAUSE *forparse(void)
1283
{
1284
CLAUSE *root, *ptr;
1285
1286
scan();
1287
1288
if (symbol != leftpar)
1289
{
1290
error("for: missing leftpar.\n");
1291
}
1292
1293
root = ptr = (CLAUSE *)ALLOCMEM(sizeof(CLAUSE));
1294
ptr->data = forsym;
1295
1296
scan();
1297
ptr -> this = nameorvar();
1298
if (symbol != assignsym)
1299
{
1300
error("for: missing equalsign\n");
1301
}
1302
scan();
1303
1304
LINK(ptr->this) = equation();
1305
1306
if (symbol != rightpar)
1307
{
1308
error("Missing rightpar.\n");
1309
}
1310
scan();
1311
1312
if (symbol == nullsym)
1313
{
1314
dogets(str, PMODE_CONT);
1315
scan();
1316
}
1317
1318
if (symbol == beginsym)
1319
{
1320
LINK(ptr) = blockparse();
1321
if (bendsym != endsym)
1322
error("for: missing end.\n");
1323
}
1324
else
1325
LINK(ptr) = parse();
1326
1327
while(LINK(ptr) != NULL)
1328
{
1329
ptr = LINK(ptr);
1330
}
1331
1332
root -> jmp = LINK(ptr) = (CLAUSE *)ALLOCMEM(sizeof(CLAUSE));
1333
LINK(ptr)->data = endsym;
1334
1335
return root;
1336
}
1337
1338
CLAUSE *parse(void)
1339
{
1340
CLAUSE *ptr = (CLAUSE *)NULL;
1341
1342
switch(symbol)
1343
{
1344
case funcsym:
1345
ptr = funcparse();
1346
break;
1347
1348
case beginsym:
1349
ptr = blockparse();
1350
if (bendsym != endsym)
1351
error("begin: missing end.\n");
1352
break;
1353
1354
case ifsym:
1355
ptr = ifparse();
1356
break;
1357
1358
case whilesym:
1359
ptr = whileparse();
1360
break;
1361
1362
case forsym:
1363
ptr = forparse();
1364
break;
1365
1366
case systemcall:
1367
ptr = scallparse();
1368
break;
1369
1370
case comment:
1371
ptr = commentparse();
1372
break;
1373
1374
default:
1375
ptr = statement();
1376
break;
1377
}
1378
1379
while( symbol == statemend ) scan();
1380
1381
if (ptr == (CLAUSE *)NULL)
1382
ptr = (CLAUSE *)ALLOCMEM(sizeof(CLAUSE));
1383
1384
return ptr;
1385
}
1386
1387
void free_treeentry(TREEENTRY *root)
1388
{
1389
if (root == NULL) return;
1390
1391
free_tree(root->args);
1392
1393
free_tree(root->subs);
1394
if ( root->entrytype == ETYPE_STRING || root->entrytype == ETYPE_NAME )
1395
FREEMEM(root->entrydata.s_data);
1396
else if ( root->entrytype == ETYPE_CONST )
1397
var_delete_temp(root->entrydata.c_data);
1398
}
1399
1400
void free_tree(TREE *root)
1401
{
1402
if (root == NULL) return;
1403
1404
free_tree(NEXT(root));
1405
free_tree(LINK(root));
1406
free_tree(LEFT(root));
1407
free_tree(RIGHT(root));
1408
free_treeentry(&root->tentry);
1409
FREEMEM((char *)root);
1410
}
1411
1412
void free_clause(CLAUSE *root)
1413
{
1414
if (root == NULL) return;
1415
1416
free_clause(LINK(root));
1417
free_tree(root->this);
1418
FREEMEM((char *)root);
1419
}
1420
1421
VARIABLE *doit(char *line)
1422
{
1423
CLAUSE *ptr, *root;
1424
VARIABLE *res;
1425
1426
str = buf;
1427
strcpy( str, line );
1428
1429
root = ptr = (CLAUSE *)ALLOCMEM(sizeof(CLAUSE));
1430
1431
scan();
1432
1433
while(symbol != nullsym)
1434
{
1435
LINK(ptr) = parse();
1436
while(LINK(ptr) != NULL)
1437
{
1438
ptr = LINK(ptr);
1439
}
1440
}
1441
1442
/* root = optimclause(root); */
1443
/* printclause(root, math_out, 0); */
1444
res = evalclause(root);
1445
1446
free_clause(root);
1447
1448
return res;
1449
}
1450
1451