Annotation of gcc/parse.y, revision 1.1.1.2

1.1       root        1: /* YACC parser for C syntax.
1.1.1.2 ! root        2:    Copyright (C) 1987, 1988 Free Software Foundation, Inc.
1.1       root        3: 
                      4: This file is part of GNU CC.
                      5: 
                      6: GNU CC is distributed in the hope that it will be useful,
                      7: but WITHOUT ANY WARRANTY.  No author or distributor
                      8: accepts responsibility to anyone for the consequences of using it
                      9: or for whether it serves any particular purpose or works at all,
                     10: unless he says so in writing.  Refer to the GNU CC General Public
                     11: License for full details.
                     12: 
                     13: Everyone is granted permission to copy, modify and redistribute
                     14: GNU CC, but only under the conditions described in the
                     15: GNU CC General Public License.   A copy of this license is
                     16: supposed to have been given to you along with GNU CC so you
                     17: can know your rights and responsibilities.  It should be in a
                     18: file named COPYING.  Among other things, the copyright notice
                     19: and this notice must be preserved on all copies.  */
                     20: 
                     21: 
                     22: /*  To whomever it may concern: I have heard that such a thing was once
                     23:  written by AT&T, but I have never seen it.  */
                     24: 
1.1.1.2 ! root       25: %expect 19
        !            26: 
        !            27: /* These are the 19 conflicts you should get in parse.output;
        !            28:    the state numbers may vary if minor changes in the grammar are made.
        !            29: 
        !            30: State 41 contains 1 shift/reduce conflict.  (Two ways to recover from error.)
        !            31: State 96 contains 1 shift/reduce conflict.  (Two ways to recover from error.)
        !            32: State 100 contains 1 shift/reduce conflict.  (Two ways to recover from error.)
        !            33: State 116 contains 1 shift/reduce conflict.  (See comment at component_decl.)
        !            34: State 166 contains 2 shift/reduce conflicts.  (make notype_declarator longer.)
        !            35: State 241 contains 2 shift/reduce conflicts.  (make absdcl1 longer if poss.)
        !            36: State 275 contains 2 shift/reduce conflicts.  (same for after_type_declarator).
        !            37: State 306 contains 2 shift/reduce conflicts.  (similar for absdcl1 again.)
        !            38: State 314 contains 2 shift/reduce conflicts.  (like 241, other context.)
        !            39: State 318 contains 2 shift/reduce conflicts.  (like 241, other context.)
        !            40: State 362 contains 1 shift/reduce conflict.  (dangling else.)
        !            41: State 369 contains 2 shift/reduce conflicts.  (like 166 for parm_declarator).
        !            42: */
        !            43: 
1.1       root       44: %{
                     45: #include "config.h"
                     46: #include "tree.h"
                     47: #include "parse.h"
                     48: #include "c-tree.h"
1.1.1.2 ! root       49: #include "flags.h"
        !            50: 
        !            51: #include <stdio.h>
        !            52: 
        !            53: /* Cause the `yydebug' variable to be defined.  */
        !            54: #define YYDEBUG
1.1       root       55: %}
                     56: 
                     57: %start program
                     58: 
1.1.1.2 ! root       59: %union {long itype; tree ttype; enum tree_code code; char *cptr; }
1.1       root       60: 
1.1.1.2 ! root       61: /* All identifiers that are not reserved words
1.1       root       62:    and are not declared typedefs in the current block */
                     63: %token IDENTIFIER
1.1.1.2 ! root       64: 
        !            65: /* All identifiers that are declared typedefs in the current block.
1.1       root       66:    In some contexts, they are treated just like IDENTIFIER,
                     67:    but they can also serve as typespecs in declarations.  */
                     68: %token TYPENAME
                     69: 
1.1.1.2 ! root       70: /* Reserved words that specify storage class.
        !            71:    yylval contains an IDENTIFIER_NODE which indicates which one.  */
1.1       root       72: %token SCSPEC
                     73: 
1.1.1.2 ! root       74: /* Reserved words that specify type.
        !            75:    yylval contains an IDENTIFIER_NODE which indicates which one.  */
1.1       root       76: %token TYPESPEC
                     77: 
1.1.1.2 ! root       78: /* Reserved words that qualify type: "const" or "volatile".
        !            79:    yylval contains an IDENTIFIER_NODE which indicates which one.  */
        !            80: %token TYPE_QUAL
1.1       root       81: 
1.1.1.2 ! root       82: /* Character or numeric constants.
1.1       root       83:    yylval is the node for the constant.  */
                     84: %token CONSTANT
                     85: 
                     86: /* String constants in raw form.
                     87:    yylval is a STRING_CST node.  */
                     88: %token STRING
                     89: 
                     90: /* "...", used for functions with variable arglists.  */
                     91: %token ELLIPSIS
                     92: 
                     93: /* the reserved words */
                     94: %token SIZEOF ENUM STRUCT UNION IF ELSE WHILE DO FOR SWITCH CASE DEFAULT
1.1.1.2 ! root       95: %token BREAK CONTINUE RETURN GOTO ASM TYPEOF ALIGNOF
1.1       root       96: 
                     97: /* Define the operator tokens and their precedences.
                     98:    The value is an integer because, if used, it is the tree code
                     99:    to use in the expression made from the operator.  */
                    100: 
                    101: %right <code> ASSIGN '='
                    102: %right <code> '?' ':'
                    103: %left <code> OROR
                    104: %left <code> ANDAND
                    105: %left <code> '|'
                    106: %left <code> '^'
                    107: %left <code> '&'
                    108: %left <code> EQCOMPARE
                    109: %left <code> ARITHCOMPARE
                    110: %left <code> LSHIFT RSHIFT
                    111: %left <code> '+' '-'
                    112: %left <code> '*' '/' '%'
                    113: %right <code> UNARY PLUSPLUS MINUSMINUS
                    114: %left HYPERUNARY
                    115: %left <code> POINTSAT '.'
                    116: 
                    117: %type <code> unop
                    118: 
                    119: %type <ttype> identifier IDENTIFIER TYPENAME CONSTANT expr nonnull_exprlist exprlist
                    120: %type <ttype> expr_no_commas primary string STRING
1.1.1.2 ! root      121: %type <ttype> typed_declspecs reserved_declspecs
        !           122: %type <ttype> typed_typespecs reserved_typespecquals
        !           123: %type <ttype> declmods typespec typespecqual_reserved
        !           124: %type <ttype> SCSPEC TYPESPEC TYPE_QUAL nonempty_type_quals maybe_type_qual
1.1       root      125: %type <ttype> initdecls notype_initdecls initdcl notype_initdcl
1.1.1.2 ! root      126: %type <ttype> init initlist maybeasm
        !           127: %type <ttype> asm_operands asm_operand
1.1       root      128: 
                    129: %type <ttype> declarator
                    130: %type <ttype> notype_declarator after_type_declarator
1.1.1.2 ! root      131: %type <ttype> parm_declarator
1.1       root      132: 
                    133: %type <ttype> structsp component_decl_list component_decl components component_declarator
                    134: %type <ttype> enumlist enumerator
1.1.1.2 ! root      135: %type <ttype> typename absdcl absdcl1 type_quals
        !           136: %type <ttype> xexpr parms parm identifiers
        !           137: 
        !           138: %type <ttype> parmlist parmlist_1 parmlist_2
        !           139: %type <ttype> parmlist_or_identifiers parmlist_or_identifiers_1
        !           140: 
        !           141: %type <itype> setspecs
1.1       root      142: 
                    143: %{
                    144: /* the declaration found for the last IDENTIFIER token read in.
                    145:    yylex must look this up to detect typedefs, which get token type TYPENAME,
                    146:    so it is left around in case the identifier is not a typedef but is
                    147:    used in a context which makes it a reference to a variable.  */
                    148: static tree lastiddecl;
                    149: 
                    150: static tree make_pointer_declarator ();
                    151: static tree combine_strings ();
1.1.1.2 ! root      152: static void reinit_parse_for_function ();
1.1       root      153: 
1.1.1.2 ! root      154: extern double atof ();
        !           155: 
        !           156: /* List of types and structure classes of the current declaration */
1.1       root      157: tree current_declspecs;
                    158: 
1.1.1.2 ! root      159: char *input_filename;          /* source file current line is coming from */
        !           160: char *main_input_filename;     /* top-level source file */
1.1       root      161: %}
                    162: 
                    163: %%
1.1.1.2 ! root      164: program: /* empty */
        !           165:        | extdefs
1.1       root      166:        ;
                    167: 
                    168: /* the reason for the strange actions in this rule
                    169:  is so that notype_initdecls when reached via datadef
                    170:  can find a valid list of type and sc specs in $0. */
                    171: 
                    172: extdefs:
1.1.1.2 ! root      173:        {$<ttype>$ = NULL_TREE; } extdef
        !           174:        | extdefs {$<ttype>$ = NULL_TREE; } extdef
1.1       root      175:        ;
                    176: 
                    177: extdef:
                    178:        fndef
                    179:        | datadef
1.1.1.2 ! root      180:        | ASM '(' string ')' ';'
        !           181:                { if (pedantic)
        !           182:                    warning ("ANSI C forbids use of `asm' keyword");
        !           183:                  if (TREE_CHAIN ($3)) $3 = combine_strings ($3);
        !           184:                  assemble_asm ($3); }
1.1       root      185:        ;
                    186: 
                    187: datadef:
                    188:          setspecs notype_initdecls ';'
1.1.1.2 ! root      189:                { if (pedantic)
        !           190:                    error ("ANSI C forbids data definition lacking type or storage class");
        !           191:                  else
        !           192:                    warning ("data definition lacks type or storage class"); }
        !           193:         | declmods setspecs notype_initdecls ';'
1.1       root      194:          {}
                    195:        | typed_declspecs setspecs initdecls ';'
                    196:          {}
1.1.1.2 ! root      197:         | declmods ';'
        !           198:          { error ("empty declaration"); }
1.1       root      199:        | typed_declspecs ';'
                    200:          { shadow_tag ($1); }
                    201:        | error ';'
                    202:        | error '}'
                    203:        | ';'
                    204:        ;
                    205: 
                    206: fndef:
                    207:          typed_declspecs setspecs declarator
                    208:                { if (! start_function ($1, $3))
1.1.1.2 ! root      209:                    YYFAIL;
        !           210:                  reinit_parse_for_function (); }
1.1       root      211:          xdecls
                    212:                { store_parm_decls (); }
                    213:          compstmt
1.1.1.2 ! root      214:                { finish_function (input_filename, @7.first_line); }
1.1       root      215:        | typed_declspecs setspecs declarator error
                    216:                { }
1.1.1.2 ! root      217:        | declmods setspecs notype_declarator
1.1       root      218:                { if (! start_function ($1, $3))
1.1.1.2 ! root      219:                    YYFAIL;
        !           220:                  reinit_parse_for_function (); }
1.1       root      221:          xdecls
                    222:                { store_parm_decls (); }
                    223:          compstmt
1.1.1.2 ! root      224:                { finish_function (input_filename, @7.first_line); }
        !           225:        | declmods setspecs notype_declarator error
1.1       root      226:                { }
                    227:        | setspecs notype_declarator
                    228:                { if (! start_function (0, $2))
1.1.1.2 ! root      229:                    YYFAIL;
        !           230:                  reinit_parse_for_function (); }
1.1       root      231:          xdecls
                    232:                { store_parm_decls (); }
                    233:          compstmt
1.1.1.2 ! root      234:                { finish_function (input_filename, @6.first_line); }
1.1       root      235:        | setspecs notype_declarator error
1.1.1.2 ! root      236:                { }
1.1       root      237:        ;
                    238: 
                    239: identifier:
                    240:        IDENTIFIER
                    241:        | TYPENAME
                    242:        ;
                    243: 
                    244: unop:     '&'
                    245:                { $$ = ADDR_EXPR; }
                    246:        | '-'
                    247:                { $$ = NEGATE_EXPR; }
                    248:        | '+'
                    249:                { $$ = CONVERT_EXPR; }
                    250:        | PLUSPLUS
                    251:                { $$ = PREINCREMENT_EXPR; }
                    252:        | MINUSMINUS
                    253:                { $$ = PREDECREMENT_EXPR; }
                    254:        | '~'
                    255:                { $$ = BIT_NOT_EXPR; }
                    256:        | '!'
                    257:                { $$ = TRUTH_NOT_EXPR; }
                    258:        ;
                    259: 
                    260: expr:  nonnull_exprlist
1.1.1.2 ! root      261:                { $$ = build_compound_expr ($1); }
1.1       root      262:        ;
                    263: 
                    264: exprlist:
                    265:          /* empty */
                    266:                { $$ = NULL_TREE; }
                    267:        | nonnull_exprlist
                    268:        ;
                    269: 
                    270: nonnull_exprlist:
                    271:        expr_no_commas
                    272:                { $$ = build_tree_list (NULL_TREE, $1); }
                    273:        | nonnull_exprlist ',' expr_no_commas
                    274:                { chainon ($1, build_tree_list (NULL_TREE, $3)); }
                    275:        ;
                    276: 
                    277: expr_no_commas:
                    278:        primary
                    279:        | '*' expr_no_commas   %prec UNARY
1.1.1.2 ! root      280:                { $$ = build_indirect_ref ($2, "unary *"); }
1.1       root      281:        | unop expr_no_commas  %prec UNARY
                    282:                { $$ = build_unary_op ($1, $2, 0); }
                    283:        | '(' typename ')' expr_no_commas  %prec UNARY
1.1.1.2 ! root      284:                { tree type = groktypename ($2);
        !           285:                  $$ = build_c_cast (type, $4); }
        !           286:        | '(' typename ')' '{' initlist maybecomma '}'  %prec UNARY
        !           287:                { tree type = groktypename ($2);
        !           288:                  if (pedantic)
        !           289:                    warning ("ANSI C forbids constructor-expressions");
        !           290:                  $$ = digest_init (type, build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($5)), 0);
        !           291:                  if (TREE_CODE (type) == ARRAY_TYPE && TYPE_SIZE (type) == 0)
        !           292:                    {
        !           293:                      int failure = complete_array_type (type, $$, 1);
        !           294:                      if (failure)
        !           295:                        abort ();
        !           296:                    }
        !           297:                }
1.1       root      298:        | SIZEOF expr_no_commas  %prec UNARY
1.1.1.2 ! root      299:                { if (TREE_CODE ($2) == COMPONENT_REF
        !           300:                      && TREE_PACKED (TREE_OPERAND ($2, 1)))
        !           301:                    error ("sizeof applied to a bit-field");
        !           302:                  $$ = c_sizeof (TREE_TYPE ($2)); }
1.1       root      303:        | SIZEOF '(' typename ')'  %prec HYPERUNARY
1.1.1.2 ! root      304:                { $$ = c_sizeof (groktypename ($3)); }
        !           305:        | ALIGNOF expr_no_commas  %prec UNARY
        !           306:                { if (TREE_CODE ($2) == COMPONENT_REF
        !           307:                      && TREE_PACKED (TREE_OPERAND ($2, 1)))
        !           308:                    error ("__alignof applied to a bit-field");
        !           309:                  $$ = c_alignof (TREE_TYPE ($2)); }
        !           310:        | ALIGNOF '(' typename ')'  %prec HYPERUNARY
        !           311:                { $$ = c_alignof (groktypename ($3)); }
1.1       root      312:        | expr_no_commas '+' expr_no_commas
                    313:                { $$ = build_binary_op ($2, $1, $3); }
                    314:        | expr_no_commas '-' expr_no_commas
                    315:                { $$ = build_binary_op ($2, $1, $3); }
                    316:        | expr_no_commas '*' expr_no_commas
                    317:                { $$ = build_binary_op ($2, $1, $3); }
                    318:        | expr_no_commas '/' expr_no_commas
                    319:                { $$ = build_binary_op ($2, $1, $3); }
                    320:        | expr_no_commas '%' expr_no_commas
                    321:                { $$ = build_binary_op ($2, $1, $3); }
                    322:        | expr_no_commas LSHIFT expr_no_commas
                    323:                { $$ = build_binary_op ($2, $1, $3); }
                    324:        | expr_no_commas RSHIFT expr_no_commas
                    325:                { $$ = build_binary_op ($2, $1, $3); }
                    326:        | expr_no_commas ARITHCOMPARE expr_no_commas
                    327:                { $$ = build_binary_op ($2, $1, $3); }
                    328:        | expr_no_commas EQCOMPARE expr_no_commas
                    329:                { $$ = build_binary_op ($2, $1, $3); }
                    330:        | expr_no_commas '&' expr_no_commas
                    331:                { $$ = build_binary_op ($2, $1, $3); }
                    332:        | expr_no_commas '|' expr_no_commas
                    333:                { $$ = build_binary_op ($2, $1, $3); }
                    334:        | expr_no_commas '^' expr_no_commas
                    335:                { $$ = build_binary_op ($2, $1, $3); }
                    336:        | expr_no_commas ANDAND expr_no_commas
                    337:                { $$ = build_binary_op (TRUTH_ANDIF_EXPR, $1, $3); }
                    338:        | expr_no_commas OROR expr_no_commas
                    339:                { $$ = build_binary_op (TRUTH_ORIF_EXPR, $1, $3); }
1.1.1.2 ! root      340:        | expr_no_commas '?' xexpr ':' expr_no_commas
        !           341:                { $$ = build_conditional_expr ($1, $3, $5); }
1.1       root      342:        | expr_no_commas '=' expr_no_commas
1.1.1.2 ! root      343:                { $$ = build_modify_expr ($1, NOP_EXPR, $3); }
1.1       root      344:        | expr_no_commas ASSIGN expr_no_commas
1.1.1.2 ! root      345:                { $$ = build_modify_expr ($1, $2, $3); }
1.1       root      346:        ;
                    347: 
                    348: primary:
                    349:        IDENTIFIER
                    350:                { $$ = lastiddecl;
                    351:                  if (!$$)
                    352:                    {
                    353:                      if (yychar == YYEMPTY)
                    354:                        yychar = YYLEX;
                    355:                      if (yychar == '(')
1.1.1.2 ! root      356:                        $$ = implicitly_declare ($1);
1.1       root      357:                      else
                    358:                        {
1.1.1.2 ! root      359:                          if (IDENTIFIER_GLOBAL_VALUE ($1) != error_mark_node)
        !           360:                            error ("undeclared variable `%s' (first use here)",
        !           361:                                   IDENTIFIER_POINTER ($1));
1.1       root      362:                          $$ = error_mark_node;
1.1.1.2 ! root      363:                          /* Prevent repeated error messages.  */
        !           364:                          IDENTIFIER_GLOBAL_VALUE ($1) = error_mark_node;
1.1       root      365:                        }
                    366:                    }
                    367:                  if (TREE_CODE ($$) == CONST_DECL)
                    368:                    $$ = DECL_INITIAL ($$);
                    369:                }
                    370:        | CONSTANT
                    371:        | string
                    372:                { $$ = combine_strings ($1); }
                    373:        | '(' expr ')'
                    374:                { $$ = $2; }
                    375:        | '(' error ')'
                    376:                { $$ = error_mark_node; }
1.1.1.2 ! root      377:        | '(' 
        !           378:                { if (current_function_decl == 0)
        !           379:                    {
        !           380:                      error ("braced-group within expression allowed only inside a function");
        !           381:                      YYFAIL;
        !           382:                    }
        !           383:                  expand_start_stmt_expr (); }
        !           384:          compstmt ')'
        !           385:                { if (pedantic)
        !           386:                    warning ("ANSI C forbids braced-groups within expressions");
        !           387:                  $$ = get_last_expr ();
        !           388:                  expand_end_stmt_expr (); }
1.1       root      389:        | primary '(' exprlist ')'   %prec '.'
                    390:                { $$ = build_function_call ($1, $3); }
                    391:        | primary '[' expr ']'   %prec '.'
                    392:                { $$ = build_array_ref ($1, $3); }
                    393:        | primary '.' identifier
1.1.1.2 ! root      394:                { $$ = build_component_ref ($1, $3); }
1.1       root      395:        | primary POINTSAT identifier
1.1.1.2 ! root      396:                { $$ = build_component_ref (build_indirect_ref ($1, "->"), $3); }
1.1       root      397:        | primary PLUSPLUS
                    398:                { $$ = build_unary_op (POSTINCREMENT_EXPR, $1, 0); }
                    399:        | primary MINUSMINUS
                    400:                { $$ = build_unary_op (POSTDECREMENT_EXPR, $1, 0); }
                    401:        ;
                    402: 
                    403: /* Produces a STRING_CST with perhaps more STRING_CSTs chained onto it.  */
                    404: string:
                    405:          STRING
                    406:        | string STRING
                    407:                { $$ = chainon ($1, $2); }
                    408:        ;
                    409: 
                    410: xdecls:
                    411:        /* empty */
                    412:        | decls
                    413:        ;
                    414: 
                    415: decls:
                    416:        decl
                    417:        | errstmt
                    418:        | decls decl
                    419:        | decl errstmt
                    420:        ;
                    421: 
                    422: /* records the type and storage class specs to use for processing
                    423:    the declarators that follow */
                    424: setspecs: /* empty */
1.1.1.2 ! root      425:                { current_declspecs = $<ttype>0;
        !           426:                  $$ = suspend_momentary (); }
1.1       root      427:        ;
                    428: 
                    429: decl:
                    430:        typed_declspecs setspecs initdecls ';'
1.1.1.2 ! root      431:                { resume_momentary ($2); }
        !           432:        | declmods setspecs notype_initdecls ';'
        !           433:                { resume_momentary ($2); }
1.1       root      434:        | typed_declspecs ';'
                    435:                { shadow_tag ($1); }
1.1.1.2 ! root      436:        | declmods ';'
1.1       root      437:                { warning ("empty declaration"); }
                    438:        ;
                    439: 
1.1.1.2 ! root      440: /* Declspecs which contain at least one type specifier or typedef name.
        !           441:    (Just `const' or `volatile' is not enough.)
1.1       root      442:    A typedef'd name following these is taken as a name to be declared.  */
1.1.1.2 ! root      443: 
1.1       root      444: typed_declspecs:
1.1.1.2 ! root      445:          typespec reserved_declspecs
        !           446:                { $$ = tree_cons (NULL_TREE, $1, $2); }
        !           447:        | declmods typespec reserved_declspecs
        !           448:                { $$ = chainon ($3, tree_cons (NULL_TREE, $2, $1)); }
        !           449:        ;
        !           450: 
        !           451: reserved_declspecs:  /* empty */
        !           452:                { $$ = NULL_TREE; }
        !           453:        | reserved_declspecs typespecqual_reserved
1.1       root      454:                { $$ = tree_cons (NULL_TREE, $2, $1); }
1.1.1.2 ! root      455:        | reserved_declspecs SCSPEC
1.1       root      456:                { $$ = tree_cons (NULL_TREE, $2, $1); }
1.1.1.2 ! root      457:        ;
        !           458: 
        !           459: /* List of just storage classes and type modifiers.
        !           460:    A declaration can start with just this, but then it cannot be used
        !           461:    to redeclare a typedef-name.  */
        !           462: 
        !           463: declmods:
        !           464:          TYPE_QUAL
        !           465:                { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); }
        !           466:        | SCSPEC
        !           467:                { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); }
        !           468:        | declmods TYPE_QUAL
1.1       root      469:                { $$ = tree_cons (NULL_TREE, $2, $1); }
1.1.1.2 ! root      470:        | declmods SCSPEC
1.1       root      471:                { $$ = tree_cons (NULL_TREE, $2, $1); }
                    472:        ;
                    473: 
1.1.1.2 ! root      474: 
        !           475: /* Used instead of declspecs where storage classes are not allowed
        !           476:    (that is, for typenames and structure components).
        !           477:    Don't accept a typedef-name if anything but a modifier precedes it.  */
        !           478: 
        !           479: typed_typespecs:
        !           480:          typespec reserved_typespecquals
        !           481:                { $$ = tree_cons (NULL_TREE, $1, $2); }
        !           482:        | nonempty_type_quals typespec reserved_typespecquals
        !           483:                { $$ = chainon ($3, tree_cons (NULL_TREE, $2, $1)); }
1.1       root      484:        ;
                    485: 
1.1.1.2 ! root      486: reserved_typespecquals:  /* empty */
        !           487:                { $$ = NULL_TREE; }
        !           488:        | reserved_typespecquals typespecqual_reserved
1.1       root      489:                { $$ = tree_cons (NULL_TREE, $2, $1); }
                    490:        ;
                    491: 
1.1.1.2 ! root      492: /* A typespec (but not a type qualifier).
        !           493:    Once we have seen one of these in a declaration,
        !           494:    if a typedef name appears then it is being redeclared.  */
        !           495: 
1.1       root      496: typespec: TYPESPEC
                    497:        | structsp
                    498:        | TYPENAME
1.1.1.2 ! root      499:        | TYPEOF '(' expr ')'
        !           500:                { $$ = TREE_TYPE ($3);
        !           501:                  if (pedantic)
        !           502:                    warning ("ANSI C forbids `typeof'") }
        !           503:        | TYPEOF '(' typename ')'
        !           504:                { $$ = groktypename ($3);
        !           505:                  if (pedantic)
        !           506:                    warning ("ANSI C forbids `typeof'") }
        !           507:        ;
        !           508: 
        !           509: /* A typespec that is a reserved word, or a type qualifier.  */
        !           510: 
        !           511: typespecqual_reserved: TYPESPEC
        !           512:        | TYPE_QUAL
        !           513:        | structsp
1.1       root      514:        ;
                    515: 
                    516: initdecls:
                    517:        initdcl
                    518:        | initdecls ',' initdcl
                    519:        ;
                    520: 
                    521: notype_initdecls:
                    522:        notype_initdcl
                    523:        | notype_initdecls ',' initdcl
                    524:        ;
                    525: 
1.1.1.2 ! root      526: maybeasm:
        !           527:          /* empty */
        !           528:                { $$ = NULL_TREE; }
        !           529:        | ASM '(' string ')'
        !           530:                { if (TREE_CHAIN ($3)) $3 = combine_strings ($3);
        !           531:                  $$ = $3;
        !           532:                  if (pedantic)
        !           533:                    warning ("ANSI C forbids use of `asm' keyword");
        !           534:                }
        !           535:        ;
        !           536: 
1.1       root      537: initdcl:
1.1.1.2 ! root      538:          declarator maybeasm '='
1.1       root      539:                { $<ttype>$ = start_decl ($1, current_declspecs, 1); }
                    540:          init
                    541: /* Note how the declaration of the variable is in effect while its init is parsed! */
1.1.1.2 ! root      542:                { finish_decl ($<ttype>4, $5, $2); }
        !           543:        | declarator maybeasm
1.1       root      544:                { tree d = start_decl ($1, current_declspecs, 0);
1.1.1.2 ! root      545:                  finish_decl (d, NULL_TREE, $2); }
1.1       root      546:        ;
                    547: 
                    548: notype_initdcl:
1.1.1.2 ! root      549:          notype_declarator maybeasm '='
1.1       root      550:                { $<ttype>$ = start_decl ($1, current_declspecs, 1); }
                    551:          init
                    552: /* Note how the declaration of the variable is in effect while its init is parsed! */
1.1.1.2 ! root      553:                { finish_decl ($<ttype>4, $5, $2); }
        !           554:        | notype_declarator maybeasm
1.1       root      555:                { tree d = start_decl ($1, current_declspecs, 0);
1.1.1.2 ! root      556:                  finish_decl (d, NULL_TREE, $2); }
1.1       root      557:        ;
                    558: 
                    559: init:
                    560:        expr_no_commas
                    561:        | '{' initlist '}'
1.1.1.2 ! root      562:                { $$ = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($2)); }
1.1       root      563:        | '{' initlist ',' '}'
1.1.1.2 ! root      564:                { $$ = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($2)); }
        !           565:        | error
        !           566:                { $$ = NULL_TREE; }
1.1       root      567:        ;
                    568: 
                    569: /* This chain is built in reverse order,
                    570:    and put in forward order where initlist is used.  */
                    571: initlist:
                    572:        init
                    573:                { $$ = build_tree_list (NULL_TREE, $1); }
                    574:        | initlist ',' init
1.1.1.2 ! root      575:                { $$ = tree_cons (NULL_TREE, $3, $1); }
1.1       root      576:        ;
                    577: 
                    578: /* Any kind of declarator (thus, all declarators allowed
                    579:    after an explicit typespec).  */
                    580: 
                    581: declarator:
                    582:          after_type_declarator
                    583:        | notype_declarator
                    584:        ;
                    585: 
                    586: /* A declarator that is allowed only after an explicit typespec.  */
                    587: 
                    588: after_type_declarator:
1.1.1.2 ! root      589:          '(' after_type_declarator ')'
        !           590:                { $$ = $2; }
        !           591:        | after_type_declarator '(' parmlist_or_identifiers  %prec '.'
        !           592:                { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); }
        !           593: /*     | after_type_declarator '(' error ')'  %prec '.'
        !           594:                { $$ = build_nt (CALL_EXPR, $1, NULL_TREE, NULL_TREE);
        !           595:                  poplevel (0, 0, 0); }  */
1.1       root      596:        | after_type_declarator '[' expr ']'  %prec '.'
1.1.1.2 ! root      597:                { $$ = build_nt (ARRAY_REF, $1, $3); }
1.1       root      598:        | after_type_declarator '[' ']'  %prec '.'
1.1.1.2 ! root      599:                { $$ = build_nt (ARRAY_REF, $1, NULL_TREE); }
        !           600:        | '*' type_quals after_type_declarator  %prec UNARY
        !           601:                { $$ = make_pointer_declarator ($2, $3); }
        !           602:        | TYPENAME
        !           603:        ;
        !           604: 
        !           605: /* Kinds of declarator that can appear in a parameter list
        !           606:    in addition to notype_declarator.  This is like after_type_declarator
        !           607:    but does not allow a typedef name in parentheses as an identifier
        !           608:    (because it would conflict with a function with that typedef as arg).  */
        !           609: 
        !           610: parm_declarator:
        !           611:          parm_declarator '(' parmlist_or_identifiers  %prec '.'
        !           612:                { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); }
        !           613: /*     | parm_declarator '(' error ')'  %prec '.'
        !           614:                { $$ = build_nt (CALL_EXPR, $1, NULL_TREE, NULL_TREE);
        !           615:                  poplevel (0, 0, 0); }  */
        !           616:        | parm_declarator '[' expr ']'  %prec '.'
        !           617:                { $$ = build_nt (ARRAY_REF, $1, $3); }
        !           618:        | parm_declarator '[' ']'  %prec '.'
        !           619:                { $$ = build_nt (ARRAY_REF, $1, NULL_TREE); }
        !           620:        | '*' type_quals parm_declarator  %prec UNARY
        !           621:                { $$ = make_pointer_declarator ($2, $3); }
1.1       root      622:        | TYPENAME
                    623:        ;
                    624: 
                    625: /* A declarator allowed whether or not there has been
                    626:    an explicit typespec.  These cannot redeclare a typedef-name.  */
                    627: 
                    628: notype_declarator:
1.1.1.2 ! root      629:          notype_declarator '(' parmlist_or_identifiers  %prec '.'
        !           630:                { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); }
        !           631: /*     | notype_declarator '(' error ')'  %prec '.'
        !           632:                { $$ = build_nt (CALL_EXPR, $1, NULL_TREE, NULL_TREE);
        !           633:                  poplevel (0, 0, 0); }  */
1.1       root      634:        | '(' notype_declarator ')'
                    635:                { $$ = $2; }
1.1.1.2 ! root      636:        | '*' type_quals notype_declarator  %prec UNARY
1.1       root      637:                { $$ = make_pointer_declarator ($2, $3); }
                    638:        | notype_declarator '[' expr ']'  %prec '.'
1.1.1.2 ! root      639:                { $$ = build_nt (ARRAY_REF, $1, $3); }
1.1       root      640:        | notype_declarator '[' ']'  %prec '.'
1.1.1.2 ! root      641:                { $$ = build_nt (ARRAY_REF, $1, NULL_TREE); }
1.1       root      642:        | IDENTIFIER
                    643:        ;
                    644: 
                    645: structsp:
1.1.1.2 ! root      646:          STRUCT identifier '{'
        !           647:                { $$ = start_struct (RECORD_TYPE, $2);
        !           648:                  /* Start scope of tag before parsing components.  */
        !           649:                }
        !           650:          component_decl_list '}'
        !           651:                { $$ = finish_struct ($<ttype>4, $5);
        !           652:                  /* Really define the structure.  */
        !           653:                }
1.1       root      654:        | STRUCT '{' component_decl_list '}'
1.1.1.2 ! root      655:                { $$ = finish_struct (start_struct (RECORD_TYPE, NULL_TREE),
        !           656:                                      $3); }
1.1       root      657:        | STRUCT identifier
1.1.1.2 ! root      658:                { $$ = xref_tag (RECORD_TYPE, $2); }
        !           659:        | UNION identifier '{'
        !           660:                { $$ = start_struct (UNION_TYPE, $2); }
        !           661:          component_decl_list '}'
        !           662:                { $$ = finish_struct ($<ttype>4, $5); }
1.1       root      663:        | UNION '{' component_decl_list '}'
1.1.1.2 ! root      664:                { $$ = finish_struct (start_struct (UNION_TYPE, NULL_TREE),
        !           665:                                      $3); }
1.1       root      666:        | UNION identifier
1.1.1.2 ! root      667:                { $$ = xref_tag (UNION_TYPE, $2); }
1.1       root      668:        | ENUM identifier '{'
1.1.1.2 ! root      669:                { $<itype>3 = suspend_momentary ();
        !           670:                  $$ = start_enum ($2); }
        !           671:          enumlist maybecomma '}'
        !           672:                { $$ = finish_enum ($<ttype>4, nreverse ($5));
        !           673:                  resume_momentary ($<itype>3); }
1.1       root      674:        | ENUM '{'
1.1.1.2 ! root      675:                { $<itype>2 = suspend_momentary ();
        !           676:                  $$ = start_enum (NULL_TREE); }
        !           677:          enumlist maybecomma '}'
        !           678:                { $$ = finish_enum ($<ttype>3, nreverse ($4));
        !           679:                  resume_momentary ($<itype>2); }
1.1       root      680:        | ENUM identifier
1.1.1.2 ! root      681:                { $$ = xref_tag (ENUMERAL_TYPE, $2); }
        !           682:        ;
        !           683: 
        !           684: maybecomma:
        !           685:          /* empty */
        !           686:        | ','
1.1       root      687:        ;
                    688: 
                    689: component_decl_list:   /* empty */
                    690:                { $$ = NULL_TREE; }
1.1.1.2 ! root      691:        | component_decl_list component_decl ';'
        !           692:                { $$ = chainon ($1, $2); }
1.1       root      693:        | component_decl_list ';'
1.1.1.2 ! root      694:                { if (pedantic) 
        !           695:                    warning ("extra semicolon in struct or union specified"); }
1.1       root      696:        ;
                    697: 
1.1.1.2 ! root      698: /* There is a shift-reduce conflict here, because `components' may
        !           699:    start with a `typename'.  It happens that shifting (the default resolution)
        !           700:    does the right thing, because it treats the `typename' as part of
        !           701:    a `typed_typespecs'.
        !           702: 
        !           703:    It is possible that this same technique would allow the distinction
        !           704:    between `notype_initdecls' and `initdecls' to be eliminated.
        !           705:    But I am being cautious and not trying it.  */
        !           706: 
1.1       root      707: component_decl:
1.1.1.2 ! root      708:        typed_typespecs setspecs components
        !           709:                { $$ = $3;
        !           710:                  resume_momentary ($2); }
        !           711:        | nonempty_type_quals setspecs components
        !           712:                { $$ = $3;
        !           713:                  resume_momentary ($2); }
1.1       root      714:        | error
1.1.1.2 ! root      715:                { $$ = NULL_TREE; }
1.1       root      716:        ;
                    717: 
                    718: components:
                    719:          /* empty */
                    720:                { $$ = NULL_TREE; }
                    721:        | component_declarator
                    722:        | components ',' component_declarator
                    723:                { $$ = chainon ($1, $3); }
                    724:        ;
                    725: 
                    726: component_declarator:
                    727:        declarator
                    728:                { $$ = grokfield (input_filename, @1.first_line, $1, current_declspecs, NULL_TREE); }
                    729:        | declarator ':' expr_no_commas
                    730:                { $$ = grokfield (input_filename, @1.first_line, $1, current_declspecs, $3); }
                    731:        | ':' expr_no_commas
                    732:                { $$ = grokfield (input_filename, @1.first_line, NULL_TREE, current_declspecs, $2); }
                    733:        ;
                    734: 
                    735: /* We chain the enumerators in reverse order.
                    736:    They are put in forward order where enumlist is used.
                    737:    (The order used to be significant, but no longer is so.
                    738:    However, we still maintain the order, just to be clean.)  */
                    739: 
                    740: enumlist:
                    741:          enumerator
                    742:        | enumlist ',' enumerator
                    743:                { $$ = chainon ($3, $1); }
                    744:        ;
                    745: 
                    746: 
                    747: enumerator:
                    748:          identifier
                    749:                { $$ = build_enumerator ($1, NULL_TREE); }
                    750:        | identifier '=' expr_no_commas
                    751:                { $$ = build_enumerator ($1, $3); }
                    752:        ;
                    753: 
                    754: typename:
1.1.1.2 ! root      755:        typed_typespecs absdcl
        !           756:                { $$ = build_tree_list ($1, $2); }
        !           757:        | nonempty_type_quals absdcl
1.1       root      758:                { $$ = build_tree_list ($1, $2); }
                    759:        ;
                    760:        
                    761: absdcl:   /* an absolute declarator */
                    762:        /* empty */
                    763:                { $$ = NULL_TREE; }
                    764:        | absdcl1
                    765:        ;
                    766: 
1.1.1.2 ! root      767: nonempty_type_quals:
        !           768:          TYPE_QUAL
        !           769:                { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); }
        !           770:        | nonempty_type_quals TYPE_QUAL
        !           771:                { $$ = tree_cons (NULL_TREE, $2, $1); }
        !           772:        ;
        !           773: 
        !           774: type_quals:
1.1       root      775:          /* empty */
                    776:                { $$ = NULL_TREE; }
1.1.1.2 ! root      777:        | type_quals TYPE_QUAL
1.1       root      778:                { $$ = tree_cons (NULL_TREE, $2, $1); }
                    779:        ;
                    780: 
                    781: absdcl1:  /* a nonempty absolute declarator */
                    782:          '(' absdcl1 ')'
                    783:                { $$ = $2; }
1.1.1.2 ! root      784:          /* `(typedef)1' is `int'.  */
        !           785:        | '*' type_quals absdcl1  %prec UNARY
1.1       root      786:                { $$ = make_pointer_declarator ($2, $3); }
1.1.1.2 ! root      787:        | '*' type_quals  %prec UNARY
1.1       root      788:                { $$ = make_pointer_declarator ($2, NULL_TREE); }
1.1.1.2 ! root      789:        | absdcl1 '(' parmlist  %prec '.'
        !           790:                { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); }
1.1       root      791:        | absdcl1 '[' expr ']'  %prec '.'
1.1.1.2 ! root      792:                { $$ = build_nt (ARRAY_REF, $1, $3); }
1.1       root      793:        | absdcl1 '[' ']'  %prec '.'
1.1.1.2 ! root      794:                { $$ = build_nt (ARRAY_REF, $1, NULL_TREE); }
        !           795:        | '(' parmlist  %prec '.'
        !           796:                { $$ = build_nt (CALL_EXPR, NULL_TREE, $2, NULL_TREE); }
1.1       root      797:        | '[' expr ']'  %prec '.'
1.1.1.2 ! root      798:                { $$ = build_nt (ARRAY_REF, NULL_TREE, $2); }
1.1       root      799:        | '[' ']'  %prec '.'
1.1.1.2 ! root      800:                { $$ = build_nt (ARRAY_REF, NULL_TREE, NULL_TREE); }
1.1       root      801:        ;
                    802: 
                    803: /* at least one statement, the first of which parses without error.  */
                    804: /* stmts is used only after decls, so an invalid first statement
                    805:    is actually regarded as an invalid decl and part of the decls.  */
                    806: 
                    807: stmts:
                    808:        stmt
                    809:        | stmts stmt
                    810:        | stmts errstmt
                    811:        ;
                    812: 
1.1.1.2 ! root      813: xstmts:
        !           814:        /* empty */
        !           815:        | stmts
1.1       root      816:        ;
                    817: 
1.1.1.2 ! root      818: errstmt:  error ';'
        !           819:        ;
1.1       root      820: 
                    821: pushlevel:  /* empty */
1.1.1.2 ! root      822:                { pushlevel (0);
        !           823:                  clear_last_expr ();
        !           824:                  push_momentary ();
        !           825:                  expand_start_bindings (0); }
1.1       root      826:        ;
                    827: 
                    828: compstmt: '{' '}'
1.1.1.2 ! root      829:        | '{' pushlevel decls xstmts '}'
        !           830:                { expand_end_bindings (getdecls (), 1);
        !           831:                  poplevel (1, 1, 0);
        !           832:                  pop_momentary (); }
1.1       root      833:        | '{' pushlevel error '}'
1.1.1.2 ! root      834:                { expand_end_bindings (getdecls (), 0);
        !           835:                  poplevel (0, 0, 0);
        !           836:                  pop_momentary (); }
1.1       root      837:        | '{' pushlevel stmts '}'
1.1.1.2 ! root      838:                { expand_end_bindings (getdecls (), 0);
        !           839:                  poplevel (0, 0, 0);
        !           840:                  pop_momentary (); }
1.1       root      841:        ;
                    842: 
1.1.1.2 ! root      843: simple_if:
        !           844:          IF '(' expr ')'
        !           845:                { emit_note (input_filename, @1.first_line);
        !           846:                  expand_start_cond (truthvalue_conversion ($3), 0); }
        !           847:          stmt
        !           848:        ;
        !           849: 
        !           850: stmt:
        !           851:          compstmt
1.1       root      852:        | expr ';'
1.1.1.2 ! root      853:                { emit_note (input_filename, @1.first_line);
        !           854:                  expand_expr_stmt ($1);
        !           855:                  clear_momentary (); }
        !           856:        | simple_if ELSE
        !           857:                { expand_start_else (); }
        !           858:          stmt
        !           859:                { expand_end_else (); }
        !           860:        | simple_if
        !           861:                { expand_end_cond (); }
1.1       root      862:        | WHILE
1.1.1.2 ! root      863:                { emit_note (input_filename, @1.first_line);
        !           864:                  expand_start_loop (1); }
        !           865:          '(' expr ')'
        !           866:                { expand_exit_loop_if_false (truthvalue_conversion ($4)); }
        !           867:          stmt
        !           868:                { expand_end_loop (); }
1.1       root      869:        | DO
1.1.1.2 ! root      870:                { emit_note (input_filename, @1.first_line);
        !           871:                  expand_start_loop_continue_elsewhere (1); }
        !           872:          stmt WHILE
        !           873:                { expand_loop_continue_here (); }
        !           874:          '(' expr ')' ';'
        !           875:                { emit_note (input_filename, @7.first_line);
        !           876:                  expand_exit_loop_if_false (truthvalue_conversion ($7));
        !           877:                  expand_end_loop ();
        !           878:                  clear_momentary (); }
1.1       root      879:        | FOR 
1.1.1.2 ! root      880:          '(' xexpr ';'
        !           881:                { emit_note (input_filename, @1.first_line);
        !           882:                  if ($3) expand_expr_stmt ($3);
        !           883:                  expand_start_loop_continue_elsewhere (1); }
        !           884:          xexpr ';'
        !           885:                { emit_note (input_filename, @6.first_line);
        !           886:                  if ($6)
        !           887:                    expand_exit_loop_if_false (truthvalue_conversion ($6)); }
        !           888:          xexpr ')'
        !           889:                /* Don't let the tree nodes for $9 be discarded
        !           890:                   by clear_momentary during the parsing of the next stmt.  */
        !           891:                { push_momentary (); }
        !           892:          stmt
        !           893:                { emit_note (input_filename, @9.first_line);
        !           894:                  expand_loop_continue_here ();
        !           895:                  if ($9)
        !           896:                    {
        !           897:                      expand_expr_stmt ($9);
        !           898:                    }
        !           899:                  pop_momentary ();
        !           900:                  expand_end_loop (); }
1.1       root      901:        | SWITCH '(' expr ')'
1.1.1.2 ! root      902:                { emit_note (input_filename, @1.first_line);
        !           903:                  c_expand_start_case ($3);
        !           904:                  /* Don't let the tree nodes for $3 be discarded by
        !           905:                     clear_momentary during the parsing of the next stmt.  */
        !           906:                  push_momentary (); }
1.1       root      907:          stmt
1.1.1.2 ! root      908:                { expand_end_case ();
        !           909:                  pop_momentary (); }
        !           910:        | CASE expr ':'
        !           911:                { register tree value = fold ($2);
        !           912:                  register tree label
        !           913:                    = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
1.1       root      914: 
1.1.1.2 ! root      915:                  if (TREE_CODE (value) != INTEGER_CST
        !           916:                      && value != error_mark_node)
1.1       root      917:                    {
1.1.1.2 ! root      918:                      error ("case label does not reduce to an integer constant");
1.1       root      919:                      value = error_mark_node;
                    920:                    }
                    921:                  else
1.1.1.2 ! root      922:                    /* Promote char or short to int.  */
        !           923:                    value = default_conversion (value);
        !           924:                  if (value != error_mark_node)
1.1       root      925:                    {
1.1.1.2 ! root      926:                      int success = pushcase (value, label);
        !           927:                      if (success == 1)
        !           928:                        error ("case label not within a switch statement");
        !           929:                      else if (success == 2)
        !           930:                        error ("duplicate case value");
        !           931:                      else if (success == 3)
        !           932:                        warning ("case value out of range");
1.1       root      933:                    }
                    934:                }
1.1.1.2 ! root      935:          stmt
        !           936:        | DEFAULT ':'
        !           937:                {
        !           938:                  register tree label
        !           939:                    = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
        !           940:                  int success = pushcase (NULL_TREE, label);
        !           941:                  if (success == 1)
        !           942:                    error ("default label not within a switch statement");
        !           943:                  else if (success == 2)
        !           944:                    error ("multiple default labels in one switch");
1.1       root      945:                }
1.1.1.2 ! root      946:          stmt
        !           947:        | BREAK ';'
        !           948:                { emit_note (input_filename, @1.first_line);
        !           949:                  if ( ! expand_exit_something ())
        !           950:                    error ("break statement not within loop or switch"); }
        !           951:        | CONTINUE ';'  
        !           952:                { emit_note (input_filename, @1.first_line);
        !           953:                  if (! expand_continue_loop ())
        !           954:                    error ("continue statement not within a loop"); }
1.1       root      955:        | RETURN ';'
1.1.1.2 ! root      956:                { emit_note (input_filename, @1.first_line);
        !           957:                  c_expand_return (NULL_TREE); }
1.1       root      958:        | RETURN expr ';'
1.1.1.2 ! root      959:                { emit_note (input_filename, @1.first_line);
        !           960:                  c_expand_return ($2); }
        !           961:        | ASM maybe_type_qual '(' string ')' ';'
        !           962:                { if (pedantic)
        !           963:                    warning ("ANSI C forbids use of `asm' keyword");
        !           964:                  emit_note (input_filename, @1.first_line);
        !           965:                  if (TREE_CHAIN ($4)) $4 = combine_strings ($4);
        !           966:                  expand_asm ($4); }
        !           967:        /* This is the case with just output operands.  */
        !           968:        | ASM maybe_type_qual '(' string ':' asm_operands ')' ';'
        !           969:                { if (pedantic)
        !           970:                    warning ("ANSI C forbids use of `asm' keyword");
        !           971:                  emit_note (input_filename, @1.first_line);
        !           972:                  if (TREE_CHAIN ($4)) $4 = combine_strings ($4);
        !           973:                  c_expand_asm_operands ($4, $6, NULL_TREE,
        !           974:                                         $2 == ridpointers[(int)RID_VOLATILE]); }
        !           975:        /* This is the case with input operands as well.  */
        !           976:        | ASM maybe_type_qual '(' string ':' asm_operands ':' asm_operands ')' ';'
        !           977:                { if (pedantic)
        !           978:                    warning ("ANSI C forbids use of `asm' keyword");
        !           979:                  emit_note (input_filename, @1.first_line);
        !           980:                  if (TREE_CHAIN ($4)) $4 = combine_strings ($4);
        !           981:                  c_expand_asm_operands ($4, $6, $8,
        !           982:                                         $2 == ridpointers[(int)RID_VOLATILE]); }
1.1       root      983:        | GOTO identifier ';'
1.1.1.2 ! root      984:                { tree decl;
        !           985:                  emit_note (input_filename, @1.first_line);
        !           986:                  decl = lookup_label ($2);
        !           987:                  expand_goto (decl); }
        !           988:        | identifier ':'
        !           989:                { tree label = define_label (input_filename, @1.first_line, $1);
        !           990:                  if (label)
        !           991:                    expand_label (label); }
        !           992:          stmt
1.1       root      993:        | ';'
1.1.1.2 ! root      994:        ;
        !           995: 
        !           996: maybe_type_qual:
        !           997:        /* empty */
        !           998:        | TYPE_QUAL
1.1       root      999:        ;
                   1000: 
                   1001: xexpr:
                   1002:        /* empty */
                   1003:                { $$ = NULL_TREE; }
                   1004:        | expr
                   1005:        ;
                   1006: 
1.1.1.2 ! root     1007: /* These are the operands other than the first string and comma
        !          1008:    in  asm ("addextend %2,%1", "=dm" (x), "0" (y), "g" (*x))  */
        !          1009: asm_operands: asm_operand
        !          1010:        | asm_operands ',' asm_operand
        !          1011:                { $$ = chainon ($1, $3); }
        !          1012:        ;
        !          1013: 
        !          1014: asm_operand:
        !          1015:        | STRING '(' expr ')'
        !          1016:                { $$ = build_tree_list ($1, $3); }
        !          1017:        ;
        !          1018: 
1.1       root     1019: /* This is what appears inside the parens in a function declarator.
1.1.1.2 ! root     1020:    Its value is a list of ..._TYPE nodes.
        !          1021:    The caller must do `poplevel (0, 0, 0);' after return from this.
        !          1022:    (The caller does it so that error recovery to the closeparen
        !          1023:    can also do it.)  */
        !          1024: parmlist:
        !          1025:                { pushlevel (0); }
        !          1026:          parmlist_1
        !          1027:                { $$ = $2; poplevel (0); }
        !          1028:        ;
        !          1029: 
        !          1030: /* This is referred to where either a parmlist or an identifier list is ok.
        !          1031:    Its value is a list of ..._TYPE nodes or a list of identifiers.
        !          1032:    The caller must do `poplevel (0, 0, 0);' after return from this.  */
        !          1033: parmlist_or_identifiers:
        !          1034:                { pushlevel (0); }
        !          1035:          parmlist_or_identifiers_1
        !          1036:                { $$ = $2; poplevel (0, 0, 0); }
        !          1037:        ;
        !          1038: 
        !          1039: parmlist_or_identifiers_1:
        !          1040:          parmlist_2 ')'
        !          1041:        | identifiers ')'
        !          1042:        | error ')'
        !          1043:                { $$ = NULL_TREE; }
        !          1044:        ;
        !          1045: 
        !          1046: parmlist_1:
        !          1047:          parmlist_2 ')'
        !          1048:        | error ')'
1.1       root     1049:                { $$ = NULL_TREE; }
1.1.1.2 ! root     1050:        ;
        !          1051: 
        !          1052: /* This is what appears inside the parens in a function declarator.
        !          1053:    Is value is represented in the format that grokdeclarator expects.  */
        !          1054: parmlist_2:  /* empty */
        !          1055:                { $$ = get_parm_types (0); }
1.1       root     1056:        | parms
1.1.1.2 ! root     1057:                { $$ = get_parm_types (1); }
1.1       root     1058:        | parms ',' ELLIPSIS
1.1.1.2 ! root     1059:                { $$ = get_parm_types (0); }
1.1       root     1060:        ;
                   1061: 
                   1062: parms: 
                   1063:        parm
1.1.1.2 ! root     1064:                { push_parm_decl ($1); }
1.1       root     1065:        | parms ',' parm
1.1.1.2 ! root     1066:                { push_parm_decl ($3); }
1.1       root     1067:        ;
                   1068: 
1.1.1.2 ! root     1069: /* A single parameter declaration or parameter type name,
        !          1070:    as found in a parmlist.  */
1.1       root     1071: parm:
1.1.1.2 ! root     1072:          typed_declspecs parm_declarator
        !          1073:                { $$ = build_tree_list ($1, $2) ; }
        !          1074:        | typed_declspecs notype_declarator
1.1       root     1075:                { $$ = build_tree_list ($1, $2) ; }
1.1.1.2 ! root     1076:        | typed_declspecs absdcl
        !          1077:                { $$ = build_tree_list ($1, $2); }
        !          1078:        | declmods notype_declarator
        !          1079:                { $$ = build_tree_list ($1, $2) ; }
        !          1080:        | declmods absdcl
1.1       root     1081:                { $$ = build_tree_list ($1, $2); }
                   1082:        ;
                   1083: 
                   1084: /* A nonempty list of identifiers.  */
                   1085: identifiers:   
                   1086:        IDENTIFIER
                   1087:                { $$ = build_tree_list (NULL_TREE, $1); }
                   1088:        | identifiers ',' IDENTIFIER
                   1089:                { $$ = chainon ($1, build_tree_list (NULL_TREE, $3)); }
                   1090:        ;
                   1091: %%
                   1092: 
                   1093: /* Return something to represent absolute declarators containing a *.
                   1094:    TARGET is the absolute declarator that the * contains.
1.1.1.2 ! root     1095:    TYPE_QUALS is a list of modifiers such as const or volatile
1.1       root     1096:    to apply to the pointer type, represented as identifiers.
                   1097: 
                   1098:    We return an INDIRECT_REF whose "contents" are TARGET
                   1099:    and whose type is the modifier list.  */
                   1100:    
                   1101: static tree
1.1.1.2 ! root     1102: make_pointer_declarator (type_quals, target)
        !          1103:      tree type_quals, target;
1.1       root     1104: {
1.1.1.2 ! root     1105:   return build (INDIRECT_REF, type_quals, target);
1.1       root     1106: }
                   1107: 
                   1108: /* Given a chain of STRING_CST nodes,
                   1109:    concatenate them into one STRING_CST
1.1.1.2 ! root     1110:    and give it a suitable array-of-chars data type.  */
1.1       root     1111: 
                   1112: static tree
                   1113: combine_strings (strings)
                   1114:      tree strings;
                   1115: {
                   1116:   register tree value, t;
1.1.1.2 ! root     1117:   register int length = 1;
        !          1118:   int wide_length = 0;
        !          1119:   int wide_flag = 0;
1.1       root     1120: 
                   1121:   if (TREE_CHAIN (strings))
                   1122:     {
                   1123:       /* More than one in the chain, so concatenate.  */
                   1124:       register char *p, *q;
                   1125: 
                   1126:       /* Don't include the \0 at the end of each substring,
1.1.1.2 ! root     1127:         except for the last one.
        !          1128:         Count wide strings and ordinary strings separately.  */
1.1       root     1129:       for (t = strings; t; t = TREE_CHAIN (t))
1.1.1.2 ! root     1130:        {
        !          1131:          if (TREE_TYPE (t) == int_array_type_node)
        !          1132:            {
        !          1133:              wide_length += (TREE_STRING_LENGTH (t) - 1);
        !          1134:              wide_flag = 1;
        !          1135:            }
        !          1136:          else
        !          1137:            length += (TREE_STRING_LENGTH (t) - 1);
        !          1138:        }
        !          1139: 
        !          1140:       /* If anything is wide, the non-wides will be converted,
        !          1141:         which makes them take more space.  */
        !          1142:       if (wide_flag)
        !          1143:        length = length * UNITS_PER_WORD + wide_length;
1.1       root     1144: 
                   1145:       p = (char *) oballoc (length);
                   1146: 
1.1.1.2 ! root     1147:       /* Copy the individual strings into the new combined string.
        !          1148:         If the combined string is wide, convert the chars to ints
        !          1149:         for any individual strings that are not wide.  */
        !          1150: 
1.1       root     1151:       q = p;
                   1152:       for (t = strings; t; t = TREE_CHAIN (t))
                   1153:        {
1.1.1.2 ! root     1154:          int len = TREE_STRING_LENGTH (t) - 1;
        !          1155:          if ((TREE_TYPE (t) == int_array_type_node) == wide_flag)
        !          1156:            {
        !          1157:              bcopy (TREE_STRING_POINTER (t), q, len);
        !          1158:              q += len;
        !          1159:            }
        !          1160:          else
        !          1161:            {
        !          1162:              int i;
        !          1163:              for (i = 0; i < len; i++)
        !          1164:                ((int *) q)[i] = TREE_STRING_POINTER (t)[i];
        !          1165:              q += len * UNITS_PER_WORD;
        !          1166:            }
1.1       root     1167:        }
                   1168:       *q = 0;
                   1169: 
                   1170:       value = make_node (STRING_CST);
                   1171:       TREE_STRING_POINTER (value) = p;
                   1172:       TREE_STRING_LENGTH (value) = length;
                   1173:       TREE_LITERAL (value) = 1;
                   1174:     }
                   1175:   else
1.1.1.2 ! root     1176:     {
        !          1177:       value = strings;
        !          1178:       length = TREE_STRING_LENGTH (value);
        !          1179:       if (TREE_TYPE (value) == int_array_type_node)
        !          1180:        wide_flag = 1;
        !          1181:     }
1.1       root     1182: 
1.1.1.2 ! root     1183:   TREE_TYPE (value)
        !          1184:     = build_array_type (wide_flag ? integer_type_node : char_type_node,
        !          1185:                        make_index_type (build_int_2 (length - 1, 0)));
1.1       root     1186:   TREE_LITERAL (value) = 1;
1.1.1.2 ! root     1187:   TREE_STATIC (value) = 1;
1.1       root     1188:   return value;
                   1189: }
                   1190: 
                   1191: int lineno;                    /* current line number in file being read */
                   1192: 
                   1193: FILE *finput;                  /* input file.
                   1194:                                   Normally a pipe from the preprocessor.  */
                   1195: 
                   1196: /* lexical analyzer */
                   1197: 
1.1.1.2 ! root     1198: static int maxtoken;           /* Current nominal length of token buffer */
        !          1199: static char *token_buffer;     /* Pointer to token buffer.
        !          1200:                                   Actual allocated length is maxtoken + 2.  */
        !          1201: static dollar_seen = 0;                /* Nonzero if have warned about `$'.  */
1.1       root     1202: 
                   1203: #define MAXRESERVED 9
                   1204: 
1.1.1.2 ! root     1205: /* frw[I] is index in `reswords' of the first word whose length is I;
        !          1206:    frw[I+1] is one plus the index of the last word whose length is I.
        !          1207:    The length of frw must be MAXRESERVED + 2 so there is an element
        !          1208:    at MAXRESERVED+1 for the case I == MAXRESERVED.  */
        !          1209: 
        !          1210: static char frw[MAXRESERVED+2] =
        !          1211:   { 0, 0, 0, 2, 5, 13, 19, 29, 32, 36, 37 };
        !          1212: 
        !          1213: /* Table of reserved words.  */
        !          1214: 
        !          1215: struct resword { char *name; short token; enum rid rid;};
        !          1216: 
        !          1217: #define NORID RID_UNUSED
        !          1218: 
        !          1219: static struct resword reswords[]
        !          1220:   = {{"if", IF, NORID},
        !          1221:      {"do", DO, NORID},
        !          1222:      {"int", TYPESPEC, RID_INT},
        !          1223:      {"for", FOR, NORID},
        !          1224:      {"asm", ASM, NORID},
        !          1225:      {"case", CASE, NORID},
        !          1226:      {"char", TYPESPEC, RID_CHAR},
        !          1227:      {"auto", SCSPEC, RID_AUTO},
        !          1228:      {"goto", GOTO, NORID},
        !          1229:      {"else", ELSE, NORID},
        !          1230:      {"long", TYPESPEC, RID_LONG},
        !          1231:      {"void", TYPESPEC, RID_VOID},
        !          1232:      {"enum", ENUM, NORID},
        !          1233:      {"float", TYPESPEC, RID_FLOAT},
        !          1234:      {"short", TYPESPEC, RID_SHORT},
        !          1235:      {"union", UNION, NORID},
        !          1236:      {"break", BREAK, NORID},
        !          1237:      {"while", WHILE, NORID},
        !          1238:      {"const", TYPE_QUAL, RID_CONST},
        !          1239:      {"double", TYPESPEC, RID_DOUBLE},
        !          1240:      {"static", SCSPEC, RID_STATIC},
        !          1241:      {"extern", SCSPEC, RID_EXTERN},
        !          1242:      {"struct", STRUCT, NORID},
        !          1243:      {"return", RETURN, NORID},
        !          1244:      {"sizeof", SIZEOF, NORID},
        !          1245:      {"typeof", TYPEOF, NORID},
        !          1246:      {"switch", SWITCH, NORID},
        !          1247:      {"signed", TYPESPEC, RID_SIGNED},
        !          1248:      {"inline", SCSPEC, RID_INLINE},
        !          1249:      {"typedef", SCSPEC, RID_TYPEDEF},
        !          1250:      {"default", DEFAULT, NORID},
        !          1251:      {"noalias", TYPE_QUAL, RID_NOALIAS},
        !          1252:      {"unsigned", TYPESPEC, RID_UNSIGNED},
        !          1253:      {"continue", CONTINUE, NORID},
        !          1254:      {"register", SCSPEC, RID_REGISTER},
        !          1255:      {"volatile", TYPE_QUAL, RID_VOLATILE},
        !          1256:      {"__alignof", ALIGNOF, NORID}};
1.1       root     1257: 
                   1258: /* The elements of `ridpointers' are identifier nodes
1.1.1.2 ! root     1259:    for the reserved type names and storage classes.
        !          1260:    It is indexed by a RID_... value.  */
1.1       root     1261: 
                   1262: tree ridpointers[(int) RID_MAX];
                   1263: 
                   1264: static tree line_identifier;   /* The identifier node named "line" */
                   1265: 
1.1.1.2 ! root     1266: void check_newline ();
1.1       root     1267: 
                   1268: void
1.1.1.2 ! root     1269: init_lex ()
1.1       root     1270: {
1.1.1.2 ! root     1271:   extern char *malloc ();
1.1       root     1272: 
1.1.1.2 ! root     1273:   /* Start it at 0, because check_newline is called at the very beginning
1.1       root     1274:      and will increment it to 1.  */
                   1275:   lineno = 0;
1.1.1.2 ! root     1276:   line_identifier = get_identifier ("line");
1.1       root     1277: 
                   1278:   maxtoken = 40;
1.1.1.2 ! root     1279:   token_buffer = malloc (maxtoken + 2);
        !          1280:   ridpointers[(int) RID_INT] = get_identifier ("int");
        !          1281:   ridpointers[(int) RID_CHAR] = get_identifier ("char");
        !          1282:   ridpointers[(int) RID_VOID] = get_identifier ("void");
        !          1283:   ridpointers[(int) RID_FLOAT] = get_identifier ("float");
        !          1284:   ridpointers[(int) RID_DOUBLE] = get_identifier ("double");
        !          1285:   ridpointers[(int) RID_SHORT] = get_identifier ("short");
        !          1286:   ridpointers[(int) RID_LONG] = get_identifier ("long");
        !          1287:   ridpointers[(int) RID_UNSIGNED] = get_identifier ("unsigned");
        !          1288:   ridpointers[(int) RID_SIGNED] = get_identifier ("signed");
        !          1289:   ridpointers[(int) RID_INLINE] = get_identifier ("inline");
        !          1290:   ridpointers[(int) RID_CONST] = get_identifier ("const");
        !          1291:   ridpointers[(int) RID_VOLATILE] = get_identifier ("volatile");
        !          1292:   ridpointers[(int) RID_AUTO] = get_identifier ("auto");
        !          1293:   ridpointers[(int) RID_STATIC] = get_identifier ("static");
        !          1294:   ridpointers[(int) RID_EXTERN] = get_identifier ("extern");
        !          1295:   ridpointers[(int) RID_TYPEDEF] = get_identifier ("typedef");
        !          1296:   ridpointers[(int) RID_REGISTER] = get_identifier ("register");
        !          1297: }
        !          1298: 
        !          1299: static void
        !          1300: reinit_parse_for_function ()
        !          1301: {
1.1       root     1302: }
                   1303: 
                   1304: static int
1.1.1.2 ! root     1305: skip_white_space ()
1.1       root     1306: {
                   1307:   register int c;
                   1308:   register int inside;
                   1309: 
1.1.1.2 ! root     1310:   c = getc (finput);
1.1       root     1311: 
                   1312:   for (;;)
                   1313:     {
                   1314:       switch (c)
                   1315:        {
                   1316:        case '/':
1.1.1.2 ! root     1317:          c = getc (finput);
1.1       root     1318:          if (c != '*')
                   1319:            {
1.1.1.2 ! root     1320:              ungetc (c, finput);
1.1       root     1321:              return '/';
                   1322:            }
                   1323: 
1.1.1.2 ! root     1324:          c = getc (finput);
1.1       root     1325: 
                   1326:          inside = 1;
                   1327:          while (inside)
                   1328:            {
                   1329:              if (c == '*')
                   1330:                {
                   1331:                  while (c == '*')
1.1.1.2 ! root     1332:                    c = getc (finput);
1.1       root     1333: 
                   1334:                  if (c == '/')
                   1335:                    {
                   1336:                      inside = 0;
1.1.1.2 ! root     1337:                      c = getc (finput);
1.1       root     1338:                    }
                   1339:                }
                   1340:              else if (c == '\n')
                   1341:                {
                   1342:                  lineno++;
1.1.1.2 ! root     1343:                  c = getc (finput);
1.1       root     1344:                }
                   1345:              else if (c == EOF)
1.1.1.2 ! root     1346:                {
        !          1347:                  error ("unterminated comment");
        !          1348:                  break;
        !          1349:                }
1.1       root     1350:              else
1.1.1.2 ! root     1351:                c = getc (finput);
1.1       root     1352:            }
                   1353: 
                   1354:          break;
                   1355: 
                   1356:        case '\n':
1.1.1.2 ! root     1357:          check_newline ();
1.1       root     1358: 
                   1359:        case ' ':
                   1360:        case '\t':
                   1361:        case '\f':
                   1362:        case '\r':
                   1363:        case '\b':
1.1.1.2 ! root     1364:          c = getc (finput);
1.1       root     1365:          break;
                   1366: 
                   1367:        case '\\':
1.1.1.2 ! root     1368:          c = getc (finput);
1.1       root     1369:          if (c == '\n')
                   1370:            lineno++;
                   1371:          else
1.1.1.2 ! root     1372:            error ("stray '\\' in program");
        !          1373:          c = getc (finput);
1.1       root     1374:          break;
                   1375: 
                   1376:        default:
                   1377:          return (c);
                   1378:        }
                   1379:     }
                   1380: }
                   1381: 
                   1382: 
                   1383: 
1.1.1.2 ! root     1384: /* Make the token buffer longer, preserving the data in it.
        !          1385:    P should point to just beyond the last valid character in the old buffer.
        !          1386:    The value we return is a pointer to the new buffer
        !          1387:    at a place corresponding to P.  */
1.1       root     1388: 
                   1389: static char *
1.1.1.2 ! root     1390: extend_token_buffer (p)
        !          1391:      char *p;
1.1       root     1392: {
1.1.1.2 ! root     1393:   int offset = p - token_buffer;
1.1       root     1394: 
1.1.1.2 ! root     1395:   maxtoken = maxtoken * 2 + 10;
        !          1396:   token_buffer = (char *) realloc (token_buffer, maxtoken + 2);
        !          1397:   if (token_buffer == 0)
        !          1398:     fatal ("virtual memory exceeded");
1.1       root     1399: 
1.1.1.2 ! root     1400:   return token_buffer + offset;
1.1       root     1401: }
                   1402: 
1.1.1.2 ! root     1403: /* At the beginning of a line, increment the line number
1.1       root     1404:    and handle a #line directive immediately following  */
                   1405: 
                   1406: void
                   1407: check_newline ()
                   1408: {
                   1409:   register int c;
                   1410:   register int token;
                   1411: 
                   1412:   while (1)
                   1413:     {
                   1414:       lineno++;
                   1415: 
1.1.1.2 ! root     1416:       /* Read first nonwhite char on the line.  */
        !          1417: 
        !          1418:       c = getc (finput);
        !          1419:       while (c == ' ' || c == '\t')
        !          1420:        c = getc (finput);
        !          1421: 
1.1       root     1422:       if (c != '#')
                   1423:        {
1.1.1.2 ! root     1424:          /* If not #, unread it.  */
1.1       root     1425:          ungetc (c, finput);
                   1426:          return;
                   1427:        }
                   1428: 
1.1.1.2 ! root     1429:       /* Read first nonwhite char after the `#'.  */
1.1       root     1430: 
1.1.1.2 ! root     1431:       c = getc (finput);
        !          1432:       while (c == ' ' || c == '\t')
        !          1433:        c = getc (finput);
        !          1434: 
        !          1435:       /* If a letter follows, then if the word here is `line', skip
        !          1436:         it and ignore it; otherwise, ignore the line, with an error
        !          1437:         if the word isn't `pragma'.  */
        !          1438: 
        !          1439:       if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
1.1       root     1440:        {
1.1.1.2 ! root     1441:          if (c == 'p')
        !          1442:            {
        !          1443:              if (getc (finput) == 'r'
        !          1444:                  && getc (finput) == 'a'
        !          1445:                  && getc (finput) == 'g'
        !          1446:                  && getc (finput) == 'm'
        !          1447:                  && getc (finput) == 'a'
        !          1448:                  && ((c = getc (finput)) == ' ' || c == '\t'))
        !          1449:                goto noerror;
        !          1450:            }
        !          1451: 
        !          1452:          else if (c == 'l')
        !          1453:            {
        !          1454:              if (getc (finput) == 'i'
        !          1455:                  && getc (finput) == 'n'
        !          1456:                  && getc (finput) == 'e'
        !          1457:                  && ((c = getc (finput)) == ' ' || c == '\t'))
        !          1458:                goto linenum;
        !          1459:            }
        !          1460: 
        !          1461:          error ("undefined or invalid # directive");
        !          1462:        noerror:
        !          1463: 
        !          1464:          while ((c = getc (finput)) && c != '\n');
        !          1465: 
        !          1466:          continue;
1.1       root     1467:        }
                   1468: 
1.1.1.2 ! root     1469:     linenum:
        !          1470:       /* Here we have either `#line' or `# <nonletter>'.
        !          1471:         In either case, it should be a line number; a digit should follow.
        !          1472: 
        !          1473:       while (c == ' ' || c == '\t')
        !          1474:        c = getc (finput);
        !          1475: 
1.1       root     1476:       /* If the # is the only nonwhite char on the line,
                   1477:         just ignore it.  Check the new newline.  */
                   1478:       if (c == '\n')
                   1479:        continue;
                   1480: 
                   1481:       /* Something follows the #; read a token.  */
                   1482: 
                   1483:       ungetc (c, finput);
                   1484:       token = yylex ();
                   1485: 
                   1486:       if (token == CONSTANT
                   1487:          && TREE_CODE (yylval.ttype) == INTEGER_CST)
                   1488:        {
                   1489:          /* subtract one, because it is the following line that
                   1490:             gets the specified number */
                   1491: 
                   1492:          int l = TREE_INT_CST_LOW (yylval.ttype) - 1;
                   1493: 
1.1.1.2 ! root     1494:          /* Is this the last nonwhite stuff on the line?  */
        !          1495:          c = getc (finput);
        !          1496:          while (c == ' ' || c == '\t')
        !          1497:            c = getc (finput);
        !          1498:          if (c == '\n')
        !          1499:            {
        !          1500:              /* No more: store the line number and check following line.  */
        !          1501:              lineno = l;
        !          1502:              continue;
        !          1503:            }
        !          1504:          ungetc (c, finput);
        !          1505: 
        !          1506:          /* More follows: it must be a string constant (filename).  */
        !          1507: 
1.1       root     1508:          token = yylex ();
                   1509:          if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)
1.1.1.2 ! root     1510:            {
        !          1511:              error ("invalid #line");
        !          1512:              return;
        !          1513:            }
1.1       root     1514: 
                   1515:          input_filename
                   1516:            = (char *) permalloc (TREE_STRING_LENGTH (yylval.ttype) + 1);
                   1517:          strcpy (input_filename, TREE_STRING_POINTER (yylval.ttype));
                   1518:          lineno = l;
1.1.1.2 ! root     1519: 
        !          1520:          if (main_input_filename == 0)
        !          1521:            main_input_filename = input_filename;
1.1       root     1522:        }
                   1523:       else
1.1.1.2 ! root     1524:        error ("invalid #line");
1.1       root     1525: 
                   1526:       /* skip the rest of this line.  */
                   1527:       while ((c = getc (finput)) != '\n');
                   1528:     }
                   1529: }
                   1530: 
                   1531: 
                   1532: 
                   1533: #define isalnum(char) ((char >= 'a' && char <= 'z') || (char >= 'A' && char <= 'Z') || (char >= '0' && char <= '9'))
                   1534: #define isdigit(char) (char >= '0' && char <= '9')
                   1535: #define ENDFILE -1  /* token that represents end-of-file */
                   1536: 
                   1537: 
                   1538: static int
                   1539: readescape ()
                   1540: {
                   1541:   register int c = getc (finput);
                   1542:   register int count, code;
                   1543: 
                   1544:   switch (c)
                   1545:     {
                   1546:     case 'x':
                   1547:       code = 0;
                   1548:       count = 0;
                   1549:       while (1)
                   1550:        {
                   1551:          c = getc (finput);
                   1552:          if (!(c >= 'a' && c <= 'f')
                   1553:              && !(c >= 'A' && c <= 'F')
                   1554:              && !(c >= '0' && c <= '9'))
                   1555:            {
                   1556:              ungetc (c, finput);
                   1557:              break;
                   1558:            }
                   1559:          code *= 16;
                   1560:          if (c >= 'a' && c <= 'f')
                   1561:            code += c - 'a' + 10;
                   1562:          if (c >= 'A' && c <= 'F')
                   1563:            code += c - 'A' + 10;
                   1564:          if (c >= '0' && c <= '9')
                   1565:            code += c - '0';
                   1566:          count++;
                   1567:        }
                   1568:       if (count == 0)
1.1.1.2 ! root     1569:        error ("\\x used with no following hex digits");
1.1       root     1570:       return code;
                   1571: 
                   1572:     case '0':  case '1':  case '2':  case '3':  case '4':
                   1573:     case '5':  case '6':  case '7':
                   1574:       code = 0;
                   1575:       count = 0;
                   1576:       while ((c <= '7') && (c >= '0') && (count++ < 3))
                   1577:        {
                   1578:          code = (code * 8) + (c - '0');
                   1579:          c = getc (finput);
                   1580:        }
                   1581:       ungetc (c, finput);
                   1582:       return code;
                   1583: 
                   1584:     case '\\': case '\'': case '"':
                   1585:       return c;
                   1586: 
                   1587:     case '\n':
                   1588:       lineno++;
                   1589:       return -1;
                   1590: 
                   1591:     case 'n':
                   1592:       return TARGET_NEWLINE;
                   1593: 
                   1594:     case 't':
                   1595:       return TARGET_TAB;
                   1596: 
                   1597:     case 'r':
                   1598:       return TARGET_CR;
                   1599: 
                   1600:     case 'f':
                   1601:       return TARGET_FF;
                   1602: 
                   1603:     case 'b':
                   1604:       return TARGET_BS;
                   1605: 
                   1606:     case 'a':
                   1607:       return TARGET_BELL;
                   1608: 
                   1609:     case 'v':
                   1610:       return TARGET_VT;
1.1.1.2 ! root     1611: 
        !          1612:     case 'E':
        !          1613:       return 033;
        !          1614: 
        !          1615:     case '?':
        !          1616:       return c;
1.1       root     1617:     }
1.1.1.2 ! root     1618:   if (c >= 040 && c <= 0177)
        !          1619:     warning ("unknown escape sequence `\\%c'", c);
        !          1620:   else
        !          1621:     warning ("unknown escape sequence: `\\' followed by char code 0x%x", c);
1.1       root     1622:   return c;
                   1623: }
                   1624: 
1.1.1.2 ! root     1625: void
        !          1626: yyerror ()
        !          1627: {
        !          1628:   /* We can't print string and character constants well
        !          1629:      because the token_buffer contains the result of processing escapes.  */
        !          1630:   if (token_buffer[0] == 0)
        !          1631:     error ("parse error at end of input");
        !          1632:   else if (token_buffer[0] == '"')
        !          1633:     error ("parse error at string constant");
        !          1634:   else if (token_buffer[0] == '\'')
        !          1635:     error ("parse error at character constant");
        !          1636:   else
        !          1637:     error ("parse error at `%s'", token_buffer);
        !          1638: }
1.1       root     1639: 
                   1640: static int
1.1.1.2 ! root     1641: yylex ()
1.1       root     1642: {
                   1643:   register int c;
                   1644:   register char *p;
                   1645:   register int value;
1.1.1.2 ! root     1646:   int wide_flag = 0;
1.1       root     1647: 
1.1.1.2 ! root     1648:   token_buffer[0] = c = skip_white_space ();
        !          1649:   token_buffer[1] = 0;
1.1       root     1650: 
                   1651:   yylloc.first_line = lineno;
                   1652: 
                   1653:   switch (c)
                   1654:     {
                   1655:     case EOF:
1.1.1.2 ! root     1656:       token_buffer[0] = 0;
        !          1657:       value = ENDFILE;
        !          1658:       break;
        !          1659: 
        !          1660:     case 'L':
        !          1661:       /* Capital L may start a wide-string or wide-character constant.  */
        !          1662:       {
        !          1663:        register int c = getc (finput);
        !          1664:        if (c == '\'')
        !          1665:          {
        !          1666:            wide_flag = 1;
        !          1667:            goto char_constant;
        !          1668:          }
        !          1669:        if (c == '"')
        !          1670:          {
        !          1671:            wide_flag = 1;
        !          1672:            goto string_constant;
        !          1673:          }
        !          1674:        ungetc (c, finput);
        !          1675:       }
1.1       root     1676: 
                   1677:     case 'A':  case 'B':  case 'C':  case 'D':  case 'E':
                   1678:     case 'F':  case 'G':  case 'H':  case 'I':  case 'J':
1.1.1.2 ! root     1679:     case 'K':            case 'M':  case 'N':  case 'O':
1.1       root     1680:     case 'P':  case 'Q':  case 'R':  case 'S':  case 'T':
                   1681:     case 'U':  case 'V':  case 'W':  case 'X':  case 'Y':
                   1682:     case 'Z':
                   1683:     case 'a':  case 'b':  case 'c':  case 'd':  case 'e':
                   1684:     case 'f':  case 'g':  case 'h':  case 'i':  case 'j':
                   1685:     case 'k':  case 'l':  case 'm':  case 'n':  case 'o':
                   1686:     case 'p':  case 'q':  case 'r':  case 's':  case 't':
                   1687:     case 'u':  case 'v':  case 'w':  case 'x':  case 'y':
                   1688:     case 'z':
                   1689:     case '_':
1.1.1.2 ! root     1690:     case '$':
1.1       root     1691:       p = token_buffer;
1.1.1.2 ! root     1692:       while (isalnum (c) || c == '_' || c == '$')
1.1       root     1693:        {
                   1694:          if (p >= token_buffer + maxtoken)
1.1.1.2 ! root     1695:            p = extend_token_buffer (p);
        !          1696:          if (c == '$')
        !          1697:            {
        !          1698:              if (pedantic)
        !          1699:                {
        !          1700:                  if (! dollar_seen)
        !          1701:                    warning ("ANSI C forbids `$' (first use here)");
        !          1702:                  dollar_seen = 1;
        !          1703:                }
        !          1704:            }
        !          1705: 
1.1       root     1706:          *p++ = c;
1.1.1.2 ! root     1707:          c = getc (finput);
1.1       root     1708:        }
                   1709: 
                   1710:       *p = 0;
1.1.1.2 ! root     1711:       ungetc (c, finput);
1.1       root     1712: 
                   1713:       value = IDENTIFIER;
                   1714:       yylval.itype = 0;
                   1715: 
1.1.1.2 ! root     1716:       /* Try to recognize a keyword.  */
        !          1717: 
1.1       root     1718:       if (p - token_buffer <= MAXRESERVED)
                   1719:        {
                   1720:          register int lim = frw [p - token_buffer + 1];
1.1.1.2 ! root     1721:          register int i = frw[p - token_buffer];
        !          1722:          register struct resword *p = &reswords[i];
1.1       root     1723: 
1.1.1.2 ! root     1724:          for (; i < lim; i++, p++)
        !          1725:            if (p->name[0] == token_buffer[0]
        !          1726:                && !strcmp (p->name, token_buffer))
1.1       root     1727:              {
1.1.1.2 ! root     1728:                if (p->rid)
        !          1729:                  yylval.ttype = ridpointers[(int) p->rid];
        !          1730:                if ((! flag_no_asm
        !          1731:                     || ((int) p->token != ASM
        !          1732:                         && (int) p->token != TYPEOF
        !          1733:                         && strcmp (p->name, "inline")))
        !          1734:                    /* -ftraditional means don't recognize
        !          1735:                       typeof, const, volatile, noalias, signed or inline.  */
        !          1736:                    && (! flag_traditional
        !          1737:                        || ((int) p->token != TYPE_QUAL
        !          1738:                            && (int) p->token != TYPEOF
        !          1739:                            && strcmp (p->name, "signed")
        !          1740:                            && strcmp (p->name, "inline"))))
        !          1741:                  value = (int) p->token;
1.1       root     1742:                break;
                   1743:              }
                   1744:        }
                   1745: 
1.1.1.2 ! root     1746:       /* If we did not find a keyword, look for an identifier
        !          1747:         (or a typename).  */
        !          1748: 
1.1       root     1749:       if (value == IDENTIFIER)
                   1750:        {
1.1.1.2 ! root     1751:           yylval.ttype = get_identifier (token_buffer);
1.1       root     1752:          lastiddecl = lookup_name (yylval.ttype);
                   1753: 
                   1754:          if (lastiddecl != 0 && TREE_CODE (lastiddecl) == TYPE_DECL)
                   1755:            value = TYPENAME;
                   1756:        }
                   1757: 
                   1758:       break;
                   1759: 
                   1760:     case '0':  case '1':  case '2':  case '3':  case '4':
                   1761:     case '5':  case '6':  case '7':  case '8':  case '9':
                   1762:     case '.':
                   1763:       {
                   1764:        int base = 10;
                   1765:        int count = 0;
1.1.1.2 ! root     1766:        int largest_digit = 0;
        !          1767:        int numdigits = 0;
        !          1768:        /* for multi-precision arithmetic,
        !          1769:           we store only 8 live bits in each short,
1.1       root     1770:           giving us 64 bits of reliable precision */
                   1771:        short shorts[8];
1.1.1.2 ! root     1772:        int floatflag = 0;  /* Set 1 if we learn this is a floating constant */
1.1       root     1773: 
                   1774:        for (count = 0; count < 8; count++)
                   1775:          shorts[count] = 0;
                   1776: 
                   1777:        p = token_buffer;
                   1778:        *p++ = c;
                   1779: 
                   1780:        if (c == '0')
                   1781:          {
1.1.1.2 ! root     1782:            *p++ = (c = getc (finput));
1.1       root     1783:            if ((c == 'x') || (c == 'X'))
                   1784:              {
                   1785:                base = 16;
1.1.1.2 ! root     1786:                *p++ = (c = getc (finput));
1.1       root     1787:              }
                   1788:            else
                   1789:              {
                   1790:                base = 8;
1.1.1.2 ! root     1791:                numdigits++;
1.1       root     1792:              }
                   1793:          }
                   1794: 
1.1.1.2 ! root     1795:        /* Read all the digits-and-decimal-points.  */
        !          1796: 
1.1       root     1797:        while (c == '.'
                   1798:               || (isalnum (c) && (c != 'l') && (c != 'L')
1.1.1.2 ! root     1799:                   && (c != 'u') && (c != 'U')
        !          1800:                   && (!floatflag || ((c != 'f') && (c != 'F')))))
1.1       root     1801:          {
                   1802:            if (c == '.')
                   1803:              {
1.1.1.2 ! root     1804:                if (base == 16)
        !          1805:                  error ("floating constant may not be in radix 16");
        !          1806:                floatflag = 1;
        !          1807:                base = 10;
        !          1808:                *p++ = c = getc (finput);
1.1       root     1809:                /* Accept '.' as the start of a floating-point number
                   1810:                   only when it is followed by a digit.
                   1811:                   Otherwise, unread the following non-digit
                   1812:                   and use the '.' as a structural token.  */
1.1.1.2 ! root     1813:                if (p == token_buffer + 2 && !isdigit (c))
1.1       root     1814:                  {
                   1815:                    if (c == '.')
                   1816:                      {
                   1817:                        c = getc (finput);
                   1818:                        if (c == '.')
1.1.1.2 ! root     1819:                          {
        !          1820:                            *p++ = c;
        !          1821:                            *p = 0;
        !          1822:                            return ELLIPSIS;
        !          1823:                          }
        !          1824:                        error ("parse error at `..'");
1.1       root     1825:                      }
                   1826:                    ungetc (c, finput);
1.1.1.2 ! root     1827:                    token_buffer[1] = 0;
        !          1828:                    value = '.';
        !          1829:                    goto done;
1.1       root     1830:                  }
                   1831:              }
                   1832:            else
                   1833:              {
1.1.1.2 ! root     1834:                /* It is not a decimal point.
        !          1835:                   It should be a digit (perhaps a hex digit).  */
        !          1836: 
        !          1837:                if (isdigit (c))
1.1       root     1838:                  {
                   1839:                    c = c - '0';
                   1840:                  }
                   1841:                else if (base <= 10)
                   1842:                  {
                   1843:                    if ((c&~040) == 'E')
                   1844:                      {
1.1.1.2 ! root     1845:                        base = 10;
        !          1846:                        floatflag = 1;
1.1       root     1847:                        break;   /* start of exponent */
                   1848:                      }
1.1.1.2 ! root     1849:                    error ("nondigits in number and not hexadecimal");
1.1       root     1850:                    c = 0;
                   1851:                  }
                   1852:                else if (c >= 'a')
                   1853:                  {
                   1854:                    c = c - 'a' + 10;
                   1855:                  }
                   1856:                else
                   1857:                  {
                   1858:                    c = c - 'A' + 10;
                   1859:                  }
1.1.1.2 ! root     1860:                if (c >= largest_digit)
        !          1861:                  largest_digit = c;
        !          1862:                numdigits++;
1.1       root     1863:            
                   1864:                for (count = 0; count < 8; count++)
                   1865:                  {
                   1866:                    (shorts[count] *= base);
                   1867:                    if (count)
                   1868:                      {
                   1869:                        shorts[count] += (shorts[count-1] >> 8);
                   1870:                        shorts[count-1] &= (1<<8)-1;
                   1871:                      }
                   1872:                    else shorts[0] += c;
                   1873:                  }
                   1874:     
1.1.1.2 ! root     1875:                if (p >= token_buffer + maxtoken - 3)
        !          1876:                  p = extend_token_buffer (p);
        !          1877:                *p++ = (c = getc (finput));
1.1       root     1878:              }
                   1879:          }
                   1880: 
1.1.1.2 ! root     1881:        if (numdigits == 0)
        !          1882:          error ("numeric constant with no digits");
        !          1883: 
        !          1884:        if (largest_digit >= base)
        !          1885:          error ("numeric constant contains digits beyond the radix");
        !          1886: 
1.1       root     1887:        /* Remove terminating char from the token buffer and delimit the string */
                   1888:        *--p = 0;
                   1889: 
                   1890:        if (floatflag)
                   1891:          {
                   1892:            tree type = double_type_node;
1.1.1.2 ! root     1893:            char f_seen = 0;
        !          1894:            char l_seen = 0;
1.1       root     1895: 
1.1.1.2 ! root     1896:            /* Read explicit exponent if any, and put it in tokenbuf.  */
1.1       root     1897: 
                   1898:            if ((c == 'e') || (c == 'E'))
                   1899:              {
1.1.1.2 ! root     1900:                if (p >= token_buffer + maxtoken - 3)
        !          1901:                  p = extend_token_buffer (p);
        !          1902:                *p++ = c;
        !          1903:                c = getc (finput);
1.1       root     1904:                if ((c == '+') || (c == '-'))
                   1905:                  {
1.1.1.2 ! root     1906:                    *p++ = c;
        !          1907:                    c = getc (finput);
1.1       root     1908:                  }
1.1.1.2 ! root     1909:                if (! isdigit (c))
        !          1910:                  error ("floating constant exponent has no digits");
        !          1911:                while (isdigit (c))
1.1       root     1912:                  {
1.1.1.2 ! root     1913:                    if (p >= token_buffer + maxtoken - 3)
        !          1914:                      p = extend_token_buffer (p);
        !          1915:                    *p++ = c;
        !          1916:                    c = getc (finput);
1.1       root     1917:                  }
                   1918:              }
                   1919: 
1.1.1.2 ! root     1920:            *p = 0;
        !          1921:            yylval.ttype = build_real (atof (token_buffer));
        !          1922: 
1.1       root     1923:            while (1)
                   1924:              {
                   1925:                if (c == 'f' || c == 'F')
1.1.1.2 ! root     1926:                  {
        !          1927:                    if (f_seen)
        !          1928:                      error ("two `f's in floating constant");
        !          1929:                    f_seen = 1;
        !          1930:                    type = float_type_node;
        !          1931:                  }
1.1       root     1932:                else if (c == 'l' || c == 'L')
1.1.1.2 ! root     1933:                  {
        !          1934:                    if (l_seen)
        !          1935:                      error ("two `l's in floating constant");
        !          1936:                    l_seen = 1;
        !          1937:                    type = long_double_type_node;
        !          1938:                  }
        !          1939:                else
        !          1940:                  {
        !          1941:                    if (isalnum (c))
        !          1942:                      {
        !          1943:                        error ("garbage at end of number");
        !          1944:                        while (isalnum (c))
        !          1945:                          {
        !          1946:                            if (p >= token_buffer + maxtoken - 3)
        !          1947:                              p = extend_token_buffer (p);
        !          1948:                            *p++ = c;
        !          1949:                            c = getc (finput);
        !          1950:                          }
        !          1951:                      }
        !          1952:                    break;
        !          1953:                  }
        !          1954:                if (p >= token_buffer + maxtoken - 3)
        !          1955:                  p = extend_token_buffer (p);
        !          1956:                *p++ = c;
1.1       root     1957:                c = getc (finput);
                   1958:              }
                   1959: 
1.1.1.2 ! root     1960:            ungetc (c, finput);
        !          1961:            *p = 0;
1.1       root     1962: 
                   1963:            TREE_TYPE (yylval.ttype) = type;
                   1964:          }
                   1965:        else
                   1966:          {
                   1967:            tree type;
                   1968:            int spec_unsigned = 0;
                   1969:            int spec_long = 0;
                   1970: 
                   1971:            while (1)
                   1972:              {
                   1973:                if (c == 'u' || c == 'U')
                   1974:                  {
1.1.1.2 ! root     1975:                    if (spec_unsigned)
        !          1976:                      error ("two `u's in integer constant");
1.1       root     1977:                    spec_unsigned = 1;
                   1978:                  }
                   1979:                else if (c == 'l' || c == 'L')
                   1980:                  {
1.1.1.2 ! root     1981:                    if (spec_long)
        !          1982:                      error ("two `l's in integer constant");
1.1       root     1983:                    spec_long = 1;
                   1984:                  }
1.1.1.2 ! root     1985:                else
        !          1986:                  {
        !          1987:                    if (isalnum (c))
        !          1988:                      {
        !          1989:                        error ("garbage at end of number");
        !          1990:                        while (isalnum (c))
        !          1991:                          {
        !          1992:                            if (p >= token_buffer + maxtoken - 3)
        !          1993:                              p = extend_token_buffer (p);
        !          1994:                            *p++ = c;
        !          1995:                            c = getc (finput);
        !          1996:                          }
        !          1997:                      }
        !          1998:                    break;
        !          1999:                  }
        !          2000:                if (p >= token_buffer + maxtoken - 3)
        !          2001:                  p = extend_token_buffer (p);
        !          2002:                *p++ = c;
        !          2003:                c = getc (finput);
1.1       root     2004:              }
                   2005: 
                   2006:            ungetc (c, finput);
                   2007: 
1.1.1.2 ! root     2008:            if (shorts[7] | shorts[6] | shorts[5] | shorts[4])
        !          2009:              warning ("integer constant out of range");
        !          2010: 
1.1       root     2011:            /* This is simplified by the fact that our constant
                   2012:               is always positive.  */
                   2013:            yylval.ttype
                   2014:              = build_int_2 ((shorts[3]<<24) + (shorts[2]<<16) + (shorts[1]<<8) + shorts[0],
1.1.1.2 ! root     2015:                             0);
1.1       root     2016:     
                   2017:            if (!spec_long && !spec_unsigned
                   2018:                && int_fits_type_p (yylval.ttype, integer_type_node))
                   2019:              type = integer_type_node;
                   2020: 
                   2021:            else if (!spec_long && base != 10
                   2022:                && int_fits_type_p (yylval.ttype, unsigned_type_node))
                   2023:              type = unsigned_type_node;
                   2024: 
                   2025:            else if (!spec_unsigned
                   2026:                && int_fits_type_p (yylval.ttype, long_integer_type_node))
                   2027:              type = long_integer_type_node;
                   2028: 
                   2029:            else
1.1.1.2 ! root     2030:              {
        !          2031:                type = long_unsigned_type_node;
        !          2032:                if (! int_fits_type_p (yylval.ttype, long_unsigned_type_node))
        !          2033:                  warning ("integer constant out of range");
        !          2034:              }
1.1       root     2035:            TREE_TYPE (yylval.ttype) = type;
                   2036:          }
                   2037: 
                   2038:        value = CONSTANT; break;
                   2039:       }
                   2040: 
                   2041:     case '\'':
1.1.1.2 ! root     2042:     char_constant:
        !          2043:       c = getc (finput);
1.1       root     2044:       {
                   2045:        register int code = 0;
                   2046: 
                   2047:       tryagain:
                   2048: 
                   2049:        if (c == '\\')
                   2050:          {
                   2051:            c = readescape ();
                   2052:            if (c < 0)
                   2053:              goto tryagain;
                   2054:          }
1.1.1.2 ! root     2055:        else if (c == '\n')
        !          2056:          {
        !          2057:            if (pedantic)
        !          2058:              warning ("ANSI C forbids newline in character constant");
        !          2059:            lineno++;
        !          2060:          }
        !          2061: 
1.1       root     2062:        code = c;
1.1.1.2 ! root     2063:        token_buffer[1] = c;
        !          2064:        token_buffer[2] = '\'';
        !          2065:        token_buffer[3] = 0;
        !          2066: 
1.1       root     2067:        c = getc (finput);
                   2068:        if (c != '\'')
1.1.1.2 ! root     2069:          error ("malformatted character constant");
1.1       root     2070: 
1.1.1.2 ! root     2071:        /* If char type is signed, sign-extend the constant.  */
        !          2072:        if (TREE_UNSIGNED (char_type_node)
        !          2073:            || ((code >> (BITS_PER_UNIT - 1)) & 1) == 0)
        !          2074:          yylval.ttype = build_int_2 (code & ((1 << BITS_PER_UNIT) - 1), 0);
1.1       root     2075:        else
1.1.1.2 ! root     2076:          yylval.ttype = build_int_2 (code | ((-1) << BITS_PER_UNIT), -1);
1.1       root     2077: 
1.1.1.2 ! root     2078:        TREE_TYPE (yylval.ttype) = integer_type_node;
1.1       root     2079:        value = CONSTANT; break;
                   2080:       }
                   2081: 
                   2082:     case '"':
1.1.1.2 ! root     2083:     string_constant:
1.1       root     2084:       {
1.1.1.2 ! root     2085:        c = getc (finput);
        !          2086:        p = token_buffer + 1;
1.1       root     2087: 
                   2088:        while (c != '"')
                   2089:          {
                   2090:            if (c == '\\')
                   2091:              {
                   2092:                c = readescape ();
                   2093:                if (c < 0)
                   2094:                  goto skipnewline;
                   2095:              }
                   2096:            else if (c == '\n')
                   2097:              {
1.1.1.2 ! root     2098:                if (pedantic)
        !          2099:                  warning ("ANSI C forbids newline in string constant");
1.1       root     2100:                lineno++;
                   2101:              }
                   2102: 
                   2103:            if (p == token_buffer + maxtoken)
1.1.1.2 ! root     2104:              p = extend_token_buffer (p);
1.1       root     2105:            *p++ = c;
                   2106: 
                   2107:          skipnewline:
                   2108:            c = getc (finput);
                   2109:          }
                   2110: 
1.1.1.2 ! root     2111:        *p = 0;
        !          2112: 
        !          2113:        if (wide_flag)
        !          2114:          {
        !          2115:            /* If this is a L"..." wide-string, convert each char
        !          2116:               to an int, making a vector of ints.  */
        !          2117:            int *widebuf = (int *) alloca (p - token_buffer);
        !          2118:            char *p1 = token_buffer + 1;
        !          2119:            for (; p1 == p; p1++)
        !          2120:              widebuf[p1 - token_buffer - 1] = *p1;
        !          2121:            yylval.ttype = build_string ((p - token_buffer) * sizeof (int),
        !          2122:                                         widebuf);
        !          2123:            TREE_TYPE (yylval.ttype) = int_array_type_node;
        !          2124:          }
        !          2125:        else
        !          2126:          {
        !          2127:            yylval.ttype = build_string (p - token_buffer, token_buffer + 1);
        !          2128:            TREE_TYPE (yylval.ttype) = char_array_type_node;
        !          2129:          }
1.1       root     2130: 
1.1.1.2 ! root     2131:        *p++ = '"';
        !          2132:        *p = 0;
1.1       root     2133: 
                   2134:        value = STRING; break;
                   2135:       }
                   2136:       
                   2137:     case '+':
                   2138:     case '-':
                   2139:     case '&':
                   2140:     case '|':
                   2141:     case '<':
                   2142:     case '>':
                   2143:     case '*':
                   2144:     case '/':
                   2145:     case '%':
                   2146:     case '^':
                   2147:     case '!':
                   2148:     case '=':
                   2149:       {
                   2150:        register int c1;
                   2151: 
                   2152:       combine:
                   2153: 
                   2154:        switch (c)
                   2155:          {
                   2156:          case '+':
                   2157:            yylval.code = PLUS_EXPR; break;
                   2158:          case '-':
                   2159:            yylval.code = MINUS_EXPR; break;
                   2160:          case '&':
                   2161:            yylval.code = BIT_AND_EXPR; break;
                   2162:          case '|':
                   2163:            yylval.code = BIT_IOR_EXPR; break;
                   2164:          case '*':
                   2165:            yylval.code = MULT_EXPR; break;
                   2166:          case '/':
                   2167:            yylval.code = TRUNC_DIV_EXPR; break;
                   2168:          case '%':
                   2169:            yylval.code = TRUNC_MOD_EXPR; break;
                   2170:          case '^':
                   2171:            yylval.code = BIT_XOR_EXPR; break;
                   2172:          case LSHIFT:
                   2173:            yylval.code = LSHIFT_EXPR; break;
                   2174:          case RSHIFT:
                   2175:            yylval.code = RSHIFT_EXPR; break;
                   2176:          case '<':
                   2177:            yylval.code = LT_EXPR; break;
                   2178:          case '>':
                   2179:            yylval.code = GT_EXPR; break;
                   2180:          }     
                   2181: 
1.1.1.2 ! root     2182:        token_buffer[1] = c1 = getc (finput);
        !          2183:        token_buffer[2] = 0;
1.1       root     2184: 
                   2185:        if (c1 == '=')
                   2186:          {
                   2187:            switch (c)
                   2188:              {
                   2189:              case '<':
                   2190:                value = ARITHCOMPARE; yylval.code = LE_EXPR; goto done;
                   2191:              case '>':
                   2192:                value = ARITHCOMPARE; yylval.code = GE_EXPR; goto done;
                   2193:              case '!':
                   2194:                value = EQCOMPARE; yylval.code = NE_EXPR; goto done;
                   2195:              case '=':
                   2196:                value = EQCOMPARE; yylval.code = EQ_EXPR; goto done;
                   2197:              } 
                   2198:            value = ASSIGN; goto done;
                   2199:          }
                   2200:        else if (c == c1)
                   2201:          switch (c)
                   2202:            {
                   2203:            case '+':
                   2204:              value = PLUSPLUS; goto done;
                   2205:            case '-':
                   2206:              value = MINUSMINUS; goto done;
                   2207:            case '&':
                   2208:              value = ANDAND; goto done;
                   2209:            case '|':
                   2210:              value = OROR; goto done;
                   2211:            case '<':
                   2212:              c = LSHIFT;
                   2213:              goto combine;
                   2214:            case '>':
                   2215:              c = RSHIFT;
                   2216:              goto combine;
                   2217:            }
                   2218:        else if ((c == '-') && (c1 == '>'))
                   2219:          { value = POINTSAT; goto done; }
                   2220:        ungetc (c1, finput);
1.1.1.2 ! root     2221:        token_buffer[1] = 0;
1.1       root     2222: 
                   2223:        if ((c == '<') || (c == '>'))
                   2224:          value = ARITHCOMPARE;
                   2225:        else value = c;
                   2226:        goto done;
                   2227:       }
                   2228: 
                   2229:     default:
                   2230:       value = c;
                   2231:     }
                   2232: 
                   2233: done:
                   2234:   yylloc.last_line = lineno;
                   2235: 
1.1.1.2 ! root     2236:   return value;
1.1       root     2237: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.