home *** CD-ROM | disk | FTP | other *** search
/ Education Sampler 1992 [NeXTSTEP] / Education_1992_Sampler.iso / NeXT / GnuSource / cc-61.0.1 / cc / c-parse.y < prev    next >
Text File  |  1991-10-01  |  84KB  |  3,205 lines

  1. /* YACC parser for C syntax.
  2.    Copyright (C) 1987, 1988, 1989 Free Software Foundation, Inc.
  3.  
  4. This file is part of GNU CC.
  5.  
  6. GNU CC is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2, or (at your option)
  9. any later version.
  10.  
  11. GNU CC is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with GNU CC; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20.  
  21. /* To whomever it may concern: I have heard that such a thing was once
  22. written by AT&T, but I have never seen it.  */
  23.  
  24. %expect 8
  25.  
  26. /* These are the 8 conflicts you should get in parse.output;
  27.    the state numbers may vary if minor changes in the grammar are made.
  28.  
  29. State 41 contains 1 shift/reduce conflict.  (Two ways to recover from error.)
  30. State 92 contains 1 shift/reduce conflict.  (Two ways to recover from error.)
  31. State 99 contains 1 shift/reduce conflict.  (Two ways to recover from error.)
  32. State 103 contains 1 shift/reduce conflict.  (Two ways to recover from error.)
  33. State 119 contains 1 shift/reduce conflict.  (See comment at component_decl.)
  34. State 183 contains 1 shift/reduce conflict.  (Two ways to recover from error.)
  35. State 193 contains 1 shift/reduce conflict.  (Two ways to recover from error.)
  36. State 199 contains 1 shift/reduce conflict.  (Two ways to recover from error.)
  37. */
  38.  
  39. %{
  40. #include <stdio.h>
  41. #include <errno.h>
  42. #include <setjmp.h>
  43.  
  44. #include "config.h"
  45. #include "tree.h"
  46. #include "input.h"
  47. #include "c-parse.h"
  48. #include "c-tree.h"
  49. #include "flags.h"
  50.  
  51. #ifdef MULTIBYTE_CHARS
  52. #include <stdlib.h>
  53. #include <locale.h>
  54. #endif
  55.  
  56. #ifndef errno
  57. extern int errno;
  58. #endif
  59.  
  60. void yyerror ();
  61.  
  62. /* Like YYERROR but do call yyerror.  */
  63. #define YYERROR1 { yyerror ("syntax error"); YYERROR; }
  64.  
  65. static void position_after_white_space ();
  66.  
  67. /* The elements of `ridpointers' are identifier nodes
  68.    for the reserved type names and storage classes.
  69.    It is indexed by a RID_... value.  */
  70.  
  71. tree ridpointers[(int) RID_MAX];
  72. #define NORID RID_UNUSED
  73.  
  74. /* Cause the `yydebug' variable to be defined.  */
  75. #define YYDEBUG 1
  76. %}
  77.  
  78. %start program
  79.  
  80. %union {long itype; tree ttype; enum tree_code code;
  81.     char *filename; int lineno; }
  82.  
  83. /* All identifiers that are not reserved words
  84.    and are not declared typedefs in the current block */
  85. %token IDENTIFIER
  86.  
  87. /* All identifiers that are declared typedefs in the current block.
  88.    In some contexts, they are treated just like IDENTIFIER,
  89.    but they can also serve as typespecs in declarations.  */
  90. %token TYPENAME
  91.  
  92. /* Reserved words that specify storage class.
  93.    yylval contains an IDENTIFIER_NODE which indicates which one.  */
  94. %token SCSPEC
  95.  
  96. /* Reserved words that specify type.
  97.    yylval contains an IDENTIFIER_NODE which indicates which one.  */
  98. %token TYPESPEC
  99.  
  100. /* Reserved words that qualify type: "const" or "volatile".
  101.    yylval contains an IDENTIFIER_NODE which indicates which one.  */
  102. %token TYPE_QUAL
  103.  
  104. /* Character or numeric constants.
  105.    yylval is the node for the constant.  */
  106. %token CONSTANT
  107.  
  108. /* String constants in raw form.
  109.    yylval is a STRING_CST node.  */
  110. %token STRING
  111.  
  112. /* "...", used for functions with variable arglists.  */
  113. %token ELLIPSIS
  114.  
  115. /* the reserved words */
  116. %token SIZEOF ENUM STRUCT UNION IF ELSE WHILE DO FOR SWITCH CASE DEFAULT
  117. %token BREAK CONTINUE RETURN GOTO ASM TYPEOF ALIGNOF ALIGN
  118. %token ATTRIBUTE EXTENSION LABEL
  119.  
  120. /* Add precedence rules to solve dangling else s/r conflict */
  121. %nonassoc IF
  122. %nonassoc ELSE
  123.  
  124. /* Define the operator tokens and their precedences.
  125.    The value is an integer because, if used, it is the tree code
  126.    to use in the expression made from the operator.  */
  127.  
  128. %right <code> ASSIGN '='
  129. %right <code> '?' ':'
  130. %left <code> OROR
  131. %left <code> ANDAND
  132. %left <code> '|'
  133. %left <code> '^'
  134. %left <code> '&'
  135. %left <code> EQCOMPARE
  136. %left <code> ARITHCOMPARE
  137. %left <code> LSHIFT RSHIFT
  138. %left <code> '+' '-'
  139. %left <code> '*' '/' '%'
  140. %right <code> UNARY PLUSPLUS MINUSMINUS
  141. %left HYPERUNARY
  142. %left <code> POINTSAT '.' '(' '['
  143.  
  144. %type <code> unop
  145.  
  146. %type <ttype> identifier IDENTIFIER TYPENAME CONSTANT expr nonnull_exprlist exprlist
  147. %type <ttype> expr_no_commas cast_expr unary_expr primary string STRING
  148. %type <ttype> typed_declspecs reserved_declspecs
  149. %type <ttype> typed_typespecs reserved_typespecquals
  150. %type <ttype> declmods typespec typespecqual_reserved
  151. %type <ttype> SCSPEC TYPESPEC TYPE_QUAL nonempty_type_quals maybe_type_qual
  152. %type <ttype> initdecls notype_initdecls initdcl notype_initdcl
  153. %type <ttype> init initlist maybeasm
  154. %type <ttype> asm_operands nonnull_asm_operands asm_operand asm_clobbers
  155. %type <ttype> maybe_attribute attribute_list attrib
  156.  
  157. %type <ttype> compstmt
  158.  
  159. %type <ttype> declarator
  160. %type <ttype> notype_declarator after_type_declarator
  161. %type <ttype> parm_declarator
  162.  
  163. %type <ttype> structsp component_decl_list component_decl_list2
  164. %type <ttype> component_decl components component_declarator
  165. %type <ttype> enumlist enumerator
  166. %type <ttype> typename absdcl absdcl1 type_quals
  167. %type <ttype> xexpr parms parm identifiers
  168.  
  169. %type <ttype> parmlist parmlist_1 parmlist_2
  170. %type <ttype> parmlist_or_identifiers parmlist_or_identifiers_1
  171.  
  172. %type <itype> setspecs
  173.  
  174. %type <filename> save_filename
  175. %type <lineno> save_lineno
  176.  
  177. %{
  178. /* the declaration found for the last IDENTIFIER token read in.
  179.    yylex must look this up to detect typedefs, which get token type TYPENAME,
  180.    so it is left around in case the identifier is not a typedef but is
  181.    used in a context which makes it a reference to a variable.  */
  182. static tree lastiddecl;
  183.  
  184. static tree make_pointer_declarator ();
  185. static void reinit_parse_for_function ();
  186.  
  187. /* Number of statements (loosely speaking) seen so far.  */
  188. static int stmt_count;
  189.  
  190. /* Input file and line number of the end of the body of last simple_if;
  191.    used by the stmt-rule immediately after simple_if returns.  */
  192. static char *if_stmt_file;
  193. static int if_stmt_line;
  194.  
  195. /* List of types and structure classes of the current declaration.  */
  196. tree current_declspecs;
  197.  
  198. /* Stack of saved values of current_declspecs.  */
  199. tree declspec_stack;
  200.  
  201. int undeclared_variable_notice;    /* 1 if we explained undeclared var errors.  */
  202.  
  203. static int yylex ();
  204.  
  205. /* Tell yyparse how to print a token's value, if yydebug is set.  */
  206.  
  207. #define YYPRINT(FILE,YYCHAR,YYLVAL) yyprint(FILE,YYCHAR,YYLVAL)
  208.  
  209. static void
  210. yyprint (file, yychar, yylval)
  211.      FILE *file;
  212.      int yychar;
  213.      YYSTYPE yylval;
  214. {
  215.   tree t;
  216.   switch (yychar)
  217.     {
  218.     case IDENTIFIER:
  219.     case TYPENAME:
  220.       t = yylval.ttype;
  221.       if (IDENTIFIER_POINTER (t))
  222.     fprintf (file, " `%s'", IDENTIFIER_POINTER (t));
  223.       break;
  224.  
  225.     case CONSTANT:
  226.       t = yylval.ttype;
  227.       if (TREE_CODE (t) == INTEGER_CST)
  228.     fprintf (file, " 0x%8x%8x", TREE_INT_CST_HIGH (t),
  229.          TREE_INT_CST_LOW (t));
  230.       break;
  231.     }
  232. }
  233.  
  234. /* Sets the value of the 'yydebug' varable to VALUE.
  235.    This is a function so we don't have to have YYDEBUG defined
  236.    in order to build the compiler.  */
  237. void
  238. set_yydebug (value)
  239.      int value;
  240. {
  241. #if YYDEBUG != 0
  242.   extern int yydebug;
  243.   yydebug = value;
  244. #else
  245.   warning ("YYDEBUG not defined.");
  246. #endif
  247. }
  248. %}
  249.  
  250. %%
  251. program: /* empty */
  252.         { if (pedantic)
  253.             pedwarn ("ANSI C forbids an empty source file"); }
  254.     | extdefs
  255.     ;
  256.  
  257. /* the reason for the strange actions in this rule
  258.  is so that notype_initdecls when reached via datadef
  259.  can find a valid list of type and sc specs in $0. */
  260.  
  261. extdefs:
  262.     {$<ttype>$ = NULL_TREE; } extdef
  263.     | extdefs {$<ttype>$ = NULL_TREE; } extdef
  264.     ;
  265.  
  266. extdef:
  267.     fndef
  268.     | datadef
  269.     | ASM '(' string ')' ';'
  270.         { if (pedantic)
  271.             pedwarn ("ANSI C forbids use of `asm' keyword");
  272.           if (TREE_CHAIN ($3)) $3 = combine_strings ($3);
  273.           assemble_asm ($3); }
  274.     ;
  275.  
  276. datadef:
  277.       setspecs notype_initdecls ';'
  278.         { if (pedantic)
  279.             error ("ANSI C forbids data definition with no type or storage class");
  280.           else if (!flag_traditional)
  281.             warning ("data definition has no type or storage class"); }
  282.         | declmods setspecs notype_initdecls ';'
  283.       {}
  284.     | typed_declspecs setspecs initdecls ';'
  285.       {}
  286.         | declmods ';'
  287.       { error ("empty declaration"); }
  288.     | typed_declspecs ';'
  289.       { shadow_tag ($1); }
  290.     | error ';'
  291.     | error '}'
  292.     | ';'
  293.         { if (pedantic)
  294.             pedwarn ("ANSI C does not allow extra `;' outside of a function"); }
  295.     ;
  296.  
  297. fndef:
  298.       typed_declspecs setspecs declarator
  299.         { if (! start_function ($1, $3, 0))
  300.             YYERROR1;
  301.           reinit_parse_for_function (); }
  302.       xdecls
  303.         { store_parm_decls (); }
  304.       compstmt_or_error
  305.         { finish_function (0); }
  306.     | typed_declspecs setspecs declarator error
  307.         { }
  308.     | declmods setspecs notype_declarator
  309.         { if (! start_function ($1, $3, 0))
  310.             YYERROR1;
  311.           reinit_parse_for_function (); }
  312.       xdecls
  313.         { store_parm_decls (); }
  314.       compstmt_or_error
  315.         { finish_function (0); }
  316.     | declmods setspecs notype_declarator error
  317.         { }
  318.     | setspecs notype_declarator
  319.         { if (! start_function (0, $2, 0))
  320.             YYERROR1;
  321.           reinit_parse_for_function (); }
  322.       xdecls
  323.         { store_parm_decls (); }
  324.       compstmt_or_error
  325.         { finish_function (0); }
  326.     | setspecs notype_declarator error
  327.         { }
  328.     ;
  329.  
  330. identifier:
  331.     IDENTIFIER
  332.     | TYPENAME
  333.     ;
  334.  
  335. unop:     '&'
  336.         { $$ = ADDR_EXPR; }
  337.     | '-'
  338.         { $$ = NEGATE_EXPR; }
  339.     | '+'
  340.         { $$ = CONVERT_EXPR; }
  341.     | PLUSPLUS
  342.         { $$ = PREINCREMENT_EXPR; }
  343.     | MINUSMINUS
  344.         { $$ = PREDECREMENT_EXPR; }
  345.     | '~'
  346.         { $$ = BIT_NOT_EXPR; }
  347.     | '!'
  348.         { $$ = TRUTH_NOT_EXPR; }
  349.     ;
  350.  
  351. expr:    nonnull_exprlist
  352.         { $$ = build_compound_expr ($1); }
  353.     ;
  354.  
  355. exprlist:
  356.       /* empty */
  357.         { $$ = NULL_TREE; }
  358.     | nonnull_exprlist
  359.     ;
  360.  
  361. nonnull_exprlist:
  362.     expr_no_commas
  363.         { $$ = build_tree_list (NULL_TREE, $1); }
  364.     | nonnull_exprlist ',' expr_no_commas
  365.         { chainon ($1, build_tree_list (NULL_TREE, $3)); }
  366.     ;
  367.  
  368. unary_expr:
  369.     primary
  370.     | '*' cast_expr   %prec UNARY
  371.         { $$ = build_indirect_ref ($2, "unary *"); }
  372.     /* __extension__ turns off -pedantic for following primary.  */
  373.     | EXTENSION
  374.         { $<itype>1 = pedantic;
  375.           pedantic = 0; }
  376.       cast_expr      %prec UNARY
  377.         { $$ = $3;
  378.           pedantic = $<itype>1; }
  379.     | unop cast_expr  %prec UNARY
  380.         { $$ = build_unary_op ($1, $2, 0); }
  381.     /* Refer to the address of a label as a pointer.  */
  382.     | ANDAND identifier
  383.         { tree label = lookup_label ($2);
  384.           TREE_USED (label) = 1;
  385.           $$ = build1 (ADDR_EXPR, ptr_type_node, label);
  386.           TREE_CONSTANT ($$) = 1; }
  387. /* This seems to be impossible on some machines, so let's turn it off.
  388.     | '&' ELLIPSIS
  389.         { tree types = TYPE_ARG_TYPES (TREE_TYPE (current_function_decl));
  390.           $$ = error_mark_node;
  391.           if (TREE_VALUE (tree_last (types)) == void_type_node)
  392.             error ("`&...' used in function with fixed number of arguments");
  393.           else
  394.             {
  395.               if (pedantic)
  396.             pedwarn ("ANSI C forbids `&...'");
  397.               $$ = tree_last (DECL_ARGUMENTS (current_function_decl));
  398.               $$ = build_unary_op (ADDR_EXPR, $$, 0);
  399.             } }
  400. */
  401.     | SIZEOF unary_expr  %prec UNARY
  402.         { if (TREE_CODE ($2) == COMPONENT_REF
  403.               && DECL_BIT_FIELD (TREE_OPERAND ($2, 1)))
  404.             error ("`sizeof' applied to a bit-field");
  405.           $$ = c_sizeof (TREE_TYPE ($2)); }
  406.     | SIZEOF '(' typename ')'  %prec HYPERUNARY
  407.         { $$ = c_sizeof (groktypename ($3)); }
  408.     | ALIGNOF unary_expr  %prec UNARY
  409.         { $$ = c_alignof_expr ($2); }
  410.     | ALIGNOF '(' typename ')'  %prec HYPERUNARY
  411.         { $$ = c_alignof (groktypename ($3)); }
  412.     ;
  413.  
  414. cast_expr:
  415.     unary_expr
  416.     | '(' typename ')' cast_expr  %prec UNARY
  417.         { tree type = groktypename ($2);
  418.           $$ = build_c_cast (type, $4); }
  419.     | '(' typename ')' '{' initlist maybecomma '}'  %prec UNARY
  420.         { tree type = groktypename ($2);
  421.           if (pedantic)
  422.             pedwarn ("ANSI C forbids constructor expressions");
  423.           $$ = digest_init (type, build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($5)), 0, 0, 0);
  424.           if (TREE_CODE (type) == ARRAY_TYPE && TYPE_SIZE (type) == 0)
  425.             {
  426.               int failure = complete_array_type (type, $$, 1);
  427.               if (failure)
  428.             abort ();
  429.             }
  430.         }
  431.     ;
  432.  
  433. expr_no_commas:
  434.       cast_expr
  435.     | expr_no_commas '+' expr_no_commas
  436.         { $$ = parser_build_binary_op ($2, $1, $3); }
  437.     | expr_no_commas '-' expr_no_commas
  438.         { $$ = parser_build_binary_op ($2, $1, $3); }
  439.     | expr_no_commas '*' expr_no_commas
  440.         { $$ = parser_build_binary_op ($2, $1, $3); }
  441.     | expr_no_commas '/' expr_no_commas
  442.         { $$ = parser_build_binary_op ($2, $1, $3); }
  443.     | expr_no_commas '%' expr_no_commas
  444.         { $$ = parser_build_binary_op ($2, $1, $3); }
  445.     | expr_no_commas LSHIFT expr_no_commas
  446.         { $$ = parser_build_binary_op ($2, $1, $3); }
  447.     | expr_no_commas RSHIFT expr_no_commas
  448.         { $$ = parser_build_binary_op ($2, $1, $3); }
  449.     | expr_no_commas ARITHCOMPARE expr_no_commas
  450.         { $$ = parser_build_binary_op ($2, $1, $3); }
  451.     | expr_no_commas EQCOMPARE expr_no_commas
  452.         { $$ = parser_build_binary_op ($2, $1, $3); }
  453.     | expr_no_commas '&' expr_no_commas
  454.         { $$ = parser_build_binary_op ($2, $1, $3); }
  455.     | expr_no_commas '|' expr_no_commas
  456.         { $$ = parser_build_binary_op ($2, $1, $3); }
  457.     | expr_no_commas '^' expr_no_commas
  458.         { $$ = parser_build_binary_op ($2, $1, $3); }
  459.     | expr_no_commas ANDAND expr_no_commas
  460.         { $$ = parser_build_binary_op (TRUTH_ANDIF_EXPR, $1, $3); }
  461.     | expr_no_commas OROR expr_no_commas
  462.         { $$ = parser_build_binary_op (TRUTH_ORIF_EXPR, $1, $3); }
  463.     | expr_no_commas '?' xexpr ':' expr_no_commas
  464.         { $$ = build_conditional_expr ($1, $3, $5); }
  465.     | expr_no_commas '=' expr_no_commas
  466.         { $$ = build_modify_expr ($1, NOP_EXPR, $3); }
  467.     | expr_no_commas ASSIGN expr_no_commas
  468.         { $$ = build_modify_expr ($1, $2, $3); }
  469.     ;
  470.  
  471. primary:
  472.     IDENTIFIER
  473.         {
  474.           tree context;
  475.  
  476.           $$ = lastiddecl;
  477.           if (!$$ || $$ == error_mark_node)
  478.             {
  479.               if (yychar == YYEMPTY)
  480.             yychar = YYLEX;
  481.               if (yychar == '(')
  482.             {
  483.               $$ = implicitly_declare ($1);
  484.               assemble_external ($$);
  485.               TREE_USED ($$) = 1;
  486.             }
  487.               else if (current_function_decl == 0)
  488.             {
  489.               error ("`%s' undeclared, outside of functions",
  490.                  IDENTIFIER_POINTER ($1));
  491.               $$ = error_mark_node;
  492.             }
  493.               else
  494.             {
  495.               if (IDENTIFIER_GLOBAL_VALUE ($1) != error_mark_node
  496.                   || IDENTIFIER_ERROR_LOCUS ($1) != current_function_decl)
  497.                 {
  498.                   error ("`%s' undeclared (first use this function)",
  499.                      IDENTIFIER_POINTER ($1));
  500.  
  501.                   if (! undeclared_variable_notice)
  502.                 {
  503.                   error ("(Each undeclared identifier is reported only once");
  504.                   error ("for each function it appears in.)");
  505.                   undeclared_variable_notice = 1;
  506.                 }
  507.                 }
  508.               $$ = error_mark_node;
  509.               /* Prevent repeated error messages.  */
  510.               IDENTIFIER_GLOBAL_VALUE ($1) = error_mark_node;
  511.               IDENTIFIER_ERROR_LOCUS ($1) = current_function_decl;
  512.             }
  513.             }
  514.           else if (! TREE_USED ($$))
  515.             {
  516.               if (TREE_EXTERNAL ($$))
  517.             assemble_external ($$);
  518.               TREE_USED ($$) = 1;
  519.             }
  520.           if (TREE_CODE ($$) == CONST_DECL)
  521.             $$ = DECL_INITIAL ($$);
  522.         }
  523.     | CONSTANT
  524.     | string
  525.         { $$ = combine_strings ($1); }
  526.     | '(' expr ')'
  527.         { char class = TREE_CODE_CLASS (TREE_CODE ($2));
  528.           if (class == 'e' || class == '1'
  529.               || class == '2' || class == '<')
  530.             C_SET_EXP_ORIGINAL_CODE ($2, ERROR_MARK);
  531.           $$ = $2; }
  532.     | '(' error ')'
  533.         { $$ = error_mark_node; }
  534.     | '('
  535.         { if (current_function_decl == 0)
  536.             {
  537.               error ("braced-group within expression allowed only inside a function");
  538.               YYERROR;
  539.             }
  540.           /* We must force a BLOCK for this level
  541.              so that, if it is not expanded later,
  542.              there is a way to turn off the entire subtree of blocks
  543.              that are contained in it.  */
  544.           keep_next_level ();
  545.           push_label_level ();
  546.           $<ttype>$ = expand_start_stmt_expr (); }
  547.       compstmt ')'
  548.         { tree rtl_exp;
  549.           if (pedantic)
  550.             pedwarn ("ANSI C forbids braced-groups within expressions");
  551.           pop_label_level ();
  552.           rtl_exp = expand_end_stmt_expr ($<ttype>2);
  553.           /* The statements have side effects, so the group does.  */
  554.           TREE_SIDE_EFFECTS (rtl_exp) = 1;
  555.  
  556.           /* Make a BIND_EXPR for the BLOCK already made.  */
  557.           $$ = build (BIND_EXPR, TREE_TYPE (rtl_exp),
  558.                   NULL_TREE, rtl_exp, $3);
  559.         }
  560.     | primary '(' exprlist ')'   %prec '.'
  561.         { $$ = build_function_call ($1, $3); }
  562.     | primary '[' expr ']'   %prec '.'
  563.         { $$ = build_array_ref ($1, $3); }
  564.     | primary '.' identifier
  565.         { $$ = build_component_ref ($1, $3); }
  566.     | primary POINTSAT identifier
  567.         { $$ = build_component_ref (build_indirect_ref ($1, "->"), $3); }
  568.     | primary PLUSPLUS
  569.         { $$ = build_unary_op (POSTINCREMENT_EXPR, $1, 0); }
  570.     | primary MINUSMINUS
  571.         { $$ = build_unary_op (POSTDECREMENT_EXPR, $1, 0); }
  572.     ;
  573.  
  574. /* Produces a STRING_CST with perhaps more STRING_CSTs chained onto it.  */
  575. string:
  576.       STRING
  577.     | string STRING
  578.         { $$ = chainon ($1, $2); }
  579.     ;
  580.  
  581. xdecls:
  582.     /* empty */
  583.     | decls
  584.     | decls ELLIPSIS
  585.         /* ... is used here to indicate a varargs function.  */
  586.         { c_mark_varargs ();
  587.           if (pedantic)
  588.             pedwarn ("ANSI C does not permit use of `varargs.h'"); }
  589.     ;
  590.  
  591. /* This combination which saves a lineno before a decl
  592.    is the normal thing to use, rather than decl itself.
  593.    This is to avoid shift/reduce conflicts in contexts
  594.    where statement labels are allowed.  */
  595. lineno_decl:
  596.       save_filename save_lineno decl
  597.         { }
  598.     ;
  599.  
  600. decls:
  601.     lineno_decl
  602.     | errstmt
  603.     | decls lineno_decl
  604.     | lineno_decl errstmt
  605.     ;
  606.  
  607. /* records the type and storage class specs to use for processing
  608.    the declarators that follow.
  609.    Maintains a stack of outer-level values of current_declspecs,
  610.    for the sake of parm declarations nested in function declarators.  */
  611. setspecs: /* empty */
  612.         { $$ = suspend_momentary ();
  613.           pending_xref_error ();
  614.           declspec_stack = tree_cons (0, current_declspecs,
  615.                           declspec_stack);
  616.           current_declspecs = $<ttype>0; }
  617.     ;
  618.  
  619. decl:
  620.     typed_declspecs setspecs initdecls ';'
  621.         { current_declspecs = TREE_VALUE (declspec_stack);
  622.           declspec_stack = TREE_CHAIN (declspec_stack);
  623.           resume_momentary ($2); }
  624.     | declmods setspecs notype_initdecls ';'
  625.         { current_declspecs = TREE_VALUE (declspec_stack);
  626.           declspec_stack = TREE_CHAIN (declspec_stack);
  627.           resume_momentary ($2); }
  628.     | typed_declspecs setspecs nested_function
  629.         { current_declspecs = TREE_VALUE (declspec_stack);
  630.           declspec_stack = TREE_CHAIN (declspec_stack);
  631.           resume_momentary ($2); }
  632.     | declmods setspecs notype_nested_function
  633.         { current_declspecs = TREE_VALUE (declspec_stack);
  634.           declspec_stack = TREE_CHAIN (declspec_stack);
  635.           resume_momentary ($2); }
  636.     | typed_declspecs ';'
  637.         { shadow_tag ($1); }
  638.     | declmods ';'
  639.         { pedwarn ("empty declaration"); }
  640.     ;
  641.  
  642. /* Declspecs which contain at least one type specifier or typedef name.
  643.    (Just `const' or `volatile' is not enough.)
  644.    A typedef'd name following these is taken as a name to be declared.  */
  645.  
  646. typed_declspecs:
  647.       typespec reserved_declspecs
  648.         { $$ = tree_cons (NULL_TREE, $1, $2); }
  649.     | declmods typespec reserved_declspecs
  650.         { $$ = chainon ($3, tree_cons (NULL_TREE, $2, $1)); }
  651.     ;
  652.  
  653. reserved_declspecs:  /* empty */
  654.         { $$ = NULL_TREE; }
  655.     | reserved_declspecs typespecqual_reserved
  656.         { $$ = tree_cons (NULL_TREE, $2, $1); }
  657.     | reserved_declspecs SCSPEC
  658.         { $$ = tree_cons (NULL_TREE, $2, $1); }
  659.     ;
  660.  
  661. /* List of just storage classes and type modifiers.
  662.    A declaration can start with just this, but then it cannot be used
  663.    to redeclare a typedef-name.  */
  664.  
  665. declmods:
  666.       TYPE_QUAL
  667.         { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); }
  668.     | SCSPEC
  669.         { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); }
  670.     | declmods TYPE_QUAL
  671.         { $$ = tree_cons (NULL_TREE, $2, $1); }
  672.     | declmods SCSPEC
  673.         { $$ = tree_cons (NULL_TREE, $2, $1); }
  674.     ;
  675.  
  676.  
  677. /* Used instead of declspecs where storage classes are not allowed
  678.    (that is, for typenames and structure components).
  679.    Don't accept a typedef-name if anything but a modifier precedes it.  */
  680.  
  681. typed_typespecs:
  682.       typespec reserved_typespecquals
  683.         { $$ = tree_cons (NULL_TREE, $1, $2); }
  684.     | nonempty_type_quals typespec reserved_typespecquals
  685.         { $$ = chainon ($3, tree_cons (NULL_TREE, $2, $1)); }
  686.     ;
  687.  
  688. reserved_typespecquals:  /* empty */
  689.         { $$ = NULL_TREE; }
  690.     | reserved_typespecquals typespecqual_reserved
  691.         { $$ = tree_cons (NULL_TREE, $2, $1); }
  692.     ;
  693.  
  694. /* A typespec (but not a type qualifier).
  695.    Once we have seen one of these in a declaration,
  696.    if a typedef name appears then it is being redeclared.  */
  697.  
  698. typespec: TYPESPEC
  699.     | structsp
  700.     | TYPENAME
  701.         { /* For a typedef name, record the meaning, not the name.
  702.              In case of `foo foo, bar;'.  */
  703.           $$ = lookup_name ($1); }
  704.     | TYPEOF '(' expr ')'
  705.         { $$ = TREE_TYPE ($3);
  706.           if (pedantic)
  707.             pedwarn ("ANSI C forbids `typeof'"); }
  708.     | TYPEOF '(' typename ')'
  709.         { $$ = groktypename ($3);
  710.           if (pedantic)
  711.             pedwarn ("ANSI C forbids `typeof'"); }
  712.     ;
  713.  
  714. /* A typespec that is a reserved word, or a type qualifier.  */
  715.  
  716. typespecqual_reserved: TYPESPEC
  717.     | TYPE_QUAL
  718.     | structsp
  719.     ;
  720.  
  721. initdecls:
  722.     initdcl
  723.     | initdecls ',' initdcl
  724.     ;
  725.  
  726. notype_initdecls:
  727.     notype_initdcl
  728.     | notype_initdecls ',' initdcl
  729.     ;
  730.  
  731. maybeasm:
  732.       /* empty */
  733.         { $$ = NULL_TREE; }
  734.     | ASM '(' string ')'
  735.         { if (TREE_CHAIN ($3)) $3 = combine_strings ($3);
  736.           $$ = $3;
  737.           if (pedantic)
  738.             pedwarn ("ANSI C forbids use of `asm' keyword");
  739.         }
  740.     ;
  741.  
  742. initdcl:
  743.       declarator maybeasm maybe_attribute '='
  744.         { $<ttype>$ = start_decl ($1, current_declspecs, 1); }
  745.       init
  746. /* Note how the declaration of the variable is in effect while its init is parsed! */
  747.         { decl_attributes ($<ttype>5, $3);
  748.           finish_decl ($<ttype>5, $6, $2); }
  749.     | declarator maybeasm maybe_attribute
  750.         { tree d = start_decl ($1, current_declspecs, 0);
  751.           decl_attributes (d, $3);
  752.           finish_decl (d, NULL_TREE, $2); }
  753.     ;
  754.  
  755. notype_initdcl:
  756.       notype_declarator maybeasm maybe_attribute '='
  757.         { $<ttype>$ = start_decl ($1, current_declspecs, 1); }
  758.       init
  759. /* Note how the declaration of the variable is in effect while its init is parsed! */
  760.         { decl_attributes ($<ttype>5, $3);
  761.           finish_decl ($<ttype>5, $6, $2); }
  762.     | notype_declarator maybeasm maybe_attribute
  763.         { tree d = start_decl ($1, current_declspecs, 0);
  764.           decl_attributes (d, $3);
  765.           finish_decl (d, NULL_TREE, $2); }
  766.     ;
  767. /* the * rules are dummies to accept the Apollo extended syntax
  768.    so that the header files compile. */
  769. maybe_attribute:
  770.     /* empty */
  771.         { $$ = NULL_TREE; }
  772.     | ATTRIBUTE '(' '(' attribute_list ')' ')'
  773.         { $$ = $4; }
  774.     ;
  775.  
  776. attribute_list
  777.     : attrib
  778.     { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); }
  779.     | attribute_list ',' attrib
  780.     { $$ = tree_cons (NULL_TREE, $3, $1); }
  781.     ;
  782.  
  783. attrib
  784.     : IDENTIFIER
  785.     { warning ("`%s' attribute directive ignored",
  786.            IDENTIFIER_POINTER ($1));
  787.       $$ = $1; }
  788.     | IDENTIFIER '(' CONSTANT ')'
  789.     { /* if not "aligned(n)", then issue warning */
  790.       if (strcmp (IDENTIFIER_POINTER ($1), "aligned") != 0
  791.           || TREE_CODE ($3) != INTEGER_CST)
  792.         {
  793.           warning ("`%s' attribute directive ignored",
  794.                IDENTIFIER_POINTER ($1));
  795.           $$ = $1;
  796.         }
  797.       else
  798.         $$ = tree_cons ($1, $3); }
  799.     | IDENTIFIER '(' IDENTIFIER ',' CONSTANT ',' CONSTANT ')'
  800.     { /* if not "format(...)", then issue warning */
  801.       if (strcmp (IDENTIFIER_POINTER ($1), "format") != 0
  802.           || TREE_CODE ($5) != INTEGER_CST
  803.           || TREE_CODE ($7) != INTEGER_CST)
  804.         {
  805.           warning ("`%s' attribute directive ignored",
  806.                IDENTIFIER_POINTER ($1));
  807.           $$ = $1;
  808.         }
  809.       else
  810.         $$ = tree_cons ($1, tree_cons ($3, tree_cons ($5, $7))); }
  811.     ;
  812.  
  813. init:
  814.     expr_no_commas
  815.     | '{' '}'
  816.         { $$ = build_nt (CONSTRUCTOR, NULL_TREE, NULL_TREE);
  817.           if (pedantic)
  818.             pedwarn ("ANSI C forbids empty initializer braces"); }
  819.     | '{' initlist '}'
  820.         { $$ = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($2)); }
  821.     | '{' initlist ',' '}'
  822.         { $$ = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($2)); }
  823.     | error
  824.         { $$ = NULL_TREE; }
  825.     ;
  826.  
  827. /* This chain is built in reverse order,
  828.    and put in forward order where initlist is used.  */
  829. initlist:
  830.       init
  831.         { $$ = build_tree_list (NULL_TREE, $1); }
  832.     | initlist ',' init
  833.         { $$ = tree_cons (NULL_TREE, $3, $1); }
  834.     /* These are for labeled elements.  */
  835.     | '[' expr_no_commas ']' init
  836.         { $$ = build_tree_list ($2, $4); }
  837.     | initlist ',' '[' expr_no_commas ']' init
  838.         { $$ = tree_cons ($4, $6, $1); }
  839.     | identifier ':' init
  840.         { $$ = build_tree_list ($1, $3); }
  841.     | initlist ',' identifier ':' init
  842.         { $$ = tree_cons ($3, $5, $1); }
  843.     ;
  844.  
  845. nested_function:
  846.       declarator
  847.         { push_c_function_context ();
  848.           if (! start_function (current_declspecs, $1, 1))
  849.             {
  850.               pop_c_function_context ();
  851.               YYERROR1;
  852.             }
  853.           reinit_parse_for_function ();
  854.           store_parm_decls (); }
  855. /* This used to use compstmt_or_error.
  856.    That caused a bug with input `f(g) int g {}',
  857.    where the use of YYERROR1 above caused an error
  858.    which then was handled by compstmt_or_error.
  859.    There followed a repeated execution of that same rule,
  860.    which called YYERROR1 again, and so on.  */
  861.       compstmt
  862.         { finish_function (1);
  863.           pop_c_function_context (); }
  864.     ;
  865.  
  866. notype_nested_function:
  867.       notype_declarator
  868.         { push_c_function_context ();
  869.           if (! start_function (current_declspecs, $1, 1))
  870.             {
  871.               pop_c_function_context ();
  872.               YYERROR1;
  873.             }
  874.           reinit_parse_for_function ();
  875.           store_parm_decls (); }
  876. /* This used to use compstmt_or_error.
  877.    That caused a bug with input `f(g) int g {}',
  878.    where the use of YYERROR1 above caused an error
  879.    which then was handled by compstmt_or_error.
  880.    There followed a repeated execution of that same rule,
  881.    which called YYERROR1 again, and so on.  */
  882.       compstmt
  883.         { finish_function (1);
  884.           pop_c_function_context (); }
  885.     ;
  886.  
  887. /* Any kind of declarator (thus, all declarators allowed
  888.    after an explicit typespec).  */
  889.  
  890. declarator:
  891.       after_type_declarator
  892.     | notype_declarator
  893.     ;
  894.  
  895. /* A declarator that is allowed only after an explicit typespec.  */
  896.  
  897. after_type_declarator:
  898.       '(' after_type_declarator ')'
  899.         { $$ = $2; }
  900.     | after_type_declarator '(' parmlist_or_identifiers  %prec '.'
  901.         { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); }
  902. /*    | after_type_declarator '(' error ')'  %prec '.'
  903.         { $$ = build_nt (CALL_EXPR, $1, NULL_TREE, NULL_TREE);
  904.           poplevel (0, 0, 0); }  */
  905.     | after_type_declarator '[' expr ']'  %prec '.'
  906.         { $$ = build_nt (ARRAY_REF, $1, $3); }
  907.     | after_type_declarator '[' ']'  %prec '.'
  908.         { $$ = build_nt (ARRAY_REF, $1, NULL_TREE); }
  909.     | '*' type_quals after_type_declarator  %prec UNARY
  910.         { $$ = make_pointer_declarator ($2, $3); }
  911.     | TYPENAME
  912.     ;
  913.  
  914. /* Kinds of declarator that can appear in a parameter list
  915.    in addition to notype_declarator.  This is like after_type_declarator
  916.    but does not allow a typedef name in parentheses as an identifier
  917.    (because it would conflict with a function with that typedef as arg).  */
  918.  
  919. parm_declarator:
  920.       parm_declarator '(' parmlist_or_identifiers  %prec '.'
  921.         { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); }
  922. /*    | parm_declarator '(' error ')'  %prec '.'
  923.         { $$ = build_nt (CALL_EXPR, $1, NULL_TREE, NULL_TREE);
  924.           poplevel (0, 0, 0); }  */
  925.     | parm_declarator '[' expr ']'  %prec '.'
  926.         { $$ = build_nt (ARRAY_REF, $1, $3); }
  927.     | parm_declarator '[' ']'  %prec '.'
  928.         { $$ = build_nt (ARRAY_REF, $1, NULL_TREE); }
  929.     | '*' type_quals parm_declarator  %prec UNARY
  930.         { $$ = make_pointer_declarator ($2, $3); }
  931.     | TYPENAME
  932.     ;
  933.  
  934. /* A declarator allowed whether or not there has been
  935.    an explicit typespec.  These cannot redeclare a typedef-name.  */
  936.  
  937. notype_declarator:
  938.       notype_declarator '(' parmlist_or_identifiers  %prec '.'
  939.         { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); }
  940. /*    | notype_declarator '(' error ')'  %prec '.'
  941.         { $$ = build_nt (CALL_EXPR, $1, NULL_TREE, NULL_TREE);
  942.           poplevel (0, 0, 0); }  */
  943.     | '(' notype_declarator ')'
  944.         { $$ = $2; }
  945.     | '*' type_quals notype_declarator  %prec UNARY
  946.         { $$ = make_pointer_declarator ($2, $3); }
  947.     | notype_declarator '[' expr ']'  %prec '.'
  948.         { $$ = build_nt (ARRAY_REF, $1, $3); }
  949.     | notype_declarator '[' ']'  %prec '.'
  950.         { $$ = build_nt (ARRAY_REF, $1, NULL_TREE); }
  951.     | IDENTIFIER
  952.     ;
  953.  
  954. structsp:
  955.       STRUCT identifier '{'
  956.         { $$ = start_struct (RECORD_TYPE, $2);
  957.           /* Start scope of tag before parsing components.  */
  958.         }
  959.       component_decl_list '}'
  960.         { $$ = finish_struct ($<ttype>4, $5);
  961.           /* Really define the structure.  */
  962.         }
  963.     | STRUCT '{' component_decl_list '}'
  964.         { $$ = finish_struct (start_struct (RECORD_TYPE, NULL_TREE),
  965.                       $3); }
  966.     | STRUCT identifier
  967.         { $$ = xref_tag (RECORD_TYPE, $2); }
  968.     | UNION identifier '{'
  969.         { $$ = start_struct (UNION_TYPE, $2); }
  970.       component_decl_list '}'
  971.         { $$ = finish_struct ($<ttype>4, $5); }
  972.     | UNION '{' component_decl_list '}'
  973.         { $$ = finish_struct (start_struct (UNION_TYPE, NULL_TREE),
  974.                       $3); }
  975.     | UNION identifier
  976.         { $$ = xref_tag (UNION_TYPE, $2); }
  977.     | ENUM identifier '{'
  978.         { $<itype>3 = suspend_momentary ();
  979.           $$ = start_enum ($2); }
  980.       enumlist maybecomma_warn '}'
  981.         { $$ = finish_enum ($<ttype>4, nreverse ($5));
  982.           resume_momentary ($<itype>3); }
  983.     | ENUM '{'
  984.         { $<itype>2 = suspend_momentary ();
  985.           $$ = start_enum (NULL_TREE); }
  986.       enumlist maybecomma_warn '}'
  987.         { $$ = finish_enum ($<ttype>3, nreverse ($4));
  988.           resume_momentary ($<itype>2); }
  989.     | ENUM identifier
  990.         { $$ = xref_tag (ENUMERAL_TYPE, $2); }
  991.     ;
  992.  
  993. maybecomma:
  994.       /* empty */
  995.     | ','
  996.     ;
  997.  
  998. maybecomma_warn:
  999.       /* empty */
  1000.     | ','
  1001.         { if (pedantic) pedwarn ("comma at end of enumerator list"); }
  1002.     ;
  1003.  
  1004. component_decl_list:
  1005.       component_decl_list2
  1006.         { $$ = $1; }
  1007.     | component_decl_list2 component_decl
  1008.         { $$ = chainon ($1, $2);
  1009.           warning ("no semicolon at end of struct or union"); }
  1010.     ;
  1011.  
  1012. component_decl_list2:    /* empty */
  1013.         { $$ = NULL_TREE; }
  1014.     | component_decl_list2 component_decl ';'
  1015.         { $$ = chainon ($1, $2); }
  1016.     | component_decl_list2 ';'
  1017.         { if (pedantic)
  1018.             warning ("extra semicolon in struct or union specified"); }
  1019.     ;
  1020.  
  1021. /* There is a shift-reduce conflict here, because `components' may
  1022.    start with a `typename'.  It happens that shifting (the default resolution)
  1023.    does the right thing, because it treats the `typename' as part of
  1024.    a `typed_typespecs'.
  1025.  
  1026.    It is possible that this same technique would allow the distinction
  1027.    between `notype_initdecls' and `initdecls' to be eliminated.
  1028.    But I am being cautious and not trying it.  */
  1029.  
  1030. component_decl:
  1031.       typed_typespecs setspecs components
  1032.         { $$ = $3;
  1033.           current_declspecs = TREE_VALUE (declspec_stack);
  1034.           declspec_stack = TREE_CHAIN (declspec_stack);
  1035.           resume_momentary ($2); }
  1036.     | typed_typespecs
  1037.         { if (pedantic)
  1038.             pedwarn ("ANSI C forbids member declarations with no members");
  1039.           shadow_tag($1);
  1040.           $$ = NULL_TREE; }
  1041.     | nonempty_type_quals setspecs components
  1042.         { $$ = $3;
  1043.           current_declspecs = TREE_VALUE (declspec_stack);
  1044.           declspec_stack = TREE_CHAIN (declspec_stack);
  1045.           resume_momentary ($2); }
  1046.     | nonempty_type_quals
  1047.         { if (pedantic)
  1048.             pedwarn ("ANSI C forbids member declarations with no members");
  1049.           shadow_tag($1);
  1050.           $$ = NULL_TREE; }
  1051.     | error
  1052.         { $$ = NULL_TREE; }
  1053.     ;
  1054.  
  1055. components:
  1056.       component_declarator
  1057.     | components ',' component_declarator
  1058.         { $$ = chainon ($1, $3); }
  1059.     ;
  1060.  
  1061. component_declarator:
  1062.       save_filename save_lineno declarator maybe_attribute
  1063.         { $$ = grokfield ($1, $2, $3, current_declspecs, NULL_TREE);
  1064.           decl_attributes ($$, $4); }
  1065.     | save_filename save_lineno
  1066.       declarator ':' expr_no_commas maybe_attribute
  1067.         { $$ = grokfield ($1, $2, $3, current_declspecs, $5);
  1068.           decl_attributes ($$, $6); }
  1069.     | save_filename save_lineno ':' expr_no_commas
  1070.         { $$ = grokfield ($1, $2, NULL_TREE, current_declspecs, $4); }
  1071.     ;
  1072.  
  1073. /* We chain the enumerators in reverse order.
  1074.    They are put in forward order where enumlist is used.
  1075.    (The order used to be significant, but no longer is so.
  1076.    However, we still maintain the order, just to be clean.)  */
  1077.  
  1078. enumlist:
  1079.       enumerator
  1080.     | enumlist ',' enumerator
  1081.         { $$ = chainon ($3, $1); }
  1082.     ;
  1083.  
  1084.  
  1085. enumerator:
  1086.       identifier
  1087.         { $$ = build_enumerator ($1, NULL_TREE); }
  1088.     | identifier '=' expr_no_commas
  1089.         { $$ = build_enumerator ($1, $3); }
  1090.     ;
  1091.  
  1092. typename:
  1093.     typed_typespecs absdcl
  1094.         { $$ = build_tree_list ($1, $2); }
  1095.     | nonempty_type_quals absdcl
  1096.         { $$ = build_tree_list ($1, $2); }
  1097.     ;
  1098.  
  1099. absdcl:   /* an absolute declarator */
  1100.     /* empty */
  1101.         { $$ = NULL_TREE; }
  1102.     | absdcl1
  1103.     ;
  1104.  
  1105. nonempty_type_quals:
  1106.       TYPE_QUAL
  1107.         { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); }
  1108.     | nonempty_type_quals TYPE_QUAL
  1109.         { $$ = tree_cons (NULL_TREE, $2, $1); }
  1110.     ;
  1111.  
  1112. type_quals:
  1113.       /* empty */
  1114.         { $$ = NULL_TREE; }
  1115.     | type_quals TYPE_QUAL
  1116.         { $$ = tree_cons (NULL_TREE, $2, $1); }
  1117.     ;
  1118.  
  1119. absdcl1:  /* a nonempty absolute declarator */
  1120.       '(' absdcl1 ')'
  1121.         { $$ = $2; }
  1122.       /* `(typedef)1' is `int'.  */
  1123.     | '*' type_quals absdcl1  %prec UNARY
  1124.         { $$ = make_pointer_declarator ($2, $3); }
  1125.     | '*' type_quals  %prec UNARY
  1126.         { $$ = make_pointer_declarator ($2, NULL_TREE); }
  1127.     | absdcl1 '(' parmlist  %prec '.'
  1128.         { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); }
  1129.     | absdcl1 '[' expr ']'  %prec '.'
  1130.         { $$ = build_nt (ARRAY_REF, $1, $3); }
  1131.     | absdcl1 '[' ']'  %prec '.'
  1132.         { $$ = build_nt (ARRAY_REF, $1, NULL_TREE); }
  1133.     | '(' parmlist  %prec '.'
  1134.         { $$ = build_nt (CALL_EXPR, NULL_TREE, $2, NULL_TREE); }
  1135.     | '[' expr ']'  %prec '.'
  1136.         { $$ = build_nt (ARRAY_REF, NULL_TREE, $2); }
  1137.     | '[' ']'  %prec '.'
  1138.         { $$ = build_nt (ARRAY_REF, NULL_TREE, NULL_TREE); }
  1139.     ;
  1140.  
  1141. /* at least one statement, the first of which parses without error.  */
  1142. /* stmts is used only after decls, so an invalid first statement
  1143.    is actually regarded as an invalid decl and part of the decls.  */
  1144.  
  1145. stmts:
  1146.     lineno_stmt
  1147.     | stmts lineno_stmt
  1148.     | stmts errstmt
  1149.     ;
  1150.  
  1151. xstmts:
  1152.     /* empty */
  1153.     | stmts
  1154.     ;
  1155.  
  1156. errstmt:  error ';'
  1157.     ;
  1158.  
  1159. pushlevel:  /* empty */
  1160.         { emit_line_note (input_filename, lineno);
  1161.           pushlevel (0);
  1162.           clear_last_expr ();
  1163.           push_momentary ();
  1164.           expand_start_bindings (0); }
  1165.     ;
  1166.  
  1167. /* Read zero or more forward-declarations for labels
  1168.    that nested functions can jump to.  */
  1169. maybe_label_decls:
  1170.       /* empty */
  1171.     | label_decls
  1172.         { if (pedantic)
  1173.             pedwarn ("ANSI C forbids label declarations"); }
  1174.     ;
  1175.  
  1176. label_decls:
  1177.       label_decl
  1178.     | label_decls label_decl
  1179.     ;
  1180.  
  1181. label_decl:
  1182.       LABEL identifiers ';'
  1183.         { tree link;
  1184.           for (link = $2; link; link = TREE_CHAIN (link))
  1185.             {
  1186.               tree label = shadow_label (TREE_VALUE (link));
  1187.               C_DECLARED_LABEL_FLAG (label) = 1;
  1188.               declare_nonlocal_label (label);
  1189.             }
  1190.         }
  1191.     ;
  1192.  
  1193. /* This is the body of a function definition.
  1194.    It causes syntax errors to ignore to the next openbrace.  */
  1195. compstmt_or_error:
  1196.       compstmt
  1197.         {}
  1198.     | error compstmt
  1199.     ;
  1200.  
  1201. compstmt: '{' '}'
  1202.         { $$ = convert (void_type_node, integer_zero_node); }
  1203.     | '{' pushlevel maybe_label_decls decls xstmts '}'
  1204.         { emit_line_note (input_filename, lineno);
  1205.           expand_end_bindings (getdecls (), 1, 0);
  1206.           $$ = poplevel (1, 1, 0);
  1207.           pop_momentary (); }
  1208.     | '{' pushlevel maybe_label_decls error '}'
  1209.         { emit_line_note (input_filename, lineno);
  1210.           expand_end_bindings (getdecls (), kept_level_p (), 0);
  1211.           $$ = poplevel (kept_level_p (), 0, 0);
  1212.           pop_momentary (); }
  1213.     | '{' pushlevel maybe_label_decls stmts '}'
  1214.         { emit_line_note (input_filename, lineno);
  1215.           expand_end_bindings (getdecls (), kept_level_p (), 0);
  1216.           $$ = poplevel (kept_level_p (), 0, 0);
  1217.           pop_momentary (); }
  1218.     ;
  1219.  
  1220. /* Value is number of statements counted as of the closeparen.  */
  1221. simple_if:
  1222.       if_prefix lineno_stmt
  1223. /* Make sure expand_end_cond is run once
  1224.    for each call to expand_start_cond.
  1225.    Otherwise a crash is likely.  */
  1226.     | if_prefix error
  1227.     ;
  1228.  
  1229. if_prefix:
  1230.       IF '(' expr ')'
  1231.         { emit_line_note ($<filename>-1, $<lineno>0);
  1232.           expand_start_cond (truthvalue_conversion ($3), 0);
  1233.           $<itype>1 = stmt_count;
  1234.           if_stmt_file = $<filename>-1;
  1235.           if_stmt_line = $<lineno>0;
  1236.           position_after_white_space (); }
  1237.     ;
  1238.  
  1239. save_filename:
  1240.         { $$ = input_filename; }
  1241.     ;
  1242.  
  1243. save_lineno:
  1244.         { $$ = lineno; }
  1245.     ;
  1246.  
  1247. lineno_stmt:
  1248.       save_filename save_lineno stmt
  1249.         { }
  1250.     ;
  1251.  
  1252. stmt:
  1253.       compstmt
  1254.         { stmt_count++; }
  1255.     | expr ';'
  1256.         { stmt_count++;
  1257.           emit_line_note ($<filename>-1, $<lineno>0);
  1258.           c_expand_expr_stmt ($1);
  1259.           clear_momentary (); }
  1260.     | simple_if ELSE
  1261.         { expand_start_else ();
  1262.           $<itype>1 = stmt_count;
  1263.           position_after_white_space (); }
  1264.       lineno_stmt
  1265.         { expand_end_cond ();
  1266.           if (extra_warnings && stmt_count == $<itype>1)
  1267.             warning ("empty body in an else-statement"); }
  1268.     | simple_if %prec IF
  1269.         { expand_end_cond ();
  1270.           if (extra_warnings && stmt_count == $<itype>1)
  1271.             warning_with_file_and_line (if_stmt_file, if_stmt_line,
  1272.                         "empty body in an if-statement"); }
  1273. /* Make sure expand_end_cond is run once
  1274.    for each call to expand_start_cond.
  1275.    Otherwise a crash is likely.  */
  1276.     | simple_if ELSE error
  1277.         { expand_end_cond (); }
  1278.     | WHILE
  1279.         { emit_nop ();
  1280.           stmt_count++;
  1281.           emit_line_note ($<filename>-1, $<lineno>0);
  1282.           expand_start_loop (1); }
  1283.       '(' expr ')'
  1284.         { emit_line_note (input_filename, lineno);
  1285.           expand_exit_loop_if_false (0, truthvalue_conversion ($4));
  1286.           position_after_white_space (); }
  1287.       lineno_stmt
  1288.         { expand_end_loop (); }
  1289.     | DO
  1290.         { emit_nop ();
  1291.           stmt_count++;
  1292.           emit_line_note ($<filename>-1, $<lineno>0);
  1293.           expand_start_loop_continue_elsewhere (1);
  1294.           position_after_white_space (); }
  1295.       lineno_stmt WHILE
  1296.         { expand_loop_continue_here (); }
  1297.       '(' expr ')' ';'
  1298.         { emit_line_note (input_filename, lineno);
  1299.           expand_exit_loop_if_false (0, truthvalue_conversion ($7));
  1300.           expand_end_loop ();
  1301.           clear_momentary (); }
  1302.     | FOR
  1303.       '(' xexpr ';'
  1304.         { emit_nop ();
  1305.           stmt_count++;
  1306.           emit_line_note ($<filename>-1, $<lineno>0);
  1307.           if ($3) c_expand_expr_stmt ($3);
  1308.           expand_start_loop_continue_elsewhere (1); }
  1309.       xexpr ';'
  1310.         { emit_line_note (input_filename, lineno);
  1311.           if ($6)
  1312.             expand_exit_loop_if_false (0, truthvalue_conversion ($6)); }
  1313.       xexpr ')'
  1314.         /* Don't let the tree nodes for $9 be discarded
  1315.            by clear_momentary during the parsing of the next stmt.  */
  1316.         { push_momentary ();
  1317.           position_after_white_space (); }
  1318.       lineno_stmt
  1319.         { emit_line_note ($<filename>-1, $<lineno>0);
  1320.           expand_loop_continue_here ();
  1321.           if ($9)
  1322.             c_expand_expr_stmt ($9);
  1323.           pop_momentary ();
  1324.           expand_end_loop (); }
  1325.     | SWITCH '(' expr ')'
  1326.         { stmt_count++;
  1327.           emit_line_note ($<filename>-1, $<lineno>0);
  1328.           c_expand_start_case ($3);
  1329.           /* Don't let the tree nodes for $3 be discarded by
  1330.              clear_momentary during the parsing of the next stmt.  */
  1331.           push_momentary ();
  1332.           position_after_white_space (); }
  1333.       lineno_stmt
  1334.         { expand_end_case ($3);
  1335.           pop_momentary (); }
  1336.     | CASE expr ':'
  1337.         { register tree value = check_case_value ($2);
  1338.           register tree label
  1339.             = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
  1340.  
  1341.           stmt_count++;
  1342.  
  1343.           if (value != error_mark_node)
  1344.             {
  1345.               int success = pushcase (value, label);
  1346.               if (success == 1)
  1347.             error ("case label not within a switch statement");
  1348.               else if (success == 2)
  1349.             error ("duplicate case value");
  1350.               else if (success == 3)
  1351.             warning ("case value out of range");
  1352.             }
  1353.           position_after_white_space (); }
  1354.       lineno_stmt
  1355.     | CASE expr ELLIPSIS expr ':'
  1356.         { register tree value1 = check_case_value ($2);
  1357.           register tree value2 = check_case_value ($4);
  1358.           register tree label
  1359.             = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
  1360.  
  1361.           stmt_count++;
  1362.  
  1363.           if (value1 != error_mark_node && value2 != error_mark_node)
  1364.             {
  1365.               int success = pushcase_range (value1, value2, label);
  1366.               if (success == 1)
  1367.             error ("case label not within a switch statement");
  1368.               else if (success == 2)
  1369.             error ("duplicate case value");
  1370.               else if (success == 3)
  1371.             warning ("case value out of range");
  1372.               else if (success == 4)
  1373.             warning ("empty case range");
  1374.             }
  1375.           position_after_white_space (); }
  1376.       lineno_stmt
  1377.     | DEFAULT ':'
  1378.         {
  1379.           register tree label
  1380.             = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
  1381.           int success = pushcase (NULL_TREE, label);
  1382.           stmt_count++;
  1383.           if (success == 1)
  1384.             error ("default label not within a switch statement");
  1385.           else if (success == 2)
  1386.             error ("multiple default labels in one switch");
  1387.           position_after_white_space (); }
  1388.       lineno_stmt
  1389.     | BREAK ';'
  1390.         { stmt_count++;
  1391.           emit_line_note ($<filename>-1, $<lineno>0);
  1392.           if ( ! expand_exit_something ())
  1393.             error ("break statement not within loop or switch"); }
  1394.     | CONTINUE ';'
  1395.         { stmt_count++;
  1396.           emit_line_note ($<filename>-1, $<lineno>0);
  1397.           if (! expand_continue_loop (0))
  1398.             error ("continue statement not within a loop"); }
  1399.     | RETURN ';'
  1400.         { stmt_count++;
  1401.           emit_line_note ($<filename>-1, $<lineno>0);
  1402.           c_expand_return (NULL_TREE); }
  1403.     | RETURN expr ';'
  1404.         { stmt_count++;
  1405.           emit_line_note ($<filename>-1, $<lineno>0);
  1406.           c_expand_return ($2); }
  1407.     | ASM maybe_type_qual '(' string ')' ';'
  1408.         { stmt_count++;
  1409.           emit_line_note ($<filename>-1, $<lineno>0);
  1410.           if (TREE_CHAIN ($4)) $4 = combine_strings ($4);
  1411.           expand_asm ($4); }
  1412.     /* This is the case with just output operands.  */
  1413.     | ASM maybe_type_qual '(' string ':' asm_operands ')' ';'
  1414.         { stmt_count++;
  1415.           emit_line_note ($<filename>-1, $<lineno>0);
  1416.           if (TREE_CHAIN ($4)) $4 = combine_strings ($4);
  1417.           c_expand_asm_operands ($4, $6, NULL_TREE, NULL_TREE,
  1418.                      $2 == ridpointers[(int)RID_VOLATILE],
  1419.                      input_filename, lineno); }
  1420.     /* This is the case with input operands as well.  */
  1421.     | ASM maybe_type_qual '(' string ':' asm_operands ':' asm_operands ')' ';'
  1422.         { stmt_count++;
  1423.           emit_line_note ($<filename>-1, $<lineno>0);
  1424.           if (TREE_CHAIN ($4)) $4 = combine_strings ($4);
  1425.           c_expand_asm_operands ($4, $6, $8, NULL_TREE,
  1426.                      $2 == ridpointers[(int)RID_VOLATILE],
  1427.                      input_filename, lineno); }
  1428.     /* This is the case with clobbered registers as well.  */
  1429.     | ASM maybe_type_qual '(' string ':' asm_operands ':'
  1430.         asm_operands ':' asm_clobbers ')' ';'
  1431.         { stmt_count++;
  1432.           emit_line_note ($<filename>-1, $<lineno>0);
  1433.           if (TREE_CHAIN ($4)) $4 = combine_strings ($4);
  1434.           c_expand_asm_operands ($4, $6, $8, $10,
  1435.                      $2 == ridpointers[(int)RID_VOLATILE],
  1436.                      input_filename, lineno); }
  1437.     | GOTO identifier ';'
  1438.         { tree decl;
  1439.           stmt_count++;
  1440.           emit_line_note ($<filename>-1, $<lineno>0);
  1441.           decl = lookup_label ($2);
  1442.           if (decl != 0)
  1443.             {
  1444.               TREE_USED (decl) = 1;
  1445.               expand_goto (decl);
  1446.             }
  1447.         }
  1448.     | GOTO '*' expr ';'
  1449.         { stmt_count++;
  1450.           emit_line_note ($<filename>-1, $<lineno>0);
  1451.           expand_computed_goto ($3); }
  1452.     | identifier ':'
  1453.         { tree label = define_label (input_filename, lineno, $1);
  1454.           stmt_count++;
  1455.           emit_nop ();
  1456.           if (label)
  1457.             expand_label (label);
  1458.           position_after_white_space (); }
  1459.       lineno_stmt
  1460.     | ';'
  1461.     ;
  1462.  
  1463. /* Either a type-qualifier or nothing.  First thing in an `asm' statement.  */
  1464.  
  1465. maybe_type_qual:
  1466.     /* empty */
  1467.         { if (pedantic)
  1468.             pedwarn ("ANSI C forbids use of `asm' keyword");
  1469.           emit_line_note (input_filename, lineno); }
  1470.     | TYPE_QUAL
  1471.         { if (pedantic)
  1472.             pedwarn ("ANSI C forbids use of `asm' keyword");
  1473.           emit_line_note (input_filename, lineno); }
  1474.     ;
  1475.  
  1476. xexpr:
  1477.     /* empty */
  1478.         { $$ = NULL_TREE; }
  1479.     | expr
  1480.     ;
  1481.  
  1482. /* These are the operands other than the first string and colon
  1483.    in  asm ("addextend %2,%1": "=dm" (x), "0" (y), "g" (*x))  */
  1484. asm_operands: /* empty */
  1485.         { $$ = NULL_TREE; }
  1486.     | nonnull_asm_operands
  1487.     ;
  1488.  
  1489. nonnull_asm_operands:
  1490.       asm_operand
  1491.     | nonnull_asm_operands ',' asm_operand
  1492.         { $$ = chainon ($1, $3); }
  1493.     ;
  1494.  
  1495. asm_operand:
  1496.       STRING '(' expr ')'
  1497.         { $$ = build_tree_list ($1, $3); }
  1498.     ;
  1499.  
  1500. asm_clobbers:
  1501.       string
  1502.         { $$ = tree_cons (NULL_TREE, combine_strings ($1), NULL_TREE); }
  1503.     | asm_clobbers ',' string
  1504.         { $$ = tree_cons (NULL_TREE, combine_strings ($3), $1); }
  1505.     ;
  1506.  
  1507. /* This is what appears inside the parens in a function declarator.
  1508.    Its value is a list of ..._TYPE nodes.  */
  1509. parmlist:
  1510.         { pushlevel (0);
  1511.           declare_parm_level (0); }
  1512.       parmlist_1
  1513.         { $$ = $2;
  1514.           parmlist_tags_warning ();
  1515.           poplevel (0, 0, 0); }
  1516.     ;
  1517.  
  1518. /* This is referred to where either a parmlist or an identifier list is ok.
  1519.    Its value is a list of ..._TYPE nodes or a list of identifiers.  */
  1520. parmlist_or_identifiers:
  1521.         { pushlevel (0);
  1522.           declare_parm_level (1); }
  1523.       parmlist_or_identifiers_1
  1524.         { $$ = $2;
  1525.           parmlist_tags_warning ();
  1526.           poplevel (0, 0, 0); }
  1527.     ;
  1528.  
  1529. parmlist_or_identifiers_1:
  1530.       parmlist_2 ')'
  1531.     | identifiers ')'
  1532.         { $$ = tree_cons (NULL_TREE, NULL_TREE, $1); }
  1533.     | error ')'
  1534.         { $$ = tree_cons (NULL_TREE, NULL_TREE, NULL_TREE); }
  1535.     ;
  1536.  
  1537. parmlist_1:
  1538.       parmlist_2 ')'
  1539.     | error ')'
  1540.         { $$ = tree_cons (NULL_TREE, NULL_TREE, NULL_TREE); }
  1541.     ;
  1542.  
  1543. /* This is what appears inside the parens in a function declarator.
  1544.    Is value is represented in the format that grokdeclarator expects.  */
  1545. parmlist_2:  /* empty */
  1546.         { $$ = get_parm_info (0); }
  1547.     | parms
  1548.         { $$ = get_parm_info (1); }
  1549.     | parms ',' ELLIPSIS
  1550.         { $$ = get_parm_info (0); }
  1551.     ;
  1552.  
  1553. parms:
  1554.     parm
  1555.         { push_parm_decl ($1); }
  1556.     | parms ',' parm
  1557.         { push_parm_decl ($3); }
  1558.     ;
  1559.  
  1560. /* A single parameter declaration or parameter type name,
  1561.    as found in a parmlist.  */
  1562. parm:
  1563.       typed_declspecs parm_declarator
  1564.         { $$ = build_tree_list ($1, $2)    ; }
  1565.     | typed_declspecs notype_declarator
  1566.         { $$ = build_tree_list ($1, $2)    ; }
  1567.     | typed_declspecs absdcl
  1568.         { $$ = build_tree_list ($1, $2); }
  1569.     | declmods notype_declarator
  1570.         { $$ = build_tree_list ($1, $2)    ; }
  1571.     | declmods absdcl
  1572.         { $$ = build_tree_list ($1, $2); }
  1573.     ;
  1574.  
  1575. /* A nonempty list of identifiers.  */
  1576. identifiers:
  1577.     IDENTIFIER
  1578.         { $$ = build_tree_list (NULL_TREE, $1); }
  1579.     | identifiers ',' IDENTIFIER
  1580.         { $$ = chainon ($1, build_tree_list (NULL_TREE, $3)); }
  1581.     ;
  1582. %%
  1583.  
  1584. /* Return something to represent absolute declarators containing a *.
  1585.    TARGET is the absolute declarator that the * contains.
  1586.    TYPE_QUALS is a list of modifiers such as const or volatile
  1587.    to apply to the pointer type, represented as identifiers.
  1588.  
  1589.    We return an INDIRECT_REF whose "contents" are TARGET
  1590.    and whose type is the modifier list.  */
  1591.  
  1592. static tree
  1593. make_pointer_declarator (type_quals, target)
  1594.      tree type_quals, target;
  1595. {
  1596.   return build1 (INDIRECT_REF, type_quals, target);
  1597. }
  1598.  
  1599. /* lexical analyzer */
  1600.  
  1601. #ifndef WCHAR_TYPE_SIZE
  1602. #ifdef INT_TYPE_SIZE
  1603. #define WCHAR_TYPE_SIZE INT_TYPE_SIZE
  1604. #else
  1605. #define WCHAR_TYPE_SIZE    BITS_PER_WORD
  1606. #endif
  1607. #endif
  1608.  
  1609. /* Number of bytes in a wide character.  */
  1610. #define WCHAR_BYTES (WCHAR_TYPE_SIZE / BITS_PER_UNIT)
  1611.  
  1612. static int maxtoken;        /* Current nominal length of token buffer.  */
  1613. static char *token_buffer;    /* Pointer to token buffer.
  1614.                    Actual allocated length is maxtoken + 2.  */
  1615.  
  1616. /* Nonzero if end-of-file has been seen on input.  */
  1617. static int end_of_file;
  1618.  
  1619. static int nextchar = -1;
  1620.  
  1621. int check_newline ();
  1622.  
  1623. /* C code produced by gperf version 2.5 (GNU C++ version) */
  1624. /* Command-line: gperf -p -j1 -i 1 -g -o -t -N is_reserved_word -k1,3,$ c-parse.gperf  */ 
  1625. struct resword { char *name; short token; enum rid rid; };
  1626.  
  1627. #define TOTAL_KEYWORDS 53
  1628. #define MIN_WORD_LENGTH 2
  1629. #define MAX_WORD_LENGTH 13
  1630. #define MIN_HASH_VALUE 7
  1631. #define MAX_HASH_VALUE 102
  1632. /* maximum key range = 96, duplicates = 0 */
  1633.  
  1634. #ifdef __GNUC__
  1635. __inline
  1636. #endif
  1637. static unsigned int
  1638. hash (str, len)
  1639.      register char *str;
  1640.      register int unsigned len;
  1641. {
  1642.   static unsigned char asso_values[] =
  1643.     {
  1644.      103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
  1645.      103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
  1646.      103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
  1647.      103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
  1648.      103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
  1649.      103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
  1650.      103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
  1651.      103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
  1652.      103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
  1653.      103, 103, 103, 103, 103,   1, 103,   2,   1,  24,
  1654.        1,   5,  19,  39,  16,  13, 103,   1,  25,   1,
  1655.       34,  34,  24, 103,  13,  12,   1,  45,  24,   7,
  1656.      103, 103,   2, 103, 103, 103, 103, 103,
  1657.     };
  1658.   register int hval = len;
  1659.  
  1660.   switch (hval)
  1661.     {
  1662.       default:
  1663.       case 3:
  1664.         hval += asso_values[str[2]];
  1665.       case 2:
  1666.       case 1:
  1667.         hval += asso_values[str[0]];
  1668.     }
  1669.   return hval + asso_values[str[len - 1]];
  1670. }
  1671.  
  1672. #ifdef __GNUC__
  1673. __inline
  1674. #endif
  1675. struct resword *
  1676. is_reserved_word (str, len)
  1677.      register char *str;
  1678.      register unsigned int len;
  1679. {
  1680.   static struct resword wordlist[] =
  1681.     {
  1682.       {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, 
  1683.       {"asm",  ASM, NORID},
  1684.       {"",}, 
  1685.       {"__asm",  ASM, NORID},
  1686.       {"",}, 
  1687.       {"__asm__",  ASM, NORID},
  1688.       {"break",  BREAK, NORID},
  1689.       {"__typeof__",  TYPEOF, NORID},
  1690.       {"",}, 
  1691.       {"__alignof__",  ALIGNOF, NORID},
  1692.       {"",}, 
  1693.       {"__attribute__",  ATTRIBUTE, NORID},
  1694.       {"int",  TYPESPEC, RID_INT},
  1695.       {"__attribute",  ATTRIBUTE, NORID},
  1696.       {"__extension__",  EXTENSION, NORID},
  1697.       {"",}, 
  1698.       {"__signed",  TYPESPEC, RID_SIGNED},
  1699.       {"",}, 
  1700.       {"__signed__",  TYPESPEC, RID_SIGNED},
  1701.       {"__inline__",  SCSPEC, RID_INLINE},
  1702.       {"else",  ELSE, NORID},
  1703.       {"__inline",  SCSPEC, RID_INLINE},
  1704.       {"default",  DEFAULT, NORID},
  1705.       {"__typeof",  TYPEOF, NORID},
  1706.       {"while",  WHILE, NORID},
  1707.       {"__alignof",  ALIGNOF, NORID},
  1708.       {"struct",  STRUCT, NORID},
  1709.       {"__const",  TYPE_QUAL, RID_CONST},
  1710.       {"if",  IF, NORID},
  1711.       {"__const__",  TYPE_QUAL, RID_CONST},
  1712.       {"__label__",  LABEL, NORID},
  1713.       {"do",  DO, NORID},
  1714.       {"__volatile__",  TYPE_QUAL, RID_VOLATILE},
  1715.       {"sizeof",  SIZEOF, NORID},
  1716.       {"__volatile",  TYPE_QUAL, RID_VOLATILE},
  1717.       {"auto",  SCSPEC, RID_AUTO},
  1718.       {"void",  TYPESPEC, RID_VOID},
  1719.       {"char",  TYPESPEC, RID_CHAR},
  1720.       {"static",  SCSPEC, RID_STATIC},
  1721.       {"case",  CASE, NORID},
  1722.       {"extern",  SCSPEC, RID_EXTERN},
  1723.       {"switch",  SWITCH, NORID},
  1724.       {"for",  FOR, NORID},
  1725.       {"inline",  SCSPEC, RID_INLINE},
  1726.       {"typeof",  TYPEOF, NORID},
  1727.       {"typedef",  SCSPEC, RID_TYPEDEF},
  1728.       {"short",  TYPESPEC, RID_SHORT},
  1729.       {"",}, 
  1730.       {"return",  RETURN, NORID},
  1731.       {"enum",  ENUM, NORID},
  1732.       {"",}, 
  1733.       {"double",  TYPESPEC, RID_DOUBLE},
  1734.       {"signed",  TYPESPEC, RID_SIGNED},
  1735.       {"float",  TYPESPEC, RID_FLOAT},
  1736.       {"",}, {"",}, 
  1737.       {"volatile",  TYPE_QUAL, RID_VOLATILE},
  1738.       {"",}, 
  1739.       {"const",  TYPE_QUAL, RID_CONST},
  1740.       {"",}, 
  1741.       {"unsigned",  TYPESPEC, RID_UNSIGNED},
  1742.       {"",}, {"",}, {"",}, {"",}, 
  1743.       {"continue",  CONTINUE, NORID},
  1744.       {"",}, 
  1745.       {"register",  SCSPEC, RID_REGISTER},
  1746.       {"",}, {"",}, {"",}, {"",}, 
  1747.       {"goto",  GOTO, NORID},
  1748.       {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, 
  1749.       {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, 
  1750.       
  1751.       {"union",  UNION, NORID},
  1752.       {"",}, {"",}, {"",}, {"",}, 
  1753.       {"long",  TYPESPEC, RID_LONG},
  1754.     };
  1755.  
  1756.   if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
  1757.     {
  1758.       register int key = hash (str, len);
  1759.  
  1760.       if (key <= MAX_HASH_VALUE && key >= 0)
  1761.         {
  1762.           register char *s = wordlist[key].name;
  1763.  
  1764.           if (*s == *str && !strcmp (str + 1, s + 1))
  1765.             return &wordlist[key];
  1766.         }
  1767.     }
  1768.   return 0;
  1769. }
  1770.  
  1771. void
  1772. init_lex ()
  1773. {
  1774.   /* Make identifier nodes long enough for the language-specific slots.  */
  1775.   set_identifier_size (sizeof (struct lang_identifier));
  1776.  
  1777.   /* Start it at 0, because check_newline is called at the very beginning
  1778.      and will increment it to 1.  */
  1779.   lineno = 0;
  1780.  
  1781. #ifdef MULTIBYTE_CHARS
  1782.   /* Change to the native locale for multibyte conversions.  */
  1783.   setlocale (LC_CTYPE, "");
  1784. #endif
  1785.  
  1786.   maxtoken = 40;
  1787.   token_buffer = (char *) xmalloc (maxtoken + 2);
  1788.  
  1789.   ridpointers[(int) RID_INT] = get_identifier ("int");
  1790.   ridpointers[(int) RID_CHAR] = get_identifier ("char");
  1791.   ridpointers[(int) RID_VOID] = get_identifier ("void");
  1792.   ridpointers[(int) RID_FLOAT] = get_identifier ("float");
  1793.   ridpointers[(int) RID_DOUBLE] = get_identifier ("double");
  1794.   ridpointers[(int) RID_SHORT] = get_identifier ("short");
  1795.   ridpointers[(int) RID_LONG] = get_identifier ("long");
  1796.   ridpointers[(int) RID_UNSIGNED] = get_identifier ("unsigned");
  1797.   ridpointers[(int) RID_SIGNED] = get_identifier ("signed");
  1798.   ridpointers[(int) RID_INLINE] = get_identifier ("inline");
  1799.   ridpointers[(int) RID_CONST] = get_identifier ("const");
  1800.   ridpointers[(int) RID_VOLATILE] = get_identifier ("volatile");
  1801.   ridpointers[(int) RID_AUTO] = get_identifier ("auto");
  1802.   ridpointers[(int) RID_STATIC] = get_identifier ("static");
  1803.   ridpointers[(int) RID_EXTERN] = get_identifier ("extern");
  1804.   ridpointers[(int) RID_TYPEDEF] = get_identifier ("typedef");
  1805.   ridpointers[(int) RID_REGISTER] = get_identifier ("register");
  1806.  
  1807.   /* Some options inhibit certain reserved words.
  1808.      Clear those words out of the hash table so they won't be recognized.  */
  1809. #define UNSET_RESERVED_WORD(STRING) \
  1810.   do { struct resword *s = is_reserved_word (STRING, sizeof (STRING) - 1); \
  1811.        if (s) s->name = ""; } while (0)
  1812.  
  1813.   if (flag_traditional)
  1814.     {
  1815.       UNSET_RESERVED_WORD ("const");
  1816.       UNSET_RESERVED_WORD ("volatile");
  1817.       UNSET_RESERVED_WORD ("typeof");
  1818.       UNSET_RESERVED_WORD ("signed");
  1819.       UNSET_RESERVED_WORD ("inline");
  1820.     }
  1821.   if (flag_no_asm)
  1822.     {
  1823.       UNSET_RESERVED_WORD ("asm");
  1824.       UNSET_RESERVED_WORD ("typeof");
  1825.       UNSET_RESERVED_WORD ("inline");
  1826.     }
  1827. }
  1828.  
  1829. static void
  1830. reinit_parse_for_function ()
  1831. {
  1832. }
  1833.  
  1834. /* If C is not whitespace, return C.
  1835.    Otherwise skip whitespace and return first nonwhite char read.  */
  1836.  
  1837. static int
  1838. skip_white_space (c)
  1839.      register int c;
  1840. {
  1841. #if 0
  1842.   register int inside;
  1843. #endif
  1844.  
  1845.   for (;;)
  1846.     {
  1847.       switch (c)
  1848.     {
  1849.       /* Don't recognize comments in cc1: all comments are removed by cpp,
  1850.          and cpp output can include / and * consecutively as operators.  */
  1851. #if 0
  1852.     case '/':
  1853.       c = getc (finput);
  1854.       if (c != '*')
  1855.         {
  1856.           ungetc (c, finput);
  1857.           return '/';
  1858.         }
  1859.  
  1860.       c = getc (finput);
  1861.  
  1862.       inside = 1;
  1863.       while (inside)
  1864.         {
  1865.           if (c == '*')
  1866.         {
  1867.           while (c == '*')
  1868.             c = getc (finput);
  1869.  
  1870.           if (c == '/')
  1871.             {
  1872.               inside = 0;
  1873.               c = getc (finput);
  1874.             }
  1875.         }
  1876.           else if (c == '\n')
  1877.         {
  1878.           lineno++;
  1879.           c = getc (finput);
  1880.         }
  1881.           else if (c == EOF)
  1882.         {
  1883.           error ("unterminated comment");
  1884.           break;
  1885.         }
  1886.           else
  1887.         c = getc (finput);
  1888.         }
  1889.  
  1890.       break;
  1891. #endif
  1892.  
  1893.     case '\n':
  1894.       c = check_newline ();
  1895.       break;
  1896.  
  1897.     case '\r':
  1898.       if (pedantic)    /* ANSI says no */
  1899.         return (c);
  1900.     case ' ':
  1901.     case '\t':
  1902.     case '\f':
  1903.     case '\v':
  1904.     case '\b':
  1905.       c = getc (finput);
  1906.       break;
  1907.  
  1908.     case '\\':
  1909.       c = getc (finput);
  1910.       if (c == '\n')
  1911.         lineno++;
  1912.       else
  1913.         error ("stray '\\' in program");
  1914.       c = getc (finput);
  1915.       break;
  1916.  
  1917.     default:
  1918.       return (c);
  1919.     }
  1920.     }
  1921. }
  1922.  
  1923. /* Skips all of the white space at the current location in the input file.
  1924.    Must use and reset nextchar if it has the next character.  */
  1925.  
  1926. static void
  1927. position_after_white_space ()
  1928. {
  1929.   register int c;
  1930.  
  1931.   if (nextchar != -1)
  1932.     c = nextchar, nextchar = -1;
  1933.   else
  1934.     c = getc (finput);
  1935.  
  1936.   ungetc (skip_white_space (c), finput);
  1937. }
  1938.  
  1939. /* Make the token buffer longer, preserving the data in it.
  1940.    P should point to just beyond the last valid character in the old buffer.
  1941.    The value we return is a pointer to the new buffer
  1942.    at a place corresponding to P.  */
  1943.  
  1944. static char *
  1945. extend_token_buffer (p)
  1946.      char *p;
  1947. {
  1948.   int offset = p - token_buffer;
  1949.  
  1950.   maxtoken = maxtoken * 2 + 10;
  1951.   token_buffer = (char *) xrealloc (token_buffer, maxtoken + 2);
  1952.  
  1953.   return token_buffer + offset;
  1954. }
  1955.  
  1956. /* At the beginning of a line, increment the line number
  1957.    and process any #-directive on this line.
  1958.    If the line is a #-directive, read the entire line and return a newline.
  1959.    Otherwise, return the line's first non-whitespace character.  */
  1960.  
  1961. int
  1962. check_newline ()
  1963. {
  1964.   register int c;
  1965.   register int token;
  1966.  
  1967.   lineno++;
  1968.  
  1969.   /* Read first nonwhite char on the line.  */
  1970.  
  1971.   c = getc (finput);
  1972.   while (c == ' ' || c == '\t')
  1973.     c = getc (finput);
  1974.  
  1975.   if (c != '#')
  1976.     {
  1977.       /* If not #, return it so caller will use it.  */
  1978.       return c;
  1979.     }
  1980.  
  1981.   /* Read first nonwhite char after the `#'.  */
  1982.  
  1983.   c = getc (finput);
  1984.   while (c == ' ' || c == '\t')
  1985.     c = getc (finput);
  1986.  
  1987.   /* If a letter follows, then if the word here is `line', skip
  1988.      it and ignore it; otherwise, ignore the line, with an error
  1989.      if the word isn't `pragma'.  */
  1990.  
  1991.   if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
  1992.     {
  1993.       if (c == 'p')
  1994.     {
  1995.       if (getc (finput) == 'r'
  1996.           && getc (finput) == 'a'
  1997.           && getc (finput) == 'g'
  1998.           && getc (finput) == 'm'
  1999.           && getc (finput) == 'a'
  2000.           && ((c = getc (finput)) == ' ' || c == '\t' || c == '\n'))
  2001.         {
  2002. #ifdef HANDLE_PRAGMA
  2003.           HANDLE_PRAGMA (finput);
  2004. #endif /* HANDLE_PRAGMA */
  2005.           goto skipline;
  2006.         }
  2007.     }
  2008.  
  2009.       else if (c == 'l')
  2010.     {
  2011.       if (getc (finput) == 'i'
  2012.           && getc (finput) == 'n'
  2013.           && getc (finput) == 'e'
  2014.           && ((c = getc (finput)) == ' ' || c == '\t'))
  2015.         goto linenum;
  2016.     }
  2017.       else if (c == 'i')
  2018.     {
  2019.       if (getc (finput) == 'd'
  2020.           && getc (finput) == 'e'
  2021.           && getc (finput) == 'n'
  2022.           && getc (finput) == 't'
  2023.           && ((c = getc (finput)) == ' ' || c == '\t'))
  2024.         {
  2025.           extern FILE *asm_out_file;
  2026.  
  2027.           if (pedantic)
  2028.         error ("ANSI C does not allow #ident");
  2029.  
  2030.           /* Here we have just seen `#ident '.
  2031.          A string constant should follow.  */
  2032.  
  2033.           while (c == ' ' || c == '\t')
  2034.         c = getc (finput);
  2035.  
  2036.           /* If no argument, ignore the line.  */
  2037.           if (c == '\n')
  2038.         return c;
  2039.  
  2040.           ungetc (c, finput);
  2041.           token = yylex ();
  2042.           if (token != STRING
  2043.           || TREE_CODE (yylval.ttype) != STRING_CST)
  2044.         {
  2045.           error ("invalid #ident");
  2046.           goto skipline;
  2047.         }
  2048.  
  2049. #ifdef ASM_OUTPUT_IDENT
  2050.           ASM_OUTPUT_IDENT (asm_out_file, TREE_STRING_POINTER (yylval.ttype));
  2051. #endif
  2052.  
  2053.           /* Skip the rest of this line.  */
  2054.           goto skipline;
  2055.         }
  2056.     }
  2057.  
  2058.       error ("undefined or invalid # directive");
  2059.       goto skipline;
  2060.     }
  2061.  
  2062. linenum:
  2063.   /* Here we have either `#line' or `# <nonletter>'.
  2064.      In either case, it should be a line number; a digit should follow.  */
  2065.  
  2066.   while (c == ' ' || c == '\t')
  2067.     c = getc (finput);
  2068.  
  2069.   /* If the # is the only nonwhite char on the line,
  2070.      just ignore it.  Check the new newline.  */
  2071.   if (c == '\n')
  2072.     return c;
  2073.  
  2074.   /* Something follows the #; read a token.  */
  2075.  
  2076.   ungetc (c, finput);
  2077.   token = yylex ();
  2078.  
  2079.   if (token == CONSTANT
  2080.       && TREE_CODE (yylval.ttype) == INTEGER_CST)
  2081.     {
  2082.       int old_lineno = lineno;
  2083.       /* subtract one, because it is the following line that
  2084.      gets the specified number */
  2085.  
  2086.       int l = TREE_INT_CST_LOW (yylval.ttype) - 1;
  2087.  
  2088.       /* Is this the last nonwhite stuff on the line?  */
  2089.       c = getc (finput);
  2090.       while (c == ' ' || c == '\t')
  2091.     c = getc (finput);
  2092.       if (c == '\n')
  2093.     {
  2094.       /* No more: store the line number and check following line.  */
  2095.       lineno = l;
  2096.       return c;
  2097.     }
  2098.       ungetc (c, finput);
  2099.  
  2100.       /* More follows: it must be a string constant (filename).  */
  2101.  
  2102.       token = yylex ();
  2103.       if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)
  2104.     {
  2105.       error ("invalid #line");
  2106.       goto skipline;
  2107.     }
  2108.  
  2109.       input_filename
  2110.     = (char *) permalloc (TREE_STRING_LENGTH (yylval.ttype) + 1);
  2111.       strcpy (input_filename, TREE_STRING_POINTER (yylval.ttype));
  2112.       lineno = l;
  2113.  
  2114.       if (main_input_filename == 0)
  2115.     main_input_filename = input_filename;
  2116.  
  2117.       /* Is this the last nonwhite stuff on the line?  */
  2118.       c = getc (finput);
  2119.       while (c == ' ' || c == '\t')
  2120.     c = getc (finput);
  2121.       if (c == '\n')
  2122.     return c;
  2123.       ungetc (c, finput);
  2124.  
  2125.       token = yylex ();
  2126.  
  2127.       /* `1' after file name means entering new file.
  2128.      `2' after file name means just left a file.  */
  2129.  
  2130.       if (token == CONSTANT
  2131.       && TREE_CODE (yylval.ttype) == INTEGER_CST)
  2132.     {
  2133.       if (TREE_INT_CST_LOW (yylval.ttype) == 1)
  2134.         {
  2135.           struct file_stack *p
  2136.         = (struct file_stack *) xmalloc (sizeof (struct file_stack));
  2137.           input_file_stack->line = old_lineno;
  2138.           p->next = input_file_stack;
  2139.           p->name = input_filename;
  2140.           input_file_stack = p;
  2141.           input_file_stack_tick++;
  2142.         }
  2143.       else if (input_file_stack->next)
  2144.         {
  2145.           struct file_stack *p = input_file_stack;
  2146.           input_file_stack = p->next;
  2147.           free (p);
  2148.           input_file_stack_tick++;
  2149.         }
  2150.       else
  2151.         error ("#-lines for entering and leaving files don't match");
  2152.     }
  2153.     }
  2154.   else
  2155.     error ("invalid #-line");
  2156.  
  2157.   /* skip the rest of this line.  */
  2158.  skipline:
  2159.   if (c == '\n')
  2160.     return c;
  2161.   while ((c = getc (finput)) != EOF && c != '\n');
  2162.   return c;
  2163. }
  2164.  
  2165. #define isalnum(char) ((char >= 'a' && char <= 'z') || (char >= 'A' && char <= 'Z') || (char >= '0' && char <= '9'))
  2166. #define isdigit(char) (char >= '0' && char <= '9')
  2167. #define ENDFILE -1  /* token that represents end-of-file */
  2168.  
  2169.  
  2170. static int
  2171. readescape ()
  2172. {
  2173.   register int c = getc (finput);
  2174.   register int count, code;
  2175.   int firstdig;
  2176.  
  2177.   switch (c)
  2178.     {
  2179.     case 'x':
  2180.       code = 0;
  2181.       count = 0;
  2182.       while (1)
  2183.     {
  2184.       c = getc (finput);
  2185.       if (!(c >= 'a' && c <= 'f')
  2186.           && !(c >= 'A' && c <= 'F')
  2187.           && !(c >= '0' && c <= '9'))
  2188.         {
  2189.           ungetc (c, finput);
  2190.           break;
  2191.         }
  2192.       code *= 16;
  2193.       if (c >= 'a' && c <= 'f')
  2194.         code += c - 'a' + 10;
  2195.       if (c >= 'A' && c <= 'F')
  2196.         code += c - 'A' + 10;
  2197.       if (c >= '0' && c <= '9')
  2198.         code += c - '0';
  2199.       if (count == 0)
  2200.         firstdig = code;
  2201.       count++;
  2202.     }
  2203.       if (count == 0)
  2204.     error ("\\x used with no following hex digits");
  2205.       else if ((count - 1) * 4 >= TYPE_PRECISION (integer_type_node)
  2206.            || (count > 1
  2207.            && ((1 << (TYPE_PRECISION (integer_type_node) - (count - 1) * 4))
  2208.                <= firstdig)))
  2209.     pedwarn ("hex escape out of range");
  2210.       return code;
  2211.  
  2212.     case '0':  case '1':  case '2':  case '3':  case '4':
  2213.     case '5':  case '6':  case '7':
  2214.       code = 0;
  2215.       count = 0;
  2216.       while ((c <= '7') && (c >= '0') && (count++ < 3))
  2217.     {
  2218.       code = (code * 8) + (c - '0');
  2219.       c = getc (finput);
  2220.     }
  2221.       ungetc (c, finput);
  2222.       return code;
  2223.  
  2224.     case '\\': case '\'': case '"':
  2225.       return c;
  2226.  
  2227.     case '\n':
  2228.       lineno++;
  2229.       return -1;
  2230.  
  2231.     case 'n':
  2232.       return TARGET_NEWLINE;
  2233.  
  2234.     case 't':
  2235.       return TARGET_TAB;
  2236.  
  2237.     case 'r':
  2238.       return TARGET_CR;
  2239.  
  2240.     case 'f':
  2241.       return TARGET_FF;
  2242.  
  2243.     case 'b':
  2244.       return TARGET_BS;
  2245.  
  2246.     case 'a':
  2247.       return TARGET_BELL;
  2248.  
  2249.     case 'v':
  2250.       return TARGET_VT;
  2251.  
  2252.     case 'E':
  2253.       pedwarn ("non-ANSI-standard escape sequence, `\\E'");
  2254.       return 033;
  2255.  
  2256.     case '?':
  2257.       /* `\(', etc, are used at beginning of line to avoid confusing Emacs.  */
  2258.     case '(':
  2259.     case '{':
  2260.     case '[':
  2261.       return c;
  2262.     }
  2263.   if (c >= 040 && c <= 0177)
  2264.     pedwarn ("unknown escape sequence `\\%c'", c);
  2265.   else
  2266.     pedwarn ("unknown escape sequence: `\\' followed by char code 0x%x", c);
  2267.   return c;
  2268. }
  2269.  
  2270. void
  2271. yyerror (string)
  2272.      char *string;
  2273. {
  2274.   char buf[200];
  2275.  
  2276.   strcpy (buf, string);
  2277.  
  2278.   /* We can't print string and character constants well
  2279.      because the token_buffer contains the result of processing escapes.  */
  2280.   if (end_of_file)
  2281.     strcat (buf, " at end of input");
  2282.   else if (token_buffer[0] == 0)
  2283.     strcat (buf, " at null character");
  2284.   else if (token_buffer[0] == '"')
  2285.     strcat (buf, " before string constant");
  2286.   else if (token_buffer[0] == '\'')
  2287.     strcat (buf, " before character constant");
  2288.   else if (token_buffer[0] < 040 || token_buffer[0] >= 0177)
  2289.     sprintf (buf + strlen (buf), " before character 0%o", token_buffer[0]);
  2290.   else
  2291.     strcat (buf, " before `%s'");
  2292.  
  2293.   error (buf, token_buffer);
  2294. }
  2295.  
  2296. struct try_type
  2297. {
  2298.   tree *node_var;
  2299.   char unsigned_flag;
  2300.   char long_flag;
  2301.   char long_long_flag;
  2302. };
  2303.  
  2304. struct try_type type_sequence[] = 
  2305. {
  2306.   { &integer_type_node, 0, 0, 0},
  2307.   { &unsigned_type_node, 1, 0, 0},
  2308.   { &long_integer_type_node, 0, 1, 0},
  2309.   { &long_unsigned_type_node, 1, 1, 0},
  2310.   { &long_long_integer_type_node, 0, 1, 1},
  2311.   { &long_long_unsigned_type_node, 1, 1, 1}
  2312. };
  2313.  
  2314. static int
  2315. yylex ()
  2316. {
  2317.   register int c;
  2318.   register char *p;
  2319.   register int value;
  2320.   int wide_flag = 0;
  2321.  
  2322.   if (nextchar >= 0)
  2323.     c = nextchar, nextchar = -1;
  2324.   else
  2325.     c = getc (finput);
  2326.  
  2327.   /* Effectively do c = skip_white_space (c)
  2328.      but do it faster in the usual cases.  */
  2329.   while (1)
  2330.     switch (c)
  2331.       {
  2332.       case '\r':
  2333.     if (pedantic)    /* ANSI says no */
  2334.       goto found_nonwhite;
  2335.       case ' ':
  2336.       case '\t':
  2337.       case '\f':
  2338.       case '\v':
  2339.       case '\b':
  2340.     c = getc (finput);
  2341.     break;
  2342.  
  2343.       case '\n':
  2344.       case '/':
  2345.       case '\\':
  2346.     c = skip_white_space (c);
  2347.       default:
  2348.     goto found_nonwhite;
  2349.       }
  2350.  found_nonwhite:
  2351.  
  2352.   token_buffer[0] = c;
  2353.   token_buffer[1] = 0;
  2354.  
  2355. /*  yylloc.first_line = lineno; */
  2356.  
  2357.   switch (c)
  2358.     {
  2359.     case EOF:
  2360.       end_of_file = 1;
  2361.       token_buffer[0] = 0;
  2362.       value = ENDFILE;
  2363.       break;
  2364.  
  2365.     case '$':
  2366.       if (dollars_in_ident)
  2367.     goto letter;
  2368.       return '$';
  2369.  
  2370.     case 'L':
  2371.       /* Capital L may start a wide-string or wide-character constant.  */
  2372.       {
  2373.     register int c = getc (finput);
  2374.     if (c == '\'')
  2375.       {
  2376.         wide_flag = 1;
  2377.         goto char_constant;
  2378.       }
  2379.     if (c == '"')
  2380.       {
  2381.         wide_flag = 1;
  2382.         goto string_constant;
  2383.       }
  2384.     ungetc (c, finput);
  2385.       }
  2386.  
  2387.     case 'A':  case 'B':  case 'C':  case 'D':  case 'E':
  2388.     case 'F':  case 'G':  case 'H':  case 'I':  case 'J':
  2389.     case 'K':          case 'M':  case 'N':  case 'O':
  2390.     case 'P':  case 'Q':  case 'R':  case 'S':  case 'T':
  2391.     case 'U':  case 'V':  case 'W':  case 'X':  case 'Y':
  2392.     case 'Z':
  2393.     case 'a':  case 'b':  case 'c':  case 'd':  case 'e':
  2394.     case 'f':  case 'g':  case 'h':  case 'i':  case 'j':
  2395.     case 'k':  case 'l':  case 'm':  case 'n':  case 'o':
  2396.     case 'p':  case 'q':  case 'r':  case 's':  case 't':
  2397.     case 'u':  case 'v':  case 'w':  case 'x':  case 'y':
  2398.     case 'z':
  2399.     case '_':
  2400.     letter:
  2401.       p = token_buffer;
  2402.       while (isalnum (c) || c == '_' || c == '$')
  2403.     {
  2404.       if (p >= token_buffer + maxtoken)
  2405.         p = extend_token_buffer (p);
  2406.       if (c == '$' && ! dollars_in_ident)
  2407.         break;
  2408.  
  2409.       *p++ = c;
  2410.       c = getc (finput);
  2411.     }
  2412.  
  2413.       *p = 0;
  2414.       nextchar = c;
  2415.  
  2416.       value = IDENTIFIER;
  2417.       yylval.itype = 0;
  2418.  
  2419.       /* Try to recognize a keyword.  Uses minimum-perfect hash function */
  2420.  
  2421.       {
  2422.     register struct resword *ptr;
  2423.  
  2424.     if (ptr = is_reserved_word (token_buffer, p - token_buffer))
  2425.       {
  2426.         if (ptr->rid)
  2427.           yylval.ttype = ridpointers[(int) ptr->rid];
  2428.         value = (int) ptr->token;
  2429.       }
  2430.       }
  2431.  
  2432.       /* If we did not find a keyword, look for an identifier
  2433.      (or a typename).  */
  2434.  
  2435.       if (value == IDENTIFIER)
  2436.     {
  2437.           yylval.ttype = get_identifier (token_buffer);
  2438.       lastiddecl = lookup_name (yylval.ttype);
  2439.  
  2440.       if (lastiddecl != 0 && TREE_CODE (lastiddecl) == TYPE_DECL)
  2441.         value = TYPENAME;
  2442.     }
  2443.  
  2444.       break;
  2445.  
  2446.     case '0':  case '1':  case '2':  case '3':  case '4':
  2447.     case '5':  case '6':  case '7':  case '8':  case '9':
  2448.     case '.':
  2449.       {
  2450.     int base = 10;
  2451.     int count = 0;
  2452.     int largest_digit = 0;
  2453.     int numdigits = 0;
  2454.     /* for multi-precision arithmetic,
  2455.        we store only 8 live bits in each short,
  2456.        giving us 64 bits of reliable precision */
  2457.     short shorts[8];
  2458.     int overflow = 0;
  2459.  
  2460.     enum anon1 { NOT_FLOAT, AFTER_POINT, TOO_MANY_POINTS} floatflag
  2461.       = NOT_FLOAT;
  2462.  
  2463.     for (count = 0; count < 8; count++)
  2464.       shorts[count] = 0;
  2465.  
  2466.     p = token_buffer;
  2467.     *p++ = c;
  2468.  
  2469.     if (c == '0')
  2470.       {
  2471.         *p++ = (c = getc (finput));
  2472.         if ((c == 'x') || (c == 'X'))
  2473.           {
  2474.         base = 16;
  2475.         *p++ = (c = getc (finput));
  2476.           }
  2477.         /* Leading 0 forces octal unless the 0 is the only digit.  */
  2478.         else if (c >= '0' && c <= '9')
  2479.           {
  2480.         base = 8;
  2481.         numdigits++;
  2482.           }
  2483.         else
  2484.           numdigits++;
  2485.       }
  2486.  
  2487.     /* Read all the digits-and-decimal-points.  */
  2488.  
  2489.     while (c == '.'
  2490.            || (isalnum (c) && (c != 'l') && (c != 'L')
  2491.            && (c != 'u') && (c != 'U')
  2492.            && (floatflag == NOT_FLOAT || ((c != 'f') && (c != 'F')))))
  2493.       {
  2494.         if (c == '.')
  2495.           {
  2496.         if (base == 16)
  2497.           error ("floating constant may not be in radix 16");
  2498.         if (floatflag == AFTER_POINT)
  2499.           {
  2500.             error ("malformed floating constant");
  2501.             floatflag = TOO_MANY_POINTS;
  2502.           }
  2503.         else
  2504.           floatflag = AFTER_POINT;
  2505.  
  2506.         base = 10;
  2507.         *p++ = c = getc (finput);
  2508.         /* Accept '.' as the start of a floating-point number
  2509.            only when it is followed by a digit.
  2510.            Otherwise, unread the following non-digit
  2511.            and use the '.' as a structural token.  */
  2512.         if (p == token_buffer + 2 && !isdigit (c))
  2513.           {
  2514.             if (c == '.')
  2515.               {
  2516.             c = getc (finput);
  2517.             if (c == '.')
  2518.               {
  2519.                 *p++ = c;
  2520.                 *p = 0;
  2521.                 return ELLIPSIS;
  2522.               }
  2523.             error ("parse error at `..'");
  2524.               }
  2525.             ungetc (c, finput);
  2526.             token_buffer[1] = 0;
  2527.             value = '.';
  2528.             goto done;
  2529.           }
  2530.           }
  2531.         else
  2532.           {
  2533.         /* It is not a decimal point.
  2534.            It should be a digit (perhaps a hex digit).  */
  2535.  
  2536.         if (isdigit (c))
  2537.           {
  2538.             c = c - '0';
  2539.           }
  2540.         else if (base <= 10)
  2541.           {
  2542.             if ((c&~040) == 'E')
  2543.               {
  2544.             base = 10;
  2545.             floatflag = AFTER_POINT;
  2546.             break;   /* start of exponent */
  2547.               }
  2548.             error ("nondigits in number and not hexadecimal");
  2549.             c = 0;
  2550.           }
  2551.         else if (c >= 'a')
  2552.           {
  2553.             c = c - 'a' + 10;
  2554.           }
  2555.         else
  2556.           {
  2557.             c = c - 'A' + 10;
  2558.           }
  2559.         if (c >= largest_digit)
  2560.           largest_digit = c;
  2561.         numdigits++;
  2562.  
  2563.         for (count = 0; count < 8; count++)
  2564.           {
  2565.             shorts[count] *= base;
  2566.             if (count)
  2567.               {
  2568.             shorts[count] += (shorts[count-1] >> 8);
  2569.             shorts[count-1] &= (1<<8)-1;
  2570.               }
  2571.             else shorts[0] += c;
  2572.           }
  2573.  
  2574.         if (shorts[7] >= 1<<8
  2575.             || shorts[7] < - (1 << 8))
  2576.           overflow = TRUE;
  2577.  
  2578.         if (p >= token_buffer + maxtoken - 3)
  2579.           p = extend_token_buffer (p);
  2580.         *p++ = (c = getc (finput));
  2581.           }
  2582.       }
  2583.  
  2584.     if (numdigits == 0)
  2585.       error ("numeric constant with no digits");
  2586.  
  2587.     if (largest_digit >= base)
  2588.       error ("numeric constant contains digits beyond the radix");
  2589.  
  2590.     /* Remove terminating char from the token buffer and delimit the string */
  2591.     *--p = 0;
  2592.  
  2593.     if (floatflag != NOT_FLOAT)
  2594.       {
  2595.         tree type = double_type_node;
  2596.         char f_seen = 0;
  2597.         char l_seen = 0;
  2598.         REAL_VALUE_TYPE value;
  2599.         jmp_buf handler;
  2600.  
  2601.         /* Read explicit exponent if any, and put it in tokenbuf.  */
  2602.  
  2603.         if ((c == 'e') || (c == 'E'))
  2604.           {
  2605.         if (p >= token_buffer + maxtoken - 3)
  2606.           p = extend_token_buffer (p);
  2607.         *p++ = c;
  2608.         c = getc (finput);
  2609.         if ((c == '+') || (c == '-'))
  2610.           {
  2611.             *p++ = c;
  2612.             c = getc (finput);
  2613.           }
  2614.         if (! isdigit (c))
  2615.           error ("floating constant exponent has no digits");
  2616.             while (isdigit (c))
  2617.           {
  2618.             if (p >= token_buffer + maxtoken - 3)
  2619.               p = extend_token_buffer (p);
  2620.             *p++ = c;
  2621.             c = getc (finput);
  2622.           }
  2623.           }
  2624.  
  2625.         *p = 0;
  2626.         errno = 0;
  2627.  
  2628.         /* Convert string to a double, checking for overflow.  */
  2629.         if (setjmp (handler))
  2630.           {
  2631.         error ("floating constant out of range");
  2632.         value = dconst0;
  2633.           }
  2634.         else
  2635.           {
  2636.         set_float_handler (handler);
  2637.         value = REAL_VALUE_ATOF (token_buffer);
  2638.         set_float_handler (0);
  2639.           }
  2640. #ifdef ERANGE
  2641.         if (errno == ERANGE && !flag_traditional)
  2642.           {
  2643.         char *p1 = token_buffer;
  2644.         /* Check for "0.0" and variants;
  2645.            Sunos 4 spuriously returns ERANGE for them.  */
  2646.         while (*p1 == '0') p1++;
  2647.         if (*p1 == '.')
  2648.           {
  2649.             p1++;
  2650.             while (*p1 == '0') p1++;
  2651.           }
  2652.         if (*p1 == 'e' || *p1 == 'E')
  2653.           {
  2654.             /* with significand==0, ignore the exponent */
  2655.             p1++;
  2656.             while (*p1 != 0) p1++;
  2657.           }
  2658.         /* ERANGE is also reported for underflow,
  2659.            so test the value to distinguish overflow from that.  */
  2660.         if (*p1 != 0 && (value > 1.0 || value < -1.0))
  2661.           warning ("floating point number exceeds range of `double'");
  2662.           }
  2663. #endif
  2664.  
  2665.         /* Read the suffixes to choose a data type.  */
  2666.         while (1)
  2667.           {
  2668.         if (c == 'f' || c == 'F')
  2669.           {
  2670.             if (f_seen)
  2671.               error ("two `f's in floating constant");
  2672.             f_seen = 1;
  2673.             type = float_type_node;
  2674.             value = REAL_VALUE_TRUNCATE (value);
  2675.           }
  2676.         else if (c == 'l' || c == 'L')
  2677.           {
  2678.             if (l_seen)
  2679.               error ("two `l's in floating constant");
  2680.             l_seen = 1;
  2681.             type = long_double_type_node;
  2682.           }
  2683.         else
  2684.           {
  2685.             if (isalnum (c))
  2686.               {
  2687.             error ("garbage at end of number");
  2688.             while (isalnum (c))
  2689.               {
  2690.                 if (p >= token_buffer + maxtoken - 3)
  2691.                   p = extend_token_buffer (p);
  2692.                 *p++ = c;
  2693.                 c = getc (finput);
  2694.               }
  2695.               }
  2696.             break;
  2697.           }
  2698.         if (p >= token_buffer + maxtoken - 3)
  2699.           p = extend_token_buffer (p);
  2700.         *p++ = c;
  2701.         c = getc (finput);
  2702.           }
  2703.  
  2704.         /* Create a node with determined type and value.  */
  2705.         yylval.ttype = build_real (type, value);
  2706.  
  2707.         ungetc (c, finput);
  2708.         *p = 0;
  2709.       }
  2710.     else
  2711.       {
  2712.         tree type;
  2713.         int spec_unsigned = 0;
  2714.         int spec_long = 0;
  2715.         int spec_long_long = 0;
  2716.  
  2717.         while (1)
  2718.           {
  2719.         if (c == 'u' || c == 'U')
  2720.           {
  2721.             if (spec_unsigned)
  2722.               error ("two `u's in integer constant");
  2723.             spec_unsigned = 1;
  2724.           }
  2725.         else if (c == 'l' || c == 'L')
  2726.           {
  2727.             if (spec_long)
  2728.               {
  2729.             if (spec_long_long)
  2730.               error ("three `l's in integer constant");
  2731.             else if (pedantic)
  2732.               pedwarn ("ANSI C forbids long long integer constants");
  2733.             spec_long_long = 1;
  2734.               }
  2735.             spec_long = 1;
  2736.           }
  2737.         else
  2738.           {
  2739.             if (isalnum (c))
  2740.               {
  2741.             error ("garbage at end of number");
  2742.             while (isalnum (c))
  2743.               {
  2744.                 if (p >= token_buffer + maxtoken - 3)
  2745.                   p = extend_token_buffer (p);
  2746.                 *p++ = c;
  2747.                 c = getc (finput);
  2748.               }
  2749.               }
  2750.             break;
  2751.           }
  2752.         if (p >= token_buffer + maxtoken - 3)
  2753.           p = extend_token_buffer (p);
  2754.         *p++ = c;
  2755.         c = getc (finput);
  2756.           }
  2757.  
  2758.         ungetc (c, finput);
  2759.  
  2760.         if ((overflow || shorts[7] || shorts[6] || shorts[5] || shorts[4])
  2761.         && !spec_long_long)
  2762.           warning ("integer constant out of range");
  2763.  
  2764.         /* If it won't fit in a signed long long, make it unsigned.
  2765.            We can't distinguish based on the tree node because
  2766.            any integer constant fits any long long type.  */
  2767.         if (shorts[7] >= (1<<8))
  2768.           spec_unsigned = 1;
  2769.  
  2770.         /* This is simplified by the fact that our constant
  2771.            is always positive.  */
  2772.         yylval.ttype
  2773.           = (build_int_2
  2774.          ((shorts[3]<<24) + (shorts[2]<<16) + (shorts[1]<<8) + shorts[0],
  2775.           (spec_long_long
  2776.            ? (shorts[7]<<24) + (shorts[6]<<16) + (shorts[5]<<8) + shorts[4]
  2777.            : 0)));
  2778.  
  2779. #if 0
  2780.         /* Find the first allowable type that the value fits in.  */
  2781.         type = 0;
  2782.         for (i = 0; i < sizeof (type_sequence) / sizeof (type_sequence[0]);
  2783.          i++)
  2784.           if (!(spec_long && !type_sequence[i].long_flag)
  2785.           && !(spec_long_long && !type_sequence[i].long_long_flag)
  2786.           && !(spec_unsigned && !type_sequence[i].unsigned_flag)
  2787.           /* A decimal constant can't be unsigned int
  2788.              unless explicitly specified.  */
  2789.           && !(base == 10 && !spec_unsigned
  2790.                && *type_sequence[i].node_var == unsigned_type_node))
  2791.         if (int_fits_type_p (yylval.ttype, *type_sequence[i].node_var))
  2792.           {
  2793.             type = *type_sequence[i].node_var;
  2794.             break;
  2795.           }
  2796.         if (flag_traditional && type == long_unsigned_type_node
  2797.         && !spec_unsigned)
  2798.           type = long_integer_type_node;
  2799.           
  2800.         if (type == 0)
  2801.           {
  2802.         type = long_long_integer_type_node;
  2803.         warning ("integer constant out of range");
  2804.           }
  2805.  
  2806.         /* Warn about some cases where the type of a given constant
  2807.            changes from traditional C to ANSI C.  */
  2808.         if (warn_traditional)
  2809.           {
  2810.         tree other_type = 0;
  2811.  
  2812.         /* This computation is the same as the previous one
  2813.            except that flag_traditional is used backwards.  */
  2814.         for (i = 0; i < sizeof (type_sequence) / sizeof (type_sequence[0]);
  2815.              i++)
  2816.           if (!(spec_long && !type_sequence[i].long_flag)
  2817.               && !(spec_long_long && !type_sequence[i].long_long_flag)
  2818.               && !(spec_unsigned && !type_sequence[i].unsigned_flag)
  2819.               /* A decimal constant can't be unsigned int
  2820.              unless explicitly specified.  */
  2821.               && !(base == 10 && !spec_unsigned
  2822.                && *type_sequence[i].node_var == unsigned_type_node))
  2823.             if (int_fits_type_p (yylval.ttype, *type_sequence[i].node_var))
  2824.               {
  2825.             other_type = *type_sequence[i].node_var;
  2826.             break;
  2827.               }
  2828.         if (!flag_traditional && type == long_unsigned_type_node
  2829.             && !spec_unsigned)
  2830.           type = long_integer_type_node;
  2831.           
  2832.         if (other_type != 0 && other_type != type)
  2833.           {
  2834.             if (flag_traditional)
  2835.               warning ("type of integer constant would be different without -traditional");
  2836.             else
  2837.               warning ("type of integer constant would be different with -traditional");
  2838.           }
  2839.           }
  2840.  
  2841. #else /* 1 */
  2842.         if (!spec_long && !spec_unsigned
  2843.         && !(flag_traditional && base != 10)
  2844.         && int_fits_type_p (yylval.ttype, integer_type_node))
  2845.           {
  2846.         if (warn_traditional && base != 10)
  2847.           warning ("small nondecimal constant becomes signed in ANSI C");
  2848.         type = integer_type_node;
  2849.           }
  2850.         else if (!spec_long && (base != 10 || spec_unsigned)
  2851.              && int_fits_type_p (yylval.ttype, unsigned_type_node))
  2852.           {
  2853.         /* Nondecimal constants try unsigned even in traditional C.  */
  2854.         type = unsigned_type_node;
  2855.           }
  2856.  
  2857.         else if (!spec_unsigned && !spec_long_long
  2858.              && int_fits_type_p (yylval.ttype, long_integer_type_node))
  2859.           type = long_integer_type_node;
  2860.  
  2861.         else if (! spec_long_long
  2862.              && int_fits_type_p (yylval.ttype,
  2863.                      long_unsigned_type_node))
  2864.           {
  2865.         if (warn_traditional && !spec_unsigned)
  2866.           warning ("large integer constant becomes unsigned in ANSI C");
  2867.         if (flag_traditional && !spec_unsigned)
  2868.           type = long_integer_type_node;
  2869.         else
  2870.           type = long_unsigned_type_node;
  2871.           }
  2872.  
  2873.         else if (! spec_unsigned
  2874.              && int_fits_type_p (yylval.ttype,
  2875.                      long_long_integer_type_node))
  2876.           type = long_long_integer_type_node;
  2877.  
  2878.         else if (int_fits_type_p (yylval.ttype,
  2879.                       long_long_unsigned_type_node))
  2880.           {
  2881.         if (warn_traditional && !spec_unsigned)
  2882.           warning ("large nondecimal constant is unsigned in ANSI C");
  2883.         if (flag_traditional && !spec_unsigned)
  2884.           type = long_long_integer_type_node;
  2885.         else
  2886.           type = long_long_unsigned_type_node;
  2887.           }
  2888.  
  2889.         else
  2890.           {
  2891.         type = long_long_integer_type_node;
  2892.         warning ("integer constant out of range");
  2893.           }
  2894. #endif
  2895.  
  2896.         TREE_TYPE (yylval.ttype) = type;
  2897.         *p = 0;
  2898.       }
  2899.  
  2900.     value = CONSTANT; break;
  2901.       }
  2902.  
  2903.     case '\'':
  2904.     char_constant:
  2905.       {
  2906.     register int result = 0;
  2907.     register num_chars = 0;
  2908.     int width = TYPE_PRECISION (char_type_node);
  2909.     int max_chars;
  2910.  
  2911.     if (wide_flag)
  2912.       {
  2913.         width = WCHAR_TYPE_SIZE;
  2914. #ifdef MULTIBYTE_CHARS
  2915.         max_chars = MB_CUR_MAX;
  2916. #else
  2917.         max_chars = 1;
  2918. #endif
  2919.       }
  2920.     else
  2921.       max_chars = TYPE_PRECISION (integer_type_node) / width;
  2922.  
  2923.     while (1)
  2924.       {
  2925.       tryagain:
  2926.  
  2927.         c = getc (finput);
  2928.  
  2929.         if (c == '\'' || c == EOF)
  2930.           break;
  2931.  
  2932.         if (c == '\\')
  2933.           {
  2934.         c = readescape ();
  2935.         if (c < 0)
  2936.           goto tryagain;
  2937.         if (width < HOST_BITS_PER_INT
  2938.             && (unsigned) c >= (1 << width))
  2939.           pedwarn ("escape sequence out of range for character");
  2940.           }
  2941.         else if (c == '\n')
  2942.           {
  2943.         if (pedantic)
  2944.           pedwarn ("ANSI C forbids newline in character constant");
  2945.         lineno++;
  2946.           }
  2947.  
  2948.         num_chars++;
  2949.         if (num_chars > maxtoken - 4)
  2950.           extend_token_buffer (token_buffer);
  2951.  
  2952.         token_buffer[num_chars] = c;
  2953.  
  2954.         /* Merge character into result; ignore excess chars.  */
  2955.         if (num_chars < max_chars + 1)
  2956.           {
  2957.         if (width < HOST_BITS_PER_INT)
  2958.           result = (result << width) | (c & ((1 << width) - 1));
  2959.         else
  2960.           result = c;
  2961.           }
  2962.       }
  2963.  
  2964.     token_buffer[num_chars + 1] = '\'';
  2965.     token_buffer[num_chars + 2] = 0;
  2966.  
  2967.     if (c != '\'')
  2968.       error ("malformatted character constant");
  2969.     else if (num_chars == 0)
  2970.       error ("empty character constant");
  2971.     else if (num_chars > max_chars)
  2972.       {
  2973.         num_chars = max_chars;
  2974.         error ("character constant too long");
  2975.       }
  2976.     else if (num_chars != 1 && ! flag_traditional)
  2977.       warning ("multi-character character constant");
  2978.  
  2979.     /* If char type is signed, sign-extend the constant.  */
  2980.     if (! wide_flag)
  2981.       {
  2982.         int num_bits = num_chars * width;
  2983.         if (TREE_UNSIGNED (char_type_node)
  2984.         || ((result >> (num_bits - 1)) & 1) == 0)
  2985.           yylval.ttype
  2986.         = build_int_2 (result & ((unsigned) ~0
  2987.                      >> (HOST_BITS_PER_INT - num_bits)),
  2988.                    0);
  2989.         else
  2990.           yylval.ttype
  2991.         = build_int_2 (result | ~((unsigned) ~0
  2992.                       >> (HOST_BITS_PER_INT - num_bits)),
  2993.                    -1);
  2994.       }
  2995.     else
  2996.       {
  2997. #ifdef MULTIBYTE_CHARS
  2998.         /* Set the initial shift state and convert the next sequence.  */
  2999.         result = 0;
  3000.         if (num_chars)
  3001.           {
  3002.         wchar_t wc;
  3003.         (void) mbtowc (NULL, NULL, 0);
  3004.         if (mbtowc (& wc, token_buffer + 1, num_chars) == num_chars)
  3005.           result = wc;
  3006.         else
  3007.           warning ("Ignoring invalide multibyte character");
  3008.           }
  3009. #endif
  3010.         yylval.ttype = build_int_2 (result, 0);
  3011.       }
  3012.  
  3013.     TREE_TYPE (yylval.ttype) = integer_type_node;
  3014.     value = CONSTANT; break;
  3015.       }
  3016.  
  3017.     case '"':
  3018.     string_constant:
  3019.       {
  3020.     c = getc (finput);
  3021.     p = token_buffer + 1;
  3022.  
  3023.     while (c != '"' && c >= 0)
  3024.       {
  3025.         if (c == '\\')
  3026.           {
  3027.         c = readescape ();
  3028.         if (c < 0)
  3029.           goto skipnewline;
  3030.         if (!wide_flag && c >= (1 << TYPE_PRECISION (char_type_node)))
  3031.           pedwarn ("escape sequence out of range for character");
  3032.           }
  3033.         else if (c == '\n')
  3034.           {
  3035.         if (pedantic)
  3036.           pedwarn ("ANSI C forbids newline in string constant");
  3037.         lineno++;
  3038.           }
  3039.  
  3040.         if (p == token_buffer + maxtoken)
  3041.           p = extend_token_buffer (p);
  3042.         *p++ = c;
  3043.  
  3044.       skipnewline:
  3045.         c = getc (finput);
  3046.       }
  3047.     *p = 0;
  3048.  
  3049.     /* We have read the entire constant.
  3050.        Construct a STRING_CST for the result.  */
  3051.  
  3052.     if (wide_flag)
  3053.       {
  3054.         /* If this is a L"..." wide-string, convert the multibyte string
  3055.            to a wide character string.  */
  3056.         char *widep = (char *) alloca ((p - token_buffer) * WCHAR_BYTES);
  3057.         int len;
  3058.  
  3059. #ifdef MULTIBYTE_CHARS
  3060.         len = mbstowcs ((wchar_t *) widep, token_buffer + 1, p - token_buffer);
  3061.         if ((unsigned) len >= (p - token_buffer))
  3062.           {
  3063.         warning ("Ignoring invalid multibyte string");
  3064.         len = 0;
  3065.           }
  3066.         bzero (widep + (len * WCHAR_BYTES), WCHAR_BYTES);
  3067. #else
  3068.         {
  3069.           union { long l; char c[sizeof (long)]; } u;
  3070.           int big_endian;
  3071.           char *wp, *cp;
  3072.  
  3073.           /* Determine whether host is little or big endian.  */
  3074.           u.l = 1;
  3075.           big_endian = u.c[sizeof (long) - 1];
  3076.           wp = widep + (big_endian ? WCHAR_BYTES - 1 : 0);
  3077.  
  3078.           bzero (widep, (p - token_buffer) * WCHAR_BYTES);
  3079.           for (cp = token_buffer + 1; cp < p; cp++)
  3080.         *wp = *cp, wp += WCHAR_BYTES;
  3081.           len = p - token_buffer - 1;
  3082.         }
  3083. #endif
  3084.         yylval.ttype = build_string ((len + 1) * WCHAR_BYTES, widep);
  3085.         TREE_TYPE (yylval.ttype) = wchar_array_type_node;
  3086.       }
  3087.     else
  3088.       {
  3089.         yylval.ttype = build_string (p - token_buffer, token_buffer + 1);
  3090.         TREE_TYPE (yylval.ttype) = char_array_type_node;
  3091.       }
  3092.  
  3093.     *p++ = '"';
  3094.     *p = 0;
  3095.  
  3096.     value = STRING; break;
  3097.       }
  3098.  
  3099.     case '+':
  3100.     case '-':
  3101.     case '&':
  3102.     case '|':
  3103.     case '<':
  3104.     case '>':
  3105.     case '*':
  3106.     case '/':
  3107.     case '%':
  3108.     case '^':
  3109.     case '!':
  3110.     case '=':
  3111.       {
  3112.     register int c1;
  3113.  
  3114.       combine:
  3115.  
  3116.     switch (c)
  3117.       {
  3118.       case '+':
  3119.         yylval.code = PLUS_EXPR; break;
  3120.       case '-':
  3121.         yylval.code = MINUS_EXPR; break;
  3122.       case '&':
  3123.         yylval.code = BIT_AND_EXPR; break;
  3124.       case '|':
  3125.         yylval.code = BIT_IOR_EXPR; break;
  3126.       case '*':
  3127.         yylval.code = MULT_EXPR; break;
  3128.       case '/':
  3129.         yylval.code = TRUNC_DIV_EXPR; break;
  3130.       case '%':
  3131.         yylval.code = TRUNC_MOD_EXPR; break;
  3132.       case '^':
  3133.         yylval.code = BIT_XOR_EXPR; break;
  3134.       case LSHIFT:
  3135.         yylval.code = LSHIFT_EXPR; break;
  3136.       case RSHIFT:
  3137.         yylval.code = RSHIFT_EXPR; break;
  3138.       case '<':
  3139.         yylval.code = LT_EXPR; break;
  3140.       case '>':
  3141.         yylval.code = GT_EXPR; break;
  3142.       }
  3143.  
  3144.     token_buffer[1] = c1 = getc (finput);
  3145.     token_buffer[2] = 0;
  3146.  
  3147.     if (c1 == '=')
  3148.       {
  3149.         switch (c)
  3150.           {
  3151.           case '<':
  3152.         value = ARITHCOMPARE; yylval.code = LE_EXPR; goto done;
  3153.           case '>':
  3154.         value = ARITHCOMPARE; yylval.code = GE_EXPR; goto done;
  3155.           case '!':
  3156.         value = EQCOMPARE; yylval.code = NE_EXPR; goto done;
  3157.           case '=':
  3158.         value = EQCOMPARE; yylval.code = EQ_EXPR; goto done;
  3159.           }
  3160.         value = ASSIGN; goto done;
  3161.       }
  3162.     else if (c == c1)
  3163.       switch (c)
  3164.         {
  3165.         case '+':
  3166.           value = PLUSPLUS; goto done;
  3167.         case '-':
  3168.           value = MINUSMINUS; goto done;
  3169.         case '&':
  3170.           value = ANDAND; goto done;
  3171.         case '|':
  3172.           value = OROR; goto done;
  3173.         case '<':
  3174.           c = LSHIFT;
  3175.           goto combine;
  3176.         case '>':
  3177.           c = RSHIFT;
  3178.           goto combine;
  3179.         }
  3180.     else if ((c == '-') && (c1 == '>'))
  3181.       { value = POINTSAT; goto done; }
  3182.     ungetc (c1, finput);
  3183.     token_buffer[1] = 0;
  3184.  
  3185.     if ((c == '<') || (c == '>'))
  3186.       value = ARITHCOMPARE;
  3187.     else value = c;
  3188.     goto done;
  3189.       }
  3190.  
  3191.     case 0:
  3192.       /* Don't make yyparse think this is eof.  */
  3193.       value = 1;
  3194.       break;
  3195.  
  3196.     default:
  3197.       value = c;
  3198.     }
  3199.  
  3200. done:
  3201. /*  yylloc.last_line = lineno; */
  3202.  
  3203.   return value;
  3204. }
  3205.