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

📄 cppexp.c

📁 gcc库的原代码,对编程有很大帮助.
💻 C
📖 第 1 页 / 共 2 页
字号:
    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;	    cpp_warning (pfile,			  "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)	  cpp_error (pfile, "\\x used with no following hex digits");	if (overflow | (i & ~((1 << BITS_PER_UNIT) - 1)))	  {	    i &= (1 << BITS_PER_UNIT) - 1;	    cpp_warning (pfile,			 "hex character constant does not fit in a byte");	  }	return i;      }    default:      return c;    }}static voidinteger_overflow (pfile)     cpp_reader *pfile;{  if (CPP_PEDANTIC (pfile))    cpp_pedwarn (pfile, "integer overflow in preprocessor expression");}static longleft_shift (pfile, a, unsignedp, b)     cpp_reader *pfile;     long a;     int unsignedp;     unsigned long b;{  if (b >= HOST_BITS_PER_LONG)    {      if (! unsignedp && a != 0)	integer_overflow (pfile);      return 0;    }  else if (unsignedp)    return (unsigned long) a << b;  else    {      long l = a << b;      if (l >> b != a)	integer_overflow (pfile);      return l;    }}static longright_shift (pfile, a, unsignedp, b)     cpp_reader *pfile;     long a;     int unsignedp;     unsigned long b;{  if (b >= HOST_BITS_PER_LONG)    return unsignedp ? 0 : a >> (HOST_BITS_PER_LONG - 1);  else if (unsignedp)    return (unsigned long) a >> b;  else    return a >> b;}/* These priorities are all even, so we can handle associatively. */#define PAREN_INNER_PRIO 0#define COMMA_PRIO 4#define COND_PRIO (COMMA_PRIO+2)#define OROR_PRIO (COND_PRIO+2)#define ANDAND_PRIO (OROR_PRIO+2)#define OR_PRIO (ANDAND_PRIO+2)#define XOR_PRIO (OR_PRIO+2)#define AND_PRIO (XOR_PRIO+2)#define EQUAL_PRIO (AND_PRIO+2)#define LESS_PRIO (EQUAL_PRIO+2)#define SHIFT_PRIO (LESS_PRIO+2)#define PLUS_PRIO (SHIFT_PRIO+2)#define MUL_PRIO (PLUS_PRIO+2)#define UNARY_PRIO (MUL_PRIO+2)#define PAREN_OUTER_PRIO (UNARY_PRIO+2)#define COMPARE(OP) \  top->unsignedp = 0;\  top->value = (unsigned1 || unsigned2) ? (unsigned long) v1 OP v2 : (v1 OP v2)/* Parse and evaluate a C expression, reading from PFILE.   Returns the value of the expression.  */HOST_WIDE_INTcpp_parse_expr (pfile)     cpp_reader *pfile;{  /* The implementation is an operator precedence parser,     i.e. a bottom-up parser, using a stack for not-yet-reduced tokens.     The stack base is 'stack', and the current stack pointer is 'top'.     There is a stack element for each operator (only),     and the most recently pushed operator is 'top->op'.     An operand (value) is stored in the 'value' field of the stack     element of the operator that precedes it.     In that case the 'flags' field has the HAVE_VALUE flag set.  */#define INIT_STACK_SIZE 20  struct operation init_stack[INIT_STACK_SIZE];  struct operation *stack = init_stack;  struct operation *limit = stack + INIT_STACK_SIZE;  register struct operation *top = stack;  int lprio, rprio;  top->rprio = 0;  top->flags = 0;  for (;;)    {      struct operation op;      char flags = 0;      /* Read a token */      op =  cpp_lex (pfile);      /* See if the token is an operand, in which case go to set_value.	 If the token is an operator, figure out its left and right	 priorities, and then goto maybe_reduce. */      switch (op.op)	{	case NAME:	  top->value = 0, top->unsignedp = 0;	  goto set_value;	case INT:  case CHAR:	  top->value = op.value;	  top->unsignedp = op.unsignedp;	  goto set_value;	case 0:	  lprio = 0;  goto maybe_reduce;	case '+':  case '-':	  /* Is this correct if unary ? FIXME */	  flags = RIGHT_OPERAND_REQUIRED;	  lprio = PLUS_PRIO;  rprio = lprio + 1;  goto maybe_reduce;	case '!':  case '~':	  flags = RIGHT_OPERAND_REQUIRED;	  rprio = UNARY_PRIO;  lprio = rprio + 1;  goto maybe_reduce;	case '*':  case '/':  case '%':	  lprio = MUL_PRIO;  goto binop;	case '<':  case '>':  case LEQ:  case GEQ:	  lprio = LESS_PRIO;  goto binop;	case EQUAL:  case NOTEQUAL:	  lprio = EQUAL_PRIO;  goto binop;	case LSH:  case RSH:	  lprio = SHIFT_PRIO;  goto binop;	case '&':  lprio = AND_PRIO;  goto binop;	case '^':  lprio = XOR_PRIO;  goto binop;	case '|':  lprio = OR_PRIO;  goto binop;	case ANDAND:  lprio = ANDAND_PRIO;  goto binop;	case OROR:  lprio = OROR_PRIO;  goto binop;	case ',':	  lprio = COMMA_PRIO;  goto binop;	case '(':	  lprio = PAREN_OUTER_PRIO;  rprio = PAREN_INNER_PRIO;	  goto maybe_reduce;	case ')':	  lprio = PAREN_INNER_PRIO;  rprio = PAREN_OUTER_PRIO;	  goto maybe_reduce;        case ':':	  lprio = COND_PRIO;  rprio = COND_PRIO;	  goto maybe_reduce;        case '?':	  lprio = COND_PRIO + 1;  rprio = COND_PRIO;	  goto maybe_reduce;	binop:	  flags = LEFT_OPERAND_REQUIRED|RIGHT_OPERAND_REQUIRED;	  rprio = lprio + 1;	  goto maybe_reduce;	default:	  cpp_error (pfile, "invalid character in #if");	  goto syntax_error;	}    set_value:      /* Push a value onto the stack. */      if (top->flags & HAVE_VALUE)	{	  cpp_error (pfile, "syntax error in #if");	  goto syntax_error;	}      top->flags |= HAVE_VALUE;      continue;    maybe_reduce:      /* Push an operator, and check if we can reduce now. */      while (top->rprio > lprio)	{	  long v1 = top[-1].value, v2 = top[0].value;	  int unsigned1 = top[-1].unsignedp, unsigned2 = top[0].unsignedp;	  top--;	  if ((top[1].flags & LEFT_OPERAND_REQUIRED)	      && ! (top[0].flags & HAVE_VALUE))	    {	      cpp_error (pfile, "syntax error - missing left operand");	      goto syntax_error;	    }	  if ((top[1].flags & RIGHT_OPERAND_REQUIRED)	      && ! (top[1].flags & HAVE_VALUE))	    {	      cpp_error (pfile, "syntax error - missing right operand");	      goto syntax_error;	    }	  /* top[0].value = (top[1].op)(v1, v2);*/	  switch (top[1].op)	    {	    case '+':	      if (!(top->flags & HAVE_VALUE))		{ /* Unary '+' */		  top->value = v2;		  top->unsignedp = unsigned2;		  top->flags |= HAVE_VALUE;		}	      else		{		  top->value = v1 + v2;		  top->unsignedp = unsigned1 || unsigned2;		  if (! top->unsignedp		      && ! possible_sum_sign (v1, v2, top->value))		    integer_overflow (pfile);		}	      break;	    case '-':	      if (!(top->flags & HAVE_VALUE))		{ /* Unary '-' */		  top->value = - v2;		  if ((top->value & v2) < 0 && ! unsigned2)		    integer_overflow (pfile);		  top->unsignedp = unsigned2;		  top->flags |= HAVE_VALUE;		}	      else		{ /* Binary '-' */		  top->value = v1 - v2;		  top->unsignedp = unsigned1 || unsigned2;		  if (! top->unsignedp		      && ! possible_sum_sign (top->value, v2, v1))		    integer_overflow (pfile);		}	      break;	    case '*':	      top->unsignedp = unsigned1 || unsigned2;	      if (top->unsignedp)		top->value = (unsigned long) v1 * v2;	      else		{		  top->value = v1 * v2;		  if (v1		      && (top->value / v1 != v2			  || (top->value & v1 & v2) < 0))		    integer_overflow (pfile);		}	      break;	    case '/':	      if (v2 == 0)		{		  cpp_error (pfile, "division by zero in #if");		  v2 = 1;		}	      top->unsignedp = unsigned1 || unsigned2;	      if (top->unsignedp)		top->value = (unsigned long) v1 / v2;	      else		{		  top->value = v1 / v2;		  if ((top->value & v1 & v2) < 0)		    integer_overflow (pfile);		}	      break;	    case '%':	      if (v2 == 0)		{		  cpp_error (pfile, "division by zero in #if");		  v2 = 1;		}	      top->unsignedp = unsigned1 || unsigned2;	      if (top->unsignedp)		top->value = (unsigned long) v1 % v2;	      else		top->value = v1 % v2;	      break;	    case '!':	      if (top->flags & HAVE_VALUE)		{		  cpp_error (pfile, "syntax error");		  goto syntax_error;		}	      top->value = ! v2;	      top->unsignedp = 0;	      top->flags |= HAVE_VALUE;	      break;	    case '~':	      if (top->flags & HAVE_VALUE)		{		  cpp_error (pfile, "syntax error");		  goto syntax_error;		}	      top->value = ~ v2;	      top->unsignedp = unsigned2;	      top->flags |= HAVE_VALUE;	      break;	    case '<':  COMPARE(<);  break;	    case '>':  COMPARE(>);  break;	    case LEQ:  COMPARE(<=); break;	    case GEQ:  COMPARE(>=); break;	    case EQUAL:	      top->value = (v1 == v2);	      top->unsignedp = 0;	      break;	    case NOTEQUAL:	      top->value = (v1 != v2);	      top->unsignedp = 0;	      break;	    case LSH:	      top->unsignedp = unsigned1;	      if (v2 < 0 && ! unsigned2)		top->value = right_shift (pfile, v1, unsigned1, -v2);	      else		top->value = left_shift (pfile, v1, unsigned1, v2);	      break;	    case RSH:	      top->unsignedp = unsigned1;	      if (v2 < 0 && ! unsigned2)		top->value = left_shift (pfile, v1, unsigned1, -v2);	      else		top->value = right_shift (pfile, v1, unsigned1, v2);	      break;#define LOGICAL(OP) \	      top->value = v1 OP v2;\	      top->unsignedp = unsigned1 || unsigned2;	    case '&':  LOGICAL(&); break;	    case '^':  LOGICAL(^);  break;	    case '|':  LOGICAL(|);  break;	    case ANDAND:	      top->value = v1 && v2;  top->unsignedp = 0;  break;	    case OROR:	      top->value = v1 || v2;  top->unsignedp = 0;  break;	    case ',':	      if (CPP_PEDANTIC (pfile))		cpp_pedwarn (pfile, "comma operator in operand of `#if'");	      top->value = v2;	      top->unsignedp = unsigned2;	      break;	    case '(':  case '?':	      cpp_error (pfile, "syntax error in #if");	      goto syntax_error;	    case ':':	      if (top[0].op != '?')		{		  cpp_error (pfile,			     "syntax error ':' without preceding '?'");		  goto syntax_error;		}	      else if (! (top[1].flags & HAVE_VALUE)		       || !(top[-1].flags & HAVE_VALUE)		       || !(top[0].flags & HAVE_VALUE))		{		  cpp_error (pfile, "bad syntax for ?: operator");		  goto syntax_error;		}	      else		{		  top--;		  top->value = top->value ? v1 : v2;		  top->unsignedp = unsigned1 || unsigned2;		}	      break;	    case ')':	      if ((top[1].flags & HAVE_VALUE)		  || ! (top[0].flags & HAVE_VALUE)		  || top[0].op != '('		  || (top[-1].flags & HAVE_VALUE))		{		  cpp_error (pfile, "mismatched parentheses in #if");		  goto syntax_error;		}	      else		{		  top--;		  top->value = v1;		  top->unsignedp = unsigned1;		  top->flags |= HAVE_VALUE;		}	      break;	    default:	      fprintf (stderr,		       top[1].op >= ' ' && top[1].op <= '~'		       ? "unimplemented operator '%c'\n"		       : "unimplemented operator '\\%03o'\n",		       top[1].op);	    }	}      if (op.op == 0)	{	  if (top != stack)	    cpp_error (pfile, "internal error in #if expression");	  if (stack != init_stack)	    free (stack);	  return top->value;	}      top++;            /* Check for and handle stack overflow. */      if (top == limit)	{	  struct operation *new_stack;	  int old_size = (char*)limit - (char*)stack;	  int new_size = 2 * old_size;	  if (stack != init_stack)	    new_stack = (struct operation*) xrealloc (stack, new_size);	  else	    {	      new_stack = (struct operation*) xmalloc (new_size);	      bcopy ((char *) stack, (char *) new_stack, old_size);	    }	  stack = new_stack;	  top = (struct operation*)((char*) new_stack + old_size);	  limit = (struct operation*)((char*) new_stack + new_size);	}            top->flags = flags;      top->rprio = rprio;      top->op = op.op;    } syntax_error:  if (stack != init_stack)    free (stack);  skip_rest_of_line (pfile);  return 0;}

⌨️ 快捷键说明

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