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