"Fossies" - the Fresh Open Source Software Archive 
Member "ncc-2.8/parser.C" (13 Oct 2008, 37577 Bytes) of package /linux/privat/old/ncc-2.8.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
1 /*******************************************************************************
2
3 C parser
4
5 *******************************************************************************/
6 #include <stdlib.h>
7 #include <string.h>
8 #include <stdio.h>
9 #include <unistd.h>
10 #include <assert.h>
11
12 #include "global.h"
13
14 exprtree CExpr;
15 lrt last_result_type;
16
17 //***************************************************************************
18 // Forward
19 //***************************************************************************
20 static NormPtr constant_int_expression (NormPtr, int&);
21 static NormPtr parse_expression (NormPtr);
22 static NormPtr parse_structure (NormPtr);
23 //***************************************************************************
24 // Declarations I
25 //***************************************************************************
26 static NormPtr skip_parens (NormPtr);
27 static NormPtr skip_brackets (NormPtr);
28 static int initializer_nsize (NormPtr, int);
29 static NormPtr get_enum_consts (NormPtr);
30
31 class declarator
32 {
33 NormPtr p;
34 int dp;
35 inline void dcl ();
36 void dirdcl ();
37 void bitfield ();
38 void arglist_to_specs ();
39 NormPtr parse (NormPtr);
40
41 #ifdef GNU_VIOLATIONS
42 NormPtr bt_typeof (NormPtr);
43 #endif
44 NormPtr builtin (NormPtr);
45 NormPtr bt_enum (NormPtr);
46 NormPtr bt_typedef (NormPtr);
47 NormPtr bt_struct (NormPtr);
48
49 void complete_size ();
50 void argument_conversions ();
51 void semantics ();
52 bool do_argument_conversions;
53 public:
54 ObjPtr basetype;
55 bool have_extern, have_static, have_typedef, have_const,
56 have_init, have_code, is_anonymous, is_struct_dcl;
57
58 declarator (bool b = false) { do_argument_conversions = b; is_struct_dcl = false; }
59 NormPtr parse_base (NormPtr);
60 NormPtr parse_dcl (NormPtr);
61
62 typeID gentype;
63 NormPtr args;
64 NormPtr psst, pslen;
65 int symbol;
66 int spec [MSPEC];
67 };
68 //***********************************************************************
69 // definitions : declarator
70 //***********************************************************************
71
72 NormPtr declarator::parse (NormPtr i)
73 {
74 p = i; dp = 0; args = symbol = -1; have_init = have_code = false;
75
76 if (CODE [i] == ':' || (ISSYMBOL (CODE [i]) && CODE [i + 1] == ':'))
77 bitfield ();
78 else dcl ();
79
80 /* Ben Lau for M68K Kernel from uClinux */
81 if (CODE [p] == RESERVED___asm__)
82 p = skip_parens (p + 1);
83
84 spec [dp] = -1;
85 have_init = CODE [p] == '=';
86 have_code = CODE [p] == '{';
87
88 return p;
89 }
90
91 void declarator::bitfield ()
92 {
93 if (CODE [p] != ':') symbol = CODE [p++];
94 spec [0] = ':';
95 p = constant_int_expression (++p, spec [1]);
96 dp = 2;
97 }
98
99 void declarator::dcl ()
100 {
101 int ns = 0;
102
103 for (;; p++)
104 if (CODE [p] == '*') ++ns;
105 else if (CODE [p] != RESERVED_const
106 && CODE [p] != RESERVED_volatile) break;
107 dirdcl ();
108 while (ns--) spec [dp++] = '*';
109 }
110
111 NormPtr array_size_expression (NormPtr p, int &r)
112 {
113 NormPtr pe = constant_int_expression (p, r);
114 if (CODE [p] != ']' && infuncs) {
115 pe = parse_expression (p);
116 r = 0;
117 }
118 return pe;
119 }
120
121 void declarator::dirdcl ()
122 {
123 if (CODE [p] == '(') {
124 ++p;
125 dcl ();
126 if (CODE [p++] != ')') syntax_error (p, "Missing parenthesis");
127 } else if (ISSYMBOL (CODE [p]))
128 symbol = CODE [p++];
129
130 for (;;) {
131 switch (CODE [p]) {
132 case '(':
133 if (args == -1) args = p;
134 spec [dp++] = '(';
135 arglist_to_specs ();
136 continue;
137 case '[':
138 if (CODE [++p] == ']') {
139 spec [dp++] = '[';
140 spec [dp++] = 0;
141 p++; continue;
142 }
143 spec [dp++] = '[';
144 p = array_size_expression (p, spec [dp++]);
145 if (CODE [p++] != ']')
146 syntax_error (p, "No :]");
147 continue;
148 }
149 break;
150 }
151 }
152
153 void declarator::complete_size ()
154 {
155 int t = CODE [p + 1];
156 if (ISSTRING (t)) gstr: spec [1] = strlen (C_Strings [t - STRINGBASE]) + 1;
157 else if (t == '(' && ISSTRING (CODE [p + 2]) && CODE [p + 3] == ')') {
158 t = CODE [p + 2];
159 goto gstr;
160 } else if (t == '{') {
161 int i, a = esizeof_objptr (basetype);
162 for (i = 2; spec [i] == '['; i += 2)
163 a *= spec [i + 1];
164 spec [1] = initializer_nsize (p + 1, a);
165 } else syntax_error (p, "incomplete array initializer single");
166 }
167
168 void declarator::semantics ()
169 {
170 int i = 0, v, dpi = dp;
171
172 if (spec [0] == '(') {
173 if (have_init) syntax_error (p, "Function != Variable");
174 } else if (have_code) syntax_error (p, "Variable != Function");
175
176 if (spec [0] == ':') {
177 if (spec [1] < 0 || spec [1] > BITFIELD_Q)
178 syntax_error (p, "absurd");
179 return;
180 }
181
182 while (i < dpi)
183 if (spec [i] == '[') {
184 i += 2;
185 if (spec [i] == '(')
186 syntax_error (p, "array of functions");
187 } else if (spec [i] == '(') {
188 i += 2;
189 v = spec [i];
190 if (v == '(' || v == '[')
191 syntax_error (p, "Function returning invalid");
192 } else i++;
193 }
194
195 static int initializer_nsize (NormPtr p, int na)
196 {
197 int ec = 1;
198 NormPtr e = skip_brackets (p++);
199
200 while (p < e)
201 if (CODE [p] == ',') ec++, p++;
202 else if (CODE [p] == '{') {
203 ec += na;
204 p = skip_brackets (p);
205 } else p++;
206
207 return na ? ec / na : ec;
208 }
209
210 static NormPtr skip_parens (NormPtr p)
211 {
212 int ns = 0;
213
214 for (; p < C_Ntok; p++)
215 if (CODE [p] == '(') ++ns;
216 else if (CODE [p] == ')')
217 if (--ns == 0) return p + 1;
218 return syntax_error (p, "Unclosed parenthesis:)");
219 }
220
221 static NormPtr skip_brackets (NormPtr p)
222 {
223 int ns = 0;
224
225 for (; p < C_Ntok; p++)
226 if (CODE [p] == '{') ++ns;
227 else if (CODE [p] == '}')
228 if (--ns == 0) return p + 1;
229 return syntax_error (p, "Unclosed brackets:}");
230 }
231
232 //***********************************************************************
233 // definitions : declarator
234 //***********************************************************************
235
236 void declarator::argument_conversions ()
237 {
238 int tspec [MSPEC], *tp = tspec, *vp = spec;
239
240 if (basetype >= TYPEDEF_BASE && *vp == -1) {
241 type t;
242 opentype (basetype - TYPEDEF_BASE, t);
243 if (t.spec [0] == '(') *tp++ = '*';
244 }
245
246 if (*vp == '(') *tp++ = '*';
247 for (;;vp++) {
248 switch (*vp) {
249 case '*': *tp++ = '*'; continue;
250 case '[': *tp++ = '*'; vp++; continue;
251 case '(': *tp++ = '('; *tp++ = *++vp; continue;
252 }
253 *tp = -1;
254 break;
255 }
256 intcpy (spec, tspec);
257 }
258
259 NormPtr declarator::parse_dcl (NormPtr p)
260 {
261 p = parse (p);
262 if (have_init && spec [0] == '[' && spec [1] == 0) complete_size ();
263 semantics ();
264 if (do_argument_conversions) argument_conversions ();
265 gentype = gettype (basetype, spec);
266 return p;
267 }
268
269 NormPtr declarator::parse_base (NormPtr p)
270 {
271 have_extern = have_static = have_typedef = have_const = is_anonymous = false;
272
273 while (ISDCLFLAG (CODE [p]))
274 switch (CODE [p++]) {
275 case RESERVED_extern: have_extern = true; break;
276 case RESERVED_static: have_static = true; break;
277 case RESERVED_typedef: have_typedef = true; break;
278 case RESERVED_const: have_const = true; break;
279 }
280
281 if ((have_extern && have_static) || (have_extern && have_typedef)
282 || (have_static && have_typedef)) syntax_error (p, "Decide");
283
284 if (ISBASETYPE (CODE [p]) || ISHBASETYPE (CODE [p]))
285 p = builtin (p);
286 else if (CODE [p] == RESERVED_struct || CODE [p] == RESERVED_union)
287 p = bt_struct (p);
288 else if (ISSYMBOL (CODE [p]))
289 p = bt_typedef (p);
290 else if (CODE [p] == RESERVED_enum)
291 p = bt_enum (p + 1);
292 #ifdef GNU_VIOLATIONS
293 else if (CODE [p] == RESERVED___typeof__)
294 p = bt_typeof (p + 1);
295 else if (CODE [p] == RESERVED___label__) {
296 while (CODE [p] != ';') p++;
297 }
298 #endif
299 else basetype = S_INT;
300
301 while (ISDCLFLAG (CODE [p]))
302 switch (CODE [p++]) {
303 case RESERVED_extern: have_extern = true; break;
304 case RESERVED_static: have_static = true; break;
305 case RESERVED_typedef: have_typedef = true; break;
306 case RESERVED_const: have_const = true; break;
307 }
308
309 return p;
310 }
311
312 NormPtr declarator::builtin (NormPtr p)
313 {
314 int bt, sh, lo, si, us;
315
316 bt = sh = lo = si = us = 0;
317 for (;ISBASETYPE (CODE [p]) || ISHBASETYPE (CODE [p])
318 || CODE [p] == RESERVED_const; p++)
319 switch (CODE [p]) {
320 case RESERVED_long: lo++; break;
321 case RESERVED_short: sh++; break;
322 case RESERVED_signed: si++; break;
323 case RESERVED_unsigned: us++; break;
324 case RESERVED_const: continue;
325 default: if (bt) syntax_error (p, "Please specify");
326 bt = CODE [p];
327 }
328
329 if (bt == 0) bt = RESERVED_int;
330 if ((lo && sh) || (si && us)) syntax_error (p, "AMBIGUOUS specifiers");
331 switch (bt) {
332 case RESERVED_float: basetype = FLOAT; break;
333 case RESERVED_double: basetype = DOUBLE; break;
334 case RESERVED_void: basetype = VOID; break;
335 case RESERVED_char: basetype = (us) ? U_CHAR : S_CHAR; break;
336 case RESERVED_int:
337 if (sh) basetype = (us) ? U_SINT : S_SINT;
338 else if (lo == 1) basetype = (us) ? U_LINT : S_LINT;
339 else if (lo > 1) basetype = (us) ? U_LONG : S_LONG;
340 else basetype = (us) ? U_INT : S_INT;
341 }
342
343 return p;
344 }
345
346 NormPtr declarator::bt_enum (NormPtr p)
347 {
348 basetype = S_INT;
349 if (!ISSYMBOL (CODE [p]) && CODE [p] != '{')
350 syntax_error (p, "DEAD rats after enum");
351
352 if (CODE [p] != '{' && CODE [p + 1] != '{') {
353 if (!valid_enumtag (CODE [p]) &&
354 !introduce_enumtag (CODE [p], true))
355 syntax_error (p, "enum tag REDEFINED");
356 return p + 1;
357 }
358
359 if (CODE [p] != '{')
360 if (!introduce_enumtag (CODE [p++]))
361 syntax_error (p, "enum tag REDEFINED");
362
363 return get_enum_consts (p);
364 }
365
366 NormPtr declarator::bt_typedef (NormPtr p)
367 {
368 if ((basetype = lookup_typedef (CODE [p])) == -1) {
369 basetype = S_INT;
370 return p;
371 }
372 ++p;
373 return ISHBASETYPE (CODE [p]) ? p + 1 : p;
374 }
375
376 NormPtr declarator::bt_struct (NormPtr p)
377 {
378 bool isst = CODE [p++] == RESERVED_struct;
379
380 if (!ISSYMBOL (CODE [p]) && CODE [p] != '{')
381 syntax_error (p, "DEAD RATS after struct");
382
383 if (CODE [p] != '{' && CODE [p + 1] != '{') {
384 basetype = (CODE [p + 1] == ';')
385 ? fwd_struct_tag (CODE [p], isst)
386 : use_struct_tag (CODE [p], isst);
387 return p + 1;
388 }
389
390 if ((is_anonymous = CODE [p] == '{'))
391 basetype = introduce_anon_struct (isst);
392 else if ((basetype = introduce_named_struct (CODE [p++], isst)) == -1)
393 syntax_error (p, "Redefined structure tag");
394
395 is_struct_dcl = true;
396 psst = p++ - 1;
397 p = parse_structure (p);
398 pslen = p - psst;
399 return p;
400 }
401
402 static NormPtr get_enum_consts (NormPtr p)
403 {
404 int counter = 0, s;
405
406 for (++p;;) {
407 s = CODE [p++];
408 if (s == '}') break;
409 if (!ISSYMBOL (s))
410 syntax_error (p, "Random NOISE INSIDE ENUM");
411 if (CODE [p] == '=')
412 p = constant_int_expression (++p, counter);
413 if (!introduce_enumconst (s, counter++))
414 syntax_error (p, "Enumeration constant exists");
415 s = CODE [p++];
416 if (s == '}') break;
417 if (s != ',')
418 syntax_error (p, "RANDOM noise inside enum");
419 }
420
421 return p;
422 }
423
424 //***************************************************************************
425 // Forward
426 //***************************************************************************
427 static NormPtr initializer_expr (Symbol, NormPtr);
428 static NormPtr initializer_aggregate (Symbol, NormPtr);
429 static NormPtr parse_function (Symbol, NormPtr, NormPtr, NormPtr);
430 static bool is_dcl_start (int);
431 //***************************************************************************
432 // Declarations II
433 //
434 // Four places of declarators:
435 // 1) Declarator in code or global
436 // 2) Declarator inside structure block
437 // 3) Function argument list
438 // 4) (type cast)
439 //***************************************************************************
440 class cast_type
441 {
442 public:
443 typeID gentype;
444 NormPtr parse (NormPtr);
445 };
446
447 class arglist
448 {
449 NormPtr argument (NormPtr);
450 NormPtr parse_newstyle (NormPtr);
451 bool old_declaration (NormPtr);
452 NormPtr parse_oldstyle (NormPtr, bool = false);
453 public:
454 bool nolist;
455 typeID types [100];
456 int names [100], ii;
457 void parse_declare (NormPtr);
458 NormPtr parse (NormPtr);
459 };
460
461 class declaration
462 {
463 protected:
464 virtual void semantics (NormPtr);
465 NormPtr parse_initializer (NormPtr);
466 public:
467 declarator D;
468 declaration (bool b = false) : D (b) { }
469 NormPtr parse (NormPtr);
470 };
471
472 class declaration_instruct : public declaration
473 {
474 void semantics (NormPtr);
475 };
476 //***********************************************************************
477 // definitions: cast, arglist
478 //***********************************************************************
479
480 NormPtr cast_type::parse (NormPtr p)
481 {
482 declarator B;
483 p = B.parse_dcl (B.parse_base (p));
484
485 if (B.have_typedef || B.have_extern || B.have_static
486 || B.have_code || B.have_init || B.symbol != -1
487 || B.spec [0] == ':') syntax_error (p, "Improper cast");
488
489 gentype = B.gentype;
490
491 return p;
492 }
493
494 NormPtr arglist::argument (NormPtr p)
495 {
496 declarator B (true);
497 p = B.parse_dcl (B.parse_base (p));
498
499 if (B.have_typedef || B.have_extern || B.have_static
500 || B.have_code || B.have_init || B.spec [0] == ':')
501 syntax_error (p, "Crap argument");
502
503 names [ii] = B.symbol;
504 types [ii++] = B.gentype;
505
506 return p;
507 }
508
509 bool arglist::old_declaration (NormPtr p)
510 {
511 return ISSYMBOL (CODE [p])
512 && (CODE [p + 1] == ',' || CODE [p + 1] == ')')
513 && lookup_typedef (CODE [p]) == -1;
514 }
515
516 NormPtr arglist::parse_newstyle (NormPtr p)
517 {
518 ii = 0;
519
520 if (CODE [p] == ')') {
521 nolist = true;
522 return p + 1;
523 }
524
525 if (CODE [p] == RESERVED_void && CODE [p + 1] == ')')
526 return p + 2;
527
528 while (1) {
529 if (CODE [p] == ELLIPSIS) {
530 types [ii++] = SPECIAL_ELLIPSIS;
531 if (CODE [p + 1] != ')')
532 syntax_error (p, "'...' must be last");
533 return p + 2;
534 }
535 switch (CODE [p = argument (p)]) {
536 default: syntax_error (p, "Invalid argument list");
537 case ')': return p + 1;
538 case ',': p++;
539 }
540 }
541
542 return p + 1;
543 }
544
545 NormPtr arglist::parse_oldstyle (NormPtr p, bool dcl)
546 {
547 // few syntax/semantics tests. We suppose old program, which
548 // is syntactically correct for the last 10 years
549 int i = 0, j;
550 ii = 1;
551 types [0] = ARGLIST_OPEN;
552 types [1] = -1;
553
554 if (CODE [p] != ')')
555 do names [i++] = CODE [p++]; while (CODE [p++] == ',');
556
557 if (dcl) {
558 declaration D (true);
559 while (CODE [p] != '{') {
560 p = D.parse (p);
561 for (j = 0; j < i; j++)
562 if (names [j] == D.D.symbol) {
563 names [j] = -1;
564 break;
565 }
566 }
567 for (j = 0; j < i; j++) if (names [j] != -1)
568 introduce_obj (names [j], SIntType, DEFAULT);
569 } else {
570 if (!is_dcl_start (CODE [p])) return p;
571 while (CODE [p] != '{') p++;
572 }
573 return p;
574 }
575
576 void arglist::parse_declare (NormPtr p)
577 {
578 if (old_declaration (p)) {
579 parse_oldstyle (p, true);
580 return;
581 }
582
583 int i;
584 parse_newstyle (p);
585
586 for (i = 0; i < ii; i++)
587 if (types [i] != SPECIAL_ELLIPSIS) {
588 if (names [i] == -1)
589 syntax_error (p, "Abstract argument");
590 introduce_obj (names [i], types [i], DEFAULT);
591 }
592 }
593
594 NormPtr arglist::parse (NormPtr p)
595 {
596 nolist = false;
597 return old_declaration (p) ? parse_oldstyle (p) : parse_newstyle (p);
598 }
599
600 void declarator::arglist_to_specs ()
601 {
602 arglist A;
603 p = A.parse (p + 1);
604 if (A.nolist) A.types [A.ii++] = ARGLIST_OPEN;
605 A.types [A.ii] = -1;
606 spec [dp++] = make_arglist (A.types);
607 }
608
609 //***********************************************************************
610 // definitions: declaration, instructure
611 //***********************************************************************
612
613 NormPtr declaration::parse (NormPtr p)
614 {
615 VARSPC vs;
616 bool ok;
617 typeID t;
618 NormPtr dclstart = p; // to report beginning of function...
619
620 D.is_struct_dcl = false;
621 p = D.parse_base (p);
622 if (CODE [p] == ';') {
623 if (D.is_struct_dcl && usage_only && report_structs && !D.is_anonymous) {
624 D.is_struct_dcl = false;
625 struct_location (D.basetype, D.psst, D.pslen);
626 } else if (D.is_struct_dcl && D.is_anonymous)
627 spill_anonymous (D.basetype);
628 } else while (CODE [p] != ';') {
629 p = D.parse_dcl (p);
630
631 semantics (p);
632 t = D.gentype;
633
634 vs = (D.have_extern)?EXTERN:(D.have_static)?STATIC:DEFAULT;
635
636 if (D.have_typedef) ok = introduce_tdef (D.symbol, t);
637 else ok = introduce_obj (D.symbol, t, vs);
638 if (!ok) syntax_error (p, "redefined: ", expand (D.symbol));
639
640 if (D.is_anonymous) D.is_anonymous = !rename_struct (t, D.symbol);
641
642 if (D.is_struct_dcl && usage_only && report_structs) {
643 D.is_struct_dcl = false;
644 struct_location (D.basetype, D.psst, D.pslen);
645 }
646
647 if (D.have_code) return parse_function (D.symbol, D.args, p, dclstart);
648 if (D.have_init) p = parse_initializer (p + 1);
649
650 if (CODE [p] == ';') break;
651 if (CODE [p] != ',') {
652 if (CODE [p] != RESERVED___asm__)
653 syntax_error(p, "unaccaptable declaration, separator;",
654 expand (CODE [p]));
655 p = skip_parens (p + 1);
656 continue;
657 }
658 p++;
659 }
660
661 return p + 1;
662 }
663
664 NormPtr declaration::parse_initializer (NormPtr p)
665 {
666 if (CODE [p] != '{')
667 return initializer_expr (D.symbol, p);
668
669 #ifdef PARSE_ARRAY_INITIALIZERS
670 return initializer_aggregate (D.symbol, p);
671 #else
672 return base_of (D.gentype) < _BTLIMIT ?
673 skip_brackets (p) : initializer_aggregate (D.symbol, p);
674 #endif
675 }
676
677 void declaration::semantics (NormPtr p)
678 {
679 if (D.spec [0] == ':'
680 || (D.have_typedef && (D.have_init || D.have_code)))
681 syntax_error (p, "Not the \"right thing\"");
682 if (D.symbol == -1) syntax_error (p, "ABSENT symbol");
683 if (D.have_code && !INGLOBAL)
684 syntax_error (p, "Do you like nested functions?");
685 }
686
687 void declaration_instruct::semantics (NormPtr p)
688 {
689 if (D.have_static || D.have_extern || D.have_typedef
690 || D.spec [0] == '(' || D.have_init || D.have_code
691 || (D.symbol == -1 && D.spec [0] != ':'))
692 syntax_error (p, "Not good dcl in struct");
693 }
694
695 static bool is_typename (int token)
696 {
697 return token == RESERVED_struct || token == RESERVED_union
698 || ISBASETYPE(token) || ISHBASETYPE (token)
699 || token == RESERVED_enum
700 || (ISSYMBOL (token) && is_typedef (token));
701 }
702
703 static bool is_dcl_start (int token)
704 {
705 return ISDCLFLAG (token) || is_typename (token)
706 #ifdef GNU_VIOLATIONS
707 || token == RESERVED___label__
708 || token == RESERVED___typeof__
709 #endif
710 ;
711 }
712
713 //**************************************************************************
714 // Part II
715 //
716 // By now we are ok with the declarations (introducing new names
717 // to the program). Whenever we see a declaration, invoke a declarator.
718 // We can at any time lookup what's an identifier, with lookup().
719 //
720 // Missing:
721 // parsing expressions in initializers
722 //
723 // But this is ok, because this is exactly what we are going to
724 // do now.
725 //**************************************************************************
726 // C expressions
727 //**************************************************************************
728 NormPtr ExpressionPtr;
729
730 static int bopid;
731
732 static int priority (int op)
733 {
734 if (op > 256) switch (op) {
735 case LSH: bopid = SHL; return 11;
736 case RSH: bopid = SHR; return 11;
737 case GEQCMP: bopid = CGRE; return 10;
738 case LEQCMP: bopid = CLEE; return 10;
739 case EQCMP: bopid = BEQ; return 9;
740 case NEQCMP: bopid = BNEQ; return 9;
741 case ANDAND: bopid = IAND; return 5;
742 case OROR: bopid = IOR; return 4;
743 default: return 0;
744 }
745 switch (op) {
746 case '*': bopid = MUL; return 13;
747 case '/': bopid = DIV; return 13;
748 case '%': bopid = REM; return 13;
749 case '+': bopid = ADD; return 12;
750 case '-': bopid = SUB; return 12;
751 case '>': bopid = CGR; return 10;
752 case '<': bopid = CLE; return 10;
753 case '&': bopid = BAND; return 8;
754 }
755 if (op == '^') {
756 bopid = BXOR;
757 return 7;
758 }
759 if (op != '|') return 0;
760 bopid = BOR;
761 return 6;
762 }
763
764 static int xlate_uop (int op)
765 {
766 switch (op) {
767 case '!': return LNEG;
768 case '*': return PTRIND;
769 case '+': return UPLUS;
770 case '-': return UMINUS;
771 case '&': return ADDROF;
772 }
773 switch (op) {
774 case PLUSPLUS: return PPPRE;
775 case MINUSMINUS: return MMPRE;
776 default: return OCPL;
777 }
778 }
779
780 subexpr *&ee = CExpr.ee;
781 int &NeTop = CExpr.ne;
782
783 class expression_parser
784 {
785 inline void reloc ();
786 void value_to_expression (exprID, Symbol);
787 #ifdef GNU_VIOLATIONS
788 exprID gnu_st_expr ();
789 exprID gnu_ctor_expr (typeID);
790 #endif
791 #ifdef LABEL_VALUES
792 exprID gnu_label_value ();
793 #endif
794 exprID sizeof_typename ();
795 exprID unary_expression ();
796 exprID argument_expression_list ();
797 exprID primary_expression ();
798 exprID prefix_expression ();
799 exprID binary_expression (exprID, int);
800 exprID logicalOR_expression ();
801
802 int nee, extra;
803 public:
804 expression_parser (NormPtr, subexpr*);
805
806 exprID postfix_expression ();
807 exprID assignment_expression ();
808 exprID conditional_expression ();
809 exprID expression ();
810
811 NormPtr EP;
812 subexpr *ee;
813 int iee;
814 ~expression_parser ();
815 };
816
817 //***********************************************************************
818 // definitions
819 //***********************************************************************
820
821 exprID expression_parser::sizeof_typename ()
822 {
823 cast_type T;
824 EP = T.parse (EP + 2);
825 if (CODE [EP++] != ')') syntax_error (EP, "erroneous sizeof");
826 ee [iee].action = VALUE;
827 exprID c = sizeof_typeID (T.gentype);
828 ee [iee].voici.value = c;
829 return iee++;
830 }
831
832 #define ISUNARY(x) \
833 ((x<'~') ? (x=='!'||x=='*'||x=='&'||x=='-'||x=='+')\
834 : (x==PLUSPLUS || x==MINUSMINUS || x=='~'))
835
836 exprID expression_parser::unary_expression ()
837 {
838 int prefix [40];
839 typeID casts [40];
840 int ipr = 0, t;
841 exprID e = -1;
842
843 for (t = CODE [EP]; t < STRINGBASE; t = CODE [++EP])
844 if (ISUNARY (t)) prefix [ipr++] = xlate_uop (t);
845 else if (t == '(')
846 if (is_dcl_start (CODE [EP + 1])) {
847 cast_type C;
848 EP = C.parse (EP + 1);
849 casts [ipr] = C.gentype;
850 prefix [ipr++] = CAST;
851 #ifdef GNU_VIOLATIONS
852 if (CODE [EP + 1] == '{') {
853 e = gnu_ctor_expr (C.gentype);
854 goto have_unary;
855 }
856 #endif
857 } else break;
858 else if (t == RESERVED_sizeof)
859 if (CODE [EP+1] == '(' && is_dcl_start (CODE [EP+2])) {
860 e = sizeof_typename ();
861 goto have_unary;
862 } else prefix [ipr++] = SIZEOF;
863 #ifdef LABEL_VALUES
864 else if (t == ANDAND) {
865 e = gnu_label_value ();
866 goto have_unary;
867 }
868 #endif
869 else break;
870
871 if ((e = postfix_expression ()) == -1 && ipr > 0)
872 syntax_error (EP, "prefix operator w/o operand");
873
874 have_unary:
875 reloc (); /* * */
876 while (ipr--) {
877 ee [iee].voici.e = e;
878 if ((ee [iee].action = prefix [ipr]) == CAST)
879 ee [iee].voila.cast = casts [ipr];
880 e = iee++;
881 }
882
883 return e;
884 }
885
886 exprID expression_parser::primary_expression ()
887 {
888 int t = CODE [EP++];
889
890 if (ISSYMBOL (t)) {
891 ee [iee].action = SYMBOL;
892 ee [iee].voici.symbol = t;
893 return iee++;
894 }
895
896 if (ISNUMBER (t) || ISSTRING (t)) {
897 value_to_expression (iee, t);
898 return iee++;
899 }
900
901 if (t != '(') {
902 EP--;
903 return -1;
904 }
905
906 exprID e;
907 #ifdef GNU_VIOLATIONS
908 if (CODE [EP] == '{') e = gnu_st_expr (); else
909 #endif
910 e = expression ();
911 if (CODE [EP++] != ')')
912 syntax_error (EP, "parse error");
913 return e;
914 }
915
916 exprID expression_parser::postfix_expression ()
917 {
918 exprID e = primary_expression (), c;
919 if (e == -1) return -1;
920
921 int t;
922 for (t = CODE [EP];; t = CODE [++EP]) {
923 ee [iee].voici.e = e;
924
925 switch (t) {
926 case PLUSPLUS:
927 ee [e = iee++].action = PPPOST; break;
928 case MINUSMINUS:
929 ee [e = iee++].action = MMPOST; break;
930 case '[':
931 EP++;
932 ee [e = iee++].action = ARRAY;
933 c = expression ();
934 ee [e].e = c;
935 if (CODE [EP] != ']')
936 syntax_error (EP, "missing ']'");
937 break;
938 case '(':
939 EP++;
940 ee [e = iee++].action = FCALL;
941 c = argument_expression_list ();
942 ee [e].e = c;
943 if (CODE [EP] != ')')
944 syntax_error (EP, "missing ')'");
945 break;
946 case POINTSAT:
947 ee [e = iee++].action = PTRIND;
948 ee [iee].voici.e = e;
949 case '.':
950 ee [e = iee++].action = MEMB;
951 ee [e].voila.member = CODE [++EP];
952 if (!ISSYMBOL (ee [e].voila.member))
953 syntax_error (EP, "->members only");
954 break;
955 default:
956 return e;
957 }
958 }
959 }
960
961 exprID expression_parser::binary_expression (exprID lop, int pri)
962 {
963 static int p2;
964 int coperator = bopid;
965 exprID e;
966 EP++;
967 if ((e = unary_expression ()) == -1)
968 syntax_error (EP, "two operands expected");
969
970 p2 = priority (CODE [EP]);
971 while (p2 > pri)
972 e = binary_expression (e, p2);
973
974 ee [iee].voici.e = lop;
975 ee [iee].action = coperator;
976 ee [iee].e = e;
977 e = iee++;
978
979 return (p2 < pri) ? e : binary_expression (e, pri);
980 }
981
982 exprID expression_parser::logicalOR_expression ()
983 {
984 int p;
985 exprID e = unary_expression ();
986 if (e == -1) return -1;
987
988 while ((p = priority (CODE [EP])))
989 e = binary_expression (e, p);
990
991 return e;
992 }
993
994 exprID expression_parser::conditional_expression ()
995 {
996 exprID e = logicalOR_expression (), c;
997 if (e == -1) return -1;
998
999 if (CODE [EP] == '?') {
1000 ee [iee].voici.e = e;
1001 ee [e = iee++].action = COND;
1002 EP++;
1003 c = expression ();
1004 ee [e].e = c;
1005 if (CODE [EP++] != ':')
1006 syntax_error (EP, "(what) ? is ':' missing");
1007 if ((c = conditional_expression ()) == -1)
1008 syntax_error (EP, "(what) ? is : missing");
1009 ee [e].voila.eelse = c;
1010 }
1011
1012 return e;
1013 }
1014
1015 exprID expression_parser::assignment_expression ()
1016 {
1017 exprID e = conditional_expression (), c;
1018 if (e == -1) return -1;
1019
1020 if (!ISASSIGNMENT (CODE [EP])) return e;
1021
1022 ee [iee].voici.e = e;
1023 ee [e = iee++].action = CODE [EP++];
1024 if ((c = assignment_expression ()) == -1)
1025 syntax_error (EP, " = (missing operand)");
1026 ee [e].e = c;
1027
1028 return e;
1029 }
1030
1031 exprID expression_parser::expression ()
1032 {
1033 exprID e = assignment_expression (), c;
1034 if (e == -1) return -1;
1035
1036 if (CODE [EP] == ',') {
1037 ++EP;
1038 ee [iee].voici.e = e;
1039 ee [e = iee++].action = COMMA;
1040 c = expression ();
1041 ee [e].e = c;
1042 }
1043
1044 return e;
1045 }
1046
1047 exprID expression_parser::argument_expression_list ()
1048 {
1049 exprID e = assignment_expression (), c;
1050 if (e == -1) return -1;
1051
1052 if (CODE [EP] == ',') {
1053 ++EP;
1054 ee [iee].voici.e = e;
1055 ee [e = iee++].action = ARGCOMMA;
1056 c = argument_expression_list ();
1057 ee [e].e = c;
1058 }
1059
1060 return e;
1061 }
1062
1063 expression_parser::expression_parser (NormPtr p, subexpr *tee)
1064 {
1065 #define STDNEE 138
1066 ExpressionPtr = EP = p;
1067 nee = STDNEE;
1068 extra = false;
1069 ee = tee;
1070 iee = 0;
1071 }
1072
1073 void expression_parser::reloc ()
1074 {
1075 #define RELOCAT 10
1076 if (nee - iee < RELOCAT) {
1077 subexpr *bigger = new subexpr [nee += 32];
1078 memcpy (bigger, ee, iee * sizeof ee [0]);
1079 if (extra) delete [] ee;
1080 ee = bigger;
1081 extra = true;
1082 }
1083 }
1084
1085 expression_parser::~expression_parser ()
1086 {
1087 if (extra) delete [] ee;
1088 }
1089 //***********************************************************************
1090 // definitions
1091 //***********************************************************************
1092
1093 void expression_parser::value_to_expression (exprID i, Symbol s)
1094 {
1095 if (ISSTRING (s)) {
1096 ee [i].action = SVALUE;
1097 ee [i].voici.value = s - STRINGBASE;
1098 return;
1099 }
1100
1101 if (s >= INUMBER) {
1102 ee [i].action = UVALUE;
1103 ee [i].voici.uvalue = s - INUMBER;
1104 return;
1105 }
1106
1107 if (s >= FLOATBASE) {
1108 ee [i].action = FVALUE;
1109 ee [i].voici.fvalue = C_Floats [s - FLOATBASE];
1110 return;
1111 }
1112
1113 if (s >= UINT32BASE) {
1114 ee [i].action = UVALUE;
1115 ee [i].voici.uvalue = C_Unsigned [s - UINT32BASE];
1116 return;
1117 }
1118
1119 ee [i].action = VALUE;
1120 ee [i].voici.value = getint (s);
1121 }
1122
1123 static NormPtr parse_expression (NormPtr p)
1124 {
1125 subexpr tee [STDNEE];
1126 expression_parser PP (p, tee);
1127
1128 CExpr.first = PP.expression ();
1129 CExpr.ee = PP.ee;
1130 CExpr.ne = PP.iee;
1131 if (!usage_only) prcode (p, PP.EP - p);
1132 ncc->cc_expression ();
1133 return PP.EP;
1134 }
1135
1136 static NormPtr constant_int_expression (NormPtr p, int &r)
1137 {
1138 if (ISNUMBER (CODE [p]) && CODE [p] < UINT32BASE
1139 && !priority (CODE [p + 1])) {
1140 r = getint (CODE [p]);
1141 return p + 1;
1142 }
1143
1144 subexpr tee [STDNEE];
1145 expression_parser PP (p, tee);
1146
1147 CExpr.first = PP.conditional_expression ();
1148 CExpr.ee = PP.ee;
1149 CExpr.ne = PP.iee;
1150 r = cc_int_expression ();
1151 return PP.EP;
1152 }
1153
1154 //**************************************************************************
1155 //
1156 // Some GNU Violations we don't like
1157 //
1158 //**************************************************************************
1159 #ifdef GNU_VIOLATIONS
1160 static NormPtr compound_statement (NormPtr p);
1161 exprID expression_parser::gnu_st_expr ()
1162 {
1163 EP = compound_statement (EP + 1);
1164 ee [iee].action = COMPOUND_RESULT;
1165 ee [iee].voici.using_result = last_result;
1166 ee [iee].voila.result_type = gettype (last_result_type.base,
1167 last_result_type.spec);
1168 return iee++;
1169 }
1170
1171 static NormPtr initializer_aggregate (Symbol, NormPtr);
1172
1173 exprID expression_parser::gnu_ctor_expr (typeID c)
1174 {
1175 open_compound ();
1176 introduce_obj (intern_sym, c, DEFAULT);
1177 EP = initializer_aggregate (intern_sym, EP + 1);
1178 //EP = skip_brackets (EP + 1);
1179 close_region ();
1180 ee [iee].action = VALUE;
1181 return iee++;
1182 }
1183
1184 NormPtr declarator::bt_typeof (NormPtr p)
1185 {
1186 if (CODE [p++] != '(') syntax_error (p, "typeof '('");
1187 if (is_dcl_start (CODE [p])) {
1188 cast_type C;
1189 p = C.parse (p);
1190 basetype = C.gentype + TYPEDEF_BASE;
1191 } else {
1192 subexpr tee [STDNEE];
1193 expression_parser PP (p, tee);
1194 CExpr.first = PP.expression ();
1195 CExpr.ee = PP.ee;
1196 CExpr.ne = PP.iee;
1197 basetype = typeof_expression ();
1198 p = PP.EP;
1199 }
1200 if (CODE [p] != ')') syntax_error (p, "typeof ')'");
1201 return p + 1;
1202 }
1203 #endif
1204
1205 #ifdef LABEL_VALUES
1206 exprID expression_parser::gnu_label_value ()
1207 {
1208 int s = CODE [++EP];
1209 if (!ISSYMBOL (s)) syntax_error (EP, "&&identifier only, for labels");
1210 ee [iee].action = AVALUE;
1211 ee [iee].voici.symbol = s;
1212 EP++;
1213 return iee++;
1214 }
1215 #endif
1216 //**************************************************************************
1217 // Part III
1218 //
1219 // statements, this is really easy
1220 //**************************************************************************
1221
1222 static int IDLEV = -1;
1223 #define PCMD(CMD) \
1224 if (pseudo_code) {\
1225 PRINTF ("#X: %s\n", CMD);\
1226 }
1227 struct PINDENT { PINDENT () { IDLEV += 1; } ~PINDENT () { PCMD ("*"); IDLEV -= 1; } };
1228 #define PSEUDOCODE(CMD) PINDENT P; PCMD(CMD);
1229
1230 static NormPtr while_statement (NormPtr p);
1231 static NormPtr for_statement (NormPtr p);
1232 static NormPtr do_statement (NormPtr p);
1233 static NormPtr switch_statement (NormPtr p);
1234 static NormPtr if_statement (NormPtr p);
1235 static NormPtr compound_statement (NormPtr p);
1236 static NormPtr __asm___statement (NormPtr p);
1237
1238 static NormPtr statement (NormPtr p)
1239 {
1240 int t = CODE [p++];
1241
1242 if (ISSYMBOL (t) && CODE [p] == ':')
1243 return CODE [p + 1] == '}' ? p + 1 : statement (p + 1);
1244
1245 switch (t) {
1246 case RESERVED_default:
1247 if (CODE [p] != ':') syntax_error (p, "default:");
1248 return p + 1;
1249 case RESERVED_case:
1250 int tmp;
1251 p = constant_int_expression (p, tmp);
1252 if (CODE [p] == ELLIPSIS) p = constant_int_expression (p + 1, tmp);
1253 if (CODE [p] != ':') syntax_error (p, "case ERROR:");
1254 return p + 1;
1255 case RESERVED_continue:
1256 case RESERVED_break:
1257 if (CODE [p] != ';') syntax_error (p, "break | continue ';'");
1258 return p + 1;
1259 case RESERVED_goto:
1260 if (ISSYMBOL (CODE [p]) && CODE [p + 1] == ';')
1261 return p + 2;
1262 case RESERVED_return:
1263 p = parse_expression (p);
1264 if (CODE [p] != ';') syntax_error (p, "return ... ';'");
1265 return p + 1;
1266 case RESERVED_while: return while_statement (p);
1267 case RESERVED_for: return for_statement (p);
1268 case RESERVED_do: return do_statement (p);
1269 case RESERVED_switch: return switch_statement (p);
1270 case RESERVED_if: return if_statement (p);
1271 case RESERVED___asm__: return __asm___statement (p);
1272 case RESERVED_else: syntax_error (p, "else without if");
1273 case '{': return compound_statement (p);
1274 default:
1275 p = parse_expression (p - 1);
1276 if (CODE [p++] != ';')
1277 syntax_error (p, "expression + ';' = statement");
1278 case ';':
1279 return p;
1280 }
1281 }
1282
1283 static NormPtr parenth_expression (NormPtr p)
1284 {
1285 if (CODE [p++] != '(')
1286 syntax_error (p, "'(' expression");
1287 p = parse_expression (p);
1288 if (CODE [p++] != ')')
1289 syntax_error (p, "expression ')'");
1290 return p;
1291 }
1292
1293 static NormPtr while_statement (NormPtr p)
1294 {
1295 PSEUDOCODE ("REPEAT");
1296 return statement (parenth_expression (p));
1297 }
1298
1299 static NormPtr do_statement (NormPtr p)
1300 {
1301 PSEUDOCODE ("REPEAT");
1302 p = statement (p);
1303 if (CODE [p++] != RESERVED_while)
1304 syntax_error (p, "do w/o while");
1305 p = parenth_expression (p);
1306 if (CODE [p++] != ';')
1307 syntax_error (p, "This is special, but you need a ';'");
1308 return p;
1309 }
1310
1311 static NormPtr for_statement (NormPtr p)
1312 {
1313 if (CODE [p++] != '(')
1314 syntax_error (p, "for '('...");
1315 p = parse_expression (p);
1316 PSEUDOCODE ("REPEAT");
1317 if (CODE [p++] != ';')
1318 syntax_error (p, "for (expression ';' ...");
1319 p = parse_expression (p);
1320 if (CODE [p++] != ';')
1321 syntax_error (p, "for (expression; expression ';' ...");
1322 p = parse_expression (p);
1323 if (CODE [p++] != ')')
1324 syntax_error (p, "for (;; ')'");
1325 return statement (p);
1326 }
1327
1328 static NormPtr switch_statement (NormPtr p)
1329 {
1330 p = parenth_expression (p);
1331 return statement (p);
1332 }
1333
1334 static NormPtr if_statement (NormPtr p)
1335 {
1336 {
1337 PSEUDOCODE ("IF");
1338 p = statement (parenth_expression (p));
1339 }
1340 if (CODE [p] == RESERVED_else) {
1341 PSEUDOCODE ("ELSE");
1342 return statement (p + 1);
1343 }
1344 return p;
1345 }
1346
1347 static NormPtr parse_declaration (NormPtr p)
1348 {
1349 declaration D;
1350 return D.parse (p);
1351 }
1352
1353 static NormPtr compound_statement (NormPtr p)
1354 {
1355 open_compound ();
1356
1357 #ifdef NCC_ISOC99
1358 while (CODE [p] != '}')
1359 p = (is_dcl_start (CODE [p]) && CODE [p + 1] != ':') ?
1360 parse_declaration (p) : statement (p);
1361 #else
1362 while (CODE [p] != '}')
1363 if (is_dcl_start (CODE [p]))
1364 p = parse_declaration (p);
1365 else break;
1366
1367 while (CODE [p] != '}')
1368 p = statement (p);
1369 #endif
1370
1371 close_region ();
1372 return p + 1;
1373 }
1374
1375 static NormPtr __asm___statement (NormPtr p)
1376 {
1377 NormPtr ast = p + 1;
1378 if (CODE [p] != '(') syntax_error (p, "__asm__ '('");
1379 p = skip_parens (p);
1380 if (CODE [p++] != ';') syntax_error (p, "asm() ';'");
1381 ncc->inline_assembly (ast, p - ast - 1);
1382 #ifdef GNU_VIOLATIONS
1383 last_result_type.base = VOID;
1384 last_result_type.spec [0] = -1;
1385 #endif
1386 ++last_result;
1387 return p;
1388 }
1389
1390 //***********************************************************************
1391 //
1392 // Part IV - the rest
1393 //
1394 //***********************************************************************
1395
1396 //***********************************************************************
1397 //
1398 // Aggregate initializers:
1399 // The goal is to: a) Catch functions assigned to structure
1400 // members, and b) Catch function calls in initializers.
1401 //
1402 //***********************************************************************
1403
1404 static inline NormPtr join_expression (dcle &E, NormPtr p)
1405 {
1406 #if 0
1407 if (ISNUMBER (CODE [p]) || ISSTRING (CODE [p]))
1408 if (CODE [p + 1] == ',' || CODE [p + 1] == '}') {
1409 // skip these quickly (may be lots of them)
1410 E.tofield ();
1411 return p + 1;
1412 }
1413 #endif
1414 NormPtr pe, cntk;
1415 subexpr tee [STDNEE];
1416 expression_parser EEP (p, tee);
1417 exprID e;
1418 typeID t;
1419 Symbol *se, *tmp;
1420 // root subexpression manually constructed
1421 tee [0].action = '=';
1422 EEP.iee = 1;
1423 // right part of the assignment is in CODE[]
1424 // and is assignment expression
1425 if ((e = EEP.assignment_expression ()) == -1)
1426 syntax_error (p, "wrong in here");
1427 pe = EEP.EP;
1428 EEP.ee [0].e = e;
1429 // check to see if the type of the assignment is
1430 // a structure
1431 CExpr.first = e;
1432 CExpr.ee = EEP.ee;
1433 CExpr.ne = EEP.iee;
1434 t = typeof_expression () - TYPEDEF_BASE;
1435 // ..and advance E accordingly
1436 if (spec_of (t)[0] == -1 && base_of (t) > _BTLIMIT)
1437 E.tostruct (base_of (t));
1438 else E.tofield ();
1439 // skip these quickly (calculated constant exprs)
1440 #if 0
1441 if (EEP.ee [e].action <= FVALUE)
1442 return pe;
1443 #endif
1444 // left part of the assignment is made in
1445 // E.mk_current and is a postfix expression
1446 tmp = E.mk_current ();
1447 if (0||!usage_only) prcode (p, EEP.EP - p, tmp);
1448 cntk = C_Ntok;
1449 se = CODE;
1450 CODE = tmp;
1451 for (C_Ntok = 0; CODE [C_Ntok] != -1; C_Ntok++);
1452 EEP.EP = 0;
1453 e = EEP.postfix_expression ();
1454 EEP.ee [0].voici.e = e;
1455 CODE = se;
1456 C_Ntok = cntk;
1457 // these two joined at tee[0] which is an
1458 // assignment. Now send to compiler
1459 CExpr.first = 0;
1460 CExpr.ee = EEP.ee;
1461 CExpr.ne = EEP.iee;
1462 ncc->cc_expression ();
1463 return pe;
1464 }
1465
1466
1467 static NormPtr initializer_aggregate (Symbol s, NormPtr p)
1468 {
1469 // aggregates can be very complex. if something bad happens, skip analysis
1470 NormPtr p0 = p;
1471 dcle E (s);
1472 for (;;) {
1473 for (;;)
1474 if (CODE [p] == '{') {
1475 p++;
1476 if (!E.open_bracket ()) goto Bad;
1477 } else if (ISSYMBOL (CODE [p]) && CODE [p + 1] == ':') {
1478 Symbol d [2] = { CODE [p], -1 };
1479 if (!E.designator (d)) goto Bad;
1480 if (CODE [p += 2] != '{') break;
1481 } else if (CODE [p] == '.' || CODE [p] == '[') {
1482 Symbol d [20];
1483 int di = 0;
1484 while (CODE [p] == '.' || CODE [p] == '[')
1485 if (CODE [p++] == '.')
1486 d [di++] = CODE [p++];
1487 else {
1488 p = constant_int_expression (p, d [di]);
1489 if (CODE [p++] == ELLIPSIS)
1490 p = constant_int_expression (p, d [di]) + 1;
1491 if (d [di] < 0) d [di] = -1;
1492 d [di++] += INUMBER;
1493 }
1494 if (CODE [p] == '=') p++;
1495 d [di] = -1;
1496 if (!E.designator (d)) goto Bad;
1497 if (CODE [p] != '{') break;
1498 } else break;
1499
1500 if (CODE [p] != ',' && CODE [p] != '}')
1501 p = join_expression (E, p);
1502
1503 for (;;)
1504 if (CODE [p] == '}') {
1505 p++;
1506 if (!E.close_bracket ()) return p; //*/*/*/*/*/*/*> OUT
1507 } else if (CODE [p] == ',') {
1508 if (CODE [++p] == '}') continue;
1509 if (!E.comma ()) syntax_error (p, "excess");
1510 } else break;
1511 }
1512 Bad:
1513 return skip_brackets (p0);
1514 }
1515
1516 //******** end aggregate initializers
1517
1518 static NormPtr initializer_expr (Symbol s, NormPtr p)
1519 {
1520 // if (ISSTRING (CODE [p])) {
1521 // return p + 1;
1522 // }
1523
1524 subexpr tee [STDNEE];
1525 tee [0].action = '=';
1526 tee [0].voici.e = 1;
1527 tee [1].action = SYMBOL;
1528 tee [1].voici.symbol = s;
1529 expression_parser EEP (p, tee);
1530 EEP.iee = 2;
1531 exprID e;
1532
1533 if ((e = EEP.assignment_expression ()) == -1)
1534 syntax_error (p, "erroneous initialization");
1535 EEP.ee [0].e = e;
1536
1537 CExpr.first = 0;
1538 CExpr.ee = EEP.ee;
1539 CExpr.ne = EEP.iee;
1540 if (!usage_only) prcode (p, EEP.EP - p, s);
1541 ncc->cc_expression ();
1542 return EEP.EP;
1543 }
1544
1545 static NormPtr parse_structure (NormPtr p)
1546 {
1547 declaration_instruct D;
1548 while (CODE [p] != '}' && p < C_Ntok)
1549 p = D.parse (p);
1550 close_region ();
1551 return p + 1;
1552 }
1553
1554 static NormPtr parse_function (Symbol s, NormPtr a, NormPtr p, NormPtr b)
1555 {
1556 NormPtr e = skip_brackets (p);
1557 if (!function_definition (s, a, p, e, b+1))
1558 //syntax_error (p, "Function definition already defined", expand (s));
1559 ;
1560 return e;
1561 }
1562
1563 void do_functions ()
1564 {
1565 int i;
1566 NormPtr args, body;
1567
1568 infuncs = true;
1569 for (i = 0; function_no (i, &args, &body); i++) {
1570 PSEUDOCODE("PCODE.0");
1571 arglist A;
1572 A.parse_declare (args + 1);
1573 compound_statement (body + 1);
1574 close_region ();
1575 }
1576 }
1577
1578 //
1579 // Well, that's it.
1580 //
1581 void parse_translation_unit ()
1582 {
1583 NormPtr p = 0;
1584 declaration D;
1585
1586 while (p < C_Ntok)
1587 if (CODE [p] == ';') p++;
1588 else if (CODE [p] == RESERVED___asm__) p = skip_parens (p + 1);
1589 else p = D.parse (p);
1590
1591 do_functions ();
1592 }
1593
1594 void parse_C ()
1595 {
1596 parse_translation_unit ();
1597 }