X-Git-Url: https://oss.titaniummirror.com/gitweb?a=blobdiff_plain;f=gcc%2Ftradcif.y;fp=gcc%2Ftradcif.y;h=0000000000000000000000000000000000000000;hb=6fed43773c9b0ce596dca5686f37ac3fc0fa11c0;hp=953e2d6706ff5fcbe1a0e861eab657b6b2c8b093;hpb=27b11d56b743098deb193d510b337ba22dc52e5c;p=msp430-gcc.git diff --git a/gcc/tradcif.y b/gcc/tradcif.y deleted file mode 100644 index 953e2d67..00000000 --- a/gcc/tradcif.y +++ /dev/null @@ -1,567 +0,0 @@ -/* Parse C expressions for CCCP. - Copyright (C) 1987, 2000, 2001 Free Software Foundation. - Adapted from expread.y of GDB by Paul Rubin, July 1986. - Adapted to ANSI C, Richard Stallman, Jan 1987 - Dusted off, polished, and adapted for use as traditional - preprocessor only, Zack Weinberg, Jul 2000 - -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 2, or (at your option) any -later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* Parse a C expression from text in a string */ - -%{ -#include "config.h" -#include "system.h" -#include "intl.h" -#include "tradcpp.h" -#include - - static int yylex PARAMS ((void)); - static void yyerror PARAMS ((const char *msgid)) ATTRIBUTE_NORETURN; - - static int parse_number PARAMS ((int)); - static int parse_escape PARAMS ((const char **)); - - static int expression_value; - static jmp_buf parse_return_error; - - /* During parsing of a C expression, the pointer to the next - character is in this variable. */ - - static const char *lexptr; -%} - -%union { - struct constant {long value; int unsignedp;} integer; - int voidval; - char *sval; -} - -%type exp exp1 start -%token INT CHAR -%token NAME -%token ERROR - -%right '?' ':' -%left ',' -%left OR -%left AND -%left '|' -%left '^' -%left '&' -%left EQUAL NOTEQUAL -%left '<' '>' LEQ GEQ -%left LSH RSH -%left '+' '-' -%left '*' '/' '%' -%right UNARY - -/* %expect 40 */ - -%% - -start : exp1 - { expression_value = $1.value; } - ; - -/* Expressions, including the comma operator. */ -exp1 : exp - | exp1 ',' exp - { $$ = $3; } - ; - -/* Expressions, not including the comma operator. */ -exp : '-' exp %prec UNARY - { $$.value = - $2.value; - $$.unsignedp = $2.unsignedp; } - | '!' exp %prec UNARY - { $$.value = ! $2.value; - $$.unsignedp = 0; } - | '+' exp %prec UNARY - { $$ = $2; } - | '~' exp %prec UNARY - { $$.value = ~ $2.value; - $$.unsignedp = $2.unsignedp; } - | '(' exp1 ')' - { $$ = $2; } - ; - -/* Binary operators in order of decreasing precedence. */ -exp : exp '*' exp - { $$.unsignedp = $1.unsignedp || $3.unsignedp; - if ($$.unsignedp) - $$.value = (unsigned) $1.value * $3.value; - else - $$.value = $1.value * $3.value; } - | exp '/' exp - { if ($3.value == 0) - { - error ("division by zero in #if"); - $3.value = 1; - } - $$.unsignedp = $1.unsignedp || $3.unsignedp; - if ($$.unsignedp) - $$.value = (unsigned) $1.value / $3.value; - else - $$.value = $1.value / $3.value; } - | exp '%' exp - { if ($3.value == 0) - { - error ("division by zero in #if"); - $3.value = 1; - } - $$.unsignedp = $1.unsignedp || $3.unsignedp; - if ($$.unsignedp) - $$.value = (unsigned) $1.value % $3.value; - else - $$.value = $1.value % $3.value; } - | exp '+' exp - { $$.value = $1.value + $3.value; - $$.unsignedp = $1.unsignedp || $3.unsignedp; } - | exp '-' exp - { $$.value = $1.value - $3.value; - $$.unsignedp = $1.unsignedp || $3.unsignedp; } - | exp LSH exp - { $$.unsignedp = $1.unsignedp; - if ($$.unsignedp) - $$.value = (unsigned) $1.value << $3.value; - else - $$.value = $1.value << $3.value; } - | exp RSH exp - { $$.unsignedp = $1.unsignedp; - if ($$.unsignedp) - $$.value = (unsigned) $1.value >> $3.value; - else - $$.value = $1.value >> $3.value; } - | exp EQUAL exp - { $$.value = ($1.value == $3.value); - $$.unsignedp = 0; } - | exp NOTEQUAL exp - { $$.value = ($1.value != $3.value); - $$.unsignedp = 0; } - | exp LEQ exp - { $$.unsignedp = 0; - if ($1.unsignedp || $3.unsignedp) - $$.value = - (unsigned) $1.value <= (unsigned) $3.value; - else - $$.value = $1.value <= $3.value; } - | exp GEQ exp - { $$.unsignedp = 0; - if ($1.unsignedp || $3.unsignedp) - $$.value = - (unsigned) $1.value >= (unsigned) $3.value; - else - $$.value = $1.value >= $3.value; } - | exp '<' exp - { $$.unsignedp = 0; - if ($1.unsignedp || $3.unsignedp) - $$.value = - (unsigned) $1.value < (unsigned) $3.value; - else - $$.value = $1.value < $3.value; } - | exp '>' exp - { $$.unsignedp = 0; - if ($1.unsignedp || $3.unsignedp) - $$.value = - (unsigned) $1.value > (unsigned) $3.value; - else - $$.value = $1.value > $3.value; } - | exp '&' exp - { $$.value = $1.value & $3.value; - $$.unsignedp = $1.unsignedp || $3.unsignedp; } - | exp '^' exp - { $$.value = $1.value ^ $3.value; - $$.unsignedp = $1.unsignedp || $3.unsignedp; } - | exp '|' exp - { $$.value = $1.value | $3.value; - $$.unsignedp = $1.unsignedp || $3.unsignedp; } - | exp AND exp - { $$.value = ($1.value && $3.value); - $$.unsignedp = 0; } - | exp OR exp - { $$.value = ($1.value || $3.value); - $$.unsignedp = 0; } - | exp '?' exp ':' exp - { $$.value = $1.value ? $3.value : $5.value; - $$.unsignedp = $3.unsignedp || $5.unsignedp; } - | INT - { $$ = yylval.integer; } - | CHAR - { $$ = yylval.integer; } - | NAME - { $$.value = 0; - $$.unsignedp = 0; } - | '#' { $$.value = - test_assertion ((unsigned char **) &lexptr); } - ; -%% - -/* Take care of parsing a number (anything that starts with a digit). - Set yylval and return the token type; update lexptr. - LEN is the number of characters in it. */ - -/* maybe needs to actually deal with floating point numbers */ - -static int -parse_number (olen) - int olen; -{ - const char *p = lexptr; - long n = 0; - int c; - int base = 10; - int len = olen; - - for (c = 0; c < len; c++) - if (p[c] == '.') { - /* It's a float since it contains a point. */ - yyerror ("floating point numbers not allowed in #if expressions"); - return ERROR; - } - - /* Traditionally, all numbers are signed. However, we make it - unsigned if requested with a suffix. */ - yylval.integer.unsignedp = 0; - - if (len >= 3 && (!strncmp (p, "0x", 2) || !strncmp (p, "0X", 2))) { - p += 2; - base = 16; - len -= 2; - } - else if (*p == '0') - base = 8; - - while (len > 0) { - c = *p++; - len--; - if (ISUPPER (c)) - c = TOLOWER (c); - - if (ISDIGIT (c) - || (base == 16 && ISXDIGIT (c))) { - n = (n * base) + hex_value (c); - } else { - /* `l' means long, and `u' means unsigned. */ - while (1) { - if (c == 'l' || c == 'L') - ; - else if (c == 'u' || c == 'U') - yylval.integer.unsignedp = 1; - else - break; - - if (len == 0) - break; - c = *p++; - len--; - } - /* Don't look for any more digits after the suffixes. */ - break; - } - } - - if (len != 0) { - yyerror ("invalid number in #if expression"); - return ERROR; - } - - lexptr = p; - yylval.integer.value = n; - return INT; -} - -struct token { - const char *const operator; - const int token; -}; - -#ifndef NULL -#define NULL 0 -#endif - -static const struct token tokentab2[] = { - {"&&", AND}, - {"||", OR}, - {"<<", LSH}, - {">>", RSH}, - {"==", EQUAL}, - {"!=", NOTEQUAL}, - {"<=", LEQ}, - {">=", GEQ}, - {NULL, ERROR} -}; - -/* Read one token, getting characters through lexptr. */ - -static int -yylex () -{ - int c; - int namelen; - const char *tokstart; - const struct token *toktab; - - retry: - - tokstart = lexptr; - c = *tokstart; - /* See if it is a special token of length 2. */ - for (toktab = tokentab2; toktab->operator != NULL; toktab++) - if (c == *toktab->operator && tokstart[1] == toktab->operator[1]) { - lexptr += 2; - return toktab->token; - } - - switch (c) { - case 0: - return 0; - - case ' ': - case '\t': - case '\r': - case '\n': - lexptr++; - goto retry; - - case '\'': - lexptr++; - c = *lexptr++; - if (c == '\\') - c = parse_escape (&lexptr); - - /* Sign-extend the constant if chars are signed on target machine. */ - { - if (flag_signed_char == 0 - || ((c >> (CHAR_TYPE_SIZE - 1)) & 1) == 0) - yylval.integer.value = c & ((1 << CHAR_TYPE_SIZE) - 1); - else - yylval.integer.value = c | ~((1 << CHAR_TYPE_SIZE) - 1); - } - - yylval.integer.unsignedp = 0; - c = *lexptr++; - if (c != '\'') { - yyerror ("invalid character constant in #if"); - return ERROR; - } - - return CHAR; - - /* some of these chars are invalid in constant expressions; - maybe do something about them later */ - case '/': - case '+': - case '-': - case '*': - case '%': - case '|': - case '&': - case '^': - case '~': - case '!': - case '@': - case '<': - case '>': - case '(': - case ')': - case '[': - case ']': - case '.': - case '?': - case ':': - case '=': - case '{': - case '}': - case ',': - case '#': - lexptr++; - return c; - - case '"': - yyerror ("double quoted strings not allowed in #if expressions"); - return ERROR; - } - if (ISDIGIT (c)) { - /* It's a number */ - for (namelen = 0; - c = tokstart[namelen], is_idchar (c) || c == '.'; - namelen++) - ; - return parse_number (namelen); - } - - if (!is_idstart (c)) { - yyerror ("invalid token in expression"); - return ERROR; - } - - /* It is a name. See how long it is. */ - - for (namelen = 0; - is_idchar (tokstart[namelen]); - namelen++) - ; - - lexptr += namelen; - return NAME; -} - - -/* Parse a C escape sequence. STRING_PTR points to a variable - containing a pointer to the string to parse. That pointer - is updated past the characters we use. The value of the - escape sequence is returned. - - A negative value means the sequence \ newline was seen, - which is supposed to be equivalent to nothing at all. - - If \ is followed by a null character, we return a negative - value and leave the string pointer pointing at the null character. - - If \ is followed by 000, we return 0 and leave the string pointer - after the zeros. A value of 0 does not mean end of string. */ - -static int -parse_escape (string_ptr) - const char **string_ptr; -{ - int c = *(*string_ptr)++; - switch (c) - { - case 'a': - return TARGET_BELL; - case 'b': - return TARGET_BS; - case 'e': - return 033; - case 'f': - return TARGET_FF; - case 'n': - return TARGET_NEWLINE; - case 'r': - return TARGET_CR; - case 't': - return TARGET_TAB; - case 'v': - return TARGET_VT; - case '\n': - return -2; - case 0: - (*string_ptr)--; - return 0; - case '^': - c = *(*string_ptr)++; - if (c == '\\') - c = parse_escape (string_ptr); - if (c == '?') - return 0177; - return (c & 0200) | (c & 037); - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - { - int i = c - '0'; - int count = 0; - while (++count < 3) - { - c = *(*string_ptr)++; - if (c >= '0' && c <= '7') - i = (i << 3) + c - '0'; - else - { - (*string_ptr)--; - break; - } - } - if ((i & ~((1 << CHAR_TYPE_SIZE) - 1)) != 0) - { - i &= (1 << CHAR_TYPE_SIZE) - 1; - warning ("octal character constant does not fit in a byte"); - } - return i; - } - case 'x': - { - int i = 0; - for (;;) - { - c = *(*string_ptr)++; - if (hex_p (c)) - i = (i << 4) + hex_value (c); - else - { - (*string_ptr)--; - break; - } - } - if ((i & ~((1 << BITS_PER_UNIT) - 1)) != 0) - { - i &= (1 << BITS_PER_UNIT) - 1; - warning ("hex character constant does not fit in a byte"); - } - return i; - } - default: - return c; - } -} - -static void -yyerror (msgid) - const char *msgid; -{ - error ("%s", _(msgid)); - longjmp (parse_return_error, 1); -} - -/* This page contains the entry point to this file. */ - -/* Parse STRING as an expression, and complain if this fails - to use up all of the contents of STRING. */ -/* We do not support C comments. They should be removed before - this function is called. */ - -int -parse_c_expression (string) - const char *string; -{ - lexptr = string; - - if (lexptr == 0 || *lexptr == 0) { - error ("empty #if expression"); - return 0; /* don't include the #if group */ - } - - /* if there is some sort of scanning error, just return 0 and assume - the parsing routine has printed an error message somewhere. - there is surely a better thing to do than this. */ - if (setjmp (parse_return_error)) - return 0; - - if (yyparse ()) - return 0; /* actually this is never reached - the way things stand. */ - if (*lexptr) - error ("Junk after end of expression."); - - return expression_value; /* set by yyparse () */ -}