"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 }