⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cexp.y

📁 GUN开源阻止下的编译器GCC
💻 Y
📖 第 1 页 / 共 2 页
字号:
	    sprintf (buf, "`%s' not allowed in operand of `#if'", toktab->operator);	    yyerror (buf);	  }	return toktab->token;      }  switch (c) {  case 0:    return 0;      case ' ':  case '\t':  case '\r':  case '\n':    lexptr++;    goto retry;      case 'L':    /* Capital L may start a wide-string or wide-character constant.  */    if (lexptr[1] == '\'')      {	lexptr++;	wide_flag = 1;	goto char_constant;      }    if (lexptr[1] == '"')      {	lexptr++;	wide_flag = 1;	goto string_constant;      }    break;  case '\'':    wide_flag = 0;  char_constant:    lexptr++;    if (keyword_parsing) {      char *start_ptr = lexptr - 1;      while (1) {	c = *lexptr++;	if (c == '\\')	  c = parse_escape (&lexptr);	else if (c == '\'')	  break;      }      yylval.name.address = tokstart;      yylval.name.length = lexptr - start_ptr;      return NAME;    }    /* This code for reading a character constant       handles multicharacter constants and wide characters.       It is mostly copied from c-lex.c.  */    {      register int result = 0;      register num_chars = 0;      unsigned width = MAX_CHAR_TYPE_SIZE;      int max_chars;      char *token_buffer;      if (wide_flag)	{	  width = MAX_WCHAR_TYPE_SIZE;#ifdef MULTIBYTE_CHARS	  max_chars = MB_CUR_MAX;#else	  max_chars = 1;#endif	}      else	max_chars = MAX_LONG_TYPE_SIZE / width;      token_buffer = (char *) alloca (max_chars + 1);      while (1)	{	  c = *lexptr++;	  if (c == '\'' || c == EOF)	    break;	  if (c == '\\')	    {	      c = parse_escape (&lexptr);	      if (width < HOST_BITS_PER_INT		  && (unsigned) c >= (1 << width))		pedwarn ("escape sequence out of range for character");	    }	  num_chars++;	  /* Merge character into result; ignore excess chars.  */	  if (num_chars < max_chars + 1)	    {	      if (width < HOST_BITS_PER_INT)		result = (result << width) | (c & ((1 << width) - 1));	      else		result = c;	      token_buffer[num_chars - 1] = c;	    }	}      token_buffer[num_chars] = 0;      if (c != '\'')	error ("malformatted character constant");      else if (num_chars == 0)	error ("empty character constant");      else if (num_chars > max_chars)	{	  num_chars = max_chars;	  error ("character constant too long");	}      else if (num_chars != 1 && ! traditional)	warning ("multi-character character constant");      /* If char type is signed, sign-extend the constant.  */      if (! wide_flag)	{	  int num_bits = num_chars * width;	  if (lookup ("__CHAR_UNSIGNED__", sizeof ("__CHAR_UNSIGNED__")-1, -1)	      || ((result >> (num_bits - 1)) & 1) == 0)	    yylval.integer.value	      = result & ((unsigned long) ~0 >> (HOST_BITS_PER_LONG - num_bits));	  else	    yylval.integer.value	      = result | ~((unsigned long) ~0 >> (HOST_BITS_PER_LONG - num_bits));	}      else	{#ifdef MULTIBYTE_CHARS	  /* Set the initial shift state and convert the next sequence.  */	  result = 0;	  /* In all locales L'\0' is zero and mbtowc will return zero,	     so don't use it.  */	  if (num_chars > 1	      || (num_chars == 1 && token_buffer[0] != '\0'))	    {	      wchar_t wc;	      (void) mbtowc (NULL_PTR, NULL_PTR, 0);	      if (mbtowc (& wc, token_buffer, num_chars) == num_chars)		result = wc;	      else		warning ("Ignoring invalid multibyte character");	    }#endif	  yylval.integer.value = result;	}    }    /* This is always a signed type.  */    yylval.integer.unsignedp = 0;        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 '#':    if (keyword_parsing)      break;  case '(':  case ')':    lexptr++;    return c;  case '"':  string_constant:    if (keyword_parsing) {      char *start_ptr = lexptr;      lexptr++;      while (1) {	c = *lexptr++;	if (c == '\\')	  c = parse_escape (&lexptr);	else if (c == '"')	  break;      }      yylval.name.address = tokstart;      yylval.name.length = lexptr - start_ptr;      return NAME;    }    yyerror ("string constants not allowed in #if expressions");    return ERROR;  }  if (c >= '0' && c <= '9' && !keyword_parsing) {    /* It's a number */    for (namelen = 0;	 c = tokstart[namelen], is_idchar[c] || c == '.'; 	 namelen++)      ;    return parse_number (namelen);  }  /* It is a name.  See how long it is.  */  if (keyword_parsing) {    for (namelen = 0;; namelen++) {      if (is_hor_space[tokstart[namelen]])	break;      if (tokstart[namelen] == '(' || tokstart[namelen] == ')')	break;      if (tokstart[namelen] == '"' || tokstart[namelen] == '\'')	break;    }  } else {    if (!is_idstart[c]) {      yyerror ("Invalid token in expression");      return ERROR;    }    for (namelen = 0; is_idchar[tokstart[namelen]]; namelen++)      ;  }    lexptr += namelen;  yylval.name.address = tokstart;  yylval.name.length = 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.  */intparse_escape (string_ptr)     char **string_ptr;{  register int c = *(*string_ptr)++;  switch (c)    {    case 'a':      return TARGET_BELL;    case 'b':      return TARGET_BS;    case 'e':    case 'E':      if (pedantic)	pedwarn ("non-ANSI-standard escape sequence, `\\%c'", c);      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 '0':    case '1':    case '2':    case '3':    case '4':    case '5':    case '6':    case '7':      {	register int i = c - '0';	register 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 << MAX_CHAR_TYPE_SIZE) - 1)) != 0)	  {	    i &= (1 << MAX_CHAR_TYPE_SIZE) - 1;	    warning ("octal character constant does not fit in a byte");	  }	return i;      }    case 'x':      {	register unsigned i = 0, overflow = 0, digits_found = 0, digit;	for (;;)	  {	    c = *(*string_ptr)++;	    if (c >= '0' && c <= '9')	      digit = c - '0';	    else if (c >= 'a' && c <= 'f')	      digit = c - 'a' + 10;	    else if (c >= 'A' && c <= 'F')	      digit = c - 'A' + 10;	    else	      {		(*string_ptr)--;		break;	      }	    overflow |= i ^ (i << 4 >> 4);	    i = (i << 4) + digit;	    digits_found = 1;	  }	if (!digits_found)	  yyerror ("\\x used with no following hex digits");	if (overflow | (i & ~((1 << BITS_PER_UNIT) - 1)))	  {	    i &= (1 << BITS_PER_UNIT) - 1;	    warning ("hex character constant does not fit in a byte");	  }	return i;      }    default:      return c;    }}voidyyerror (s)     char *s;{  error (s);  skip_evaluation = 0;  longjmp (parse_return_error, 1);}static voidinteger_overflow (){  if (!skip_evaluation && pedantic)    pedwarn ("integer overflow in preprocessor expression");}static longleft_shift (a, b)     struct constant *a;     unsigned long b;{   /* It's unclear from the C standard whether shifts can overflow.      The following code ignores overflow; perhaps a C standard      interpretation ruling is needed.  */  if (b >= HOST_BITS_PER_LONG)    return 0;  else if (a->unsignedp)    return (unsigned long) a->value << b;  else    return a->value << b;}static longright_shift (a, b)     struct constant *a;     unsigned long b;{  if (b >= HOST_BITS_PER_LONG)    return a->unsignedp ? 0 : a->value >> (HOST_BITS_PER_LONG - 1);  else if (a->unsignedp)    return (unsigned long) a->value >> b;  else    return a->value >> b;}/* 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.  */HOST_WIDE_INTparse_c_expression (string)     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 () */}#ifdef TEST_EXP_READERextern int yydebug;/* Main program for testing purposes.  */intmain (){  int n, c;  char buf[1024];/*  yydebug = 1;*/  initialize_random_junk ();  for (;;) {    printf ("enter expression: ");    n = 0;    while ((buf[n] = getchar ()) != '\n' && buf[n] != EOF)      n++;    if (buf[n] == EOF)      break;    buf[n] = '\0';    printf ("parser returned %ld\n", parse_c_expression (buf));  }  return 0;}/* table to tell if char can be part of a C identifier. */unsigned char is_idchar[256];/* table to tell if char can be first char of a c identifier. */unsigned char is_idstart[256];/* table to tell if c is horizontal space.  isspace () thinks that   newline is space; this is not a good idea for this program. */char is_hor_space[256];/* * initialize random junk in the hash table and maybe other places */initialize_random_junk (){  register int i;  /*   * Set up is_idchar and is_idstart tables.  These should be   * faster than saying (is_alpha (c) || c == '_'), etc.   * Must do set up these things before calling any routines tthat   * refer to them.   */  for (i = 'a'; i <= 'z'; i++) {    ++is_idchar[i - 'a' + 'A'];    ++is_idchar[i];    ++is_idstart[i - 'a' + 'A'];    ++is_idstart[i];  }  for (i = '0'; i <= '9'; i++)    ++is_idchar[i];  ++is_idchar['_'];  ++is_idstart['_'];#if DOLLARS_IN_IDENTIFIERS  ++is_idchar['$'];  ++is_idstart['$'];#endif  /* horizontal space table */  ++is_hor_space[' '];  ++is_hor_space['\t'];}error (msg){  printf ("error: %s\n", msg);}warning (msg){  printf ("warning: %s\n", msg);}struct hashnode *lookup (name, len, hash)     char *name;     int len;     int hash;{  return (DEFAULT_SIGNED_CHAR) ? 0 : ((struct hashnode *) -1);}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -