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