revert between 56095 -> 55830 in arch
[AROS.git] / tools / cxref / cpp / cexp.y
blobd83de8033643c44b54e8728f80e7121fadb766ed
1 /* Parse C expressions for CCCP.
2 Copyright (C) 1987, 1992, 1994, 1995 Free Software Foundation.
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.
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.
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.
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!
23 Adapted from expread.y of GDB by Paul Rubin, July 1986. */
25 /* Parse a C expression from text in a string */
28 #include "config.h"
29 #include <setjmp.h>
30 /* #define YYDEBUG 1 */
32 #ifdef MULTIBYTE_CHARS
33 #include <stdlib.h>
34 #include <locale.h>
35 #endif
37 #include <stdio.h>
39 typedef unsigned char U_CHAR;
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;
49 /* Define a generic NULL if one hasn't already been defined. */
51 #ifndef NULL
52 #define NULL 0
53 #endif
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
63 /* Find the largest host integer type and set its size and type. */
65 #ifndef HOST_BITS_PER_WIDE_INT
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
75 #endif
77 #ifndef NULL_PTR
78 #define NULL_PTR ((GENERIC_PTR)0)
79 #endif
81 int yylex ();
82 void yyerror ();
83 HOST_WIDE_INT expression_value;
85 static jmp_buf parse_return_error;
87 /* Nonzero means count most punctuation as part of a name. */
88 static int keyword_parsing = 0;
90 /* Nonzero means do not evaluate this expression.
91 This is a count, since unevaluated expressions can nest. */
92 static int skip_evaluation;
94 /* some external tables of character types */
95 extern unsigned char is_idstart[], is_idchar[], is_hor_space[];
97 extern char *xmalloc ();
99 /* Flag for -pedantic. */
100 extern int pedantic;
102 /* Flag for -traditional. */
103 extern int traditional;
105 #ifndef CHAR_TYPE_SIZE
106 #define CHAR_TYPE_SIZE BITS_PER_UNIT
107 #endif
109 #ifndef INT_TYPE_SIZE
110 #define INT_TYPE_SIZE BITS_PER_WORD
111 #endif
113 #ifndef LONG_TYPE_SIZE
114 #define LONG_TYPE_SIZE BITS_PER_WORD
115 #endif
117 #ifndef WCHAR_TYPE_SIZE
118 #define WCHAR_TYPE_SIZE INT_TYPE_SIZE
119 #endif
121 #ifndef MAX_CHAR_TYPE_SIZE
122 #define MAX_CHAR_TYPE_SIZE CHAR_TYPE_SIZE
123 #endif
125 #ifndef MAX_INT_TYPE_SIZE
126 #define MAX_INT_TYPE_SIZE INT_TYPE_SIZE
127 #endif
129 #ifndef MAX_LONG_TYPE_SIZE
130 #define MAX_LONG_TYPE_SIZE LONG_TYPE_SIZE
131 #endif
133 #ifndef MAX_WCHAR_TYPE_SIZE
134 #define MAX_WCHAR_TYPE_SIZE WCHAR_TYPE_SIZE
135 #endif
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)
141 static void integer_overflow ();
142 static long left_shift ();
143 static long right_shift ();
146 %union {
147 struct constant {long value; int unsignedp;} integer;
148 struct name {U_CHAR *address; int length;} name;
149 struct arglist *keywords;
152 %type <integer> exp exp1 start
153 %type <keywords> keywords
154 %token <integer> INT CHAR
155 %token <name> NAME
156 %token <integer> ERROR
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
172 /* %expect 40 */
176 start : exp1
177 { expression_value = $1.value; }
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; }
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; }
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
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 ();
230 | exp '/' exp
231 { if ($3.value == 0)
233 if (!skip_evaluation)
234 error ("division by zero in #if");
235 $3.value = 1;
237 $$.unsignedp = $1.unsignedp || $3.unsignedp;
238 if ($$.unsignedp)
239 $$.value = (unsigned long) $1.value / $3.value;
240 else
242 $$.value = $1.value / $3.value;
243 if (($$.value & $1.value & $3.value) < 0)
244 integer_overflow ();
246 | exp '%' exp
247 { if ($3.value == 0)
249 if (!skip_evaluation)
250 error ("division by zero in #if");
251 $3.value = 1;
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; }
326 { skip_evaluation -= !$1.value;
327 $$.value = ($1.value && $4.value);
328 $$.unsignedp = 0; }
329 | exp OR
330 { skip_evaluation += !!$1.value; }
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; }
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; }
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; }
375 /* During parsing of a C expression, the pointer to the next character
376 is in this variable. */
378 static char *lexptr;
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. */
384 /* maybe needs to actually deal with floating point numbers */
387 parse_number (olen)
388 int olen;
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;
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;
406 yylval.integer.unsignedp = 0;
408 if (len >= 3 && (!strncmp (p, "0x", 2) || !strncmp (p, "0X", 2))) {
409 p += 2;
410 base = 16;
411 len -= 2;
413 else if (*p == '0')
414 base = 8;
416 ULONG_MAX_over_base = (unsigned long) -1 / base;
418 for (; len > 0; len--) {
419 c = *p++;
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')
432 if (spec_long)
433 yyerror ("two `l's in integer constant");
434 spec_long = 1;
436 else if (c == 'u' || c == 'U')
438 if (yylval.integer.unsignedp)
439 yyerror ("two `u's in integer constant");
440 yylval.integer.unsignedp = 1;
442 else
443 break;
445 if (--len == 0)
446 break;
447 c = *p++;
449 /* Don't look for any more digits after the suffixes. */
450 break;
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;
459 if (len != 0) {
460 yyerror ("Invalid number in #if expression");
461 return ERROR;
464 if (base <= largest_digit)
465 warning ("integer constant contains digits beyond the radix");
467 if (overflow)
468 warning ("integer constant out of range");
470 /* If too big to be signed, consider it unsigned. */
471 if ((long) n < 0 && ! yylval.integer.unsignedp)
473 if (base == 10)
474 warning ("integer constant is so large that it is unsigned");
475 yylval.integer.unsignedp = 1;
478 lexptr = p;
479 yylval.integer.value = n;
480 return INT;
483 struct token {
484 char *operator;
485 int token;
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}
502 /* Read one token, getting characters through lexptr. */
505 yylex ()
507 register int c;
508 register int namelen;
509 register unsigned char *tokstart;
510 register struct token *toktab;
511 int wide_flag;
513 retry:
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)
524 char *buf = (char *) alloca (40);
525 sprintf (buf, "`%s' not allowed in operand of `#if'", toktab->operator);
526 yyerror (buf);
528 return toktab->token;
531 switch (c) {
532 case 0:
533 return 0;
535 case ' ':
536 case '\t':
537 case '\r':
538 case '\n':
539 lexptr++;
540 goto retry;
542 case 'L':
543 /* Capital L may start a wide-string or wide-character constant. */
544 if (lexptr[1] == '\'')
546 lexptr++;
547 wide_flag = 1;
548 goto char_constant;
550 if (lexptr[1] == '"')
552 lexptr++;
553 wide_flag = 1;
554 goto string_constant;
556 break;
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;
571 yylval.name.address = tokstart;
572 yylval.name.length = lexptr - start_ptr;
573 return NAME;
576 /* This code for reading a character constant
577 handles multicharacter constants and wide characters.
578 It is mostly copied from c-lex.c. */
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;
586 if (wide_flag)
588 width = MAX_WCHAR_TYPE_SIZE;
589 #ifdef MULTIBYTE_CHARS
590 max_chars = MB_CUR_MAX;
591 #else
592 max_chars = 1;
593 #endif
595 else
596 max_chars = MAX_LONG_TYPE_SIZE / width;
598 token_buffer = (char *) alloca (max_chars + 1);
600 while (1)
602 c = *lexptr++;
604 if (c == '\'' || c == EOF)
605 break;
607 if (c == '\\')
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");
615 num_chars++;
617 /* Merge character into result; ignore excess chars. */
618 if (num_chars < max_chars + 1)
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;
628 token_buffer[num_chars] = 0;
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)
636 num_chars = max_chars;
637 error ("character constant too long");
639 else if (num_chars != 1 && ! traditional)
640 warning ("multi-character character constant");
642 /* If char type is signed, sign-extend the constant. */
643 if (! wide_flag)
645 int num_bits = num_chars * width;
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));
655 else
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'))
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");
672 #endif
673 yylval.integer.value = result;
677 /* This is always a signed type. */
678 yylval.integer.unsignedp = 0;
680 return CHAR;
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;
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;
726 yylval.name.address = tokstart;
727 yylval.name.length = lexptr - start_ptr;
728 return NAME;
730 yyerror ("string constants not allowed in #if expressions");
731 return ERROR;
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++)
740 return parse_number (namelen);
743 /* It is a name. See how long it is. */
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;
754 } else {
755 if (!is_idstart[c]) {
756 yyerror ("Invalid token in expression");
757 return ERROR;
760 for (namelen = 0; is_idchar[tokstart[namelen]]; namelen++)
764 lexptr += namelen;
765 yylval.name.address = tokstart;
766 yylval.name.length = namelen;
767 return NAME;
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.
776 A negative value means the sequence \ newline was seen,
777 which is supposed to be equivalent to nothing at all.
779 If \ is followed by a null character, we return a negative
780 value and leave the string pointer pointing at the null character.
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. */
786 parse_escape (string_ptr)
787 char **string_ptr;
789 register int c = *(*string_ptr)++;
790 switch (c)
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;
817 case '0':
818 case '1':
819 case '2':
820 case '3':
821 case '4':
822 case '5':
823 case '6':
824 case '7':
826 register int i = c - '0';
827 register int count = 0;
828 while (++count < 3)
830 c = *(*string_ptr)++;
831 if (c >= '0' && c <= '7')
832 i = (i << 3) + c - '0';
833 else
835 (*string_ptr)--;
836 break;
839 if ((i & ~((1 << MAX_CHAR_TYPE_SIZE) - 1)) != 0)
841 i &= (1 << MAX_CHAR_TYPE_SIZE) - 1;
842 warning ("octal character constant does not fit in a byte");
844 return i;
846 case 'x':
848 register unsigned i = 0, overflow = 0, digits_found = 0, digit;
849 for (;;)
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
860 (*string_ptr)--;
861 break;
863 overflow |= i ^ (i << 4 >> 4);
864 i = (i << 4) + digit;
865 digits_found = 1;
867 if (!digits_found)
868 yyerror ("\\x used with no following hex digits");
869 if (overflow | (i & ~((1 << BITS_PER_UNIT) - 1)))
871 i &= (1 << BITS_PER_UNIT) - 1;
872 warning ("hex character constant does not fit in a byte");
874 return i;
876 default:
877 return c;
881 void
882 yyerror (s)
883 char *s;
885 error (s);
886 skip_evaluation = 0;
887 longjmp (parse_return_error, 1);
890 static void
891 integer_overflow ()
893 if (!skip_evaluation && pedantic)
894 pedwarn ("integer overflow in preprocessor expression");
897 static long
898 left_shift (a, b)
899 struct constant *a;
900 unsigned long b;
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;
913 static long
914 right_shift (a, b)
915 struct constant *a;
916 unsigned long b;
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;
926 /* This page contains the entry point to this file. */
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. */
933 HOST_WIDE_INT
934 parse_c_expression (string)
935 char *string;
937 lexptr = string;
939 if (lexptr == 0 || *lexptr == 0) {
940 error ("empty #if expression");
941 return 0; /* don't include the #if group */
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;
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.");
956 return expression_value; /* set by yyparse () */
959 #ifdef TEST_EXP_READER
960 extern int yydebug;
962 /* Main program for testing purposes. */
964 main ()
966 int n, c;
967 char buf[1024];
970 yydebug = 1;
972 initialize_random_junk ();
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));
985 return 0;
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];
997 * initialize random junk in the hash table and maybe other places
999 initialize_random_junk ()
1001 register int i;
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.
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];
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
1024 /* horizontal space table */
1025 ++is_hor_space[' '];
1026 ++is_hor_space['\t'];
1029 error (msg)
1031 printf ("error: %s\n", msg);
1034 warning (msg)
1036 printf ("warning: %s\n", msg);
1039 struct hashnode *
1040 lookup (name, len, hash)
1041 char *name;
1042 int len;
1043 int hash;
1045 return (DEFAULT_SIGNED_CHAR) ? 0 : ((struct hashnode *) -1);
1047 #endif