OSDN Git Service

avoid spurious signed/unsigned comparison warnings.
[pf3gnuchains/gcc-fork.git] / gcc / cexp.y
1 /* Parse C expressions for CCCP.
2    Copyright (C) 1987, 1992, 1994, 1995 Free Software Foundation.
3
4 This program is free software; you can redistribute it and/or modify it
5 under the terms of the GNU General Public License as published by the
6 Free Software Foundation; either version 2, or (at your option) any
7 later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
17
18  In other words, you are welcome to use, share and improve this program.
19  You are forbidden to forbid anyone else to use, share and improve
20  what you give them.   Help stamp out software-hoarding!
21
22  Adapted from expread.y of GDB by Paul Rubin, July 1986.  */
23
24 /* Parse a C expression from text in a string  */
25    
26 %{
27 #include "config.h"
28 #include <setjmp.h>
29 /* #define YYDEBUG 1 */
30
31 #ifdef MULTIBYTE_CHARS
32 #include <stdlib.h>
33 #include <locale.h>
34 #endif
35
36 #include <stdio.h>
37
38 typedef unsigned char U_CHAR;
39
40 /* This is used for communicating lists of keywords with cccp.c.  */
41 struct arglist {
42   struct arglist *next;
43   U_CHAR *name;
44   int length;
45   int argno;
46 };
47
48 /* Define a generic NULL if one hasn't already been defined.  */
49
50 #ifndef NULL
51 #define NULL 0
52 #endif
53
54 #ifndef GENERIC_PTR
55 #if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
56 #define GENERIC_PTR void *
57 #else
58 #define GENERIC_PTR char *
59 #endif
60 #endif
61
62 /* Find the largest host integer type and set its size and type.  */
63
64 #ifndef HOST_BITS_PER_WIDE_INT
65
66 #if HOST_BITS_PER_LONG > HOST_BITS_PER_INT
67 #define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_LONG
68 #define HOST_WIDE_INT long
69 #else
70 #define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_INT
71 #define HOST_WIDE_INT int
72 #endif
73
74 #endif
75
76 #ifndef NULL_PTR
77 #define NULL_PTR ((GENERIC_PTR)0)
78 #endif
79
80 int yylex ();
81 void yyerror ();
82 HOST_WIDE_INT expression_value;
83
84 static jmp_buf parse_return_error;
85
86 /* Nonzero means count most punctuation as part of a name.  */
87 static int keyword_parsing = 0;
88
89 /* some external tables of character types */
90 extern unsigned char is_idstart[], is_idchar[], is_hor_space[];
91
92 extern char *xmalloc ();
93
94 /* Flag for -pedantic.  */
95 extern int pedantic;
96
97 /* Flag for -traditional.  */
98 extern int traditional;
99
100 #ifndef CHAR_TYPE_SIZE
101 #define CHAR_TYPE_SIZE BITS_PER_UNIT
102 #endif
103
104 #ifndef INT_TYPE_SIZE
105 #define INT_TYPE_SIZE BITS_PER_WORD
106 #endif
107
108 #ifndef LONG_TYPE_SIZE
109 #define LONG_TYPE_SIZE BITS_PER_WORD
110 #endif
111
112 #ifndef WCHAR_TYPE_SIZE
113 #define WCHAR_TYPE_SIZE INT_TYPE_SIZE
114 #endif
115
116 #ifndef MAX_CHAR_TYPE_SIZE
117 #define MAX_CHAR_TYPE_SIZE CHAR_TYPE_SIZE
118 #endif
119
120 #ifndef MAX_INT_TYPE_SIZE
121 #define MAX_INT_TYPE_SIZE INT_TYPE_SIZE
122 #endif
123
124 #ifndef MAX_LONG_TYPE_SIZE
125 #define MAX_LONG_TYPE_SIZE LONG_TYPE_SIZE
126 #endif
127
128 #ifndef MAX_WCHAR_TYPE_SIZE
129 #define MAX_WCHAR_TYPE_SIZE WCHAR_TYPE_SIZE
130 #endif
131
132 /* Yield nonzero if adding two numbers with A's and B's signs can yield a
133    number with SUM's sign, where A, B, and SUM are all C integers.  */
134 #define possible_sum_sign(a, b, sum) ((((a) ^ (b)) | ~ ((a) ^ (sum))) < 0)
135
136 static void integer_overflow ();
137 static long left_shift ();
138 static long right_shift ();
139 %}
140
141 %union {
142   struct constant {long value; int unsignedp;} integer;
143   struct name {U_CHAR *address; int length;} name;
144   struct arglist *keywords;
145 }
146
147 %type <integer> exp exp1 start
148 %type <keywords> keywords
149 %token <integer> INT CHAR
150 %token <name> NAME
151 %token <integer> ERROR
152
153 %right '?' ':'
154 %left ','
155 %left OR
156 %left AND
157 %left '|'
158 %left '^'
159 %left '&'
160 %left EQUAL NOTEQUAL
161 %left '<' '>' LEQ GEQ
162 %left LSH RSH
163 %left '+' '-'
164 %left '*' '/' '%'
165 %right UNARY
166
167 /* %expect 40 */
168 \f
169 %%
170
171 start   :       exp1
172                 { expression_value = $1.value; }
173         ;
174
175 /* Expressions, including the comma operator.  */
176 exp1    :       exp
177         |       exp1 ',' exp
178                         { if (pedantic)
179                             pedwarn ("comma operator in operand of `#if'");
180                           $$ = $3; }
181         ;
182
183 /* Expressions, not including the comma operator.  */
184 exp     :       '-' exp    %prec UNARY
185                         { $$.value = - $2.value;
186                           if (($$.value & $2.value) < 0 && ! $2.unsignedp)
187                             integer_overflow ();
188                           $$.unsignedp = $2.unsignedp; }
189         |       '!' exp    %prec UNARY
190                         { $$.value = ! $2.value;
191                           $$.unsignedp = 0; }
192         |       '+' exp    %prec UNARY
193                         { $$ = $2; }
194         |       '~' exp    %prec UNARY
195                         { $$.value = ~ $2.value;
196                           $$.unsignedp = $2.unsignedp; }
197         |       '#' NAME
198                         { $$.value = check_assertion ($2.address, $2.length,
199                                                       0, NULL_PTR);
200                           $$.unsignedp = 0; }
201         |       '#' NAME
202                         { keyword_parsing = 1; }
203                 '(' keywords ')'
204                         { $$.value = check_assertion ($2.address, $2.length,
205                                                       1, $5);
206                           keyword_parsing = 0;
207                           $$.unsignedp = 0; }
208         |       '(' exp1 ')'
209                         { $$ = $2; }
210         ;
211
212 /* Binary operators in order of decreasing precedence.  */
213 exp     :       exp '*' exp
214                         { $$.unsignedp = $1.unsignedp || $3.unsignedp;
215                           if ($$.unsignedp)
216                             $$.value = (unsigned long) $1.value * $3.value;
217                           else
218                             {
219                               $$.value = $1.value * $3.value;
220                               if ($1.value
221                                   && ($$.value / $1.value != $3.value
222                                       || ($$.value & $1.value & $3.value) < 0))
223                                 integer_overflow ();
224                             } }
225         |       exp '/' exp
226                         { if ($3.value == 0)
227                             {
228                               error ("division by zero in #if");
229                               $3.value = 1;
230                             }
231                           $$.unsignedp = $1.unsignedp || $3.unsignedp;
232                           if ($$.unsignedp)
233                             $$.value = (unsigned long) $1.value / $3.value;
234                           else
235                             {
236                               $$.value = $1.value / $3.value;
237                               if (($$.value & $1.value & $3.value) < 0)
238                                 integer_overflow ();
239                             } }
240         |       exp '%' exp
241                         { if ($3.value == 0)
242                             {
243                               error ("division by zero in #if");
244                               $3.value = 1;
245                             }
246                           $$.unsignedp = $1.unsignedp || $3.unsignedp;
247                           if ($$.unsignedp)
248                             $$.value = (unsigned long) $1.value % $3.value;
249                           else
250                             $$.value = $1.value % $3.value; }
251         |       exp '+' exp
252                         { $$.value = $1.value + $3.value;
253                           $$.unsignedp = $1.unsignedp || $3.unsignedp;
254                           if (! $$.unsignedp
255                               && ! possible_sum_sign ($1.value, $3.value,
256                                                       $$.value))
257                             integer_overflow (); }
258         |       exp '-' exp
259                         { $$.value = $1.value - $3.value;
260                           $$.unsignedp = $1.unsignedp || $3.unsignedp;
261                           if (! $$.unsignedp
262                               && ! possible_sum_sign ($$.value, $3.value,
263                                                       $1.value))
264                             integer_overflow (); }
265         |       exp LSH exp
266                         { $$.unsignedp = $1.unsignedp;
267                           if ($3.value < 0 && ! $3.unsignedp)
268                             $$.value = right_shift (&$1, -$3.value);
269                           else
270                             $$.value = left_shift (&$1, $3.value); }
271         |       exp RSH exp
272                         { $$.unsignedp = $1.unsignedp;
273                           if ($3.value < 0 && ! $3.unsignedp)
274                             $$.value = left_shift (&$1, -$3.value);
275                           else
276                             $$.value = right_shift (&$1, $3.value); }
277         |       exp EQUAL exp
278                         { $$.value = ($1.value == $3.value);
279                           $$.unsignedp = 0; }
280         |       exp NOTEQUAL exp
281                         { $$.value = ($1.value != $3.value);
282                           $$.unsignedp = 0; }
283         |       exp LEQ exp
284                         { $$.unsignedp = 0;
285                           if ($1.unsignedp || $3.unsignedp)
286                             $$.value = (unsigned long) $1.value <= $3.value;
287                           else
288                             $$.value = $1.value <= $3.value; }
289         |       exp GEQ exp
290                         { $$.unsignedp = 0;
291                           if ($1.unsignedp || $3.unsignedp)
292                             $$.value = (unsigned long) $1.value >= $3.value;
293                           else
294                             $$.value = $1.value >= $3.value; }
295         |       exp '<' exp
296                         { $$.unsignedp = 0;
297                           if ($1.unsignedp || $3.unsignedp)
298                             $$.value = (unsigned long) $1.value < $3.value;
299                           else
300                             $$.value = $1.value < $3.value; }
301         |       exp '>' exp
302                         { $$.unsignedp = 0;
303                           if ($1.unsignedp || $3.unsignedp)
304                             $$.value = (unsigned long) $1.value > $3.value;
305                           else
306                             $$.value = $1.value > $3.value; }
307         |       exp '&' exp
308                         { $$.value = $1.value & $3.value;
309                           $$.unsignedp = $1.unsignedp || $3.unsignedp; }
310         |       exp '^' exp
311                         { $$.value = $1.value ^ $3.value;
312                           $$.unsignedp = $1.unsignedp || $3.unsignedp; }
313         |       exp '|' exp
314                         { $$.value = $1.value | $3.value;
315                           $$.unsignedp = $1.unsignedp || $3.unsignedp; }
316         |       exp AND exp
317                         { $$.value = ($1.value && $3.value);
318                           $$.unsignedp = 0; }
319         |       exp OR exp
320                         { $$.value = ($1.value || $3.value);
321                           $$.unsignedp = 0; }
322         |       exp '?' exp ':' exp
323                         { $$.value = $1.value ? $3.value : $5.value;
324                           $$.unsignedp = $3.unsignedp || $5.unsignedp; }
325         |       INT
326                         { $$ = yylval.integer; }
327         |       CHAR
328                         { $$ = yylval.integer; }
329         |       NAME
330                         { $$.value = 0;
331                           $$.unsignedp = 0; }
332         ;
333
334 keywords :
335                         { $$ = 0; } 
336         |       '(' keywords ')' keywords
337                         { struct arglist *temp;
338                           $$ = (struct arglist *) xmalloc (sizeof (struct arglist));
339                           $$->next = $2;
340                           $$->name = (U_CHAR *) "(";
341                           $$->length = 1;
342                           temp = $$;
343                           while (temp != 0 && temp->next != 0)
344                             temp = temp->next;
345                           temp->next = (struct arglist *) xmalloc (sizeof (struct arglist));
346                           temp->next->next = $4;
347                           temp->next->name = (U_CHAR *) ")";
348                           temp->next->length = 1; }
349         |       NAME keywords
350                         { $$ = (struct arglist *) xmalloc (sizeof (struct arglist));
351                           $$->name = $1.address;
352                           $$->length = $1.length;
353                           $$->next = $2; } 
354         ;
355 %%
356 \f
357 /* During parsing of a C expression, the pointer to the next character
358    is in this variable.  */
359
360 static char *lexptr;
361
362 /* Take care of parsing a number (anything that starts with a digit).
363    Set yylval and return the token type; update lexptr.
364    LEN is the number of characters in it.  */
365
366 /* maybe needs to actually deal with floating point numbers */
367
368 int
369 parse_number (olen)
370      int olen;
371 {
372   register char *p = lexptr;
373   register int c;
374   register unsigned long n = 0, nd, ULONG_MAX_over_base;
375   register int base = 10;
376   register int len = olen;
377   register int overflow = 0;
378   register int digit, largest_digit = 0;
379   int spec_long = 0;
380
381   for (c = 0; c < len; c++)
382     if (p[c] == '.') {
383       /* It's a float since it contains a point.  */
384       yyerror ("floating point numbers not allowed in #if expressions");
385       return ERROR;
386     }
387
388   yylval.integer.unsignedp = 0;
389
390   if (len >= 3 && (!strncmp (p, "0x", 2) || !strncmp (p, "0X", 2))) {
391     p += 2;
392     base = 16;
393     len -= 2;
394   }
395   else if (*p == '0')
396     base = 8;
397
398   ULONG_MAX_over_base = (unsigned long) -1 / base;
399
400   for (; len > 0; len--) {
401     c = *p++;
402
403     if (c >= '0' && c <= '9')
404       digit = c - '0';
405     else if (base == 16 && c >= 'a' && c <= 'f')
406       digit = c - 'a' + 10;
407     else if (base == 16 && c >= 'A' && c <= 'F')
408       digit = c - 'A' + 10;
409     else {
410       /* `l' means long, and `u' means unsigned.  */
411       while (1) {
412         if (c == 'l' || c == 'L')
413           {
414             if (spec_long)
415               yyerror ("two `l's in integer constant");
416             spec_long = 1;
417           }
418         else if (c == 'u' || c == 'U')
419           {
420             if (yylval.integer.unsignedp)
421               yyerror ("two `u's in integer constant");
422             yylval.integer.unsignedp = 1;
423           }
424         else
425           break;
426
427         if (--len == 0)
428           break;
429         c = *p++;
430       }
431       /* Don't look for any more digits after the suffixes.  */
432       break;
433     }
434     if (largest_digit < digit)
435       largest_digit = digit;
436     nd = n * base + digit;
437     overflow |= ULONG_MAX_over_base < n | nd < n;
438     n = nd;
439   }
440
441   if (len != 0) {
442     yyerror ("Invalid number in #if expression");
443     return ERROR;
444   }
445
446   if (base <= largest_digit)
447     warning ("integer constant contains digits beyond the radix");
448
449   if (overflow)
450     warning ("integer constant out of range");
451
452   /* If too big to be signed, consider it unsigned.  */
453   if ((long) n < 0 && ! yylval.integer.unsignedp)
454     {
455       if (base == 10)
456         warning ("integer constant is so large that it is unsigned");
457       yylval.integer.unsignedp = 1;
458     }
459
460   lexptr = p;
461   yylval.integer.value = n;
462   return INT;
463 }
464
465 struct token {
466   char *operator;
467   int token;
468 };
469
470 static struct token tokentab2[] = {
471   {"&&", AND},
472   {"||", OR},
473   {"<<", LSH},
474   {">>", RSH},
475   {"==", EQUAL},
476   {"!=", NOTEQUAL},
477   {"<=", LEQ},
478   {">=", GEQ},
479   {"++", ERROR},
480   {"--", ERROR},
481   {NULL, ERROR}
482 };
483
484 /* Read one token, getting characters through lexptr.  */
485
486 int
487 yylex ()
488 {
489   register int c;
490   register int namelen;
491   register unsigned char *tokstart;
492   register struct token *toktab;
493   int wide_flag;
494
495  retry:
496
497   tokstart = (unsigned char *) lexptr;
498   c = *tokstart;
499   /* See if it is a special token of length 2.  */
500   if (! keyword_parsing)
501     for (toktab = tokentab2; toktab->operator != NULL; toktab++)
502       if (c == *toktab->operator && tokstart[1] == toktab->operator[1]) {
503         lexptr += 2;
504         if (toktab->token == ERROR)
505           {
506             char *buf = (char *) alloca (40);
507             sprintf (buf, "`%s' not allowed in operand of `#if'", toktab->operator);
508             yyerror (buf);
509           }
510         return toktab->token;
511       }
512
513   switch (c) {
514   case 0:
515     return 0;
516     
517   case ' ':
518   case '\t':
519   case '\r':
520   case '\n':
521     lexptr++;
522     goto retry;
523     
524   case 'L':
525     /* Capital L may start a wide-string or wide-character constant.  */
526     if (lexptr[1] == '\'')
527       {
528         lexptr++;
529         wide_flag = 1;
530         goto char_constant;
531       }
532     if (lexptr[1] == '"')
533       {
534         lexptr++;
535         wide_flag = 1;
536         goto string_constant;
537       }
538     break;
539
540   case '\'':
541     wide_flag = 0;
542   char_constant:
543     lexptr++;
544     if (keyword_parsing) {
545       char *start_ptr = lexptr - 1;
546       while (1) {
547         c = *lexptr++;
548         if (c == '\\')
549           c = parse_escape (&lexptr);
550         else if (c == '\'')
551           break;
552       }
553       yylval.name.address = tokstart;
554       yylval.name.length = lexptr - start_ptr;
555       return NAME;
556     }
557
558     /* This code for reading a character constant
559        handles multicharacter constants and wide characters.
560        It is mostly copied from c-lex.c.  */
561     {
562       register int result = 0;
563       register num_chars = 0;
564       unsigned width = MAX_CHAR_TYPE_SIZE;
565       int max_chars;
566       char *token_buffer;
567
568       if (wide_flag)
569         {
570           width = MAX_WCHAR_TYPE_SIZE;
571 #ifdef MULTIBYTE_CHARS
572           max_chars = MB_CUR_MAX;
573 #else
574           max_chars = 1;
575 #endif
576         }
577       else
578         max_chars = MAX_LONG_TYPE_SIZE / width;
579
580       token_buffer = (char *) alloca (max_chars + 1);
581
582       while (1)
583         {
584           c = *lexptr++;
585
586           if (c == '\'' || c == EOF)
587             break;
588
589           if (c == '\\')
590             {
591               c = parse_escape (&lexptr);
592               if (width < HOST_BITS_PER_INT
593                   && (unsigned) c >= (1 << width))
594                 pedwarn ("escape sequence out of range for character");
595             }
596
597           num_chars++;
598
599           /* Merge character into result; ignore excess chars.  */
600           if (num_chars < max_chars + 1)
601             {
602               if (width < HOST_BITS_PER_INT)
603                 result = (result << width) | (c & ((1 << width) - 1));
604               else
605                 result = c;
606               token_buffer[num_chars - 1] = c;
607             }
608         }
609
610       token_buffer[num_chars] = 0;
611
612       if (c != '\'')
613         error ("malformatted character constant");
614       else if (num_chars == 0)
615         error ("empty character constant");
616       else if (num_chars > max_chars)
617         {
618           num_chars = max_chars;
619           error ("character constant too long");
620         }
621       else if (num_chars != 1 && ! traditional)
622         warning ("multi-character character constant");
623
624       /* If char type is signed, sign-extend the constant.  */
625       if (! wide_flag)
626         {
627           int num_bits = num_chars * width;
628
629           if (lookup ("__CHAR_UNSIGNED__", sizeof ("__CHAR_UNSIGNED__")-1, -1)
630               || ((result >> (num_bits - 1)) & 1) == 0)
631             yylval.integer.value
632               = result & ((unsigned long) ~0 >> (HOST_BITS_PER_LONG - num_bits));
633           else
634             yylval.integer.value
635               = result | ~((unsigned long) ~0 >> (HOST_BITS_PER_LONG - num_bits));
636         }
637       else
638         {
639 #ifdef MULTIBYTE_CHARS
640           /* Set the initial shift state and convert the next sequence.  */
641           result = 0;
642           /* In all locales L'\0' is zero and mbtowc will return zero,
643              so don't use it.  */
644           if (num_chars > 1
645               || (num_chars == 1 && token_buffer[0] != '\0'))
646             {
647               wchar_t wc;
648               (void) mbtowc (NULL_PTR, NULL_PTR, 0);
649               if (mbtowc (& wc, token_buffer, num_chars) == num_chars)
650                 result = wc;
651               else
652                 warning ("Ignoring invalid multibyte character");
653             }
654 #endif
655           yylval.integer.value = result;
656         }
657     }
658
659     /* This is always a signed type.  */
660     yylval.integer.unsignedp = 0;
661     
662     return CHAR;
663
664     /* some of these chars are invalid in constant expressions;
665        maybe do something about them later */
666   case '/':
667   case '+':
668   case '-':
669   case '*':
670   case '%':
671   case '|':
672   case '&':
673   case '^':
674   case '~':
675   case '!':
676   case '@':
677   case '<':
678   case '>':
679   case '[':
680   case ']':
681   case '.':
682   case '?':
683   case ':':
684   case '=':
685   case '{':
686   case '}':
687   case ',':
688   case '#':
689     if (keyword_parsing)
690       break;
691   case '(':
692   case ')':
693     lexptr++;
694     return c;
695
696   case '"':
697   string_constant:
698     if (keyword_parsing) {
699       char *start_ptr = lexptr;
700       lexptr++;
701       while (1) {
702         c = *lexptr++;
703         if (c == '\\')
704           c = parse_escape (&lexptr);
705         else if (c == '"')
706           break;
707       }
708       yylval.name.address = tokstart;
709       yylval.name.length = lexptr - start_ptr;
710       return NAME;
711     }
712     yyerror ("string constants not allowed in #if expressions");
713     return ERROR;
714   }
715
716   if (c >= '0' && c <= '9' && !keyword_parsing) {
717     /* It's a number */
718     for (namelen = 0;
719          c = tokstart[namelen], is_idchar[c] || c == '.'; 
720          namelen++)
721       ;
722     return parse_number (namelen);
723   }
724
725   /* It is a name.  See how long it is.  */
726
727   if (keyword_parsing) {
728     for (namelen = 0;; namelen++) {
729       if (is_hor_space[tokstart[namelen]])
730         break;
731       if (tokstart[namelen] == '(' || tokstart[namelen] == ')')
732         break;
733       if (tokstart[namelen] == '"' || tokstart[namelen] == '\'')
734         break;
735     }
736   } else {
737     if (!is_idstart[c]) {
738       yyerror ("Invalid token in expression");
739       return ERROR;
740     }
741
742     for (namelen = 0; is_idchar[tokstart[namelen]]; namelen++)
743       ;
744   }
745   
746   lexptr += namelen;
747   yylval.name.address = tokstart;
748   yylval.name.length = namelen;
749   return NAME;
750 }
751
752
753 /* Parse a C escape sequence.  STRING_PTR points to a variable
754    containing a pointer to the string to parse.  That pointer
755    is updated past the characters we use.  The value of the
756    escape sequence is returned.
757
758    A negative value means the sequence \ newline was seen,
759    which is supposed to be equivalent to nothing at all.
760
761    If \ is followed by a null character, we return a negative
762    value and leave the string pointer pointing at the null character.
763
764    If \ is followed by 000, we return 0 and leave the string pointer
765    after the zeros.  A value of 0 does not mean end of string.  */
766
767 int
768 parse_escape (string_ptr)
769      char **string_ptr;
770 {
771   register int c = *(*string_ptr)++;
772   switch (c)
773     {
774     case 'a':
775       return TARGET_BELL;
776     case 'b':
777       return TARGET_BS;
778     case 'e':
779     case 'E':
780       if (pedantic)
781         pedwarn ("non-ANSI-standard escape sequence, `\\%c'", c);
782       return 033;
783     case 'f':
784       return TARGET_FF;
785     case 'n':
786       return TARGET_NEWLINE;
787     case 'r':
788       return TARGET_CR;
789     case 't':
790       return TARGET_TAB;
791     case 'v':
792       return TARGET_VT;
793     case '\n':
794       return -2;
795     case 0:
796       (*string_ptr)--;
797       return 0;
798       
799     case '0':
800     case '1':
801     case '2':
802     case '3':
803     case '4':
804     case '5':
805     case '6':
806     case '7':
807       {
808         register int i = c - '0';
809         register int count = 0;
810         while (++count < 3)
811           {
812             c = *(*string_ptr)++;
813             if (c >= '0' && c <= '7')
814               i = (i << 3) + c - '0';
815             else
816               {
817                 (*string_ptr)--;
818                 break;
819               }
820           }
821         if ((i & ~((1 << MAX_CHAR_TYPE_SIZE) - 1)) != 0)
822           {
823             i &= (1 << MAX_CHAR_TYPE_SIZE) - 1;
824             warning ("octal character constant does not fit in a byte");
825           }
826         return i;
827       }
828     case 'x':
829       {
830         register unsigned i = 0, overflow = 0, digits_found = 0, digit;
831         for (;;)
832           {
833             c = *(*string_ptr)++;
834             if (c >= '0' && c <= '9')
835               digit = c - '0';
836             else if (c >= 'a' && c <= 'f')
837               digit = c - 'a' + 10;
838             else if (c >= 'A' && c <= 'F')
839               digit = c - 'A' + 10;
840             else
841               {
842                 (*string_ptr)--;
843                 break;
844               }
845             overflow |= i ^ (i << 4 >> 4);
846             i = (i << 4) + digit;
847             digits_found = 1;
848           }
849         if (!digits_found)
850           yyerror ("\\x used with no following hex digits");
851         if (overflow | (i & ~((1 << BITS_PER_UNIT) - 1)))
852           {
853             i &= (1 << BITS_PER_UNIT) - 1;
854             warning ("hex character constant does not fit in a byte");
855           }
856         return i;
857       }
858     default:
859       return c;
860     }
861 }
862
863 void
864 yyerror (s)
865      char *s;
866 {
867   error (s);
868   longjmp (parse_return_error, 1);
869 }
870
871 static void
872 integer_overflow ()
873 {
874   if (pedantic)
875     pedwarn ("integer overflow in preprocessor expression");
876 }
877
878 static long
879 left_shift (a, b)
880      struct constant *a;
881      unsigned long b;
882 {
883   if (b >= HOST_BITS_PER_LONG)
884     {
885       if (! a->unsignedp && a->value != 0)
886         integer_overflow ();
887       return 0;
888     }
889   else if (a->unsignedp)
890     return (unsigned long) a->value << b;
891   else
892     {
893       long l = a->value << b;
894       if (l >> b != a->value)
895         integer_overflow ();
896       return l;
897     }
898 }
899
900 static long
901 right_shift (a, b)
902      struct constant *a;
903      unsigned long b;
904 {
905   if (b >= HOST_BITS_PER_LONG)
906     return a->unsignedp ? 0 : a->value >> (HOST_BITS_PER_LONG - 1);
907   else if (a->unsignedp)
908     return (unsigned long) a->value >> b;
909   else
910     return a->value >> b;
911 }
912 \f
913 /* This page contains the entry point to this file.  */
914
915 /* Parse STRING as an expression, and complain if this fails
916    to use up all of the contents of STRING.  */
917 /* We do not support C comments.  They should be removed before
918    this function is called.  */
919
920 HOST_WIDE_INT
921 parse_c_expression (string)
922      char *string;
923 {
924   lexptr = string;
925   
926   if (lexptr == 0 || *lexptr == 0) {
927     error ("empty #if expression");
928     return 0;                   /* don't include the #if group */
929   }
930
931   /* if there is some sort of scanning error, just return 0 and assume
932      the parsing routine has printed an error message somewhere.
933      there is surely a better thing to do than this.     */
934   if (setjmp (parse_return_error))
935     return 0;
936
937   if (yyparse ())
938     return 0;                   /* actually this is never reached
939                                    the way things stand. */
940   if (*lexptr)
941     error ("Junk after end of expression.");
942
943   return expression_value;      /* set by yyparse () */
944 }
945 \f
946 #ifdef TEST_EXP_READER
947 extern int yydebug;
948
949 /* Main program for testing purposes.  */
950 int
951 main ()
952 {
953   int n, c;
954   char buf[1024];
955
956 /*
957   yydebug = 1;
958 */
959   initialize_random_junk ();
960
961   for (;;) {
962     printf ("enter expression: ");
963     n = 0;
964     while ((buf[n] = getchar ()) != '\n' && buf[n] != EOF)
965       n++;
966     if (buf[n] == EOF)
967       break;
968     buf[n] = '\0';
969     printf ("parser returned %ld\n", parse_c_expression (buf));
970   }
971
972   return 0;
973 }
974
975 /* table to tell if char can be part of a C identifier. */
976 unsigned char is_idchar[256];
977 /* table to tell if char can be first char of a c identifier. */
978 unsigned char is_idstart[256];
979 /* table to tell if c is horizontal space.  isspace () thinks that
980    newline is space; this is not a good idea for this program. */
981 char is_hor_space[256];
982
983 /*
984  * initialize random junk in the hash table and maybe other places
985  */
986 initialize_random_junk ()
987 {
988   register int i;
989
990   /*
991    * Set up is_idchar and is_idstart tables.  These should be
992    * faster than saying (is_alpha (c) || c == '_'), etc.
993    * Must do set up these things before calling any routines tthat
994    * refer to them.
995    */
996   for (i = 'a'; i <= 'z'; i++) {
997     ++is_idchar[i - 'a' + 'A'];
998     ++is_idchar[i];
999     ++is_idstart[i - 'a' + 'A'];
1000     ++is_idstart[i];
1001   }
1002   for (i = '0'; i <= '9'; i++)
1003     ++is_idchar[i];
1004   ++is_idchar['_'];
1005   ++is_idstart['_'];
1006 #if DOLLARS_IN_IDENTIFIERS
1007   ++is_idchar['$'];
1008   ++is_idstart['$'];
1009 #endif
1010
1011   /* horizontal space table */
1012   ++is_hor_space[' '];
1013   ++is_hor_space['\t'];
1014 }
1015
1016 error (msg)
1017 {
1018   printf ("error: %s\n", msg);
1019 }
1020
1021 warning (msg)
1022 {
1023   printf ("warning: %s\n", msg);
1024 }
1025
1026 struct hashnode *
1027 lookup (name, len, hash)
1028      char *name;
1029      int len;
1030      int hash;
1031 {
1032   return (DEFAULT_SIGNED_CHAR) ? 0 : ((struct hashnode *) -1);
1033 }
1034 #endif