Remove the last vestiges of -DCCVER from 2.95.x contrib so we can remove
[dragonfly.git] / contrib / gcc / c-lex.c
1 /* Lexical analyzer for C and Objective C.
2    Copyright (C) 1987, 88, 89, 92, 94-97, 1998 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, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.  */
20
21 #include "config.h"
22 #include "system.h"
23
24 #include "rtl.h"
25 #include "tree.h"
26 #include "input.h"
27 #include "output.h"
28 #include "c-lex.h"
29 #include "c-tree.h"
30 #include "flags.h"
31 #include "c-parse.h"
32 #include "c-pragma.h"
33 #include "toplev.h"
34 #include "intl.h"
35
36 /* MULTIBYTE_CHARS support only works for native compilers.
37    ??? Ideally what we want is to model widechar support after
38    the current floating point support.  */
39 #ifdef CROSS_COMPILE
40 #undef MULTIBYTE_CHARS
41 #endif
42
43 #ifdef MULTIBYTE_CHARS
44 #include "mbchar.h"
45 #include <locale.h>
46 #endif /* MULTIBYTE_CHARS */
47
48 #if USE_CPPLIB
49 #include "cpplib.h"
50 extern cpp_reader  parse_in;
51 extern cpp_options parse_options;
52 #else
53 /* Stream for reading from the input file.  */
54 FILE *finput;
55 #endif
56
57 extern void yyprint                     PROTO((FILE *, int, YYSTYPE));
58
59 /* The elements of `ridpointers' are identifier nodes
60    for the reserved type names and storage classes.
61    It is indexed by a RID_... value.  */
62 tree ridpointers[(int) RID_MAX];
63
64 /* Cause the `yydebug' variable to be defined.  */
65 #define YYDEBUG 1
66
67 #if USE_CPPLIB
68 extern unsigned char *yy_cur, *yy_lim;
69
70 extern int yy_get_token ();
71
72 #define GETC() (yy_cur < yy_lim ? *yy_cur++ : yy_get_token ())
73 #define UNGETC(c) ((c) == EOF ? 0 : yy_cur--)
74 #else
75 #define GETC() getc (finput)
76 #define UNGETC(c) ungetc (c, finput)
77 #endif
78
79 /* the declaration found for the last IDENTIFIER token read in.
80    yylex must look this up to detect typedefs, which get token type TYPENAME,
81    so it is left around in case the identifier is not a typedef but is
82    used in a context which makes it a reference to a variable.  */
83 tree lastiddecl;
84
85 /* Nonzero enables objc features.  */
86
87 int doing_objc_thang;
88
89 extern int yydebug;
90
91 /* File used for outputting assembler code.  */
92 extern FILE *asm_out_file;
93
94 #ifndef WCHAR_TYPE_SIZE
95 #ifdef INT_TYPE_SIZE
96 #define WCHAR_TYPE_SIZE INT_TYPE_SIZE
97 #else
98 #define WCHAR_TYPE_SIZE BITS_PER_WORD
99 #endif
100 #endif
101
102 /* Number of bytes in a wide character.  */
103 #define WCHAR_BYTES (WCHAR_TYPE_SIZE / BITS_PER_UNIT)
104
105 static int maxtoken;            /* Current nominal length of token buffer.  */
106 char *token_buffer;     /* Pointer to token buffer.
107                            Actual allocated length is maxtoken + 2.
108                            This is not static because objc-parse.y uses it.  */
109
110 static int indent_level = 0;        /* Number of { minus number of }. */
111
112 /* Nonzero if end-of-file has been seen on input.  */
113 static int end_of_file;
114
115 #if !USE_CPPLIB
116 /* Buffered-back input character; faster than using ungetc.  */
117 static int nextchar = -1;
118 #endif
119
120 #ifdef HANDLE_GENERIC_PRAGMAS
121 static int handle_generic_pragma        PROTO((int));
122 #endif /* HANDLE_GENERIC_PRAGMAS */
123 static int whitespace_cr                PROTO((int));
124 static int skip_white_space             PROTO((int));
125 static int skip_white_space_on_line     PROTO((void));
126 static char *extend_token_buffer        PROTO((const char *));
127 static int readescape                   PROTO((int *));
128 static void parse_float                 PROTO((PTR));
129 \f
130 /* Do not insert generated code into the source, instead, include it.
131    This allows us to build gcc automatically even for targets that
132    need to add or modify the reserved keyword lists.  */
133 #include "c-gperf.h"
134 \f
135 /* Return something to represent absolute declarators containing a *.
136    TARGET is the absolute declarator that the * contains.
137    TYPE_QUALS is a list of modifiers such as const or volatile
138    to apply to the pointer type, represented as identifiers.
139
140    We return an INDIRECT_REF whose "contents" are TARGET
141    and whose type is the modifier list.  */
142
143 tree
144 make_pointer_declarator (type_quals, target)
145      tree type_quals, target;
146 {
147   return build1 (INDIRECT_REF, type_quals, target);
148 }
149 \f
150 void
151 forget_protocol_qualifiers ()
152 {
153   int i, n = sizeof wordlist / sizeof (struct resword);
154
155   for (i = 0; i < n; i++)
156     if ((int) wordlist[i].rid >= (int) RID_IN
157         && (int) wordlist[i].rid <= (int) RID_ONEWAY)
158       wordlist[i].name = "";
159 }
160
161 void
162 remember_protocol_qualifiers ()
163 {
164   int i, n = sizeof wordlist / sizeof (struct resword);
165
166   for (i = 0; i < n; i++)
167     if (wordlist[i].rid == RID_IN)
168       wordlist[i].name = "in";
169     else if (wordlist[i].rid == RID_OUT)
170       wordlist[i].name = "out";
171     else if (wordlist[i].rid == RID_INOUT)
172       wordlist[i].name = "inout";
173     else if (wordlist[i].rid == RID_BYCOPY)
174       wordlist[i].name = "bycopy";
175     else if (wordlist[i].rid == RID_BYREF)
176       wordlist[i].name = "byref";
177     else if (wordlist[i].rid == RID_ONEWAY)
178       wordlist[i].name = "oneway";
179 }
180 \f
181 char *
182 init_parse (filename)
183      char *filename;
184 {
185 #if !USE_CPPLIB
186   /* Open input file.  */
187   if (filename == 0 || !strcmp (filename, "-"))
188     {
189       finput = stdin;
190       filename = "stdin";
191     }
192   else
193     finput = fopen (filename, "r");
194   if (finput == 0)
195     pfatal_with_name (filename);
196
197 #ifdef IO_BUFFER_SIZE
198   setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE);
199 #endif
200 #else /* !USE_CPPLIB */
201   parse_in.show_column = 1;
202   if (! cpp_start_read (&parse_in, filename))
203     abort ();
204
205   if (filename == 0 || !strcmp (filename, "-"))
206     filename = "stdin";
207
208   /* cpp_start_read always puts at least one line directive into the
209      token buffer.  We must arrange to read it out here. */
210   yy_cur = parse_in.token_buffer;
211   yy_lim = CPP_PWRITTEN (&parse_in);
212 #endif
213
214   init_lex ();
215
216   return filename;
217 }
218
219 void
220 finish_parse ()
221 {
222 #if USE_CPPLIB
223   cpp_finish (&parse_in);
224 #else
225   fclose (finput);
226 #endif
227 }
228
229 void
230 init_lex ()
231 {
232   /* Make identifier nodes long enough for the language-specific slots.  */
233   set_identifier_size (sizeof (struct lang_identifier));
234
235   /* Start it at 0, because check_newline is called at the very beginning
236      and will increment it to 1.  */
237   lineno = 0;
238
239 #ifdef MULTIBYTE_CHARS
240   /* Change to the native locale for multibyte conversions.  */
241   setlocale (LC_CTYPE, "");
242   literal_codeset = getenv ("LANG");
243 #endif
244
245   maxtoken = 40;
246   token_buffer = (char *) xmalloc (maxtoken + 2);
247
248   ridpointers[(int) RID_INT] = get_identifier ("int");
249   ridpointers[(int) RID_CHAR] = get_identifier ("char");
250   ridpointers[(int) RID_VOID] = get_identifier ("void");
251   ridpointers[(int) RID_FLOAT] = get_identifier ("float");
252   ridpointers[(int) RID_DOUBLE] = get_identifier ("double");
253   ridpointers[(int) RID_SHORT] = get_identifier ("short");
254   ridpointers[(int) RID_LONG] = get_identifier ("long");
255   ridpointers[(int) RID_UNSIGNED] = get_identifier ("unsigned");
256   ridpointers[(int) RID_SIGNED] = get_identifier ("signed");
257   ridpointers[(int) RID_INLINE] = get_identifier ("inline");
258   ridpointers[(int) RID_CONST] = get_identifier ("const");
259   ridpointers[(int) RID_RESTRICT] = get_identifier ("restrict");
260   ridpointers[(int) RID_VOLATILE] = get_identifier ("volatile");
261   ridpointers[(int) RID_AUTO] = get_identifier ("auto");
262   ridpointers[(int) RID_STATIC] = get_identifier ("static");
263   ridpointers[(int) RID_EXTERN] = get_identifier ("extern");
264   ridpointers[(int) RID_TYPEDEF] = get_identifier ("typedef");
265   ridpointers[(int) RID_REGISTER] = get_identifier ("register");
266   ridpointers[(int) RID_ITERATOR] = get_identifier ("iterator");
267   ridpointers[(int) RID_COMPLEX] = get_identifier ("complex");
268   ridpointers[(int) RID_ID] = get_identifier ("id");
269   ridpointers[(int) RID_IN] = get_identifier ("in");
270   ridpointers[(int) RID_OUT] = get_identifier ("out");
271   ridpointers[(int) RID_INOUT] = get_identifier ("inout");
272   ridpointers[(int) RID_BYCOPY] = get_identifier ("bycopy");
273   ridpointers[(int) RID_BYREF] = get_identifier ("byref");
274   ridpointers[(int) RID_ONEWAY] = get_identifier ("oneway");
275   forget_protocol_qualifiers();
276
277   /* Some options inhibit certain reserved words.
278      Clear those words out of the hash table so they won't be recognized.  */
279 #define UNSET_RESERVED_WORD(STRING) \
280   do { struct resword *s = is_reserved_word (STRING, sizeof (STRING) - 1); \
281        if (s) s->name = ""; } while (0)
282
283   if (! doing_objc_thang)
284     UNSET_RESERVED_WORD ("id");
285
286   if (flag_traditional)
287     {
288       UNSET_RESERVED_WORD ("const");
289       UNSET_RESERVED_WORD ("restrict");
290       UNSET_RESERVED_WORD ("volatile");
291       UNSET_RESERVED_WORD ("typeof");
292       UNSET_RESERVED_WORD ("signed");
293       UNSET_RESERVED_WORD ("inline");
294       UNSET_RESERVED_WORD ("iterator");
295       UNSET_RESERVED_WORD ("complex");
296     }
297   else if (!flag_isoc9x)
298     UNSET_RESERVED_WORD ("restrict");
299
300   if (flag_no_asm)
301     {
302       UNSET_RESERVED_WORD ("asm");
303       UNSET_RESERVED_WORD ("typeof");
304       UNSET_RESERVED_WORD ("inline");
305       UNSET_RESERVED_WORD ("iterator");
306       UNSET_RESERVED_WORD ("complex");
307     }
308 }
309
310 void
311 reinit_parse_for_function ()
312 {
313 }
314 \f
315 /* Function used when yydebug is set, to print a token in more detail.  */
316
317 void
318 yyprint (file, yychar, yylval)
319      FILE *file;
320      int yychar;
321      YYSTYPE yylval;
322 {
323   tree t;
324   switch (yychar)
325     {
326     case IDENTIFIER:
327     case TYPENAME:
328     case OBJECTNAME:
329       t = yylval.ttype;
330       if (IDENTIFIER_POINTER (t))
331         fprintf (file, " `%s'", IDENTIFIER_POINTER (t));
332       break;
333
334     case CONSTANT:
335       t = yylval.ttype;
336       if (TREE_CODE (t) == INTEGER_CST)
337         fprintf (file,
338 #if HOST_BITS_PER_WIDE_INT == 64
339 #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
340                  " 0x%x%016x",
341 #else
342 #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
343                  " 0x%lx%016lx",
344 #else
345                  " 0x%llx%016llx",
346 #endif
347 #endif
348 #else
349 #if HOST_BITS_PER_WIDE_INT != HOST_BITS_PER_INT
350                  " 0x%lx%08lx",
351 #else
352                  " 0x%x%08x",
353 #endif
354 #endif
355                  TREE_INT_CST_HIGH (t), TREE_INT_CST_LOW (t));
356       break;
357     }
358 }
359 \f
360 /* Iff C is a carriage return, warn about it - if appropriate -
361    and return nonzero.  */
362 static int
363 whitespace_cr (c)
364      int c;
365 {
366   static int newline_warning = 0;
367
368   if (c == '\r')
369     {
370       /* ANSI C says the effects of a carriage return in a source file
371          are undefined.  */
372       if (pedantic && !newline_warning)
373         {
374           warning ("carriage return in source file");
375           warning ("(we only warn about the first carriage return)");
376           newline_warning = 1;
377         }
378       return 1;
379     }
380   return 0;
381 }
382
383 /* If C is not whitespace, return C.
384    Otherwise skip whitespace and return first nonwhite char read.  */
385
386 static int
387 skip_white_space (c)
388      register int c;
389 {
390   for (;;)
391     {
392       switch (c)
393         {
394           /* We don't recognize comments here, because
395              cpp output can include / and * consecutively as operators.
396              Also, there's no need, since cpp removes all comments.  */
397
398         case '\n':
399           c = check_newline ();
400           break;
401
402         case ' ':
403         case '\t':
404         case '\f':
405         case '\v':
406         case '\b':
407           c = GETC();
408           break;
409
410         case '\r':
411           whitespace_cr (c);
412           c = GETC();
413           break;
414
415         case '\\':
416           c = GETC();
417           if (c == '\n')
418             lineno++;
419           else
420             error ("stray '\\' in program");
421           c = GETC();
422           break;
423
424         default:
425           return (c);
426         }
427     }
428 }
429
430 /* Skips all of the white space at the current location in the input file.
431    Must use and reset nextchar if it has the next character.  */
432
433 void
434 position_after_white_space ()
435 {
436   register int c;
437
438 #if !USE_CPPLIB
439   if (nextchar != -1)
440     c = nextchar, nextchar = -1;
441   else
442 #endif
443     c = GETC();
444
445   UNGETC (skip_white_space (c));
446 }
447
448 /* Like skip_white_space, but don't advance beyond the end of line.
449    Moreover, we don't get passed a character to start with.  */
450 static int
451 skip_white_space_on_line ()
452 {
453   register int c;
454
455   while (1)
456     {
457       c = GETC();
458       switch (c)
459         {
460         case '\n':
461         default:
462           break;
463
464         case ' ':
465         case '\t':
466         case '\f':
467         case '\v':
468         case '\b':
469           continue;
470
471         case '\r':
472           whitespace_cr (c);
473           continue;
474         }
475       break;
476     }
477   return c;
478 }
479
480 /* Make the token buffer longer, preserving the data in it.
481    P should point to just beyond the last valid character in the old buffer.
482    The value we return is a pointer to the new buffer
483    at a place corresponding to P.  */
484
485 static char *
486 extend_token_buffer (p)
487      const char *p;
488 {
489   int offset = p - token_buffer;
490
491   maxtoken = maxtoken * 2 + 10;
492   token_buffer = (char *) xrealloc (token_buffer, maxtoken + 2);
493
494   return token_buffer + offset;
495 }
496 \f
497 #if defined HANDLE_PRAGMA
498 /* Local versions of these macros, that can be passed as function pointers.  */
499 static int
500 pragma_getc ()
501 {
502   return GETC();
503 }
504
505 static void
506 pragma_ungetc (arg)
507      int arg;
508 {
509   UNGETC (arg);
510 }
511 #endif
512
513 /* At the beginning of a line, increment the line number
514    and process any #-directive on this line.
515    If the line is a #-directive, read the entire line and return a newline.
516    Otherwise, return the line's first non-whitespace character.  */
517
518 int
519 check_newline ()
520 {
521   register int c;
522   register int token;
523
524   lineno++;
525
526   /* Read first nonwhite char on the line.  */
527
528   c = GETC();
529   while (c == ' ' || c == '\t')
530     c = GETC();
531
532   if (c != '#')
533     {
534       /* If not #, return it so caller will use it.  */
535       return c;
536     }
537
538   /* Read first nonwhite char after the `#'.  */
539
540   c = GETC();
541   while (c == ' ' || c == '\t')
542     c = GETC();
543
544   /* If a letter follows, then if the word here is `line', skip
545      it and ignore it; otherwise, ignore the line, with an error
546      if the word isn't `pragma', `ident', `define', or `undef'.  */
547
548   if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
549     {
550       if (c == 'p')
551         {
552           if (GETC() == 'r'
553               && GETC() == 'a'
554               && GETC() == 'g'
555               && GETC() == 'm'
556               && GETC() == 'a'
557               && ((c = GETC()) == ' ' || c == '\t' || c == '\n'
558                    || whitespace_cr (c) ))
559             {
560               while (c == ' ' || c == '\t' || whitespace_cr (c))
561                 c = GETC ();
562               if (c == '\n')
563                 return c;
564
565 #if defined HANDLE_PRAGMA || defined HANDLE_GENERIC_PRAGMAS
566               UNGETC (c);
567               token = yylex ();
568               if (token != IDENTIFIER)
569                 goto skipline;
570 #endif /* HANDLE_PRAGMA || HANDLE_GENERIC_PRAGMAS */
571
572 #ifdef HANDLE_PRAGMA
573               /* We invoke HANDLE_PRAGMA before HANDLE_GENERIC_PRAGMAS (if
574                  both are defined), in order to give the back end a chance to
575                  override the interpretation of generic style pragmas.  */
576 #if !USE_CPPLIB
577               if (nextchar >= 0)
578                 {
579                   c = nextchar, nextchar = -1;
580                   UNGETC (c);
581                 }
582 #endif /* !USE_CPPLIB */
583
584               if (TREE_CODE (yylval.ttype) != IDENTIFIER_NODE)
585                 goto skipline;
586
587               if (HANDLE_PRAGMA (pragma_getc, pragma_ungetc,
588                                  IDENTIFIER_POINTER (yylval.ttype)))
589                 return GETC ();
590 #endif /* HANDLE_PRAGMA */
591
592 #ifdef HANDLE_GENERIC_PRAGMAS
593               if (handle_generic_pragma (token))
594                 return GETC ();
595 #endif /* HANDLE_GENERIC_PRAGMAS */
596
597               /* Issue a warning message if we have been asked to do so.
598                  Ignoring unknown pragmas in system header file unless
599                  an explcit -Wunknown-pragmas has been given. */
600               if (warn_unknown_pragmas > 1
601                   || (warn_unknown_pragmas && ! in_system_header))
602                 warning ("ignoring pragma: %s", token_buffer);
603
604               goto skipline;
605             }
606         }
607
608       else if (c == 'd')
609         {
610           if (GETC() == 'e'
611               && GETC() == 'f'
612               && GETC() == 'i'
613               && GETC() == 'n'
614               && GETC() == 'e'
615               && ((c = GETC()) == ' ' || c == '\t' || c == '\n'))
616             {
617               if (c != '\n')
618                 debug_define (lineno, GET_DIRECTIVE_LINE ());
619               goto skipline;
620             }
621         }
622       else if (c == 'u')
623         {
624           if (GETC() == 'n'
625               && GETC() == 'd'
626               && GETC() == 'e'
627               && GETC() == 'f'
628               && ((c = GETC()) == ' ' || c == '\t' || c == '\n'))
629             {
630               if (c != '\n')
631                 debug_undef (lineno, GET_DIRECTIVE_LINE ());
632               goto skipline;
633             }
634         }
635       else if (c == 'l')
636         {
637           if (GETC() == 'i'
638               && GETC() == 'n'
639               && GETC() == 'e'
640               && ((c = GETC()) == ' ' || c == '\t'))
641             goto linenum;
642         }
643       else if (c == 'i')
644         {
645           if (GETC() == 'd'
646               && GETC() == 'e'
647               && GETC() == 'n'
648               && GETC() == 't'
649               && ((c = GETC()) == ' ' || c == '\t'))
650             {
651               /* #ident.  The pedantic warning is now in cccp.c.  */
652
653               /* Here we have just seen `#ident '.
654                  A string constant should follow.  */
655
656               c = skip_white_space_on_line ();
657
658               /* If no argument, ignore the line.  */
659               if (c == '\n')
660                 return c;
661
662               UNGETC (c);
663               token = yylex ();
664               if (token != STRING
665                   || TREE_CODE (yylval.ttype) != STRING_CST)
666                 {
667                   error ("invalid #ident");
668                   goto skipline;
669                 }
670
671               if (!flag_no_ident)
672                 {
673 #ifdef ASM_OUTPUT_IDENT
674                   ASM_OUTPUT_IDENT (asm_out_file, TREE_STRING_POINTER (yylval.ttype));
675 #endif
676                 }
677
678               /* Skip the rest of this line.  */
679               goto skipline;
680             }
681         }
682
683       error ("undefined or invalid # directive");
684       goto skipline;
685     }
686
687 linenum:
688   /* Here we have either `#line' or `# <nonletter>'.
689      In either case, it should be a line number; a digit should follow.  */
690
691   /* Can't use skip_white_space here, but must handle all whitespace
692      that is not '\n', lest we get a recursion for '\r' '\n' when
693      calling yylex.  */
694   UNGETC (c);
695   c = skip_white_space_on_line ();
696
697   /* If the # is the only nonwhite char on the line,
698      just ignore it.  Check the new newline.  */
699   if (c == '\n')
700     return c;
701
702   /* Something follows the #; read a token.  */
703
704   UNGETC (c);
705   token = yylex ();
706
707   if (token == CONSTANT
708       && TREE_CODE (yylval.ttype) == INTEGER_CST)
709     {
710       int old_lineno = lineno;
711       int used_up = 0;
712       /* subtract one, because it is the following line that
713          gets the specified number */
714
715       int l = TREE_INT_CST_LOW (yylval.ttype) - 1;
716
717       /* Is this the last nonwhite stuff on the line?  */
718       c = skip_white_space_on_line ();
719       if (c == '\n')
720         {
721           /* No more: store the line number and check following line.  */
722           lineno = l;
723           return c;
724         }
725       UNGETC (c);
726
727       /* More follows: it must be a string constant (filename).  */
728
729       /* Read the string constant.  */
730       token = yylex ();
731
732       if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)
733         {
734           error ("invalid #line");
735           goto skipline;
736         }
737
738       input_filename
739         = (char *) permalloc (TREE_STRING_LENGTH (yylval.ttype) + 1);
740       strcpy (input_filename, TREE_STRING_POINTER (yylval.ttype));
741       lineno = l;
742
743       /* Each change of file name
744          reinitializes whether we are now in a system header.  */
745       in_system_header = 0;
746
747       if (main_input_filename == 0)
748         main_input_filename = input_filename;
749
750       /* Is this the last nonwhite stuff on the line?  */
751       c = skip_white_space_on_line ();
752       if (c == '\n')
753         {
754           /* Update the name in the top element of input_file_stack.  */
755           if (input_file_stack)
756             input_file_stack->name = input_filename;
757
758           return c;
759         }
760       UNGETC (c);
761
762       token = yylex ();
763       used_up = 0;
764
765       /* `1' after file name means entering new file.
766          `2' after file name means just left a file.  */
767
768       if (token == CONSTANT
769           && TREE_CODE (yylval.ttype) == INTEGER_CST)
770         {
771           if (TREE_INT_CST_LOW (yylval.ttype) == 1)
772             {
773               /* Pushing to a new file.  */
774               struct file_stack *p
775                 = (struct file_stack *) xmalloc (sizeof (struct file_stack));
776               input_file_stack->line = old_lineno;
777               p->next = input_file_stack;
778               p->name = input_filename;
779               p->indent_level = indent_level;
780               input_file_stack = p;
781               input_file_stack_tick++;
782               debug_start_source_file (input_filename);
783               used_up = 1;
784             }
785           else if (TREE_INT_CST_LOW (yylval.ttype) == 2)
786             {
787               /* Popping out of a file.  */
788               if (input_file_stack->next)
789                 {
790                   struct file_stack *p = input_file_stack;
791                   if (indent_level != p->indent_level)
792                     {
793                       warning_with_file_and_line
794                         (p->name, old_lineno,
795                          "This file contains more `%c's than `%c's.",
796                          indent_level > p->indent_level ? '{' : '}',
797                          indent_level > p->indent_level ? '}' : '{');
798                     }
799                   input_file_stack = p->next;
800                   free (p);
801                   input_file_stack_tick++;
802                   debug_end_source_file (input_file_stack->line);
803                 }
804               else
805                 error ("#-lines for entering and leaving files don't match");
806
807               used_up = 1;
808             }
809         }
810
811       /* Now that we've pushed or popped the input stack,
812          update the name in the top element.  */
813       if (input_file_stack)
814         input_file_stack->name = input_filename;
815
816       /* If we have handled a `1' or a `2',
817          see if there is another number to read.  */
818       if (used_up)
819         {
820           /* Is this the last nonwhite stuff on the line?  */
821           c = skip_white_space_on_line ();
822           if (c == '\n')
823             return c;
824           UNGETC (c);
825
826           token = yylex ();
827           used_up = 0;
828         }
829
830       /* `3' after file name means this is a system header file.  */
831
832       if (token == CONSTANT
833           && TREE_CODE (yylval.ttype) == INTEGER_CST
834           && TREE_INT_CST_LOW (yylval.ttype) == 3)
835         in_system_header = 1, used_up = 1;
836
837       if (used_up)
838         {
839           /* Is this the last nonwhite stuff on the line?  */
840           c = skip_white_space_on_line ();
841           if (c == '\n')
842             return c;
843           UNGETC (c);
844         }
845
846       warning ("unrecognized text at end of #line");
847     }
848   else
849     error ("invalid #-line");
850
851   /* skip the rest of this line.  */
852  skipline:
853 #if !USE_CPPLIB
854   if (c != '\n' && c != EOF && nextchar >= 0)
855     c = nextchar, nextchar = -1;
856 #endif
857   while (c != '\n' && c != EOF)
858     c = GETC();
859   return c;
860 }
861 \f
862 #ifdef HANDLE_GENERIC_PRAGMAS
863
864 /* Handle a #pragma directive.
865    TOKEN is the token we read after `#pragma'.  Processes the entire input
866    line and return non-zero iff the pragma has been successfully parsed.  */
867
868 /* This function has to be in this file, in order to get at
869    the token types.  */
870
871 static int
872 handle_generic_pragma (token)
873      register int token;
874 {
875   register int c;
876
877   for (;;)
878     {
879       switch (token)
880         {
881         case IDENTIFIER:
882         case TYPENAME:
883         case STRING:
884         case CONSTANT:
885           handle_pragma_token (token_buffer, yylval.ttype);
886           break;
887         default:
888           handle_pragma_token (token_buffer, NULL);
889         }
890 #if !USE_CPPLIB
891       if (nextchar >= 0)
892         c = nextchar, nextchar = -1;
893       else
894 #endif
895         c = GETC ();
896
897       while (c == ' ' || c == '\t')
898         c = GETC ();
899       UNGETC (c);
900
901       if (c == '\n' || c == EOF)
902         return handle_pragma_token (NULL, NULL);
903
904       token = yylex ();
905     }
906 }
907
908 #endif /* HANDLE_GENERIC_PRAGMAS */
909 \f
910 #define ENDFILE -1  /* token that represents end-of-file */
911
912 /* Read an escape sequence, returning its equivalent as a character,
913    or store 1 in *ignore_ptr if it is backslash-newline.  */
914
915 static int
916 readescape (ignore_ptr)
917      int *ignore_ptr;
918 {
919   register int c = GETC();
920   register int code;
921   register unsigned count;
922   unsigned firstdig = 0;
923   int nonnull;
924
925   switch (c)
926     {
927     case 'x':
928       if (warn_traditional)
929         warning ("the meaning of `\\x' varies with -traditional");
930
931       if (flag_traditional)
932         return c;
933
934       code = 0;
935       count = 0;
936       nonnull = 0;
937       while (1)
938         {
939           c = GETC();
940           if (!(c >= 'a' && c <= 'f')
941               && !(c >= 'A' && c <= 'F')
942               && !(c >= '0' && c <= '9'))
943             {
944               UNGETC (c);
945               break;
946             }
947           code *= 16;
948           if (c >= 'a' && c <= 'f')
949             code += c - 'a' + 10;
950           if (c >= 'A' && c <= 'F')
951             code += c - 'A' + 10;
952           if (c >= '0' && c <= '9')
953             code += c - '0';
954           if (code != 0 || count != 0)
955             {
956               if (count == 0)
957                 firstdig = code;
958               count++;
959             }
960           nonnull = 1;
961         }
962       if (! nonnull)
963         error ("\\x used with no following hex digits");
964       else if (count == 0)
965         /* Digits are all 0's.  Ok.  */
966         ;
967       else if ((count - 1) * 4 >= TYPE_PRECISION (integer_type_node)
968                || (count > 1
969                    && (((unsigned)1 << (TYPE_PRECISION (integer_type_node) - (count - 1) * 4))
970                        <= firstdig)))
971         pedwarn ("hex escape out of range");
972       return code;
973
974     case '0':  case '1':  case '2':  case '3':  case '4':
975     case '5':  case '6':  case '7':
976       code = 0;
977       count = 0;
978       while ((c <= '7') && (c >= '0') && (count++ < 3))
979         {
980           code = (code * 8) + (c - '0');
981           c = GETC();
982         }
983       UNGETC (c);
984       return code;
985
986     case '\\': case '\'': case '"':
987       return c;
988
989     case '\n':
990       lineno++;
991       *ignore_ptr = 1;
992       return 0;
993
994     case 'n':
995       return TARGET_NEWLINE;
996
997     case 't':
998       return TARGET_TAB;
999
1000     case 'r':
1001       return TARGET_CR;
1002
1003     case 'f':
1004       return TARGET_FF;
1005
1006     case 'b':
1007       return TARGET_BS;
1008
1009     case 'a':
1010       if (warn_traditional)
1011         warning ("the meaning of `\\a' varies with -traditional");
1012
1013       if (flag_traditional)
1014         return c;
1015       return TARGET_BELL;
1016
1017     case 'v':
1018 #if 0 /* Vertical tab is present in common usage compilers.  */
1019       if (flag_traditional)
1020         return c;
1021 #endif
1022       return TARGET_VT;
1023
1024     case 'e':
1025     case 'E':
1026       if (pedantic)
1027         pedwarn ("non-ANSI-standard escape sequence, `\\%c'", c);
1028       return 033;
1029
1030     case '?':
1031       return c;
1032
1033       /* `\(', etc, are used at beginning of line to avoid confusing Emacs.  */
1034     case '(':
1035     case '{':
1036     case '[':
1037       /* `\%' is used to prevent SCCS from getting confused.  */
1038     case '%':
1039       if (pedantic)
1040         pedwarn ("non-ANSI escape sequence `\\%c'", c);
1041       return c;
1042     }
1043   if (c >= 040 && c < 0177)
1044     pedwarn ("unknown escape sequence `\\%c'", c);
1045   else
1046     pedwarn ("unknown escape sequence: `\\' followed by char code 0x%x", c);
1047   return c;
1048 }
1049 \f
1050 void
1051 yyerror (msgid)
1052      const char *msgid;
1053 {
1054   const char *string = _(msgid);
1055
1056   /* We can't print string and character constants well
1057      because the token_buffer contains the result of processing escapes.  */
1058   if (end_of_file)
1059     error ("%s at end of input", string);
1060   else if (token_buffer[0] == 0)
1061     error ("%s at null character", string);
1062   else if (token_buffer[0] == '"')
1063     error ("%s before string constant", string);
1064   else if (token_buffer[0] == '\'')
1065     error ("%s before character constant", string);
1066   else if (token_buffer[0] < 040 || (unsigned char) token_buffer[0] >= 0177)
1067     error ("%s before character 0%o", string, (unsigned char) token_buffer[0]);
1068   else
1069     error ("%s before `%s'", string, token_buffer);
1070 }
1071
1072 #if 0
1073
1074 struct try_type
1075 {
1076   tree *node_var;
1077   char unsigned_flag;
1078   char long_flag;
1079   char long_long_flag;
1080 };
1081
1082 struct try_type type_sequence[] =
1083 {
1084   { &integer_type_node, 0, 0, 0},
1085   { &unsigned_type_node, 1, 0, 0},
1086   { &long_integer_type_node, 0, 1, 0},
1087   { &long_unsigned_type_node, 1, 1, 0},
1088   { &long_long_integer_type_node, 0, 1, 1},
1089   { &long_long_unsigned_type_node, 1, 1, 1}
1090 };
1091 #endif /* 0 */
1092 \f
1093 struct pf_args
1094 {
1095   /* Input */
1096   int base;
1097   char * p;
1098   /* I/O */
1099   int c;
1100   int imag;
1101   tree type;
1102   int conversion_errno;
1103   /* Output */
1104   REAL_VALUE_TYPE value;
1105 };
1106  
1107 static void
1108 parse_float (data)
1109   PTR data;
1110 {
1111   struct pf_args * args = (struct pf_args *) data;
1112   int fflag = 0, lflag = 0;
1113   /* Copy token_buffer now, while it has just the number
1114      and not the suffixes; once we add `f' or `i',
1115      REAL_VALUE_ATOF may not work any more.  */
1116   char *copy = (char *) alloca (args->p - token_buffer + 1);
1117   bcopy (token_buffer, copy, args->p - token_buffer + 1);
1118
1119   while (1)
1120     {
1121       int lose = 0;
1122
1123       /* Read the suffixes to choose a data type.  */
1124       switch (args->c)
1125         {
1126         case 'f': case 'F':
1127           if (fflag)
1128             error ("more than one `f' in numeric constant");
1129           fflag = 1;
1130           break;
1131
1132         case 'l': case 'L':
1133           if (lflag)
1134             error ("more than one `l' in numeric constant");
1135           lflag = 1;
1136           break;
1137
1138         case 'i': case 'I':
1139           if (args->imag)
1140             error ("more than one `i' or `j' in numeric constant");
1141           else if (pedantic)
1142             pedwarn ("ANSI C forbids imaginary numeric constants");
1143           args->imag = 1;
1144           break;
1145
1146         default:
1147           lose = 1;
1148         }
1149
1150       if (lose)
1151         break;
1152
1153       if (args->p >= token_buffer + maxtoken - 3)
1154         args->p = extend_token_buffer (args->p);
1155       *(args->p++) = args->c;
1156       *(args->p) = 0;
1157       args->c = GETC();
1158     }
1159
1160   /* The second argument, machine_mode, of REAL_VALUE_ATOF
1161      tells the desired precision of the binary result
1162      of decimal-to-binary conversion.  */
1163
1164   if (fflag)
1165     {
1166       if (lflag)
1167         error ("both `f' and `l' in floating constant");
1168
1169       args->type = float_type_node;
1170       errno = 0;
1171       if (args->base == 16)
1172         args->value = REAL_VALUE_HTOF (copy, TYPE_MODE (args->type));
1173       else
1174         args->value = REAL_VALUE_ATOF (copy, TYPE_MODE (args->type));
1175       args->conversion_errno = errno;
1176       /* A diagnostic is required here by some ANSI C testsuites.
1177          This is not pedwarn, because some people don't want
1178          an error for this.  */
1179       if (REAL_VALUE_ISINF (args->value) && pedantic)
1180         warning ("floating point number exceeds range of `float'");
1181     }
1182   else if (lflag)
1183     {
1184       args->type = long_double_type_node;
1185       errno = 0;
1186       if (args->base == 16)
1187         args->value = REAL_VALUE_HTOF (copy, TYPE_MODE (args->type));
1188       else
1189         args->value = REAL_VALUE_ATOF (copy, TYPE_MODE (args->type));
1190       args->conversion_errno = errno;
1191       if (REAL_VALUE_ISINF (args->value) && pedantic)
1192         warning ("floating point number exceeds range of `long double'");
1193     }
1194   else
1195     {
1196       errno = 0;
1197       if (args->base == 16)
1198         args->value = REAL_VALUE_HTOF (copy, TYPE_MODE (args->type));
1199       else
1200         args->value = REAL_VALUE_ATOF (copy, TYPE_MODE (args->type));
1201       args->conversion_errno = errno;
1202       if (REAL_VALUE_ISINF (args->value) && pedantic)
1203         warning ("floating point number exceeds range of `double'");
1204     }
1205 }
1206  
1207 int
1208 yylex ()
1209 {
1210   register int c;
1211   register char *p;
1212   register int value;
1213   int wide_flag = 0;
1214   int objc_flag = 0;
1215
1216 #if !USE_CPPLIB
1217   if (nextchar >= 0)
1218     c = nextchar, nextchar = -1;
1219   else
1220 #endif
1221     c = GETC();
1222
1223   /* Effectively do c = skip_white_space (c)
1224      but do it faster in the usual cases.  */
1225   while (1)
1226     switch (c)
1227       {
1228       case ' ':
1229       case '\t':
1230       case '\f':
1231       case '\v':
1232       case '\b':
1233         c = GETC();
1234         break;
1235
1236       case '\r':
1237         /* Call skip_white_space so we can warn if appropriate.  */
1238
1239       case '\n':
1240       case '/':
1241       case '\\':
1242         c = skip_white_space (c);
1243       default:
1244         goto found_nonwhite;
1245       }
1246  found_nonwhite:
1247
1248   token_buffer[0] = c;
1249   token_buffer[1] = 0;
1250
1251 /*  yylloc.first_line = lineno; */
1252
1253   switch (c)
1254     {
1255     case EOF:
1256       end_of_file = 1;
1257       token_buffer[0] = 0;
1258       value = ENDFILE;
1259       break;
1260
1261     case 'L':
1262       /* Capital L may start a wide-string or wide-character constant.  */
1263       {
1264         register int c = GETC();
1265         if (c == '\'')
1266           {
1267             wide_flag = 1;
1268             goto char_constant;
1269           }
1270         if (c == '"')
1271           {
1272             wide_flag = 1;
1273             goto string_constant;
1274           }
1275         UNGETC (c);
1276       }
1277       goto letter;
1278
1279     case '@':
1280       if (!doing_objc_thang)
1281         {
1282           value = c;
1283           break;
1284         }
1285       else
1286         {
1287           /* '@' may start a constant string object.  */
1288           register int c = GETC ();
1289           if (c == '"')
1290             {
1291               objc_flag = 1;
1292               goto string_constant;
1293             }
1294           UNGETC (c);
1295           /* Fall through to treat '@' as the start of an identifier.  */
1296         }
1297
1298     case 'A':  case 'B':  case 'C':  case 'D':  case 'E':
1299     case 'F':  case 'G':  case 'H':  case 'I':  case 'J':
1300     case 'K':             case 'M':  case 'N':  case 'O':
1301     case 'P':  case 'Q':  case 'R':  case 'S':  case 'T':
1302     case 'U':  case 'V':  case 'W':  case 'X':  case 'Y':
1303     case 'Z':
1304     case 'a':  case 'b':  case 'c':  case 'd':  case 'e':
1305     case 'f':  case 'g':  case 'h':  case 'i':  case 'j':
1306     case 'k':  case 'l':  case 'm':  case 'n':  case 'o':
1307     case 'p':  case 'q':  case 'r':  case 's':  case 't':
1308     case 'u':  case 'v':  case 'w':  case 'x':  case 'y':
1309     case 'z':
1310     case '_':
1311     case '$':
1312     letter:
1313       p = token_buffer;
1314       while (ISALNUM (c) || c == '_' || c == '$' || c == '@')
1315         {
1316           /* Make sure this char really belongs in an identifier.  */
1317           if (c == '$')
1318             {
1319               if (! dollars_in_ident)
1320                 error ("`$' in identifier");
1321               else if (pedantic)
1322                 pedwarn ("`$' in identifier");
1323             }
1324
1325           if (p >= token_buffer + maxtoken)
1326             p = extend_token_buffer (p);
1327
1328           *p++ = c;
1329           c = GETC();
1330         }
1331
1332       *p = 0;
1333 #if USE_CPPLIB
1334       UNGETC (c);
1335 #else
1336       nextchar = c;
1337 #endif
1338
1339       value = IDENTIFIER;
1340       yylval.itype = 0;
1341
1342       /* Try to recognize a keyword.  Uses minimum-perfect hash function */
1343
1344       {
1345         register struct resword *ptr;
1346
1347         if ((ptr = is_reserved_word (token_buffer, p - token_buffer)))
1348           {
1349             if (ptr->rid)
1350               yylval.ttype = ridpointers[(int) ptr->rid];
1351             value = (int) ptr->token;
1352
1353             /* Only return OBJECTNAME if it is a typedef.  */
1354             if (doing_objc_thang && value == OBJECTNAME)
1355               {
1356                 lastiddecl = lookup_name(yylval.ttype);
1357
1358                 if (lastiddecl == NULL_TREE
1359                     || TREE_CODE (lastiddecl) != TYPE_DECL)
1360                   value = IDENTIFIER;
1361               }
1362
1363             /* Even if we decided to recognize asm, still perhaps warn.  */
1364             if (pedantic
1365                 && (value == ASM_KEYWORD || value == TYPEOF
1366                     || ptr->rid == RID_INLINE)
1367                 && token_buffer[0] != '_')
1368               pedwarn ("ANSI does not permit the keyword `%s'",
1369                        token_buffer);
1370           }
1371       }
1372
1373       /* If we did not find a keyword, look for an identifier
1374          (or a typename).  */
1375
1376       if (value == IDENTIFIER)
1377         {
1378           if (token_buffer[0] == '@')
1379             error("invalid identifier `%s'", token_buffer);
1380
1381           yylval.ttype = get_identifier (token_buffer);
1382           lastiddecl = lookup_name (yylval.ttype);
1383
1384           if (lastiddecl != 0 && TREE_CODE (lastiddecl) == TYPE_DECL)
1385             value = TYPENAME;
1386           /* A user-invisible read-only initialized variable
1387              should be replaced by its value.
1388              We handle only strings since that's the only case used in C.  */
1389           else if (lastiddecl != 0 && TREE_CODE (lastiddecl) == VAR_DECL
1390                    && DECL_IGNORED_P (lastiddecl)
1391                    && TREE_READONLY (lastiddecl)
1392                    && DECL_INITIAL (lastiddecl) != 0
1393                    && TREE_CODE (DECL_INITIAL (lastiddecl)) == STRING_CST)
1394             {
1395               tree stringval = DECL_INITIAL (lastiddecl);
1396
1397               /* Copy the string value so that we won't clobber anything
1398                  if we put something in the TREE_CHAIN of this one.  */
1399               yylval.ttype = build_string (TREE_STRING_LENGTH (stringval),
1400                                            TREE_STRING_POINTER (stringval));
1401               value = STRING;
1402             }
1403           else if (doing_objc_thang)
1404             {
1405               tree objc_interface_decl = is_class_name (yylval.ttype);
1406
1407               if (objc_interface_decl)
1408                 {
1409                   value = CLASSNAME;
1410                   yylval.ttype = objc_interface_decl;
1411                 }
1412             }
1413         }
1414
1415       break;
1416
1417     case '0':  case '1':
1418       {
1419         int next_c;
1420         /* Check first for common special case:  single-digit 0 or 1.  */
1421
1422         next_c = GETC ();
1423         UNGETC (next_c);        /* Always undo this lookahead.  */
1424         if (!ISALNUM (next_c) && next_c != '.')
1425           {
1426             token_buffer[0] = (char)c,  token_buffer[1] = '\0';
1427             yylval.ttype = (c == '0') ? integer_zero_node : integer_one_node;
1428             value = CONSTANT;
1429             break;
1430           }
1431         /*FALLTHRU*/
1432       }
1433     case '2':  case '3':  case '4':
1434     case '5':  case '6':  case '7':  case '8':  case '9':
1435     case '.':
1436       {
1437         int base = 10;
1438         int count = 0;
1439         int largest_digit = 0;
1440         int numdigits = 0;
1441         /* for multi-precision arithmetic,
1442            we actually store only HOST_BITS_PER_CHAR bits in each part.
1443            The number of parts is chosen so as to be sufficient to hold
1444            the enough bits to fit into the two HOST_WIDE_INTs that contain
1445            the integer value (this is always at least as many bits as are
1446            in a target `long long' value, but may be wider).  */
1447 #define TOTAL_PARTS ((HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR) * 2 + 2)
1448         int parts[TOTAL_PARTS];
1449         int overflow = 0;
1450
1451         enum anon1 { NOT_FLOAT, AFTER_POINT, TOO_MANY_POINTS, AFTER_EXPON}
1452           floatflag = NOT_FLOAT;
1453
1454         for (count = 0; count < TOTAL_PARTS; count++)
1455           parts[count] = 0;
1456
1457         p = token_buffer;
1458         *p++ = c;
1459
1460         if (c == '0')
1461           {
1462             *p++ = (c = GETC());
1463             if ((c == 'x') || (c == 'X'))
1464               {
1465                 base = 16;
1466                 *p++ = (c = GETC());
1467               }
1468             /* Leading 0 forces octal unless the 0 is the only digit.  */
1469             else if (c >= '0' && c <= '9')
1470               {
1471                 base = 8;
1472                 numdigits++;
1473               }
1474             else
1475               numdigits++;
1476           }
1477
1478         /* Read all the digits-and-decimal-points.  */
1479
1480         while (c == '.'
1481                || (ISALNUM (c) && c != 'l' && c != 'L'
1482                    && c != 'u' && c != 'U'
1483                    && c != 'i' && c != 'I' && c != 'j' && c != 'J'
1484                    && (floatflag == NOT_FLOAT || ((c != 'f') && (c != 'F')))))
1485           {
1486             if (c == '.')
1487               {
1488                 if (base == 16 && pedantic)
1489                   error ("floating constant may not be in radix 16");
1490                 if (floatflag == TOO_MANY_POINTS)
1491                   /* We have already emitted an error.  Don't need another.  */
1492                   ;
1493                 else if (floatflag == AFTER_POINT || floatflag == AFTER_EXPON)
1494                   {
1495                     error ("malformed floating constant");
1496                     floatflag = TOO_MANY_POINTS;
1497                     /* Avoid another error from atof by forcing all characters
1498                        from here on to be ignored.  */
1499                     p[-1] = '\0';
1500                   }
1501                 else
1502                   floatflag = AFTER_POINT;
1503
1504                 if (base == 8)
1505                   base = 10;
1506                 *p++ = c = GETC();
1507                 /* Accept '.' as the start of a floating-point number
1508                    only when it is followed by a digit.
1509                    Otherwise, unread the following non-digit
1510                    and use the '.' as a structural token.  */
1511                 if (p == token_buffer + 2 && !ISDIGIT (c))
1512                   {
1513                     if (c == '.')
1514                       {
1515                         c = GETC();
1516                         if (c == '.')
1517                           {
1518                             *p++ = c;
1519                             *p = 0;
1520                             return ELLIPSIS;
1521                           }
1522                         error ("parse error at `..'");
1523                       }
1524                     UNGETC (c);
1525                     token_buffer[1] = 0;
1526                     value = '.';
1527                     goto done;
1528                   }
1529               }
1530             else
1531               {
1532                 /* It is not a decimal point.
1533                    It should be a digit (perhaps a hex digit).  */
1534
1535                 if (ISDIGIT (c))
1536                   {
1537                     c = c - '0';
1538                   }
1539                 else if (base <= 10)
1540                   {
1541                     if (c == 'e' || c == 'E')
1542                       {
1543                         base = 10;
1544                         floatflag = AFTER_EXPON;
1545                         break;   /* start of exponent */
1546                       }
1547                     error ("nondigits in number and not hexadecimal");
1548                     c = 0;
1549                   }
1550                 else if (base == 16 && (c == 'p' || c == 'P'))
1551                   {
1552                     floatflag = AFTER_EXPON;
1553                     break;   /* start of exponent */
1554                   }
1555                 else if (c >= 'a')
1556                   {
1557                     c = c - 'a' + 10;
1558                   }
1559                 else
1560                   {
1561                     c = c - 'A' + 10;
1562                   }
1563                 if (c >= largest_digit)
1564                   largest_digit = c;
1565                 numdigits++;
1566
1567                 for (count = 0; count < TOTAL_PARTS; count++)
1568                   {
1569                     parts[count] *= base;
1570                     if (count)
1571                       {
1572                         parts[count]
1573                           += (parts[count-1] >> HOST_BITS_PER_CHAR);
1574                         parts[count-1]
1575                           &= (1 << HOST_BITS_PER_CHAR) - 1;
1576                       }
1577                     else
1578                       parts[0] += c;
1579                   }
1580
1581                 /* If the extra highest-order part ever gets anything in it,
1582                    the number is certainly too big.  */
1583                 if (parts[TOTAL_PARTS - 1] != 0)
1584                   overflow = 1;
1585
1586                 if (p >= token_buffer + maxtoken - 3)
1587                   p = extend_token_buffer (p);
1588                 *p++ = (c = GETC());
1589               }
1590           }
1591
1592         if (numdigits == 0)
1593           error ("numeric constant with no digits");
1594
1595         if (largest_digit >= base)
1596           error ("numeric constant contains digits beyond the radix");
1597
1598         /* Remove terminating char from the token buffer and delimit the string */
1599         *--p = 0;
1600
1601         if (floatflag != NOT_FLOAT)
1602           {
1603             tree type = double_type_node;
1604             int imag = 0;
1605             int conversion_errno = 0;
1606             REAL_VALUE_TYPE value;
1607             struct pf_args args;
1608
1609             /* Read explicit exponent if any, and put it in tokenbuf.  */
1610
1611             if ((base == 10 && ((c == 'e') || (c == 'E')))
1612                 || (base == 16 && (c == 'p' || c == 'P')))
1613               {
1614                 if (p >= token_buffer + maxtoken - 3)
1615                   p = extend_token_buffer (p);
1616                 *p++ = c;
1617                 c = GETC();
1618                 if ((c == '+') || (c == '-'))
1619                   {
1620                     *p++ = c;
1621                     c = GETC();
1622                   }
1623                 /* Exponent is decimal, even if string is a hex float.  */
1624                 if (! ISDIGIT (c))
1625                   error ("floating constant exponent has no digits");
1626                 while (ISDIGIT (c))
1627                   {
1628                     if (p >= token_buffer + maxtoken - 3)
1629                       p = extend_token_buffer (p);
1630                     *p++ = c;
1631                     c = GETC();
1632                   }
1633               }
1634             if (base == 16 && floatflag != AFTER_EXPON)
1635               error ("hexadecimal floating constant has no exponent");
1636
1637             *p = 0;
1638
1639             /* Setup input for parse_float() */
1640             args.base = base;
1641             args.p = p;
1642             args.c = c;
1643             args.imag = imag;
1644             args.type = type;
1645             args.conversion_errno = conversion_errno;
1646
1647             /* Convert string to a double, checking for overflow.  */
1648             if (do_float_handler (parse_float, (PTR) &args))
1649               {
1650                 /* Receive output from parse_float() */
1651                 value = args.value;
1652               }
1653             else
1654               {
1655                 /* We got an exception from parse_float() */
1656                 error ("floating constant out of range");
1657                 value = dconst0;
1658               }
1659
1660             /* Receive output from parse_float() */
1661             c = args.c;
1662             imag = args.imag;
1663             type = args.type;
1664             conversion_errno = args.conversion_errno;
1665             
1666 #ifdef ERANGE
1667             /* ERANGE is also reported for underflow,
1668                so test the value to distinguish overflow from that.  */
1669             if (conversion_errno == ERANGE && !flag_traditional && pedantic
1670                 && (REAL_VALUES_LESS (dconst1, value)
1671                     || REAL_VALUES_LESS (value, dconstm1)))
1672               warning ("floating point number exceeds range of `double'");
1673 #endif
1674
1675             /* If the result is not a number, assume it must have been
1676                due to some error message above, so silently convert
1677                it to a zero.  */
1678             if (REAL_VALUE_ISNAN (value))
1679               value = dconst0;
1680
1681             /* Create a node with determined type and value.  */
1682             if (imag)
1683               yylval.ttype = build_complex (NULL_TREE,
1684                                             convert (type, integer_zero_node),
1685                                             build_real (type, value));
1686             else
1687               yylval.ttype = build_real (type, value);
1688           }
1689         else
1690           {
1691             tree traditional_type, ansi_type, type;
1692             HOST_WIDE_INT high, low;
1693             int spec_unsigned = 0;
1694             int spec_long = 0;
1695             int spec_long_long = 0;
1696             int spec_imag = 0;
1697             int warn, i;
1698
1699             traditional_type = ansi_type = type = NULL_TREE;
1700             while (1)
1701               {
1702                 if (c == 'u' || c == 'U')
1703                   {
1704                     if (spec_unsigned)
1705                       error ("two `u's in integer constant");
1706                     spec_unsigned = 1;
1707                   }
1708                 else if (c == 'l' || c == 'L')
1709                   {
1710                     if (spec_long)
1711                       {
1712                         if (spec_long_long)
1713                           error ("three `l's in integer constant");
1714                         else if (pedantic && ! in_system_header && warn_long_long)
1715                           pedwarn ("ANSI C forbids long long integer constants");
1716                         spec_long_long = 1;
1717                       }
1718                     spec_long = 1;
1719                   }
1720                 else if (c == 'i' || c == 'j' || c == 'I' || c == 'J')
1721                   {
1722                     if (spec_imag)
1723                       error ("more than one `i' or `j' in numeric constant");
1724                     else if (pedantic)
1725                       pedwarn ("ANSI C forbids imaginary numeric constants");
1726                     spec_imag = 1;
1727                   }
1728                 else
1729                   break;
1730                 if (p >= token_buffer + maxtoken - 3)
1731                   p = extend_token_buffer (p);
1732                 *p++ = c;
1733                 c = GETC();
1734               }
1735
1736             /* If it won't fit in the host's representation for integers,
1737                then pedwarn. */
1738
1739             warn = overflow;
1740             if (warn)
1741               pedwarn ("integer constant out of range");
1742
1743             /* This is simplified by the fact that our constant
1744                is always positive.  */
1745
1746             high = low = 0;
1747
1748             for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR; i++)
1749               {
1750                 high |= ((HOST_WIDE_INT) parts[i + (HOST_BITS_PER_WIDE_INT
1751                                                     / HOST_BITS_PER_CHAR)]
1752                          << (i * HOST_BITS_PER_CHAR));
1753                 low |= (HOST_WIDE_INT) parts[i] << (i * HOST_BITS_PER_CHAR);
1754               }
1755
1756             yylval.ttype = build_int_2 (low, high);
1757             TREE_TYPE (yylval.ttype) = long_long_unsigned_type_node;
1758
1759             /* If warn_traditional, calculate both the ANSI type and the
1760                traditional type, then see if they disagree.
1761                Otherwise, calculate only the type for the dialect in use.  */
1762             if (warn_traditional || flag_traditional)
1763               {
1764                 /* Calculate the traditional type.  */
1765                 /* Traditionally, any constant is signed;
1766                    but if unsigned is specified explicitly, obey that.
1767                    Use the smallest size with the right number of bits,
1768                    except for one special case with decimal constants.  */
1769                 if (! spec_long && base != 10
1770                     && int_fits_type_p (yylval.ttype, unsigned_type_node))
1771                   traditional_type = (spec_unsigned ? unsigned_type_node
1772                                       : integer_type_node);
1773                 /* A decimal constant must be long
1774                    if it does not fit in type int.
1775                    I think this is independent of whether
1776                    the constant is signed.  */
1777                 else if (! spec_long && base == 10
1778                          && int_fits_type_p (yylval.ttype, integer_type_node))
1779                   traditional_type = (spec_unsigned ? unsigned_type_node
1780                                       : integer_type_node);
1781                 else if (! spec_long_long)
1782                   traditional_type = (spec_unsigned ? long_unsigned_type_node
1783                                       : long_integer_type_node);
1784                 else
1785                   traditional_type = (spec_unsigned
1786                                       ? long_long_unsigned_type_node
1787                                       : long_long_integer_type_node);
1788               }
1789             if (warn_traditional || ! flag_traditional)
1790               {
1791                 /* Calculate the ANSI type.  */
1792                 if (! spec_long && ! spec_unsigned
1793                     && int_fits_type_p (yylval.ttype, integer_type_node))
1794                   ansi_type = integer_type_node;
1795                 else if (! spec_long && (base != 10 || spec_unsigned)
1796                          && int_fits_type_p (yylval.ttype, unsigned_type_node))
1797                   ansi_type = unsigned_type_node;
1798                 else if (! spec_unsigned && !spec_long_long
1799                          && int_fits_type_p (yylval.ttype, long_integer_type_node))
1800                   ansi_type = long_integer_type_node;
1801                 else if (! spec_long_long
1802                          && int_fits_type_p (yylval.ttype,
1803                                              long_unsigned_type_node))
1804                   ansi_type = long_unsigned_type_node;
1805                 else if (! spec_unsigned
1806                          && int_fits_type_p (yylval.ttype,
1807                                              long_long_integer_type_node))
1808                   ansi_type = long_long_integer_type_node;
1809                 else
1810                   ansi_type = long_long_unsigned_type_node;
1811               }
1812
1813             type = flag_traditional ? traditional_type : ansi_type;
1814
1815             /* We assume that constants specified in a non-decimal
1816                base are bit patterns, and that the programmer really
1817                meant what they wrote.  */
1818             if (warn_traditional && base == 10
1819                 && traditional_type != ansi_type)
1820               {
1821                 if (TYPE_PRECISION (traditional_type)
1822                     != TYPE_PRECISION (ansi_type))
1823                   warning ("width of integer constant changes with -traditional");
1824                 else if (TREE_UNSIGNED (traditional_type)
1825                          != TREE_UNSIGNED (ansi_type))
1826                   warning ("integer constant is unsigned in ANSI C, signed with -traditional");
1827                 else
1828                   warning ("width of integer constant may change on other systems with -traditional");
1829               }
1830
1831             if (pedantic && !flag_traditional && !spec_long_long && !warn
1832                 && (TYPE_PRECISION (long_integer_type_node)
1833                     < TYPE_PRECISION (type)))
1834               {
1835                 warn = 1;
1836                 pedwarn ("integer constant out of range");
1837               }
1838
1839             if (base == 10 && ! spec_unsigned && TREE_UNSIGNED (type))
1840               warning ("decimal constant is so large that it is unsigned");
1841
1842             if (spec_imag)
1843               {
1844                 if (TYPE_PRECISION (type)
1845                     <= TYPE_PRECISION (integer_type_node))
1846                   yylval.ttype
1847                     = build_complex (NULL_TREE, integer_zero_node,
1848                                      convert (integer_type_node,
1849                                               yylval.ttype));
1850                 else
1851                   error ("complex integer constant is too wide for `complex int'");
1852               }
1853             else if (flag_traditional && !int_fits_type_p (yylval.ttype, type))
1854               /* The traditional constant 0x80000000 is signed
1855                  but doesn't fit in the range of int.
1856                  This will change it to -0x80000000, which does fit.  */
1857               {
1858                 TREE_TYPE (yylval.ttype) = unsigned_type (type);
1859                 yylval.ttype = convert (type, yylval.ttype);
1860                 TREE_OVERFLOW (yylval.ttype)
1861                   = TREE_CONSTANT_OVERFLOW (yylval.ttype) = 0;
1862               }
1863             else
1864               TREE_TYPE (yylval.ttype) = type;
1865
1866
1867             /* If it's still an integer (not a complex), and it doesn't
1868                fit in the type we choose for it, then pedwarn. */
1869
1870             if (! warn
1871                 && TREE_CODE (TREE_TYPE (yylval.ttype)) == INTEGER_TYPE
1872                 && ! int_fits_type_p (yylval.ttype, TREE_TYPE (yylval.ttype)))
1873               pedwarn ("integer constant out of range");
1874           }
1875
1876         UNGETC (c);
1877         *p = 0;
1878
1879         if (ISALNUM (c) || c == '.' || c == '_' || c == '$'
1880             || (!flag_traditional && (c == '-' || c == '+')
1881                 && (p[-1] == 'e' || p[-1] == 'E')))
1882           error ("missing white space after number `%s'", token_buffer);
1883
1884         value = CONSTANT; break;
1885       }
1886
1887     case '\'':
1888     char_constant:
1889       {
1890         register int result = 0;
1891         register int num_chars = 0;
1892         int chars_seen = 0;
1893         unsigned width = TYPE_PRECISION (char_type_node);
1894         int max_chars;
1895 #ifdef MULTIBYTE_CHARS
1896         int longest_char = local_mb_cur_max ();
1897         (void) local_mbtowc (NULL_PTR, NULL_PTR, 0);
1898 #endif
1899
1900         max_chars = TYPE_PRECISION (integer_type_node) / width;
1901         if (wide_flag)
1902           width = WCHAR_TYPE_SIZE;
1903
1904         while (1)
1905           {
1906           tryagain:
1907             c = GETC();
1908
1909             if (c == '\'' || c == EOF)
1910               break;
1911
1912             ++chars_seen;
1913             if (c == '\\')
1914               {
1915                 int ignore = 0;
1916                 c = readescape (&ignore);
1917                 if (ignore)
1918                   goto tryagain;
1919                 if (width < HOST_BITS_PER_INT
1920                     && (unsigned) c >= ((unsigned)1 << width))
1921                   pedwarn ("escape sequence out of range for character");
1922 #ifdef MAP_CHARACTER
1923                 if (ISPRINT (c))
1924                   c = MAP_CHARACTER (c);
1925 #endif
1926               }
1927             else if (c == '\n')
1928               {
1929                 if (pedantic)
1930                   pedwarn ("ANSI C forbids newline in character constant");
1931                 lineno++;
1932               }
1933             else
1934               {
1935 #ifdef MULTIBYTE_CHARS
1936                 wchar_t wc;
1937                 int i;
1938                 int char_len = -1;
1939                 for (i = 1; i <= longest_char; ++i)
1940                   {
1941                     if (i > maxtoken - 4)
1942                       extend_token_buffer (token_buffer);
1943
1944                     token_buffer[i] = c;
1945                     char_len = local_mbtowc (& wc,
1946                                              token_buffer + 1,
1947                                              i);
1948                     if (char_len != -1)
1949                       break;
1950                     c = GETC ();
1951                   }
1952                 if (char_len > 1)
1953                   {
1954                     /* mbtowc sometimes needs an extra char before accepting */
1955                     if (char_len < i)
1956                       UNGETC (c);
1957                     if (! wide_flag)
1958                       {
1959                         /* Merge character into result; ignore excess chars.  */
1960                         for (i = 1; i <= char_len; ++i)
1961                           {
1962                             if (i > max_chars)
1963                               break;
1964                             if (width < HOST_BITS_PER_INT)
1965                               result = (result << width)
1966                                 | (token_buffer[i]
1967                                    & ((1 << width) - 1));
1968                             else
1969                               result = token_buffer[i];
1970                           }
1971                         num_chars += char_len;
1972                         goto tryagain;
1973                       }
1974                     c = wc;
1975                   }
1976                 else
1977                   {
1978                     if (char_len == -1)
1979                       warning ("Ignoring invalid multibyte character");
1980                     if (wide_flag)
1981                       c = wc;
1982 #ifdef MAP_CHARACTER
1983                     else
1984                       c = MAP_CHARACTER (c);
1985 #endif
1986                   }
1987 #else /* ! MULTIBYTE_CHARS */
1988 #ifdef MAP_CHARACTER
1989                 c = MAP_CHARACTER (c);
1990 #endif
1991 #endif /* ! MULTIBYTE_CHARS */
1992               }
1993
1994             if (wide_flag)
1995               {
1996                 if (chars_seen == 1) /* only keep the first one */
1997                   result = c;
1998                 goto tryagain;
1999               }
2000
2001             /* Merge character into result; ignore excess chars.  */
2002             num_chars += (width / TYPE_PRECISION (char_type_node));
2003             if (num_chars < max_chars + 1)
2004               {
2005                 if (width < HOST_BITS_PER_INT)
2006                   result = (result << width) | (c & ((1 << width) - 1));
2007                 else
2008                   result = c;
2009               }
2010           }
2011
2012         if (c != '\'')
2013           error ("malformatted character constant");
2014         else if (chars_seen == 0)
2015           error ("empty character constant");
2016         else if (num_chars > max_chars)
2017           {
2018             num_chars = max_chars;
2019             error ("character constant too long");
2020           }
2021         else if (chars_seen != 1 && ! flag_traditional && warn_multichar)
2022           warning ("multi-character character constant");
2023
2024         /* If char type is signed, sign-extend the constant.  */
2025         if (! wide_flag)
2026           {
2027             int num_bits = num_chars * width;
2028             if (num_bits == 0)
2029               /* We already got an error; avoid invalid shift.  */
2030               yylval.ttype = build_int_2 (0, 0);
2031             else if (TREE_UNSIGNED (char_type_node)
2032                      || ((result >> (num_bits - 1)) & 1) == 0)
2033               yylval.ttype
2034                 = build_int_2 (result & (~(unsigned HOST_WIDE_INT) 0
2035                                          >> (HOST_BITS_PER_WIDE_INT - num_bits)),
2036                                0);
2037             else
2038               yylval.ttype
2039                 = build_int_2 (result | ~(~(unsigned HOST_WIDE_INT) 0
2040                                           >> (HOST_BITS_PER_WIDE_INT - num_bits)),
2041                                -1);
2042             TREE_TYPE (yylval.ttype) = integer_type_node;
2043           }
2044         else
2045           {
2046             yylval.ttype = build_int_2 (result, 0);
2047             TREE_TYPE (yylval.ttype) = wchar_type_node;
2048           }
2049
2050         value = CONSTANT;
2051         break;
2052       }
2053
2054     case '"':
2055     string_constant:
2056       {
2057         unsigned width = wide_flag ? WCHAR_TYPE_SIZE
2058                                    : TYPE_PRECISION (char_type_node);
2059 #ifdef MULTIBYTE_CHARS
2060         int longest_char = local_mb_cur_max ();
2061         (void) local_mbtowc (NULL_PTR, NULL_PTR, 0);
2062 #endif
2063         c = GETC ();
2064         p = token_buffer + 1;
2065
2066         while (c != '"' && c >= 0)
2067           {
2068             if (c == '\\')
2069               {
2070                 int ignore = 0;
2071                 c = readescape (&ignore);
2072                 if (ignore)
2073                   goto skipnewline;
2074                 if (width < HOST_BITS_PER_INT
2075                     && (unsigned) c >= ((unsigned)1 << width))
2076                   pedwarn ("escape sequence out of range for character");
2077               }
2078             else if (c == '\n')
2079               {
2080                 if (pedantic)
2081                   pedwarn ("ANSI C forbids newline in string constant");
2082                 lineno++;
2083               }
2084             else
2085               {
2086 #ifdef MULTIBYTE_CHARS
2087                 wchar_t wc;
2088                 int i;
2089                 int char_len = -1;
2090                 for (i = 0; i < longest_char; ++i)
2091                   {
2092                     if (p + i >= token_buffer + maxtoken)
2093                       p = extend_token_buffer (p);
2094                     p[i] = c;
2095
2096                     char_len = local_mbtowc (& wc, p, i + 1);
2097                     if (char_len != -1)
2098                       break;
2099                     c = GETC ();
2100                   }
2101                 if (char_len == -1)
2102                   warning ("Ignoring invalid multibyte character");
2103                 else
2104                   {
2105                     /* mbtowc sometimes needs an extra char before accepting */
2106                     if (char_len <= i)
2107                       UNGETC (c);
2108                     if (! wide_flag)
2109                       {
2110                         p += (i + 1);
2111                         c = GETC ();
2112                         continue;
2113                       }
2114                     c = wc;
2115                   }
2116 #endif /* MULTIBYTE_CHARS */
2117               }
2118
2119             /* Add this single character into the buffer either as a wchar_t
2120                or as a single byte.  */
2121             if (wide_flag)
2122               {
2123                 unsigned width = TYPE_PRECISION (char_type_node);
2124                 unsigned bytemask = (1 << width) - 1;
2125                 int byte;
2126
2127                 if (p + WCHAR_BYTES > token_buffer + maxtoken)
2128                   p = extend_token_buffer (p);
2129
2130                 for (byte = 0; byte < WCHAR_BYTES; ++byte)
2131                   {
2132                     int value;
2133                     if (byte >= (int) sizeof (c))
2134                       value = 0;
2135                     else
2136                       value = (c >> (byte * width)) & bytemask;
2137                     if (BYTES_BIG_ENDIAN)
2138                       p[WCHAR_BYTES - byte - 1] = value;
2139                     else
2140                       p[byte] = value;
2141                   }
2142                 p += WCHAR_BYTES;
2143               }
2144             else
2145               {
2146                 if (p >= token_buffer + maxtoken)
2147                   p = extend_token_buffer (p);
2148                 *p++ = c;
2149               }
2150
2151           skipnewline:
2152             c = GETC ();
2153           }
2154
2155         /* Terminate the string value, either with a single byte zero
2156            or with a wide zero.  */
2157         if (wide_flag)
2158           {
2159             if (p + WCHAR_BYTES > token_buffer + maxtoken)
2160               p = extend_token_buffer (p);
2161             bzero (p, WCHAR_BYTES);
2162             p += WCHAR_BYTES;
2163           }
2164         else
2165           {
2166             if (p >= token_buffer + maxtoken)
2167               p = extend_token_buffer (p);
2168             *p++ = 0;
2169           }
2170
2171         if (c < 0)
2172           error ("Unterminated string constant");
2173
2174         /* We have read the entire constant.
2175            Construct a STRING_CST for the result.  */
2176
2177         if (wide_flag)
2178           {
2179             yylval.ttype = build_string (p - (token_buffer + 1),
2180                                          token_buffer + 1);
2181             TREE_TYPE (yylval.ttype) = wchar_array_type_node;
2182             value = STRING;
2183           }
2184         else if (objc_flag)
2185           {
2186             /* Return an Objective-C @"..." constant string object.  */
2187             yylval.ttype = build_objc_string (p - (token_buffer + 1),
2188                                               token_buffer + 1);
2189             TREE_TYPE (yylval.ttype) = char_array_type_node;
2190             value = OBJC_STRING;
2191           }
2192         else
2193           {
2194             yylval.ttype = build_string (p - (token_buffer + 1),
2195                                          token_buffer + 1);
2196             TREE_TYPE (yylval.ttype) = char_array_type_node;
2197             value = STRING;
2198           }
2199
2200         break;
2201       }
2202
2203     case '+':
2204     case '-':
2205     case '&':
2206     case '|':
2207     case ':':
2208     case '<':
2209     case '>':
2210     case '*':
2211     case '/':
2212     case '%':
2213     case '^':
2214     case '!':
2215     case '=':
2216       {
2217         register int c1;
2218
2219       combine:
2220
2221         switch (c)
2222           {
2223           case '+':
2224             yylval.code = PLUS_EXPR; break;
2225           case '-':
2226             yylval.code = MINUS_EXPR; break;
2227           case '&':
2228             yylval.code = BIT_AND_EXPR; break;
2229           case '|':
2230             yylval.code = BIT_IOR_EXPR; break;
2231           case '*':
2232             yylval.code = MULT_EXPR; break;
2233           case '/':
2234             yylval.code = TRUNC_DIV_EXPR; break;
2235           case '%':
2236             yylval.code = TRUNC_MOD_EXPR; break;
2237           case '^':
2238             yylval.code = BIT_XOR_EXPR; break;
2239           case LSHIFT:
2240             yylval.code = LSHIFT_EXPR; break;
2241           case RSHIFT:
2242             yylval.code = RSHIFT_EXPR; break;
2243           case '<':
2244             yylval.code = LT_EXPR; break;
2245           case '>':
2246             yylval.code = GT_EXPR; break;
2247           }
2248
2249         token_buffer[1] = c1 = GETC();
2250         token_buffer[2] = 0;
2251
2252         if (c1 == '=')
2253           {
2254             switch (c)
2255               {
2256               case '<':
2257                 value = ARITHCOMPARE; yylval.code = LE_EXPR; goto done;
2258               case '>':
2259                 value = ARITHCOMPARE; yylval.code = GE_EXPR; goto done;
2260               case '!':
2261                 value = EQCOMPARE; yylval.code = NE_EXPR; goto done;
2262               case '=':
2263                 value = EQCOMPARE; yylval.code = EQ_EXPR; goto done;
2264               }
2265             value = ASSIGN; goto done;
2266           }
2267         else if (c == c1)
2268           switch (c)
2269             {
2270             case '+':
2271               value = PLUSPLUS; goto done;
2272             case '-':
2273               value = MINUSMINUS; goto done;
2274             case '&':
2275               value = ANDAND; goto done;
2276             case '|':
2277               value = OROR; goto done;
2278             case '<':
2279               c = LSHIFT;
2280               goto combine;
2281             case '>':
2282               c = RSHIFT;
2283               goto combine;
2284             }
2285         else
2286           switch (c)
2287             {
2288             case '-':
2289               if (c1 == '>')
2290                 { value = POINTSAT; goto done; }
2291               break;
2292             case ':':
2293               if (c1 == '>')
2294                 { value = ']'; goto done; }
2295               break;
2296             case '<':
2297               if (c1 == '%')
2298                 { value = '{'; indent_level++; goto done; }
2299               if (c1 == ':')
2300                 { value = '['; goto done; }
2301               break;
2302             case '%':
2303               if (c1 == '>')
2304                 { value = '}'; indent_level--; goto done; }
2305               break;
2306             }
2307         UNGETC (c1);
2308         token_buffer[1] = 0;
2309
2310         if ((c == '<') || (c == '>'))
2311           value = ARITHCOMPARE;
2312         else value = c;
2313         goto done;
2314       }
2315
2316     case 0:
2317       /* Don't make yyparse think this is eof.  */
2318       value = 1;
2319       break;
2320
2321     case '{':
2322       indent_level++;
2323       value = c;
2324       break;
2325
2326     case '}':
2327       indent_level--;
2328       value = c;
2329       break;
2330
2331     default:
2332       value = c;
2333     }
2334
2335 done:
2336 /*  yylloc.last_line = lineno; */
2337
2338   return value;
2339 }
2340
2341 /* Sets the value of the 'yydebug' variable to VALUE.
2342    This is a function so we don't have to have YYDEBUG defined
2343    in order to build the compiler.  */
2344
2345 void
2346 set_yydebug (value)
2347      int value;
2348 {
2349 #if YYDEBUG != 0
2350   yydebug = value;
2351 #else
2352   warning ("YYDEBUG not defined.");
2353 #endif
2354 }