Declare malloc, free, and atexit if inhibit_libc is defined.
[official-gcc.git] / gcc / cexp.y
blob410f671fbb9860a6a0dc280b1f11ea5ea374727c
1 /* Parse C expressions for CCCP.
2 Copyright (C) 1987, 92, 94-98, 1999 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"
30 #include "system.h"
31 #include "intl.h"
32 #include <setjmp.h>
33 /* #define YYDEBUG 1 */
35 #ifdef MULTIBYTE_CHARS
36 #include "mbchar.h"
37 #include <locale.h>
38 #endif /* MULTIBYTE_CHARS */
40 typedef unsigned char U_CHAR;
42 /* This is used for communicating lists of keywords with cccp.c. */
43 struct arglist {
44 struct arglist *next;
45 U_CHAR *name;
46 int length;
47 int argno;
50 HOST_WIDEST_INT parse_c_expression PROTO((char *, int));
52 static int yylex PROTO((void));
53 static void yyerror PVPROTO((const char *, ...))
54 ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
55 static HOST_WIDEST_INT expression_value;
56 #ifdef TEST_EXP_READER
57 static int expression_signedp;
58 #endif
60 static jmp_buf parse_return_error;
62 /* Nonzero means count most punctuation as part of a name. */
63 static int keyword_parsing = 0;
65 /* Nonzero means do not evaluate this expression.
66 This is a count, since unevaluated expressions can nest. */
67 static int skip_evaluation;
69 /* Nonzero means warn if undefined identifiers are evaluated. */
70 static int warn_undef;
72 /* some external tables of character types */
73 extern unsigned char is_idstart[], is_idchar[], is_space[];
75 /* Flag for -pedantic. */
76 extern int pedantic;
78 /* Flag for -traditional. */
79 extern int traditional;
81 /* Flag for -lang-c89. */
82 extern int c89;
84 #ifndef CHAR_TYPE_SIZE
85 #define CHAR_TYPE_SIZE BITS_PER_UNIT
86 #endif
88 #ifndef INT_TYPE_SIZE
89 #define INT_TYPE_SIZE BITS_PER_WORD
90 #endif
92 #ifndef LONG_TYPE_SIZE
93 #define LONG_TYPE_SIZE BITS_PER_WORD
94 #endif
96 #ifndef WCHAR_TYPE_SIZE
97 #define WCHAR_TYPE_SIZE INT_TYPE_SIZE
98 #endif
100 #ifndef MAX_CHAR_TYPE_SIZE
101 #define MAX_CHAR_TYPE_SIZE CHAR_TYPE_SIZE
102 #endif
104 #ifndef MAX_INT_TYPE_SIZE
105 #define MAX_INT_TYPE_SIZE INT_TYPE_SIZE
106 #endif
108 #ifndef MAX_LONG_TYPE_SIZE
109 #define MAX_LONG_TYPE_SIZE LONG_TYPE_SIZE
110 #endif
112 #ifndef MAX_WCHAR_TYPE_SIZE
113 #define MAX_WCHAR_TYPE_SIZE WCHAR_TYPE_SIZE
114 #endif
116 #define MAX_CHAR_TYPE_MASK (MAX_CHAR_TYPE_SIZE < HOST_BITS_PER_WIDEST_INT \
117 ? (~ (~ (HOST_WIDEST_INT) 0 << MAX_CHAR_TYPE_SIZE)) \
118 : ~ (HOST_WIDEST_INT) 0)
120 #define MAX_WCHAR_TYPE_MASK (MAX_WCHAR_TYPE_SIZE < HOST_BITS_PER_WIDEST_INT \
121 ? ~ (~ (HOST_WIDEST_INT) 0 << MAX_WCHAR_TYPE_SIZE) \
122 : ~ (HOST_WIDEST_INT) 0)
124 /* Suppose A1 + B1 = SUM1, using 2's complement arithmetic ignoring overflow.
125 Suppose A, B and SUM have the same respective signs as A1, B1, and SUM1.
126 Suppose SIGNEDP is negative if the result is signed, zero if unsigned.
127 Then this yields nonzero if overflow occurred during the addition.
128 Overflow occurs if A and B have the same sign, but A and SUM differ in sign,
129 and SIGNEDP is negative.
130 Use `^' to test whether signs differ, and `< 0' to isolate the sign. */
131 #define overflow_sum_sign(a, b, sum, signedp) \
132 ((~((a) ^ (b)) & ((a) ^ (sum)) & (signedp)) < 0)
134 struct constant;
136 HOST_WIDEST_INT parse_escape PROTO((char **, HOST_WIDEST_INT));
137 int check_assertion PROTO((U_CHAR *, int, int, struct arglist *));
138 struct hashnode *lookup PROTO((U_CHAR *, int, int));
139 void error PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1;
140 void verror PROTO((const char *, va_list));
141 void pedwarn PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1;
142 void warning PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1;
144 static int parse_number PROTO((int));
145 static HOST_WIDEST_INT left_shift PROTO((struct constant *, unsigned HOST_WIDEST_INT));
146 static HOST_WIDEST_INT right_shift PROTO((struct constant *, unsigned HOST_WIDEST_INT));
147 static void integer_overflow PROTO((void));
149 /* `signedp' values */
150 #define SIGNED (~0)
151 #define UNSIGNED 0
154 %union {
155 struct constant {HOST_WIDEST_INT value; int signedp;} integer;
156 struct name {U_CHAR *address; int length;} name;
157 struct arglist *keywords;
160 %type <integer> exp exp1 start
161 %type <keywords> keywords
162 %token <integer> INT CHAR
163 %token <name> NAME
164 %token <integer> ERROR
166 %right '?' ':'
167 %left ','
168 %left OR
169 %left AND
170 %left '|'
171 %left '^'
172 %left '&'
173 %left EQUAL NOTEQUAL
174 %left '<' '>' LEQ GEQ
175 %left LSH RSH
176 %left '+' '-'
177 %left '*' '/' '%'
178 %right UNARY
180 /* %expect 40 */
184 start : exp1
186 expression_value = $1.value;
187 #ifdef TEST_EXP_READER
188 expression_signedp = $1.signedp;
189 #endif
193 /* Expressions, including the comma operator. */
194 exp1 : exp
195 | exp1 ',' exp
196 { if (pedantic)
197 pedwarn ("comma operator in operand of `#if'");
198 $$ = $3; }
201 /* Expressions, not including the comma operator. */
202 exp : '-' exp %prec UNARY
203 { $$.value = - $2.value;
204 $$.signedp = $2.signedp;
205 if (($$.value & $2.value & $$.signedp) < 0)
206 integer_overflow (); }
207 | '!' exp %prec UNARY
208 { $$.value = ! $2.value;
209 $$.signedp = SIGNED; }
210 | '+' exp %prec UNARY
211 { $$ = $2; }
212 | '~' exp %prec UNARY
213 { $$.value = ~ $2.value;
214 $$.signedp = $2.signedp; }
215 | '#' NAME
216 { $$.value = check_assertion ($2.address, $2.length,
217 0, NULL_PTR);
218 $$.signedp = SIGNED; }
219 | '#' NAME
220 { keyword_parsing = 1; }
221 '(' keywords ')'
222 { $$.value = check_assertion ($2.address, $2.length,
223 1, $5);
224 keyword_parsing = 0;
225 $$.signedp = SIGNED; }
226 | '(' exp1 ')'
227 { $$ = $2; }
230 /* Binary operators in order of decreasing precedence. */
231 exp : exp '*' exp
232 { $$.signedp = $1.signedp & $3.signedp;
233 if ($$.signedp)
235 $$.value = $1.value * $3.value;
236 if ($1.value
237 && ($$.value / $1.value != $3.value
238 || ($$.value & $1.value & $3.value) < 0))
239 integer_overflow ();
241 else
242 $$.value = ((unsigned HOST_WIDEST_INT) $1.value
243 * $3.value); }
244 | exp '/' exp
245 { if ($3.value == 0)
247 if (!skip_evaluation)
248 error ("division by zero in #if");
249 $3.value = 1;
251 $$.signedp = $1.signedp & $3.signedp;
252 if ($$.signedp)
254 $$.value = $1.value / $3.value;
255 if (($$.value & $1.value & $3.value) < 0)
256 integer_overflow ();
258 else
259 $$.value = ((unsigned HOST_WIDEST_INT) $1.value
260 / $3.value); }
261 | exp '%' exp
262 { if ($3.value == 0)
264 if (!skip_evaluation)
265 error ("division by zero in #if");
266 $3.value = 1;
268 $$.signedp = $1.signedp & $3.signedp;
269 if ($$.signedp)
270 $$.value = $1.value % $3.value;
271 else
272 $$.value = ((unsigned HOST_WIDEST_INT) $1.value
273 % $3.value); }
274 | exp '+' exp
275 { $$.value = $1.value + $3.value;
276 $$.signedp = $1.signedp & $3.signedp;
277 if (overflow_sum_sign ($1.value, $3.value,
278 $$.value, $$.signedp))
279 integer_overflow (); }
280 | exp '-' exp
281 { $$.value = $1.value - $3.value;
282 $$.signedp = $1.signedp & $3.signedp;
283 if (overflow_sum_sign ($$.value, $3.value,
284 $1.value, $$.signedp))
285 integer_overflow (); }
286 | exp LSH exp
287 { $$.signedp = $1.signedp;
288 if (($3.value & $3.signedp) < 0)
289 $$.value = right_shift (&$1, -$3.value);
290 else
291 $$.value = left_shift (&$1, $3.value); }
292 | exp RSH exp
293 { $$.signedp = $1.signedp;
294 if (($3.value & $3.signedp) < 0)
295 $$.value = left_shift (&$1, -$3.value);
296 else
297 $$.value = right_shift (&$1, $3.value); }
298 | exp EQUAL exp
299 { $$.value = ($1.value == $3.value);
300 $$.signedp = SIGNED; }
301 | exp NOTEQUAL exp
302 { $$.value = ($1.value != $3.value);
303 $$.signedp = SIGNED; }
304 | exp LEQ exp
305 { $$.signedp = SIGNED;
306 if ($1.signedp & $3.signedp)
307 $$.value = $1.value <= $3.value;
308 else
309 $$.value = ((unsigned HOST_WIDEST_INT) $1.value
310 <= $3.value); }
311 | exp GEQ exp
312 { $$.signedp = SIGNED;
313 if ($1.signedp & $3.signedp)
314 $$.value = $1.value >= $3.value;
315 else
316 $$.value = ((unsigned HOST_WIDEST_INT) $1.value
317 >= $3.value); }
318 | exp '<' exp
319 { $$.signedp = SIGNED;
320 if ($1.signedp & $3.signedp)
321 $$.value = $1.value < $3.value;
322 else
323 $$.value = ((unsigned HOST_WIDEST_INT) $1.value
324 < $3.value); }
325 | exp '>' exp
326 { $$.signedp = SIGNED;
327 if ($1.signedp & $3.signedp)
328 $$.value = $1.value > $3.value;
329 else
330 $$.value = ((unsigned HOST_WIDEST_INT) $1.value
331 > $3.value); }
332 | exp '&' exp
333 { $$.value = $1.value & $3.value;
334 $$.signedp = $1.signedp & $3.signedp; }
335 | exp '^' exp
336 { $$.value = $1.value ^ $3.value;
337 $$.signedp = $1.signedp & $3.signedp; }
338 | exp '|' exp
339 { $$.value = $1.value | $3.value;
340 $$.signedp = $1.signedp & $3.signedp; }
341 | exp AND
342 { skip_evaluation += !$1.value; }
344 { skip_evaluation -= !$1.value;
345 $$.value = ($1.value && $4.value);
346 $$.signedp = SIGNED; }
347 | exp OR
348 { skip_evaluation += !!$1.value; }
350 { skip_evaluation -= !!$1.value;
351 $$.value = ($1.value || $4.value);
352 $$.signedp = SIGNED; }
353 | exp '?'
354 { skip_evaluation += !$1.value; }
355 exp ':'
356 { skip_evaluation += !!$1.value - !$1.value; }
358 { skip_evaluation -= !!$1.value;
359 $$.value = $1.value ? $4.value : $7.value;
360 $$.signedp = $4.signedp & $7.signedp; }
361 | INT
362 { $$ = yylval.integer; }
363 | CHAR
364 { $$ = yylval.integer; }
365 | NAME
366 { if (warn_undef && !skip_evaluation)
367 warning ("`%.*s' is not defined",
368 $1.length, $1.address);
369 $$.value = 0;
370 $$.signedp = SIGNED; }
373 keywords :
374 { $$ = 0; }
375 | '(' keywords ')' keywords
376 { struct arglist *temp;
377 $$ = (struct arglist *) xmalloc (sizeof (struct arglist));
378 $$->next = $2;
379 $$->name = (U_CHAR *) "(";
380 $$->length = 1;
381 temp = $$;
382 while (temp != 0 && temp->next != 0)
383 temp = temp->next;
384 temp->next = (struct arglist *) xmalloc (sizeof (struct arglist));
385 temp->next->next = $4;
386 temp->next->name = (U_CHAR *) ")";
387 temp->next->length = 1; }
388 | NAME keywords
389 { $$ = (struct arglist *) xmalloc (sizeof (struct arglist));
390 $$->name = $1.address;
391 $$->length = $1.length;
392 $$->next = $2; }
396 /* During parsing of a C expression, the pointer to the next character
397 is in this variable. */
399 static char *lexptr;
401 /* Take care of parsing a number (anything that starts with a digit).
402 Set yylval and return the token type; update lexptr.
403 LEN is the number of characters in it. */
405 /* maybe needs to actually deal with floating point numbers */
407 static int
408 parse_number (olen)
409 int olen;
411 register char *p = lexptr;
412 register int c;
413 register unsigned HOST_WIDEST_INT n = 0, nd, max_over_base;
414 register int base = 10;
415 register int len = olen;
416 register int overflow = 0;
417 register int digit, largest_digit = 0;
418 int spec_long = 0;
420 yylval.integer.signedp = SIGNED;
422 if (*p == '0') {
423 base = 8;
424 if (len >= 3 && (p[1] == 'x' || p[1] == 'X')) {
425 p += 2;
426 base = 16;
427 len -= 2;
431 max_over_base = (unsigned HOST_WIDEST_INT) -1 / base;
433 for (; len > 0; len--) {
434 c = *p++;
436 if (c >= '0' && c <= '9')
437 digit = c - '0';
438 else if (base == 16 && c >= 'a' && c <= 'f')
439 digit = c - 'a' + 10;
440 else if (base == 16 && c >= 'A' && c <= 'F')
441 digit = c - 'A' + 10;
442 else {
443 /* `l' means long, and `u' means unsigned. */
444 while (1) {
445 if (c == 'l' || c == 'L')
447 if (!pedantic < spec_long)
448 yyerror ("too many `l's in integer constant");
449 spec_long++;
451 else if (c == 'u' || c == 'U')
453 if (! yylval.integer.signedp)
454 yyerror ("two `u's in integer constant");
455 yylval.integer.signedp = UNSIGNED;
457 else {
458 if (c == '.' || c == 'e' || c == 'E' || c == 'p' || c == 'P')
459 yyerror ("Floating point numbers not allowed in #if expressions");
460 else
461 yyerror ("missing white space after number `%.*s'",
462 (int) (p - lexptr - 1), lexptr);
465 if (--len == 0)
466 break;
467 c = *p++;
469 /* Don't look for any more digits after the suffixes. */
470 break;
472 if (largest_digit < digit)
473 largest_digit = digit;
474 nd = n * base + digit;
475 overflow |= (max_over_base < n) | (nd < n);
476 n = nd;
479 if (base <= largest_digit)
480 pedwarn ("integer constant contains digits beyond the radix");
482 if (overflow)
483 pedwarn ("integer constant out of range");
485 /* If too big to be signed, consider it unsigned. */
486 if (((HOST_WIDEST_INT) n & yylval.integer.signedp) < 0)
488 if (base == 10)
489 warning ("integer constant is so large that it is unsigned");
490 yylval.integer.signedp = UNSIGNED;
493 lexptr = p;
494 yylval.integer.value = n;
495 return INT;
498 struct token {
499 const char *operator;
500 int token;
503 static struct token tokentab2[] = {
504 {"&&", AND},
505 {"||", OR},
506 {"<<", LSH},
507 {">>", RSH},
508 {"==", EQUAL},
509 {"!=", NOTEQUAL},
510 {"<=", LEQ},
511 {">=", GEQ},
512 {"++", ERROR},
513 {"--", ERROR},
514 {NULL, ERROR}
517 /* Read one token, getting characters through lexptr. */
519 static int
520 yylex ()
522 register int c;
523 register int namelen;
524 register unsigned char *tokstart;
525 register struct token *toktab;
526 int wide_flag;
527 HOST_WIDEST_INT mask;
529 retry:
531 tokstart = (unsigned char *) lexptr;
532 c = *tokstart;
533 /* See if it is a special token of length 2. */
534 if (! keyword_parsing)
535 for (toktab = tokentab2; toktab->operator != NULL; toktab++)
536 if (c == *toktab->operator && tokstart[1] == toktab->operator[1]) {
537 lexptr += 2;
538 if (toktab->token == ERROR)
539 yyerror ("`%s' not allowed in operand of `#if'", toktab->operator);
540 return toktab->token;
543 switch (c) {
544 case '\n':
545 return 0;
547 case ' ':
548 case '\t':
549 case '\r':
550 lexptr++;
551 goto retry;
553 case 'L':
554 /* Capital L may start a wide-string or wide-character constant. */
555 if (lexptr[1] == '\'')
557 lexptr++;
558 wide_flag = 1;
559 mask = MAX_WCHAR_TYPE_MASK;
560 goto char_constant;
562 if (lexptr[1] == '"')
564 lexptr++;
565 wide_flag = 1;
566 mask = MAX_WCHAR_TYPE_MASK;
567 goto string_constant;
569 break;
571 case '\'':
572 wide_flag = 0;
573 mask = MAX_CHAR_TYPE_MASK;
574 char_constant:
575 lexptr++;
576 if (keyword_parsing) {
577 char *start_ptr = lexptr - 1;
578 while (1) {
579 c = *lexptr++;
580 if (c == '\\')
581 c = parse_escape (&lexptr, mask);
582 else if (c == '\'')
583 break;
585 yylval.name.address = tokstart;
586 yylval.name.length = lexptr - start_ptr;
587 return NAME;
590 /* This code for reading a character constant
591 handles multicharacter constants and wide characters.
592 It is mostly copied from c-lex.c. */
594 register HOST_WIDEST_INT result = 0;
595 register int num_chars = 0;
596 int chars_seen = 0;
597 unsigned width = MAX_CHAR_TYPE_SIZE;
598 int max_chars;
599 #ifdef MULTIBYTE_CHARS
600 int longest_char = local_mb_cur_max ();
601 char *token_buffer = (char *) alloca (longest_char);
602 (void) local_mbtowc (NULL_PTR, NULL_PTR, 0);
603 #endif
605 max_chars = MAX_LONG_TYPE_SIZE / width;
606 if (wide_flag)
607 width = MAX_WCHAR_TYPE_SIZE;
609 while (1)
611 c = *lexptr++;
613 if (c == '\'' || c == EOF)
614 break;
616 ++chars_seen;
617 if (c == '\\')
619 c = parse_escape (&lexptr, mask);
621 else
623 #ifdef MULTIBYTE_CHARS
624 wchar_t wc;
625 int i;
626 int char_len = -1;
627 for (i = 1; i <= longest_char; ++i)
629 token_buffer[i - 1] = c;
630 char_len = local_mbtowc (& wc, token_buffer, i);
631 if (char_len != -1)
632 break;
633 c = *lexptr++;
635 if (char_len > 1)
637 /* mbtowc sometimes needs an extra char before accepting */
638 if (char_len < i)
639 lexptr--;
640 if (! wide_flag)
642 /* Merge character into result; ignore excess chars. */
643 for (i = 1; i <= char_len; ++i)
645 if (i > max_chars)
646 break;
647 if (width < HOST_BITS_PER_INT)
648 result = (result << width)
649 | (token_buffer[i - 1]
650 & ((1 << width) - 1));
651 else
652 result = token_buffer[i - 1];
654 num_chars += char_len;
655 continue;
658 else
660 if (char_len == -1)
661 warning ("Ignoring invalid multibyte character");
663 if (wide_flag)
664 c = wc;
665 #endif /* ! MULTIBYTE_CHARS */
668 if (wide_flag)
670 if (chars_seen == 1) /* only keep the first one */
671 result = c;
672 continue;
675 /* Merge character into result; ignore excess chars. */
676 num_chars++;
677 if (num_chars <= max_chars)
679 if (width < HOST_BITS_PER_INT)
680 result = (result << width) | (c & ((1 << width) - 1));
681 else
682 result = c;
686 if (c != '\'')
687 error ("malformatted character constant");
688 else if (chars_seen == 0)
689 error ("empty character constant");
690 else if (num_chars > max_chars)
692 num_chars = max_chars;
693 error ("character constant too long");
695 else if (chars_seen != 1 && ! traditional)
696 warning ("multi-character character constant");
698 /* If char type is signed, sign-extend the constant. */
699 if (! wide_flag)
701 int num_bits = num_chars * width;
702 if (num_bits == 0)
703 /* We already got an error; avoid invalid shift. */
704 yylval.integer.value = 0;
705 else if (lookup ((U_CHAR *) "__CHAR_UNSIGNED__",
706 sizeof ("__CHAR_UNSIGNED__") - 1, -1)
707 || ((result >> (num_bits - 1)) & 1) == 0)
708 yylval.integer.value
709 = result & (~ (unsigned HOST_WIDEST_INT) 0
710 >> (HOST_BITS_PER_WIDEST_INT - num_bits));
711 else
712 yylval.integer.value
713 = result | ~(~ (unsigned HOST_WIDEST_INT) 0
714 >> (HOST_BITS_PER_WIDEST_INT - num_bits));
716 else
718 yylval.integer.value = result;
722 /* This is always a signed type. */
723 yylval.integer.signedp = SIGNED;
725 return CHAR;
727 /* some of these chars are invalid in constant expressions;
728 maybe do something about them later */
729 case '/':
730 case '+':
731 case '-':
732 case '*':
733 case '%':
734 case '|':
735 case '&':
736 case '^':
737 case '~':
738 case '!':
739 case '@':
740 case '<':
741 case '>':
742 case '[':
743 case ']':
744 case '.':
745 case '?':
746 case ':':
747 case '=':
748 case '{':
749 case '}':
750 case ',':
751 case '#':
752 if (keyword_parsing)
753 break;
754 case '(':
755 case ')':
756 lexptr++;
757 return c;
759 case '"':
760 mask = MAX_CHAR_TYPE_MASK;
761 string_constant:
762 if (keyword_parsing) {
763 char *start_ptr = lexptr;
764 lexptr++;
765 while (1) {
766 c = *lexptr++;
767 if (c == '\\')
768 c = parse_escape (&lexptr, mask);
769 else if (c == '"')
770 break;
772 yylval.name.address = tokstart;
773 yylval.name.length = lexptr - start_ptr;
774 return NAME;
776 yyerror ("string constants not allowed in #if expressions");
777 return ERROR;
780 if (c >= '0' && c <= '9' && !keyword_parsing) {
781 /* It's a number */
782 for (namelen = 1; ; namelen++) {
783 int d = tokstart[namelen];
784 if (! ((is_idchar[d] || d == '.')
785 || ((d == '-' || d == '+')
786 && (c == 'e' || c == 'E'
787 || ((c == 'p' || c == 'P') && ! c89))
788 && ! traditional)))
789 break;
790 c = d;
792 return parse_number (namelen);
795 /* It is a name. See how long it is. */
797 if (keyword_parsing) {
798 for (namelen = 0;; namelen++) {
799 if (is_space[tokstart[namelen]])
800 break;
801 if (tokstart[namelen] == '(' || tokstart[namelen] == ')')
802 break;
803 if (tokstart[namelen] == '"' || tokstart[namelen] == '\'')
804 break;
806 } else {
807 if (!is_idstart[c]) {
808 yyerror ("Invalid token in expression");
809 return ERROR;
812 for (namelen = 0; is_idchar[tokstart[namelen]]; namelen++)
816 lexptr += namelen;
817 yylval.name.address = tokstart;
818 yylval.name.length = namelen;
819 return NAME;
823 /* Parse a C escape sequence. STRING_PTR points to a variable
824 containing a pointer to the string to parse. That pointer
825 is updated past the characters we use. The value of the
826 escape sequence is returned.
828 RESULT_MASK is used to mask out the result;
829 an error is reported if bits are lost thereby.
831 A negative value means the sequence \ newline was seen,
832 which is supposed to be equivalent to nothing at all.
834 If \ is followed by a null character, we return a negative
835 value and leave the string pointer pointing at the null character.
837 If \ is followed by 000, we return 0 and leave the string pointer
838 after the zeros. A value of 0 does not mean end of string. */
840 HOST_WIDEST_INT
841 parse_escape (string_ptr, result_mask)
842 char **string_ptr;
843 HOST_WIDEST_INT result_mask;
845 register int c = *(*string_ptr)++;
846 switch (c)
848 case 'a':
849 return TARGET_BELL;
850 case 'b':
851 return TARGET_BS;
852 case 'e':
853 case 'E':
854 if (pedantic)
855 pedwarn ("non-ANSI-standard escape sequence, `\\%c'", c);
856 return TARGET_ESC;
857 case 'f':
858 return TARGET_FF;
859 case 'n':
860 return TARGET_NEWLINE;
861 case 'r':
862 return TARGET_CR;
863 case 't':
864 return TARGET_TAB;
865 case 'v':
866 return TARGET_VT;
867 case '\n':
868 return -2;
869 case 0:
870 (*string_ptr)--;
871 return 0;
873 case '0':
874 case '1':
875 case '2':
876 case '3':
877 case '4':
878 case '5':
879 case '6':
880 case '7':
882 register HOST_WIDEST_INT i = c - '0';
883 register int count = 0;
884 while (++count < 3)
886 c = *(*string_ptr)++;
887 if (c >= '0' && c <= '7')
888 i = (i << 3) + c - '0';
889 else
891 (*string_ptr)--;
892 break;
895 if (i != (i & result_mask))
897 i &= result_mask;
898 pedwarn ("octal escape sequence out of range");
900 return i;
902 case 'x':
904 register unsigned HOST_WIDEST_INT i = 0, overflow = 0;
905 register int digits_found = 0, digit;
906 for (;;)
908 c = *(*string_ptr)++;
909 if (c >= '0' && c <= '9')
910 digit = c - '0';
911 else if (c >= 'a' && c <= 'f')
912 digit = c - 'a' + 10;
913 else if (c >= 'A' && c <= 'F')
914 digit = c - 'A' + 10;
915 else
917 (*string_ptr)--;
918 break;
920 overflow |= i ^ (i << 4 >> 4);
921 i = (i << 4) + digit;
922 digits_found = 1;
924 if (!digits_found)
925 yyerror ("\\x used with no following hex digits");
926 if (overflow | (i != (i & result_mask)))
928 i &= result_mask;
929 pedwarn ("hex escape sequence out of range");
931 return i;
933 default:
934 return c;
938 static void
939 integer_overflow ()
941 if (!skip_evaluation && pedantic)
942 pedwarn ("integer overflow in preprocessor expression");
945 static HOST_WIDEST_INT
946 left_shift (a, b)
947 struct constant *a;
948 unsigned HOST_WIDEST_INT b;
950 /* It's unclear from the C standard whether shifts can overflow.
951 The following code ignores overflow; perhaps a C standard
952 interpretation ruling is needed. */
953 if (b >= HOST_BITS_PER_WIDEST_INT)
954 return 0;
955 else
956 return (unsigned HOST_WIDEST_INT) a->value << b;
959 static HOST_WIDEST_INT
960 right_shift (a, b)
961 struct constant *a;
962 unsigned HOST_WIDEST_INT b;
964 if (b >= HOST_BITS_PER_WIDEST_INT)
965 return a->signedp ? a->value >> (HOST_BITS_PER_WIDEST_INT - 1) : 0;
966 else if (a->signedp)
967 return a->value >> b;
968 else
969 return (unsigned HOST_WIDEST_INT) a->value >> b;
972 /* This page contains the entry point to this file. */
974 /* Parse STRING as an expression, and complain if this fails
975 to use up all of the contents of STRING.
976 STRING may contain '\0' bytes; it is terminated by the first '\n'
977 outside a string constant, so that we can diagnose '\0' properly.
978 If WARN_UNDEFINED is nonzero, warn if undefined identifiers are evaluated.
979 We do not support C comments. They should be removed before
980 this function is called. */
982 HOST_WIDEST_INT
983 parse_c_expression (string, warn_undefined)
984 char *string;
985 int warn_undefined;
987 lexptr = string;
988 warn_undef = warn_undefined;
990 /* if there is some sort of scanning error, just return 0 and assume
991 the parsing routine has printed an error message somewhere.
992 there is surely a better thing to do than this. */
993 if (setjmp (parse_return_error))
994 return 0;
996 if (yyparse () != 0)
997 abort ();
999 if (*lexptr != '\n')
1000 error ("Junk after end of expression.");
1002 return expression_value; /* set by yyparse () */
1005 static void
1006 yyerror VPROTO ((const char * msgid, ...))
1008 #ifndef ANSI_PROTOTYPES
1009 const char * msgid;
1010 #endif
1011 va_list args;
1013 VA_START (args, msgid);
1015 #ifndef ANSI_PROTOTYPES
1016 msgid = va_arg (args, const char *);
1017 #endif
1019 verror (msgid, args);
1020 va_end (args);
1021 skip_evaluation = 0;
1022 longjmp (parse_return_error, 1);
1026 #ifdef TEST_EXP_READER
1028 #if YYDEBUG
1029 extern int yydebug;
1030 #endif
1032 int pedantic;
1033 int traditional;
1034 int c89;
1036 int main PROTO((int, char **));
1037 static void initialize_random_junk PROTO((void));
1038 static void print_unsigned_host_widest_int PROTO((unsigned HOST_WIDEST_INT));
1040 /* Main program for testing purposes. */
1042 main (argc, argv)
1043 int argc;
1044 char **argv;
1046 int n, c;
1047 char buf[1024];
1048 unsigned HOST_WIDEST_INT u;
1050 pedantic = 1 < argc;
1051 traditional = 2 < argc;
1052 c89 = 3 < argc;
1053 #if YYDEBUG
1054 yydebug = 4 < argc;
1055 #endif
1056 initialize_random_junk ();
1058 for (;;) {
1059 printf ("enter expression: ");
1060 n = 0;
1061 while ((buf[n] = c = getchar ()) != '\n' && c != EOF)
1062 n++;
1063 if (c == EOF)
1064 break;
1065 parse_c_expression (buf, 1);
1066 printf ("parser returned ");
1067 u = (unsigned HOST_WIDEST_INT) expression_value;
1068 if (expression_value < 0 && expression_signedp) {
1069 u = -u;
1070 printf ("-");
1072 if (u == 0)
1073 printf ("0");
1074 else
1075 print_unsigned_host_widest_int (u);
1076 if (! expression_signedp)
1077 printf("u");
1078 printf ("\n");
1081 return 0;
1084 static void
1085 print_unsigned_host_widest_int (u)
1086 unsigned HOST_WIDEST_INT u;
1088 if (u) {
1089 print_unsigned_host_widest_int (u / 10);
1090 putchar ('0' + (int) (u % 10));
1094 /* table to tell if char can be part of a C identifier. */
1095 unsigned char is_idchar[256];
1096 /* table to tell if char can be first char of a c identifier. */
1097 unsigned char is_idstart[256];
1098 /* table to tell if c is horizontal or vertical space. */
1099 unsigned char is_space[256];
1102 * initialize random junk in the hash table and maybe other places
1104 static void
1105 initialize_random_junk ()
1107 register int i;
1110 * Set up is_idchar and is_idstart tables. These should be
1111 * faster than saying (is_alpha (c) || c == '_'), etc.
1112 * Must do set up these things before calling any routines tthat
1113 * refer to them.
1115 for (i = 'a'; i <= 'z'; i++) {
1116 ++is_idchar[TOUPPER(i)];
1117 ++is_idchar[i];
1118 ++is_idstart[TOUPPER(i)];
1119 ++is_idstart[i];
1121 for (i = '0'; i <= '9'; i++)
1122 ++is_idchar[i];
1123 ++is_idchar['_'];
1124 ++is_idstart['_'];
1125 ++is_idchar['$'];
1126 ++is_idstart['$'];
1128 ++is_space[' '];
1129 ++is_space['\t'];
1130 ++is_space['\v'];
1131 ++is_space['\f'];
1132 ++is_space['\n'];
1133 ++is_space['\r'];
1136 void
1137 error VPROTO ((char * msgid, ...))
1139 #ifndef ANSI_PROTOTYPES
1140 char * msgid;
1141 #endif
1142 va_list args;
1144 VA_START (args, msgid);
1146 #ifndef ANSI_PROTOTYPES
1147 msgid = va_arg (args, char *);
1148 #endif
1150 fprintf (stderr, "error: ");
1151 vfprintf (stderr, _(msgid), args);
1152 fprintf (stderr, "\n");
1153 va_end (args);
1156 void
1157 pedwarn VPROTO ((char * msgid, ...))
1159 #ifndef ANSI_PROTOTYPES
1160 char * msgid;
1161 #endif
1162 va_list args;
1164 VA_START (args, msgid);
1166 #ifndef ANSI_PROTOTYPES
1167 msgid = va_arg (args, char *);
1168 #endif
1170 fprintf (stderr, "pedwarn: ");
1171 vfprintf (stderr, _(msgid), args);
1172 fprintf (stderr, "\n");
1173 va_end (args);
1176 void
1177 warning VPROTO ((char * msgid, ...))
1179 #ifndef ANSI_PROTOTYPES
1180 char * msgid;
1181 #endif
1182 va_list args;
1184 VA_START (args, msgid);
1186 #ifndef ANSI_PROTOTYPES
1187 msgid = va_arg (args, char *);
1188 #endif
1190 fprintf (stderr, "warning: ");
1191 vfprintf (stderr, _(msgid), args);
1192 fprintf (stderr, "\n");
1193 va_end (args);
1198 check_assertion (name, sym_length, tokens_specified, tokens)
1199 U_CHAR *name;
1200 int sym_length;
1201 int tokens_specified;
1202 struct arglist *tokens;
1204 return 0;
1207 struct hashnode *
1208 lookup (name, len, hash)
1209 U_CHAR *name;
1210 int len;
1211 int hash;
1213 return (DEFAULT_SIGNED_CHAR) ? 0 : ((struct hashnode *) -1);
1217 xmalloc (size)
1218 size_t size;
1220 return (PTR) malloc (size);
1222 #endif