1 /* Parse C expressions for CCCP.
2 Copyright (C) 1987, 1992, 1994, 1995, 1996, 1997 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
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 */
30 /* #define YYDEBUG 1 */
32 /* The following symbols should be autoconfigured:
35 In the mean time, we'll get by with approximations based
36 on existing GCC configuration symbols. */
39 # ifndef HAVE_STDLIB_H
40 # define HAVE_STDLIB_H 1
43 # define STDC_HEADERS 1
45 #endif /* defined (POSIX) */
51 #if HAVE_STDLIB_H || defined (MULTIBYTE_CHARS)
55 #ifdef MULTIBYTE_CHARS
61 typedef
unsigned char U_CHAR
;
63 /* This is used for communicating lists of keywords with cccp.c. */
71 /* Define a generic NULL if one hasn't already been defined. */
78 #if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
79 #define GENERIC_PTR void *
81 #define GENERIC_PTR char *
86 #define NULL_PTR ((GENERIC_PTR) 0)
89 /* Find the largest host integer type and set its size and type.
90 Don't blindly use `long'; on some crazy hosts it is shorter than `int'. */
92 #ifndef HOST_BITS_PER_WIDE_INT
94 #if HOST_BITS_PER_LONG > HOST_BITS_PER_INT
95 #define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_LONG
96 #define HOST_WIDE_INT long
98 #define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_INT
99 #define HOST_WIDE_INT int
104 #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
105 # define __attribute__(x)
109 # if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
110 # define PROTO(ARGS) ARGS
112 # define PROTO(ARGS) ()
116 #if defined (__STDC__) && defined (HAVE_VPRINTF)
118 # define VA_START(va_list, var) va_start (va_list, var)
119 # define PRINTF_ALIST(msg) char *msg, ...
120 # define PRINTF_DCL(msg)
121 # define PRINTF_PROTO(ARGS, m, n) PROTO (ARGS) __attribute__ ((format (__printf__, m, n)))
123 # include <varargs.h>
124 # define VA_START(va_list, var) va_start (va_list)
125 # define PRINTF_ALIST(msg) msg, va_alist
126 # define PRINTF_DCL(msg) char *msg; va_dcl
127 # define PRINTF_PROTO(ARGS, m, n) () __attribute__ ((format (__printf__, m, n)))
128 # define vfprintf(file, msg, args) \
130 char *a0
= va_arg
(args
, char *); \
131 char *a1
= va_arg
(args
, char *); \
132 char *a2
= va_arg
(args
, char *); \
133 char *a3
= va_arg
(args
, char *); \
134 fprintf
(file
, msg
, a0
, a1
, a2
, a3
); \
138 #define PRINTF_PROTO_1(ARGS) PRINTF_PROTO(ARGS, 1, 2)
140 HOST_WIDE_INT parse_c_expression PROTO
((char *));
142 static int yylex PROTO
((void));
143 static void yyerror PROTO
((char *)) __attribute__
((noreturn
));
144 static HOST_WIDE_INT expression_value
;
146 static jmp_buf parse_return_error
;
148 /* Nonzero means count most punctuation as part of a name. */
149 static int keyword_parsing
= 0;
151 /* Nonzero means do not evaluate this expression.
152 This is a count, since unevaluated expressions can nest. */
153 static int skip_evaluation
;
155 /* some external tables of character types */
156 extern
unsigned char is_idstart
[], is_idchar
[], is_space
[];
158 /* Flag for -pedantic. */
161 /* Flag for -traditional. */
162 extern
int traditional
;
164 /* Flag for -lang-c89. */
167 #ifndef CHAR_TYPE_SIZE
168 #define CHAR_TYPE_SIZE BITS_PER_UNIT
171 #ifndef INT_TYPE_SIZE
172 #define INT_TYPE_SIZE BITS_PER_WORD
175 #ifndef LONG_TYPE_SIZE
176 #define LONG_TYPE_SIZE BITS_PER_WORD
179 #ifndef WCHAR_TYPE_SIZE
180 #define WCHAR_TYPE_SIZE INT_TYPE_SIZE
183 #ifndef MAX_CHAR_TYPE_SIZE
184 #define MAX_CHAR_TYPE_SIZE CHAR_TYPE_SIZE
187 #ifndef MAX_INT_TYPE_SIZE
188 #define MAX_INT_TYPE_SIZE INT_TYPE_SIZE
191 #ifndef MAX_LONG_TYPE_SIZE
192 #define MAX_LONG_TYPE_SIZE LONG_TYPE_SIZE
195 #ifndef MAX_WCHAR_TYPE_SIZE
196 #define MAX_WCHAR_TYPE_SIZE WCHAR_TYPE_SIZE
199 #if MAX_CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT
200 #define MAX_CHAR_TYPE_MASK (~ (~ (HOST_WIDE_INT) 0 << MAX_CHAR_TYPE_SIZE))
202 #define MAX_CHAR_TYPE_MASK (~ (HOST_WIDE_INT) 0)
205 #if MAX_WCHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT
206 #define MAX_WCHAR_TYPE_MASK (~ (~ (HOST_WIDE_INT) 0 << MAX_WCHAR_TYPE_SIZE))
208 #define MAX_WCHAR_TYPE_MASK (~ (HOST_WIDE_INT) 0)
211 /* Suppose A1 + B1 = SUM1, using 2's complement arithmetic ignoring overflow.
212 Suppose A, B and SUM have the same respective signs as A1, B1, and SUM1.
213 Suppose SIGNEDP is negative if the result is signed, zero if unsigned.
214 Then this yields nonzero if overflow occurred during the addition.
215 Overflow occurs if A and B have the same sign, but A and SUM differ in sign,
216 and SIGNEDP is negative.
217 Use `^' to test whether signs differ, and `< 0' to isolate the sign. */
218 #define overflow_sum_sign(a, b, sum, signedp) \
219 ((~
((a
) ^
(b
)) & ((a
) ^
(sum
)) & (signedp
)) < 0)
223 GENERIC_PTR xmalloc PROTO
((size_t));
224 HOST_WIDE_INT parse_escape PROTO
((char **, HOST_WIDE_INT
));
225 int check_assertion PROTO
((U_CHAR
*, int, int, struct arglist
*));
226 struct hashnode
*lookup PROTO
((U_CHAR
*, int, int));
227 void error PRINTF_PROTO_1
((char *, ...
));
228 void pedwarn PRINTF_PROTO_1
((char *, ...
));
229 void warning PRINTF_PROTO_1
((char *, ...
));
231 static int parse_number PROTO
((int));
232 static HOST_WIDE_INT left_shift PROTO
((struct constant
*, unsigned HOST_WIDE_INT
));
233 static HOST_WIDE_INT right_shift PROTO
((struct constant
*, unsigned HOST_WIDE_INT
));
234 static void integer_overflow PROTO
((void));
236 /* `signedp' values */
242 struct constant
{HOST_WIDE_INT value
; int signedp
;} integer
;
243 struct name
{U_CHAR
*address
; int length
;} name
;
244 struct arglist
*keywords
;
247 %type
<integer
> exp exp1 start
248 %type
<keywords
> keywords
249 %token
<integer
> INT CHAR
251 %token
<integer
> ERROR
261 %left
'<' '>' LEQ GEQ
272 { expression_value
= $1.value
; }
275 /* Expressions, including the comma operator. */
279 pedwarn
("comma operator in operand of `#if'");
283 /* Expressions, not including the comma operator. */
284 exp
: '-' exp %prec UNARY
285 { $$.value
= - $2.value
;
286 $$.signedp
= $2.signedp
;
287 if
(($$.value
& $2.value
& $$.signedp
) < 0)
288 integer_overflow
(); }
289 |
'!' exp %prec UNARY
290 { $$.value
= ! $2.value
;
291 $$.signedp
= SIGNED
; }
292 |
'+' exp %prec UNARY
294 |
'~' exp %prec UNARY
295 { $$.value
= ~
$2.value
;
296 $$.signedp
= $2.signedp
; }
298 { $$.value
= check_assertion
($2.address
, $2.length
,
300 $$.signedp
= SIGNED
; }
302 { keyword_parsing
= 1; }
304 { $$.value
= check_assertion
($2.address
, $2.length
,
307 $$.signedp
= SIGNED
; }
312 /* Binary operators in order of decreasing precedence. */
314 { $$.signedp
= $1.signedp
& $3.signedp
;
317 $$.value
= $1.value
* $3.value
;
319 && ($$.value
/ $1.value
!= $3.value
320 ||
($$.value
& $1.value
& $3.value
) < 0))
324 $$.value
= ((unsigned HOST_WIDE_INT
) $1.value
329 if
(!skip_evaluation
)
330 error ("division by zero in #if");
333 $$.signedp
= $1.signedp
& $3.signedp
;
336 $$.value
= $1.value
/ $3.value
;
337 if
(($$.value
& $1.value
& $3.value
) < 0)
341 $$.value
= ((unsigned HOST_WIDE_INT
) $1.value
346 if
(!skip_evaluation
)
347 error ("division by zero in #if");
350 $$.signedp
= $1.signedp
& $3.signedp
;
352 $$.value
= $1.value %
$3.value
;
354 $$.value
= ((unsigned HOST_WIDE_INT
) $1.value
357 { $$.value
= $1.value
+ $3.value
;
358 $$.signedp
= $1.signedp
& $3.signedp
;
359 if
(overflow_sum_sign
($1.value
, $3.value
,
360 $$.value
, $$.signedp
))
361 integer_overflow
(); }
363 { $$.value
= $1.value
- $3.value
;
364 $$.signedp
= $1.signedp
& $3.signedp
;
365 if
(overflow_sum_sign
($$.value
, $3.value
,
366 $1.value
, $$.signedp
))
367 integer_overflow
(); }
369 { $$.signedp
= $1.signedp
;
370 if
(($3.value
& $3.signedp
) < 0)
371 $$.value
= right_shift
(&$1, -$3.value
);
373 $$.value
= left_shift
(&$1, $3.value
); }
375 { $$.signedp
= $1.signedp
;
376 if
(($3.value
& $3.signedp
) < 0)
377 $$.value
= left_shift
(&$1, -$3.value
);
379 $$.value
= right_shift
(&$1, $3.value
); }
381 { $$.value
= ($1.value
== $3.value
);
382 $$.signedp
= SIGNED
; }
384 { $$.value
= ($1.value
!= $3.value
);
385 $$.signedp
= SIGNED
; }
387 { $$.signedp
= SIGNED
;
388 if
($1.signedp
& $3.signedp
)
389 $$.value
= $1.value
<= $3.value
;
391 $$.value
= ((unsigned HOST_WIDE_INT
) $1.value
394 { $$.signedp
= SIGNED
;
395 if
($1.signedp
& $3.signedp
)
396 $$.value
= $1.value
>= $3.value
;
398 $$.value
= ((unsigned HOST_WIDE_INT
) $1.value
401 { $$.signedp
= SIGNED
;
402 if
($1.signedp
& $3.signedp
)
403 $$.value
= $1.value
< $3.value
;
405 $$.value
= ((unsigned HOST_WIDE_INT
) $1.value
408 { $$.signedp
= SIGNED
;
409 if
($1.signedp
& $3.signedp
)
410 $$.value
= $1.value
> $3.value
;
412 $$.value
= ((unsigned HOST_WIDE_INT
) $1.value
415 { $$.value
= $1.value
& $3.value
;
416 $$.signedp
= $1.signedp
& $3.signedp
; }
418 { $$.value
= $1.value ^
$3.value
;
419 $$.signedp
= $1.signedp
& $3.signedp
; }
421 { $$.value
= $1.value |
$3.value
;
422 $$.signedp
= $1.signedp
& $3.signedp
; }
424 { skip_evaluation
+= !$1.value
; }
426 { skip_evaluation
-= !$1.value
;
427 $$.value
= ($1.value
&& $4.value
);
428 $$.signedp
= SIGNED
; }
430 { skip_evaluation
+= !!$1.value
; }
432 { skip_evaluation
-= !!$1.value
;
433 $$.value
= ($1.value ||
$4.value
);
434 $$.signedp
= SIGNED
; }
436 { skip_evaluation
+= !$1.value
; }
438 { skip_evaluation
+= !!$1.value
- !$1.value
; }
440 { skip_evaluation
-= !!$1.value
;
441 $$.value
= $1.value ?
$4.value
: $7.value
;
442 $$.signedp
= $4.signedp
& $7.signedp
; }
444 { $$
= yylval.integer
; }
446 { $$
= yylval.integer
; }
449 $$.signedp
= SIGNED
; }
454 |
'(' keywords
')' keywords
455 { struct arglist
*temp
;
456 $$
= (struct arglist
*) xmalloc
(sizeof
(struct arglist
));
458 $$
->name
= (U_CHAR
*) "(";
461 while
(temp
!= 0 && temp
->next
!= 0)
463 temp
->next
= (struct arglist
*) xmalloc
(sizeof
(struct arglist
));
464 temp
->next
->next
= $4;
465 temp
->next
->name
= (U_CHAR
*) ")";
466 temp
->next
->length
= 1; }
468 { $$
= (struct arglist
*) xmalloc
(sizeof
(struct arglist
));
469 $$
->name
= $1.address
;
470 $$
->length
= $1.length
;
475 /* During parsing of a C expression, the pointer to the next character
476 is in this variable. */
480 /* Take care of parsing a number (anything that starts with a digit).
481 Set yylval and return the token type; update lexptr.
482 LEN is the number of characters in it. */
484 /* maybe needs to actually deal with floating point numbers */
490 register
char *p
= lexptr
;
492 register
unsigned HOST_WIDE_INT n
= 0, nd
, max_over_base
;
493 register
int base
= 10;
494 register
int len
= olen
;
495 register
int overflow
= 0;
496 register
int digit
, largest_digit
= 0;
499 yylval.integer.signedp
= SIGNED
;
503 if
(len
>= 3 && (p
[1] == 'x' || p
[1] == 'X')) {
510 max_over_base
= (unsigned HOST_WIDE_INT
) -1 / base
;
512 for
(; len
> 0; len
--) {
515 if
(c
>= '0' && c
<= '9')
517 else if
(base
== 16 && c
>= 'a' && c
<= 'f')
518 digit
= c
- 'a' + 10;
519 else if
(base
== 16 && c
>= 'A' && c
<= 'F')
520 digit
= c
- 'A' + 10;
522 /* `l' means long, and `u' means unsigned. */
524 if
(c
== 'l' || c
== 'L')
526 if
(!pedantic
< spec_long
)
527 yyerror ("too many `l's in integer constant");
530 else if
(c
== 'u' || c
== 'U')
532 if
(! yylval.integer.signedp
)
533 yyerror ("two `u's in integer constant");
534 yylval.integer.signedp
= UNSIGNED
;
537 if
(c
== '.' || c
== 'e' || c
== 'E' || c
== 'p' || c
== 'P')
538 yyerror ("Floating point numbers not allowed in #if expressions");
540 char *buf
= (char *) alloca
(p
- lexptr
+ 40);
541 sprintf
(buf
, "missing white space after number `%.*s'",
542 (int) (p
- lexptr
- 1), lexptr
);
551 /* Don't look for any more digits after the suffixes. */
554 if
(largest_digit
< digit
)
555 largest_digit
= digit
;
556 nd
= n
* base
+ digit
;
557 overflow |
= (max_over_base
< n
) |
(nd
< n
);
561 if
(base
<= largest_digit
)
562 pedwarn
("integer constant contains digits beyond the radix");
565 pedwarn
("integer constant out of range");
567 /* If too big to be signed, consider it unsigned. */
568 if
(((HOST_WIDE_INT
) n
& yylval.integer.signedp
) < 0)
571 warning
("integer constant is so large that it is unsigned");
572 yylval.integer.signedp
= UNSIGNED
;
576 yylval.integer.value
= n
;
585 static struct token tokentab2
[] = {
599 /* Read one token, getting characters through lexptr. */
605 register
int namelen
;
606 register
unsigned char *tokstart
;
607 register
struct token
*toktab
;
613 tokstart
= (unsigned char *) lexptr
;
615 /* See if it is a special token of length 2. */
616 if
(! keyword_parsing
)
617 for
(toktab
= tokentab2
; toktab
->operator
!= NULL
; toktab
++)
618 if
(c
== *toktab
->operator
&& tokstart
[1] == toktab
->operator
[1]) {
620 if
(toktab
->token
== ERROR
)
622 char *buf
= (char *) alloca
(40);
623 sprintf
(buf
, "`%s' not allowed in operand of `#if'", toktab
->operator
);
626 return toktab
->token
;
640 /* Capital L may start a wide-string or wide-character constant. */
641 if
(lexptr
[1] == '\'')
645 mask
= MAX_WCHAR_TYPE_MASK
;
648 if
(lexptr
[1] == '"')
652 mask
= MAX_WCHAR_TYPE_MASK
;
653 goto string_constant
;
659 mask
= MAX_CHAR_TYPE_MASK
;
662 if
(keyword_parsing
) {
663 char *start_ptr
= lexptr
- 1;
667 c
= parse_escape
(&lexptr
, mask
);
671 yylval.name.address
= tokstart
;
672 yylval.name.length
= lexptr
- start_ptr
;
676 /* This code for reading a character constant
677 handles multicharacter constants and wide characters.
678 It is mostly copied from c-lex.c. */
680 register HOST_WIDE_INT result
= 0;
681 register num_chars
= 0;
682 unsigned width
= MAX_CHAR_TYPE_SIZE
;
688 width
= MAX_WCHAR_TYPE_SIZE
;
689 #ifdef MULTIBYTE_CHARS
690 max_chars
= MB_CUR_MAX
;
696 max_chars
= MAX_LONG_TYPE_SIZE
/ width
;
698 token_buffer
= (char *) alloca
(max_chars
+ 1);
704 if
(c
== '\'' || c
== EOF
)
709 c
= parse_escape
(&lexptr
, mask
);
714 /* Merge character into result; ignore excess chars. */
715 if
(num_chars
<= max_chars
)
717 if
(width
< HOST_BITS_PER_WIDE_INT
)
718 result
= (result
<< width
) | c
;
721 token_buffer
[num_chars
- 1] = c
;
725 token_buffer
[num_chars
] = 0;
728 error ("malformatted character constant");
729 else if
(num_chars
== 0)
730 error ("empty character constant");
731 else if
(num_chars
> max_chars
)
733 num_chars
= max_chars
;
734 error ("character constant too long");
736 else if
(num_chars
!= 1 && ! traditional
)
737 warning
("multi-character character constant");
739 /* If char type is signed, sign-extend the constant. */
742 int num_bits
= num_chars
* width
;
744 if
(lookup
((U_CHAR
*) "__CHAR_UNSIGNED__",
745 sizeof
("__CHAR_UNSIGNED__") - 1, -1)
746 ||
((result
>> (num_bits
- 1)) & 1) == 0)
748 = result
& (~
(unsigned HOST_WIDE_INT
) 0
749 >> (HOST_BITS_PER_WIDE_INT
- num_bits
));
752 = result | ~
(~
(unsigned HOST_WIDE_INT
) 0
753 >> (HOST_BITS_PER_WIDE_INT
- num_bits
));
757 #ifdef MULTIBYTE_CHARS
758 /* Set the initial shift state and convert the next sequence. */
760 /* In all locales L'\0' is zero and mbtowc will return zero,
763 ||
(num_chars
== 1 && token_buffer
[0] != '\0'))
766 (void) mbtowc
(NULL_PTR
, NULL_PTR
, 0);
767 if
(mbtowc
(& wc
, token_buffer
, num_chars
) == num_chars
)
770 pedwarn
("Ignoring invalid multibyte character");
773 yylval.integer.value
= result
;
777 /* This is always a signed type. */
778 yylval.integer.signedp
= SIGNED
;
782 /* some of these chars are invalid in constant expressions;
783 maybe do something about them later */
815 mask
= MAX_CHAR_TYPE_MASK
;
817 if
(keyword_parsing
) {
818 char *start_ptr
= lexptr
;
823 c
= parse_escape
(&lexptr
, mask
);
827 yylval.name.address
= tokstart
;
828 yylval.name.length
= lexptr
- start_ptr
;
831 yyerror ("string constants not allowed in #if expressions");
835 if
(c
>= '0' && c
<= '9' && !keyword_parsing
) {
837 for
(namelen
= 1; ; namelen
++) {
838 int d
= tokstart
[namelen
];
839 if
(! ((is_idchar
[d
] || d
== '.')
840 ||
((d
== '-' || d
== '+')
841 && (c
== 'e' || c
== 'E'
842 ||
((c
== 'p' || c
== 'P') && ! c89
))
847 return parse_number
(namelen
);
850 /* It is a name. See how long it is. */
852 if
(keyword_parsing
) {
853 for
(namelen
= 0;; namelen
++) {
854 if
(is_space
[tokstart
[namelen
]])
856 if
(tokstart
[namelen
] == '(' || tokstart
[namelen
] == ')')
858 if
(tokstart
[namelen
] == '"' || tokstart
[namelen
] == '\'')
862 if
(!is_idstart
[c
]) {
863 yyerror ("Invalid token in expression");
867 for
(namelen
= 0; is_idchar
[tokstart
[namelen
]]; namelen
++)
872 yylval.name.address
= tokstart
;
873 yylval.name.length
= namelen
;
878 /* Parse a C escape sequence. STRING_PTR points to a variable
879 containing a pointer to the string to parse. That pointer
880 is updated past the characters we use. The value of the
881 escape sequence is returned.
883 RESULT_MASK is used to mask out the result;
884 an error is reported if bits are lost thereby.
886 A negative value means the sequence \ newline was seen,
887 which is supposed to be equivalent to nothing at all.
889 If \ is followed by a null character, we return a negative
890 value and leave the string pointer pointing at the null character.
892 If \ is followed by 000, we return 0 and leave the string pointer
893 after the zeros. A value of 0 does not mean end of string. */
896 parse_escape
(string_ptr
, result_mask
)
898 HOST_WIDE_INT result_mask
;
900 register
int c
= *(*string_ptr
)++;
910 pedwarn
("non-ANSI-standard escape sequence, `\\%c'", c
);
915 return TARGET_NEWLINE
;
937 register HOST_WIDE_INT i
= c
- '0';
938 register
int count
= 0;
941 c
= *(*string_ptr
)++;
942 if
(c
>= '0' && c
<= '7')
943 i
= (i
<< 3) + c
- '0';
950 if
(i
!= (i
& result_mask
))
953 pedwarn
("octal escape sequence out of range");
959 register
unsigned HOST_WIDE_INT i
= 0, overflow
= 0;
960 register
int digits_found
= 0, digit
;
963 c
= *(*string_ptr
)++;
964 if
(c
>= '0' && c
<= '9')
966 else if
(c
>= 'a' && c
<= 'f')
967 digit
= c
- 'a' + 10;
968 else if
(c
>= 'A' && c
<= 'F')
969 digit
= c
- 'A' + 10;
975 overflow |
= i ^
(i
<< 4 >> 4);
976 i
= (i
<< 4) + digit
;
980 yyerror ("\\x used with no following hex digits");
981 if
(overflow |
(i
!= (i
& result_mask
)))
984 pedwarn
("hex escape sequence out of range");
999 longjmp
(parse_return_error
, 1);
1005 if
(!skip_evaluation
&& pedantic
)
1006 pedwarn
("integer overflow in preprocessor expression");
1009 static HOST_WIDE_INT
1012 unsigned HOST_WIDE_INT b
;
1014 /* It's unclear from the C standard whether shifts can overflow.
1015 The following code ignores overflow; perhaps a C standard
1016 interpretation ruling is needed. */
1017 if
(b
>= HOST_BITS_PER_WIDE_INT
)
1020 return
(unsigned HOST_WIDE_INT
) a
->value
<< b
;
1023 static HOST_WIDE_INT
1026 unsigned HOST_WIDE_INT b
;
1028 if
(b
>= HOST_BITS_PER_WIDE_INT
)
1029 return a
->signedp ? a
->value
>> (HOST_BITS_PER_WIDE_INT
- 1) : 0;
1030 else if
(a
->signedp
)
1031 return a
->value
>> b
;
1033 return
(unsigned HOST_WIDE_INT
) a
->value
>> b
;
1036 /* This page contains the entry point to this file. */
1038 /* Parse STRING as an expression, and complain if this fails
1039 to use up all of the contents of STRING. */
1040 /* STRING may contain '\0' bytes; it is terminated by the first '\n'
1041 outside a string constant, so that we can diagnose '\0' properly. */
1042 /* We do not support C comments. They should be removed before
1043 this function is called. */
1046 parse_c_expression
(string)
1051 /* if there is some sort of scanning error, just return 0 and assume
1052 the parsing routine has printed an error message somewhere.
1053 there is surely a better thing to do than this. */
1054 if
(setjmp
(parse_return_error
))
1057 if
(yyparse () != 0)
1060 if
(*lexptr
!= '\n')
1061 error ("Junk after end of expression.");
1063 return expression_value
; /* set by yyparse () */
1066 #ifdef TEST_EXP_READER
1075 int main PROTO
((int, char **));
1076 static void initialize_random_junk PROTO
((void));
1078 /* Main program for testing purposes. */
1087 pedantic
= 1 < argc
;
1088 traditional
= 2 < argc
;
1092 initialize_random_junk
();
1095 printf
("enter expression: ");
1097 while
((buf
[n
] = c
= getchar
()) != '\n' && c
!= EOF
)
1101 printf
("parser returned %ld\n", (long) parse_c_expression
(buf
));
1107 /* table to tell if char can be part of a C identifier. */
1108 unsigned char is_idchar
[256];
1109 /* table to tell if char can be first char of a c identifier. */
1110 unsigned char is_idstart
[256];
1111 /* table to tell if c is horizontal or vertical space. */
1112 unsigned char is_space
[256];
1115 * initialize random junk in the hash table and maybe other places
1118 initialize_random_junk
()
1123 * Set up is_idchar and is_idstart tables. These should be
1124 * faster than saying (is_alpha (c) || c == '_'), etc.
1125 * Must do set up these things before calling any routines tthat
1128 for
(i
= 'a'; i
<= 'z'; i
++) {
1129 ++is_idchar
[i
- 'a' + 'A'];
1131 ++is_idstart
[i
- 'a' + 'A'];
1134 for
(i
= '0'; i
<= '9'; i
++)
1150 error (PRINTF_ALIST
(msg
))
1155 VA_START
(args
, msg
);
1156 fprintf
(stderr
, "error: ");
1157 vfprintf
(stderr
, msg
, args
);
1158 fprintf
(stderr
, "\n");
1163 pedwarn
(PRINTF_ALIST
(msg
))
1168 VA_START
(args
, msg
);
1169 fprintf
(stderr
, "pedwarn: ");
1170 vfprintf
(stderr
, msg
, args
);
1171 fprintf
(stderr
, "\n");
1176 warning
(PRINTF_ALIST
(msg
))
1181 VA_START
(args
, msg
);
1182 fprintf
(stderr
, "warning: ");
1183 vfprintf
(stderr
, msg
, args
);
1184 fprintf
(stderr
, "\n");
1189 check_assertion
(name
, sym_length
, tokens_specified
, tokens
)
1192 int tokens_specified
;
1193 struct arglist
*tokens
;
1199 lookup
(name
, len
, hash
)
1204 return
(DEFAULT_SIGNED_CHAR
) ?
0 : ((struct hashnode
*) -1);
1211 return
(GENERIC_PTR
) malloc
(size
);