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

📄 cexp.c

📁 编译工具
💻 C
📖 第 1 页 / 共 4 页
字号:
      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, mask);	    }	  num_chars++;	  /* Merge character into result; ignore excess chars.  */	  if (num_chars <= max_chars)	    {	      if (width < HOST_BITS_PER_WIDE_INT)		result = (result << width) | c;	      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 ((U_CHAR *) "__CHAR_UNSIGNED__",		      sizeof ("__CHAR_UNSIGNED__") - 1, -1)	      || ((result >> (num_bits - 1)) & 1) == 0)	    yylval.integer.value	      = result & (~ (unsigned HOST_WIDE_INT) 0			  >> (HOST_BITS_PER_WIDE_INT - num_bits));	  else	    yylval.integer.value	      = result | ~(~ (unsigned HOST_WIDE_INT) 0			   >> (HOST_BITS_PER_WIDE_INT - 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		pedwarn ("Ignoring invalid multibyte character");	    }#endif	  yylval.integer.value = result;	}    }    /* This is always a signed type.  */    yylval.integer.signedp = SIGNED;        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 '"':    mask = MAX_CHAR_TYPE_MASK;  string_constant:    if (keyword_parsing) {      char *start_ptr = lexptr;      lexptr++;      while (1) {	c = *lexptr++;	if (c == '\\')	  c = parse_escape (&lexptr, mask);	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 = 1; ; namelen++) {      int d = tokstart[namelen];      if (! ((is_idchar[d] || d == '.')	     || ((d == '-' || d == '+')		 && (c == 'e' || c == 'E'		     || ((c == 'p' || c == 'P') && ! c89))		 && ! traditional)))	break;      c = d;    }    return parse_number (namelen);  }  /* It is a name.  See how long it is.  */  if (keyword_parsing) {    for (namelen = 0;; namelen++) {      if (is_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.   RESULT_MASK is used to mask out the result;   an error is reported if bits are lost thereby.   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.  */HOST_WIDE_INTparse_escape (string_ptr, result_mask)     char **string_ptr;     HOST_WIDE_INT result_mask;{  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 HOST_WIDE_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 != (i & result_mask))	  {	    i &= result_mask;	    pedwarn ("octal escape sequence out of range");	  }	return i;      }    case 'x':      {	register unsigned HOST_WIDE_INT i = 0, overflow = 0;	register int 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 != (i & result_mask)))	  {	    i &= result_mask;	    pedwarn ("hex escape sequence out of range");	  }	return i;      }    default:      return c;    }}static voidyyerror (s)     char *s;{  error ("%s", s);  skip_evaluation = 0;  longjmp (parse_return_error, 1);}static voidinteger_overflow (){  if (!skip_evaluation && pedantic)    pedwarn ("integer overflow in preprocessor expression");}static HOST_WIDE_INTleft_shift (a, b)     struct constant *a;     unsigned HOST_WIDE_INT 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_WIDE_INT)    return 0;  else    return (unsigned HOST_WIDE_INT) a->value << b;}static HOST_WIDE_INTright_shift (a, b)     struct constant *a;     unsigned HOST_WIDE_INT b;{  if (b >= HOST_BITS_PER_WIDE_INT)    return a->signedp ? a->value >> (HOST_BITS_PER_WIDE_INT - 1) : 0;  else if (a->signedp)    return a->value >> b;  else    return (unsigned HOST_WIDE_INT) 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.  *//* STRING may contain '\0' bytes; it is terminated by the first '\n'   outside a string constant, so that we can diagnose '\0' properly.  *//* 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 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 () != 0)    abort ();  if (*lexptr != '\n')    error ("Junk after end of expression.");  return expression_value;	/* set by yyparse () */}#ifdef TEST_EXP_READER#if YYDEBUGextern int yydebug;#endifint pedantic;int traditional;int main PROTO((int, char **));static void initialize_random_junk PROTO((void));/* Main program for testing purposes.  */intmain (argc, argv)     int argc;     char **argv;{  int n, c;  char buf[1024];  pedantic = 1 < argc;  traditional = 2 < argc;#if YYDEBUG  yydebug = 3 < argc;#endif  initialize_random_junk ();  for (;;) {    printf ("enter expression: ");    n = 0;    while ((buf[n] = c = getchar ()) != '\n' && c != EOF)      n++;    if (c == EOF)      break;    printf ("parser returned %ld\n", (long) 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 or vertical space.  */unsigned char is_space[256];/* * initialize random junk in the hash table and maybe other places */static voidinitialize_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['_'];  ++is_idchar['$'];  ++is_idstart['$'];  ++is_space[' '];  ++is_space['\t'];  ++is_space['\v'];  ++is_space['\f'];  ++is_space['\n'];  ++is_space['\r'];}voiderror (PRINTF_ALIST (msg))     PRINTF_DCL (msg){  va_list args;  VA_START (args, msg);  fprintf (stderr, "error: ");  vfprintf (stderr, msg, args);  fprintf (stderr, "\n");  va_end (args);}voidpedwarn (PRINTF_ALIST (msg))     PRINTF_DCL (msg){  va_list args;  VA_START (args, msg);  fprintf (stderr, "pedwarn: ");  vfprintf (stderr, msg, args);  fprintf (stderr, "\n");  va_end (args);}voidwarning (PRINTF_ALIST (msg))     PRINTF_DCL (msg){  va_list args;  VA_START (args, msg);  fprintf (stderr, "warning: ");  vfprintf (stderr, msg, args);  fprintf (stderr, "\n");  va_end (args);}intcheck_assertion (name, sym_length, tokens_specified, tokens)     U_CHAR *name;     int sym_length;     int tokens_specified;     struct arglist *tokens;{  return 0;}struct hashnode *lookup (name, len, hash)     U_CHAR *name;     int len;     int hash;{  return (DEFAULT_SIGNED_CHAR) ? 0 : ((struct hashnode *) -1);}GENERIC_PTRxmalloc (size)     size_t size;{  return (GENERIC_PTR) malloc (size);}#endif

⌨️ 快捷键说明

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