]> gcc.gnu.org Git - gcc.git/blame - gcc/cexp.y
# Fix misspellings in comments.
[gcc.git] / gcc / cexp.y
CommitLineData
f2b63869
CH
1/* Parse C expressions for CCCP.
2 Copyright (C) 1987, 1992 Free Software Foundation.
3
4This program is free software; you can redistribute it and/or modify it
5under the terms of the GNU General Public License as published by the
6Free Software Foundation; either version 2, or (at your option) any
7later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program; if not, write to the Free Software
16Foundation, 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
960e4c1c 22 Adapted from expread.y of GDB by Paul Rubin, July 1986. */
f2b63869
CH
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
5e0004ae
RS
36#include <stdio.h>
37
f2b63869
CH
38typedef unsigned char U_CHAR;
39
40/* This is used for communicating lists of keywords with cccp.c. */
41struct arglist {
42 struct arglist *next;
43 U_CHAR *name;
44 int length;
45 int argno;
46};
47
d6927cc9
TW
48/* Define a generic NULL if one hasn't already been defined. */
49
f2b63869
CH
50#ifndef NULL
51#define NULL 0
52#endif
53
d6927cc9
TW
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
f2b63869 62#ifndef NULL_PTR
d6927cc9 63#define NULL_PTR ((GENERIC_PTR)0)
f2b63869
CH
64#endif
65
66int yylex ();
67void yyerror ();
68int expression_value;
69
70static jmp_buf parse_return_error;
71
72/* Nonzero means count most punctuation as part of a name. */
73static int keyword_parsing = 0;
74
75/* some external tables of character types */
76extern unsigned char is_idstart[], is_idchar[], is_hor_space[];
77
58c8c593
RK
78extern char *xmalloc ();
79
f2b63869
CH
80/* Flag for -pedantic. */
81extern int pedantic;
82
83/* Flag for -traditional. */
84extern 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
4cf8de9f
RS
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
106static void integer_overflow ();
107static long left_shift ();
108static long right_shift ();
f2b63869
CH
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
143start : exp1
144 { expression_value = $1.value; }
145 ;
146
147/* Expressions, including the comma operator. */
148exp1 : 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. */
156exp : '-' exp %prec UNARY
157 { $$.value = - $2.value;
4cf8de9f
RS
158 if (($$.value & $2.value) < 0 && ! $2.unsignedp)
159 integer_overflow ();
f2b63869
CH
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. */
185exp : exp '*' exp
186 { $$.unsignedp = $1.unsignedp || $3.unsignedp;
187 if ($$.unsignedp)
4cf8de9f 188 $$.value = (unsigned long) $1.value * $3.value;
f2b63869 189 else
4cf8de9f
RS
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 } }
f2b63869
CH
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)
4cf8de9f 205 $$.value = (unsigned long) $1.value / $3.value;
f2b63869 206 else
4cf8de9f
RS
207 {
208 $$.value = $1.value / $3.value;
209 if (($$.value & $1.value & $3.value) < 0)
210 integer_overflow ();
211 } }
f2b63869
CH
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)
4cf8de9f 220 $$.value = (unsigned long) $1.value % $3.value;
f2b63869
CH
221 else
222 $$.value = $1.value % $3.value; }
223 | exp '+' exp
224 { $$.value = $1.value + $3.value;
4cf8de9f
RS
225 $$.unsignedp = $1.unsignedp || $3.unsignedp;
226 if (! $$.unsignedp
227 && ! possible_sum_sign ($1.value, $3.value,
228 $$.value))
229 integer_overflow (); }
f2b63869
CH
230 | exp '-' exp
231 { $$.value = $1.value - $3.value;
4cf8de9f
RS
232 $$.unsignedp = $1.unsignedp || $3.unsignedp;
233 if (! $$.unsignedp
234 && ! possible_sum_sign ($$.value, $3.value,
235 $1.value))
236 integer_overflow (); }
f2b63869
CH
237 | exp LSH exp
238 { $$.unsignedp = $1.unsignedp;
4cf8de9f
RS
239 if ($3.value < 0 && ! $3.unsignedp)
240 $$.value = right_shift (&$1, -$3.value);
f2b63869 241 else
4cf8de9f 242 $$.value = left_shift (&$1, $3.value); }
f2b63869
CH
243 | exp RSH exp
244 { $$.unsignedp = $1.unsignedp;
4cf8de9f
RS
245 if ($3.value < 0 && ! $3.unsignedp)
246 $$.value = left_shift (&$1, -$3.value);
f2b63869 247 else
4cf8de9f 248 $$.value = right_shift (&$1, $3.value); }
f2b63869
CH
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)
4cf8de9f 258 $$.value = (unsigned long) $1.value <= $3.value;
f2b63869
CH
259 else
260 $$.value = $1.value <= $3.value; }
261 | exp GEQ exp
262 { $$.unsignedp = 0;
263 if ($1.unsignedp || $3.unsignedp)
4cf8de9f 264 $$.value = (unsigned long) $1.value >= $3.value;
f2b63869
CH
265 else
266 $$.value = $1.value >= $3.value; }
267 | exp '<' exp
268 { $$.unsignedp = 0;
269 if ($1.unsignedp || $3.unsignedp)
4cf8de9f 270 $$.value = (unsigned long) $1.value < $3.value;
f2b63869
CH
271 else
272 $$.value = $1.value < $3.value; }
273 | exp '>' exp
274 { $$.unsignedp = 0;
275 if ($1.unsignedp || $3.unsignedp)
4cf8de9f 276 $$.value = (unsigned long) $1.value > $3.value;
f2b63869
CH
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
306keywords :
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
332static 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
340int
341parse_number (olen)
342 int olen;
343{
344 register char *p = lexptr;
f2b63869 345 register int c;
ce73f2a5 346 register unsigned long n = 0, nd, ULONG_MAX_over_base;
f2b63869
CH
347 register int base = 10;
348 register int len = olen;
ce73f2a5 349 register int overflow = 0;
3292923d 350 register int digit, largest_digit = 0;
ce73f2a5 351 int spec_long = 0;
f2b63869
CH
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
ce73f2a5
RS
370 ULONG_MAX_over_base = (unsigned long) -1 / base;
371
372 for (; len > 0; len--) {
f2b63869 373 c = *p++;
3292923d
RS
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 {
f2b63869
CH
382 /* `l' means long, and `u' means unsigned. */
383 while (1) {
384 if (c == 'l' || c == 'L')
ce73f2a5
RS
385 {
386 if (spec_long)
387 yyerror ("two `l's in integer constant");
388 spec_long = 1;
389 }
f2b63869 390 else if (c == 'u' || c == 'U')
ce73f2a5
RS
391 {
392 if (yylval.integer.unsignedp)
393 yyerror ("two `u's in integer constant");
394 yylval.integer.unsignedp = 1;
395 }
f2b63869
CH
396 else
397 break;
398
ce73f2a5 399 if (--len == 0)
f2b63869
CH
400 break;
401 c = *p++;
f2b63869
CH
402 }
403 /* Don't look for any more digits after the suffixes. */
404 break;
405 }
3292923d
RS
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;
f2b63869
CH
411 }
412
413 if (len != 0) {
414 yyerror ("Invalid number in #if expression");
415 return ERROR;
416 }
417
3292923d
RS
418 if (base <= largest_digit)
419 warning ("integer constant contains digits beyond the radix");
420
ce73f2a5
RS
421 if (overflow)
422 warning ("integer constant out of range");
423
f2b63869 424 /* If too big to be signed, consider it unsigned. */
ce73f2a5
RS
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 }
f2b63869
CH
431
432 lexptr = p;
433 yylval.integer.value = n;
434 return INT;
435}
436
437struct token {
438 char *operator;
439 int token;
440};
441
442static 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
458int
459yylex ()
460{
461 register int c;
462 register int namelen;
0671ee41 463 register unsigned char *tokstart;
f2b63869
CH
464 register struct token *toktab;
465 int wide_flag;
466
467 retry:
468
0671ee41 469 tokstart = (unsigned char *) lexptr;
f2b63869
CH
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 }
0671ee41 525 yylval.name.address = tokstart;
f2b63869
CH
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
4cf8de9f 604 = result & ((unsigned long) ~0 >> (HOST_BITS_PER_LONG - num_bits));
f2b63869
CH
605 else
606 yylval.integer.value
4cf8de9f 607 = result | ~((unsigned long) ~0 >> (HOST_BITS_PER_LONG - num_bits));
f2b63869
CH
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 }
0671ee41 680 yylval.name.address = tokstart;
f2b63869
CH
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;
0671ee41 719 yylval.name.address = tokstart;
f2b63869
CH
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
739int
740parse_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 {
f46ffce4 806 register unsigned i = 0, overflow = 0, digits_found = 0, digit;
f2b63869
CH
807 for (;;)
808 {
809 c = *(*string_ptr)++;
810 if (c >= '0' && c <= '9')
f46ffce4 811 digit = c - '0';
f2b63869 812 else if (c >= 'a' && c <= 'f')
f46ffce4 813 digit = c - 'a' + 10;
f2b63869 814 else if (c >= 'A' && c <= 'F')
f46ffce4 815 digit = c - 'A' + 10;
f2b63869
CH
816 else
817 {
818 (*string_ptr)--;
819 break;
820 }
f46ffce4
RS
821 overflow |= i ^ (i << 4 >> 4);
822 i = (i << 4) + digit;
823 digits_found = 1;
f2b63869 824 }
f46ffce4
RS
825 if (!digits_found)
826 yyerror ("\\x used with no following hex digits");
827 if (overflow | (i & ~((1 << BITS_PER_UNIT) - 1)))
f2b63869
CH
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
839void
840yyerror (s)
841 char *s;
842{
843 error (s);
844 longjmp (parse_return_error, 1);
845}
4cf8de9f
RS
846
847static void
848integer_overflow ()
849{
2f6f8824
RS
850 if (pedantic)
851 pedwarn ("integer overflow in preprocessor expression");
4cf8de9f
RS
852}
853
854static long
855left_shift (a, b)
856 struct constant *a;
857 unsigned long b;
858{
859 if (b >= HOST_BITS_PER_LONG)
860 {
861 if (! a->unsignedp && a->value != 0)
862 integer_overflow ();
863 return 0;
864 }
865 else if (a->unsignedp)
866 return (unsigned long) a->value << b;
867 else
868 {
869 long l = a->value << b;
870 if (l >> b != a->value)
871 integer_overflow ();
872 return l;
873 }
874}
875
876static long
877right_shift (a, b)
878 struct constant *a;
879 unsigned long b;
880{
881 if (b >= HOST_BITS_PER_LONG)
882 return a->unsignedp ? 0 : a->value >> (HOST_BITS_PER_LONG - 1);
883 else if (a->unsignedp)
884 return (unsigned long) a->value >> b;
885 else
886 return a->value >> b;
887}
f2b63869
CH
888\f
889/* This page contains the entry point to this file. */
890
891/* Parse STRING as an expression, and complain if this fails
892 to use up all of the contents of STRING. */
893/* We do not support C comments. They should be removed before
894 this function is called. */
895
896int
897parse_c_expression (string)
898 char *string;
899{
900 lexptr = string;
901
902 if (lexptr == 0 || *lexptr == 0) {
903 error ("empty #if expression");
904 return 0; /* don't include the #if group */
905 }
906
907 /* if there is some sort of scanning error, just return 0 and assume
908 the parsing routine has printed an error message somewhere.
909 there is surely a better thing to do than this. */
910 if (setjmp (parse_return_error))
911 return 0;
912
913 if (yyparse ())
914 return 0; /* actually this is never reached
915 the way things stand. */
916 if (*lexptr)
917 error ("Junk after end of expression.");
918
919 return expression_value; /* set by yyparse () */
920}
921\f
922#ifdef TEST_EXP_READER
923extern int yydebug;
924
925/* Main program for testing purposes. */
926int
927main ()
928{
929 int n, c;
930 char buf[1024];
931
932/*
933 yydebug = 1;
934*/
935 initialize_random_junk ();
936
937 for (;;) {
938 printf ("enter expression: ");
939 n = 0;
940 while ((buf[n] = getchar ()) != '\n' && buf[n] != EOF)
941 n++;
942 if (buf[n] == EOF)
943 break;
944 buf[n] = '\0';
945 printf ("parser returned %d\n", parse_c_expression (buf));
946 }
947
948 return 0;
949}
950
951/* table to tell if char can be part of a C identifier. */
952unsigned char is_idchar[256];
953/* table to tell if char can be first char of a c identifier. */
954unsigned char is_idstart[256];
955/* table to tell if c is horizontal space. isspace () thinks that
956 newline is space; this is not a good idea for this program. */
957char is_hor_space[256];
958
959/*
960 * initialize random junk in the hash table and maybe other places
961 */
962initialize_random_junk ()
963{
964 register int i;
965
966 /*
967 * Set up is_idchar and is_idstart tables. These should be
968 * faster than saying (is_alpha (c) || c == '_'), etc.
969 * Must do set up these things before calling any routines tthat
970 * refer to them.
971 */
972 for (i = 'a'; i <= 'z'; i++) {
973 ++is_idchar[i - 'a' + 'A'];
974 ++is_idchar[i];
975 ++is_idstart[i - 'a' + 'A'];
976 ++is_idstart[i];
977 }
978 for (i = '0'; i <= '9'; i++)
979 ++is_idchar[i];
980 ++is_idchar['_'];
981 ++is_idstart['_'];
982#if DOLLARS_IN_IDENTIFIERS
983 ++is_idchar['$'];
984 ++is_idstart['$'];
985#endif
986
987 /* horizontal space table */
988 ++is_hor_space[' '];
989 ++is_hor_space['\t'];
990}
991
992error (msg)
993{
994 printf ("error: %s\n", msg);
995}
996
997warning (msg)
998{
999 printf ("warning: %s\n", msg);
1000}
1001
1002struct hashnode *
1003lookup (name, len, hash)
1004 char *name;
1005 int len;
1006 int hash;
1007{
1008 return (DEFAULT_SIGNED_CHAR) ? 0 : ((struct hashnode *) -1);
1009}
1010#endif
This page took 0.165817 seconds and 5 git commands to generate.