Improve --help support.
[official-gcc.git] / gcc / cexp.y
blob6280aedeb80affe07a8b8c0896c2e1a64768251f
1 /* Parse C expressions for CCCP.
2 Copyright (C) 1987, 1992, 94 - 97, 1998 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 #ifdef __STDC__
30 # include <stdarg.h>
31 #else
32 # include <varargs.h>
33 #endif
35 #define PRINTF_PROTO(ARGS, m, n) PVPROTO (ARGS) ATTRIBUTE_PRINTF(m, n)
37 #define PRINTF_PROTO_1(ARGS) PRINTF_PROTO(ARGS, 1, 2)
39 #include "system.h"
40 #include <setjmp.h>
41 /* #define YYDEBUG 1 */
43 #ifdef MULTIBYTE_CHARS
44 #include <locale.h>
45 #endif
47 #include "gansidecl.h"
49 typedef unsigned char U_CHAR;
51 /* This is used for communicating lists of keywords with cccp.c. */
52 struct arglist {
53 struct arglist *next;
54 U_CHAR *name;
55 int length;
56 int argno;
59 /* Find the largest host integer type and set its size and type.
60 Watch out: on some crazy hosts `long' is shorter than `int'. */
62 #ifndef HOST_WIDE_INT
63 # if HAVE_INTTYPES_H
64 # include <inttypes.h>
65 # define HOST_WIDE_INT intmax_t
66 # define unsigned_HOST_WIDE_INT uintmax_t
67 # else
68 # if (HOST_BITS_PER_LONG <= HOST_BITS_PER_INT && HOST_BITS_PER_LONGLONG <= HOST_BITS_PER_INT)
69 # define HOST_WIDE_INT int
70 # else
71 # if (HOST_BITS_PER_LONGLONG <= HOST_BITS_PER_LONG || ! (defined LONG_LONG_MAX || defined LLONG_MAX))
72 # define HOST_WIDE_INT long
73 # else
74 # define HOST_WIDE_INT long long
75 # endif
76 # endif
77 # endif
78 #endif
80 #ifndef unsigned_HOST_WIDE_INT
81 #define unsigned_HOST_WIDE_INT unsigned HOST_WIDE_INT
82 #endif
84 #ifndef CHAR_BIT
85 #define CHAR_BIT 8
86 #endif
88 #ifndef HOST_BITS_PER_WIDE_INT
89 #define HOST_BITS_PER_WIDE_INT (CHAR_BIT * sizeof (HOST_WIDE_INT))
90 #endif
92 HOST_WIDE_INT parse_c_expression PROTO((char *, int));
94 static int yylex PROTO((void));
95 static void yyerror PROTO((char *)) __attribute__ ((noreturn));
96 static HOST_WIDE_INT expression_value;
97 #ifdef TEST_EXP_READER
98 static int expression_signedp;
99 #endif
101 static jmp_buf parse_return_error;
103 /* Nonzero means count most punctuation as part of a name. */
104 static int keyword_parsing = 0;
106 /* Nonzero means do not evaluate this expression.
107 This is a count, since unevaluated expressions can nest. */
108 static int skip_evaluation;
110 /* Nonzero means warn if undefined identifiers are evaluated. */
111 static int warn_undef;
113 /* some external tables of character types */
114 extern unsigned char is_idstart[], is_idchar[], is_space[];
116 /* Flag for -pedantic. */
117 extern int pedantic;
119 /* Flag for -traditional. */
120 extern int traditional;
122 /* Flag for -lang-c89. */
123 extern int c89;
125 #ifndef CHAR_TYPE_SIZE
126 #define CHAR_TYPE_SIZE BITS_PER_UNIT
127 #endif
129 #ifndef INT_TYPE_SIZE
130 #define INT_TYPE_SIZE BITS_PER_WORD
131 #endif
133 #ifndef LONG_TYPE_SIZE
134 #define LONG_TYPE_SIZE BITS_PER_WORD
135 #endif
137 #ifndef WCHAR_TYPE_SIZE
138 #define WCHAR_TYPE_SIZE INT_TYPE_SIZE
139 #endif
141 #ifndef MAX_CHAR_TYPE_SIZE
142 #define MAX_CHAR_TYPE_SIZE CHAR_TYPE_SIZE
143 #endif
145 #ifndef MAX_INT_TYPE_SIZE
146 #define MAX_INT_TYPE_SIZE INT_TYPE_SIZE
147 #endif
149 #ifndef MAX_LONG_TYPE_SIZE
150 #define MAX_LONG_TYPE_SIZE LONG_TYPE_SIZE
151 #endif
153 #ifndef MAX_WCHAR_TYPE_SIZE
154 #define MAX_WCHAR_TYPE_SIZE WCHAR_TYPE_SIZE
155 #endif
157 #define MAX_CHAR_TYPE_MASK (MAX_CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT \
158 ? (~ (~ (HOST_WIDE_INT) 0 << MAX_CHAR_TYPE_SIZE)) \
159 : ~ (HOST_WIDE_INT) 0)
161 #define MAX_WCHAR_TYPE_MASK (MAX_WCHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT \
162 ? ~ (~ (HOST_WIDE_INT) 0 << MAX_WCHAR_TYPE_SIZE) \
163 : ~ (HOST_WIDE_INT) 0)
165 /* Suppose A1 + B1 = SUM1, using 2's complement arithmetic ignoring overflow.
166 Suppose A, B and SUM have the same respective signs as A1, B1, and SUM1.
167 Suppose SIGNEDP is negative if the result is signed, zero if unsigned.
168 Then this yields nonzero if overflow occurred during the addition.
169 Overflow occurs if A and B have the same sign, but A and SUM differ in sign,
170 and SIGNEDP is negative.
171 Use `^' to test whether signs differ, and `< 0' to isolate the sign. */
172 #define overflow_sum_sign(a, b, sum, signedp) \
173 ((~((a) ^ (b)) & ((a) ^ (sum)) & (signedp)) < 0)
175 struct constant;
177 GENERIC_PTR xmalloc PROTO((size_t));
178 HOST_WIDE_INT parse_escape PROTO((char **, HOST_WIDE_INT));
179 int check_assertion PROTO((U_CHAR *, int, int, struct arglist *));
180 struct hashnode *lookup PROTO((U_CHAR *, int, int));
181 void error PRINTF_PROTO_1((char *, ...));
182 void pedwarn PRINTF_PROTO_1((char *, ...));
183 void warning PRINTF_PROTO_1((char *, ...));
185 static int parse_number PROTO((int));
186 static HOST_WIDE_INT left_shift PROTO((struct constant *, unsigned_HOST_WIDE_INT));
187 static HOST_WIDE_INT right_shift PROTO((struct constant *, unsigned_HOST_WIDE_INT));
188 static void integer_overflow PROTO((void));
190 /* `signedp' values */
191 #define SIGNED (~0)
192 #define UNSIGNED 0
195 %union {
196 struct constant {HOST_WIDE_INT value; int signedp;} integer;
197 struct name {U_CHAR *address; int length;} name;
198 struct arglist *keywords;
201 %type <integer> exp exp1 start
202 %type <keywords> keywords
203 %token <integer> INT CHAR
204 %token <name> NAME
205 %token <integer> ERROR
207 %right '?' ':'
208 %left ','
209 %left OR
210 %left AND
211 %left '|'
212 %left '^'
213 %left '&'
214 %left EQUAL NOTEQUAL
215 %left '<' '>' LEQ GEQ
216 %left LSH RSH
217 %left '+' '-'
218 %left '*' '/' '%'
219 %right UNARY
221 /* %expect 40 */
225 start : exp1
227 expression_value = $1.value;
228 #ifdef TEST_EXP_READER
229 expression_signedp = $1.signedp;
230 #endif
234 /* Expressions, including the comma operator. */
235 exp1 : exp
236 | exp1 ',' exp
237 { if (pedantic)
238 pedwarn ("comma operator in operand of `#if'");
239 $$ = $3; }
242 /* Expressions, not including the comma operator. */
243 exp : '-' exp %prec UNARY
244 { $$.value = - $2.value;
245 $$.signedp = $2.signedp;
246 if (($$.value & $2.value & $$.signedp) < 0)
247 integer_overflow (); }
248 | '!' exp %prec UNARY
249 { $$.value = ! $2.value;
250 $$.signedp = SIGNED; }
251 | '+' exp %prec UNARY
252 { $$ = $2; }
253 | '~' exp %prec UNARY
254 { $$.value = ~ $2.value;
255 $$.signedp = $2.signedp; }
256 | '#' NAME
257 { $$.value = check_assertion ($2.address, $2.length,
258 0, NULL_PTR);
259 $$.signedp = SIGNED; }
260 | '#' NAME
261 { keyword_parsing = 1; }
262 '(' keywords ')'
263 { $$.value = check_assertion ($2.address, $2.length,
264 1, $5);
265 keyword_parsing = 0;
266 $$.signedp = SIGNED; }
267 | '(' exp1 ')'
268 { $$ = $2; }
271 /* Binary operators in order of decreasing precedence. */
272 exp : exp '*' exp
273 { $$.signedp = $1.signedp & $3.signedp;
274 if ($$.signedp)
276 $$.value = $1.value * $3.value;
277 if ($1.value
278 && ($$.value / $1.value != $3.value
279 || ($$.value & $1.value & $3.value) < 0))
280 integer_overflow ();
282 else
283 $$.value = ((unsigned_HOST_WIDE_INT) $1.value
284 * $3.value); }
285 | exp '/' exp
286 { if ($3.value == 0)
288 if (!skip_evaluation)
289 error ("division by zero in #if");
290 $3.value = 1;
292 $$.signedp = $1.signedp & $3.signedp;
293 if ($$.signedp)
295 $$.value = $1.value / $3.value;
296 if (($$.value & $1.value & $3.value) < 0)
297 integer_overflow ();
299 else
300 $$.value = ((unsigned_HOST_WIDE_INT) $1.value
301 / $3.value); }
302 | exp '%' exp
303 { if ($3.value == 0)
305 if (!skip_evaluation)
306 error ("division by zero in #if");
307 $3.value = 1;
309 $$.signedp = $1.signedp & $3.signedp;
310 if ($$.signedp)
311 $$.value = $1.value % $3.value;
312 else
313 $$.value = ((unsigned_HOST_WIDE_INT) $1.value
314 % $3.value); }
315 | exp '+' exp
316 { $$.value = $1.value + $3.value;
317 $$.signedp = $1.signedp & $3.signedp;
318 if (overflow_sum_sign ($1.value, $3.value,
319 $$.value, $$.signedp))
320 integer_overflow (); }
321 | exp '-' exp
322 { $$.value = $1.value - $3.value;
323 $$.signedp = $1.signedp & $3.signedp;
324 if (overflow_sum_sign ($$.value, $3.value,
325 $1.value, $$.signedp))
326 integer_overflow (); }
327 | exp LSH exp
328 { $$.signedp = $1.signedp;
329 if (($3.value & $3.signedp) < 0)
330 $$.value = right_shift (&$1, -$3.value);
331 else
332 $$.value = left_shift (&$1, $3.value); }
333 | exp RSH exp
334 { $$.signedp = $1.signedp;
335 if (($3.value & $3.signedp) < 0)
336 $$.value = left_shift (&$1, -$3.value);
337 else
338 $$.value = right_shift (&$1, $3.value); }
339 | exp EQUAL exp
340 { $$.value = ($1.value == $3.value);
341 $$.signedp = SIGNED; }
342 | exp NOTEQUAL exp
343 { $$.value = ($1.value != $3.value);
344 $$.signedp = SIGNED; }
345 | exp LEQ exp
346 { $$.signedp = SIGNED;
347 if ($1.signedp & $3.signedp)
348 $$.value = $1.value <= $3.value;
349 else
350 $$.value = ((unsigned_HOST_WIDE_INT) $1.value
351 <= $3.value); }
352 | exp GEQ exp
353 { $$.signedp = SIGNED;
354 if ($1.signedp & $3.signedp)
355 $$.value = $1.value >= $3.value;
356 else
357 $$.value = ((unsigned_HOST_WIDE_INT) $1.value
358 >= $3.value); }
359 | exp '<' exp
360 { $$.signedp = SIGNED;
361 if ($1.signedp & $3.signedp)
362 $$.value = $1.value < $3.value;
363 else
364 $$.value = ((unsigned_HOST_WIDE_INT) $1.value
365 < $3.value); }
366 | exp '>' exp
367 { $$.signedp = SIGNED;
368 if ($1.signedp & $3.signedp)
369 $$.value = $1.value > $3.value;
370 else
371 $$.value = ((unsigned_HOST_WIDE_INT) $1.value
372 > $3.value); }
373 | exp '&' exp
374 { $$.value = $1.value & $3.value;
375 $$.signedp = $1.signedp & $3.signedp; }
376 | exp '^' exp
377 { $$.value = $1.value ^ $3.value;
378 $$.signedp = $1.signedp & $3.signedp; }
379 | exp '|' exp
380 { $$.value = $1.value | $3.value;
381 $$.signedp = $1.signedp & $3.signedp; }
382 | exp AND
383 { skip_evaluation += !$1.value; }
385 { skip_evaluation -= !$1.value;
386 $$.value = ($1.value && $4.value);
387 $$.signedp = SIGNED; }
388 | exp OR
389 { skip_evaluation += !!$1.value; }
391 { skip_evaluation -= !!$1.value;
392 $$.value = ($1.value || $4.value);
393 $$.signedp = SIGNED; }
394 | exp '?'
395 { skip_evaluation += !$1.value; }
396 exp ':'
397 { skip_evaluation += !!$1.value - !$1.value; }
399 { skip_evaluation -= !!$1.value;
400 $$.value = $1.value ? $4.value : $7.value;
401 $$.signedp = $4.signedp & $7.signedp; }
402 | INT
403 { $$ = yylval.integer; }
404 | CHAR
405 { $$ = yylval.integer; }
406 | NAME
407 { if (warn_undef && !skip_evaluation)
408 warning ("`%.*s' is not defined",
409 $1.length, $1.address);
410 $$.value = 0;
411 $$.signedp = SIGNED; }
414 keywords :
415 { $$ = 0; }
416 | '(' keywords ')' keywords
417 { struct arglist *temp;
418 $$ = (struct arglist *) xmalloc (sizeof (struct arglist));
419 $$->next = $2;
420 $$->name = (U_CHAR *) "(";
421 $$->length = 1;
422 temp = $$;
423 while (temp != 0 && temp->next != 0)
424 temp = temp->next;
425 temp->next = (struct arglist *) xmalloc (sizeof (struct arglist));
426 temp->next->next = $4;
427 temp->next->name = (U_CHAR *) ")";
428 temp->next->length = 1; }
429 | NAME keywords
430 { $$ = (struct arglist *) xmalloc (sizeof (struct arglist));
431 $$->name = $1.address;
432 $$->length = $1.length;
433 $$->next = $2; }
437 /* During parsing of a C expression, the pointer to the next character
438 is in this variable. */
440 static char *lexptr;
442 /* Take care of parsing a number (anything that starts with a digit).
443 Set yylval and return the token type; update lexptr.
444 LEN is the number of characters in it. */
446 /* maybe needs to actually deal with floating point numbers */
448 static int
449 parse_number (olen)
450 int olen;
452 register char *p = lexptr;
453 register int c;
454 register unsigned_HOST_WIDE_INT n = 0, nd, max_over_base;
455 register int base = 10;
456 register int len = olen;
457 register int overflow = 0;
458 register int digit, largest_digit = 0;
459 int spec_long = 0;
461 yylval.integer.signedp = SIGNED;
463 if (*p == '0') {
464 base = 8;
465 if (len >= 3 && (p[1] == 'x' || p[1] == 'X')) {
466 p += 2;
467 base = 16;
468 len -= 2;
472 max_over_base = (unsigned_HOST_WIDE_INT) -1 / base;
474 for (; len > 0; len--) {
475 c = *p++;
477 if (c >= '0' && c <= '9')
478 digit = c - '0';
479 else if (base == 16 && c >= 'a' && c <= 'f')
480 digit = c - 'a' + 10;
481 else if (base == 16 && c >= 'A' && c <= 'F')
482 digit = c - 'A' + 10;
483 else {
484 /* `l' means long, and `u' means unsigned. */
485 while (1) {
486 if (c == 'l' || c == 'L')
488 if (!pedantic < spec_long)
489 yyerror ("too many `l's in integer constant");
490 spec_long++;
492 else if (c == 'u' || c == 'U')
494 if (! yylval.integer.signedp)
495 yyerror ("two `u's in integer constant");
496 yylval.integer.signedp = UNSIGNED;
498 else {
499 if (c == '.' || c == 'e' || c == 'E' || c == 'p' || c == 'P')
500 yyerror ("Floating point numbers not allowed in #if expressions");
501 else {
502 char *buf = (char *) alloca (p - lexptr + 40);
503 sprintf (buf, "missing white space after number `%.*s'",
504 (int) (p - lexptr - 1), lexptr);
505 yyerror (buf);
509 if (--len == 0)
510 break;
511 c = *p++;
513 /* Don't look for any more digits after the suffixes. */
514 break;
516 if (largest_digit < digit)
517 largest_digit = digit;
518 nd = n * base + digit;
519 overflow |= (max_over_base < n) | (nd < n);
520 n = nd;
523 if (base <= largest_digit)
524 pedwarn ("integer constant contains digits beyond the radix");
526 if (overflow)
527 pedwarn ("integer constant out of range");
529 /* If too big to be signed, consider it unsigned. */
530 if (((HOST_WIDE_INT) n & yylval.integer.signedp) < 0)
532 if (base == 10)
533 warning ("integer constant is so large that it is unsigned");
534 yylval.integer.signedp = UNSIGNED;
537 lexptr = p;
538 yylval.integer.value = n;
539 return INT;
542 struct token {
543 char *operator;
544 int token;
547 static struct token tokentab2[] = {
548 {"&&", AND},
549 {"||", OR},
550 {"<<", LSH},
551 {">>", RSH},
552 {"==", EQUAL},
553 {"!=", NOTEQUAL},
554 {"<=", LEQ},
555 {">=", GEQ},
556 {"++", ERROR},
557 {"--", ERROR},
558 {NULL, ERROR}
561 /* Read one token, getting characters through lexptr. */
563 static int
564 yylex ()
566 register int c;
567 register int namelen;
568 register unsigned char *tokstart;
569 register struct token *toktab;
570 int wide_flag;
571 HOST_WIDE_INT mask;
573 retry:
575 tokstart = (unsigned char *) lexptr;
576 c = *tokstart;
577 /* See if it is a special token of length 2. */
578 if (! keyword_parsing)
579 for (toktab = tokentab2; toktab->operator != NULL; toktab++)
580 if (c == *toktab->operator && tokstart[1] == toktab->operator[1]) {
581 lexptr += 2;
582 if (toktab->token == ERROR)
584 char *buf = (char *) alloca (40);
585 sprintf (buf, "`%s' not allowed in operand of `#if'", toktab->operator);
586 yyerror (buf);
588 return toktab->token;
591 switch (c) {
592 case '\n':
593 return 0;
595 case ' ':
596 case '\t':
597 case '\r':
598 lexptr++;
599 goto retry;
601 case 'L':
602 /* Capital L may start a wide-string or wide-character constant. */
603 if (lexptr[1] == '\'')
605 lexptr++;
606 wide_flag = 1;
607 mask = MAX_WCHAR_TYPE_MASK;
608 goto char_constant;
610 if (lexptr[1] == '"')
612 lexptr++;
613 wide_flag = 1;
614 mask = MAX_WCHAR_TYPE_MASK;
615 goto string_constant;
617 break;
619 case '\'':
620 wide_flag = 0;
621 mask = MAX_CHAR_TYPE_MASK;
622 char_constant:
623 lexptr++;
624 if (keyword_parsing) {
625 char *start_ptr = lexptr - 1;
626 while (1) {
627 c = *lexptr++;
628 if (c == '\\')
629 c = parse_escape (&lexptr, mask);
630 else if (c == '\'')
631 break;
633 yylval.name.address = tokstart;
634 yylval.name.length = lexptr - start_ptr;
635 return NAME;
638 /* This code for reading a character constant
639 handles multicharacter constants and wide characters.
640 It is mostly copied from c-lex.c. */
642 register HOST_WIDE_INT result = 0;
643 register int num_chars = 0;
644 unsigned width = MAX_CHAR_TYPE_SIZE;
645 int max_chars;
646 char *token_buffer;
648 if (wide_flag)
650 width = MAX_WCHAR_TYPE_SIZE;
651 #ifdef MULTIBYTE_CHARS
652 max_chars = MB_CUR_MAX;
653 #else
654 max_chars = 1;
655 #endif
657 else
658 max_chars = MAX_LONG_TYPE_SIZE / width;
660 token_buffer = (char *) alloca (max_chars + 1);
662 while (1)
664 c = *lexptr++;
666 if (c == '\'' || c == EOF)
667 break;
669 if (c == '\\')
671 c = parse_escape (&lexptr, mask);
674 num_chars++;
676 /* Merge character into result; ignore excess chars. */
677 if (num_chars <= max_chars)
679 if (width < HOST_BITS_PER_WIDE_INT)
680 result = (result << width) | c;
681 else
682 result = c;
683 token_buffer[num_chars - 1] = c;
687 token_buffer[num_chars] = 0;
689 if (c != '\'')
690 error ("malformatted character constant");
691 else if (num_chars == 0)
692 error ("empty character constant");
693 else if (num_chars > max_chars)
695 num_chars = max_chars;
696 error ("character constant too long");
698 else if (num_chars != 1 && ! traditional)
699 warning ("multi-character character constant");
701 /* If char type is signed, sign-extend the constant. */
702 if (! wide_flag)
704 int num_bits = num_chars * width;
706 if (lookup ((U_CHAR *) "__CHAR_UNSIGNED__",
707 sizeof ("__CHAR_UNSIGNED__") - 1, -1)
708 || ((result >> (num_bits - 1)) & 1) == 0)
709 yylval.integer.value
710 = result & (~ (unsigned_HOST_WIDE_INT) 0
711 >> (HOST_BITS_PER_WIDE_INT - num_bits));
712 else
713 yylval.integer.value
714 = result | ~(~ (unsigned_HOST_WIDE_INT) 0
715 >> (HOST_BITS_PER_WIDE_INT - num_bits));
717 else
719 #ifdef MULTIBYTE_CHARS
720 /* Set the initial shift state and convert the next sequence. */
721 result = 0;
722 /* In all locales L'\0' is zero and mbtowc will return zero,
723 so don't use it. */
724 if (num_chars > 1
725 || (num_chars == 1 && token_buffer[0] != '\0'))
727 wchar_t wc;
728 (void) mbtowc (NULL_PTR, NULL_PTR, 0);
729 if (mbtowc (& wc, token_buffer, num_chars) == num_chars)
730 result = wc;
731 else
732 pedwarn ("Ignoring invalid multibyte character");
734 #endif
735 yylval.integer.value = result;
739 /* This is always a signed type. */
740 yylval.integer.signedp = SIGNED;
742 return CHAR;
744 /* some of these chars are invalid in constant expressions;
745 maybe do something about them later */
746 case '/':
747 case '+':
748 case '-':
749 case '*':
750 case '%':
751 case '|':
752 case '&':
753 case '^':
754 case '~':
755 case '!':
756 case '@':
757 case '<':
758 case '>':
759 case '[':
760 case ']':
761 case '.':
762 case '?':
763 case ':':
764 case '=':
765 case '{':
766 case '}':
767 case ',':
768 case '#':
769 if (keyword_parsing)
770 break;
771 case '(':
772 case ')':
773 lexptr++;
774 return c;
776 case '"':
777 mask = MAX_CHAR_TYPE_MASK;
778 string_constant:
779 if (keyword_parsing) {
780 char *start_ptr = lexptr;
781 lexptr++;
782 while (1) {
783 c = *lexptr++;
784 if (c == '\\')
785 c = parse_escape (&lexptr, mask);
786 else if (c == '"')
787 break;
789 yylval.name.address = tokstart;
790 yylval.name.length = lexptr - start_ptr;
791 return NAME;
793 yyerror ("string constants not allowed in #if expressions");
794 return ERROR;
797 if (c >= '0' && c <= '9' && !keyword_parsing) {
798 /* It's a number */
799 for (namelen = 1; ; namelen++) {
800 int d = tokstart[namelen];
801 if (! ((is_idchar[d] || d == '.')
802 || ((d == '-' || d == '+')
803 && (c == 'e' || c == 'E'
804 || ((c == 'p' || c == 'P') && ! c89))
805 && ! traditional)))
806 break;
807 c = d;
809 return parse_number (namelen);
812 /* It is a name. See how long it is. */
814 if (keyword_parsing) {
815 for (namelen = 0;; namelen++) {
816 if (is_space[tokstart[namelen]])
817 break;
818 if (tokstart[namelen] == '(' || tokstart[namelen] == ')')
819 break;
820 if (tokstart[namelen] == '"' || tokstart[namelen] == '\'')
821 break;
823 } else {
824 if (!is_idstart[c]) {
825 yyerror ("Invalid token in expression");
826 return ERROR;
829 for (namelen = 0; is_idchar[tokstart[namelen]]; namelen++)
833 lexptr += namelen;
834 yylval.name.address = tokstart;
835 yylval.name.length = namelen;
836 return NAME;
840 /* Parse a C escape sequence. STRING_PTR points to a variable
841 containing a pointer to the string to parse. That pointer
842 is updated past the characters we use. The value of the
843 escape sequence is returned.
845 RESULT_MASK is used to mask out the result;
846 an error is reported if bits are lost thereby.
848 A negative value means the sequence \ newline was seen,
849 which is supposed to be equivalent to nothing at all.
851 If \ is followed by a null character, we return a negative
852 value and leave the string pointer pointing at the null character.
854 If \ is followed by 000, we return 0 and leave the string pointer
855 after the zeros. A value of 0 does not mean end of string. */
857 HOST_WIDE_INT
858 parse_escape (string_ptr, result_mask)
859 char **string_ptr;
860 HOST_WIDE_INT result_mask;
862 register int c = *(*string_ptr)++;
863 switch (c)
865 case 'a':
866 return TARGET_BELL;
867 case 'b':
868 return TARGET_BS;
869 case 'e':
870 case 'E':
871 if (pedantic)
872 pedwarn ("non-ANSI-standard escape sequence, `\\%c'", c);
873 return 033;
874 case 'f':
875 return TARGET_FF;
876 case 'n':
877 return TARGET_NEWLINE;
878 case 'r':
879 return TARGET_CR;
880 case 't':
881 return TARGET_TAB;
882 case 'v':
883 return TARGET_VT;
884 case '\n':
885 return -2;
886 case 0:
887 (*string_ptr)--;
888 return 0;
890 case '0':
891 case '1':
892 case '2':
893 case '3':
894 case '4':
895 case '5':
896 case '6':
897 case '7':
899 register HOST_WIDE_INT i = c - '0';
900 register int count = 0;
901 while (++count < 3)
903 c = *(*string_ptr)++;
904 if (c >= '0' && c <= '7')
905 i = (i << 3) + c - '0';
906 else
908 (*string_ptr)--;
909 break;
912 if (i != (i & result_mask))
914 i &= result_mask;
915 pedwarn ("octal escape sequence out of range");
917 return i;
919 case 'x':
921 register unsigned_HOST_WIDE_INT i = 0, overflow = 0;
922 register int digits_found = 0, digit;
923 for (;;)
925 c = *(*string_ptr)++;
926 if (c >= '0' && c <= '9')
927 digit = c - '0';
928 else if (c >= 'a' && c <= 'f')
929 digit = c - 'a' + 10;
930 else if (c >= 'A' && c <= 'F')
931 digit = c - 'A' + 10;
932 else
934 (*string_ptr)--;
935 break;
937 overflow |= i ^ (i << 4 >> 4);
938 i = (i << 4) + digit;
939 digits_found = 1;
941 if (!digits_found)
942 yyerror ("\\x used with no following hex digits");
943 if (overflow | (i != (i & result_mask)))
945 i &= result_mask;
946 pedwarn ("hex escape sequence out of range");
948 return i;
950 default:
951 return c;
955 static void
956 yyerror (s)
957 char *s;
959 error ("%s", s);
960 skip_evaluation = 0;
961 longjmp (parse_return_error, 1);
964 static void
965 integer_overflow ()
967 if (!skip_evaluation && pedantic)
968 pedwarn ("integer overflow in preprocessor expression");
971 static HOST_WIDE_INT
972 left_shift (a, b)
973 struct constant *a;
974 unsigned_HOST_WIDE_INT b;
976 /* It's unclear from the C standard whether shifts can overflow.
977 The following code ignores overflow; perhaps a C standard
978 interpretation ruling is needed. */
979 if (b >= HOST_BITS_PER_WIDE_INT)
980 return 0;
981 else
982 return (unsigned_HOST_WIDE_INT) a->value << b;
985 static HOST_WIDE_INT
986 right_shift (a, b)
987 struct constant *a;
988 unsigned_HOST_WIDE_INT b;
990 if (b >= HOST_BITS_PER_WIDE_INT)
991 return a->signedp ? a->value >> (HOST_BITS_PER_WIDE_INT - 1) : 0;
992 else if (a->signedp)
993 return a->value >> b;
994 else
995 return (unsigned_HOST_WIDE_INT) a->value >> b;
998 /* This page contains the entry point to this file. */
1000 /* Parse STRING as an expression, and complain if this fails
1001 to use up all of the contents of STRING.
1002 STRING may contain '\0' bytes; it is terminated by the first '\n'
1003 outside a string constant, so that we can diagnose '\0' properly.
1004 If WARN_UNDEFINED is nonzero, warn if undefined identifiers are evaluated.
1005 We do not support C comments. They should be removed before
1006 this function is called. */
1008 HOST_WIDE_INT
1009 parse_c_expression (string, warn_undefined)
1010 char *string;
1011 int warn_undefined;
1013 lexptr = string;
1014 warn_undef = warn_undefined;
1016 /* if there is some sort of scanning error, just return 0 and assume
1017 the parsing routine has printed an error message somewhere.
1018 there is surely a better thing to do than this. */
1019 if (setjmp (parse_return_error))
1020 return 0;
1022 if (yyparse () != 0)
1023 abort ();
1025 if (*lexptr != '\n')
1026 error ("Junk after end of expression.");
1028 return expression_value; /* set by yyparse () */
1031 #ifdef TEST_EXP_READER
1033 #if YYDEBUG
1034 extern int yydebug;
1035 #endif
1037 int pedantic;
1038 int traditional;
1040 int main PROTO((int, char **));
1041 static void initialize_random_junk PROTO((void));
1042 static void print_unsigned_host_wide_int PROTO((unsigned_HOST_WIDE_INT));
1044 /* Main program for testing purposes. */
1046 main (argc, argv)
1047 int argc;
1048 char **argv;
1050 int n, c;
1051 char buf[1024];
1052 unsigned_HOST_WIDE_INT u;
1054 pedantic = 1 < argc;
1055 traditional = 2 < argc;
1056 #if YYDEBUG
1057 yydebug = 3 < argc;
1058 #endif
1059 initialize_random_junk ();
1061 for (;;) {
1062 printf ("enter expression: ");
1063 n = 0;
1064 while ((buf[n] = c = getchar ()) != '\n' && c != EOF)
1065 n++;
1066 if (c == EOF)
1067 break;
1068 parse_c_expression (buf, 1);
1069 printf ("parser returned ");
1070 u = (unsigned_HOST_WIDE_INT) expression_value;
1071 if (expression_value < 0 && expression_signedp) {
1072 u = -u;
1073 printf ("-");
1075 if (u == 0)
1076 printf ("0");
1077 else
1078 print_unsigned_host_wide_int (u);
1079 if (! expression_signedp)
1080 printf("u");
1081 printf ("\n");
1084 return 0;
1087 static void
1088 print_unsigned_host_wide_int (u)
1089 unsigned_HOST_WIDE_INT u;
1091 if (u) {
1092 print_unsigned_host_wide_int (u / 10);
1093 putchar ('0' + (int) (u % 10));
1097 /* table to tell if char can be part of a C identifier. */
1098 unsigned char is_idchar[256];
1099 /* table to tell if char can be first char of a c identifier. */
1100 unsigned char is_idstart[256];
1101 /* table to tell if c is horizontal or vertical space. */
1102 unsigned char is_space[256];
1105 * initialize random junk in the hash table and maybe other places
1107 static void
1108 initialize_random_junk ()
1110 register int i;
1113 * Set up is_idchar and is_idstart tables. These should be
1114 * faster than saying (is_alpha (c) || c == '_'), etc.
1115 * Must do set up these things before calling any routines tthat
1116 * refer to them.
1118 for (i = 'a'; i <= 'z'; i++) {
1119 ++is_idchar[i - 'a' + 'A'];
1120 ++is_idchar[i];
1121 ++is_idstart[i - 'a' + 'A'];
1122 ++is_idstart[i];
1124 for (i = '0'; i <= '9'; i++)
1125 ++is_idchar[i];
1126 ++is_idchar['_'];
1127 ++is_idstart['_'];
1128 ++is_idchar['$'];
1129 ++is_idstart['$'];
1131 ++is_space[' '];
1132 ++is_space['\t'];
1133 ++is_space['\v'];
1134 ++is_space['\f'];
1135 ++is_space['\n'];
1136 ++is_space['\r'];
1139 void
1140 error VPROTO ((char * msg, ...))
1142 #ifndef __STDC__
1143 char * msg;
1144 #endif
1145 va_list args;
1147 VA_START (args, msg);
1149 #ifndef __STDC__
1150 msg = va_arg (args, char *);
1151 #endif
1153 fprintf (stderr, "error: ");
1154 vfprintf (stderr, msg, args);
1155 fprintf (stderr, "\n");
1156 va_end (args);
1159 void
1160 pedwarn VPROTO ((char * msg, ...))
1162 #ifndef __STDC__
1163 char * msg;
1164 #endif
1165 va_list args;
1167 VA_START (args, msg);
1169 #ifndef __STDC__
1170 msg = va_arg (args, char *);
1171 #endif
1173 fprintf (stderr, "pedwarn: ");
1174 vfprintf (stderr, msg, args);
1175 fprintf (stderr, "\n");
1176 va_end (args);
1179 void
1180 warning VPROTO ((char * msg, ...))
1182 #ifndef __STDC__
1183 char * msg;
1184 #endif
1185 va_list args;
1187 VA_START (args, msg);
1189 #ifndef __STDC__
1190 msg = va_arg (args, char *);
1191 #endif
1193 fprintf (stderr, "warning: ");
1194 vfprintf (stderr, msg, args);
1195 fprintf (stderr, "\n");
1196 va_end (args);
1200 check_assertion (name, sym_length, tokens_specified, tokens)
1201 U_CHAR *name;
1202 int sym_length;
1203 int tokens_specified;
1204 struct arglist *tokens;
1206 return 0;
1209 struct hashnode *
1210 lookup (name, len, hash)
1211 U_CHAR *name;
1212 int len;
1213 int hash;
1215 return (DEFAULT_SIGNED_CHAR) ? 0 : ((struct hashnode *) -1);
1218 GENERIC_PTR
1219 xmalloc (size)
1220 size_t size;
1222 return (GENERIC_PTR) malloc (size);
1224 #endif