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

📄 c-lex.c

📁 gcc库的原代码,对编程有很大帮助.
💻 C
📖 第 1 页 / 共 4 页
字号:
	      bytes = TYPE_PRECISION (long_long_integer_type_node) / 8;	    else	      bytes = TYPE_PRECISION (long_integer_type_node) / 8;	    warn = overflow;	    for (i = bytes; i < TOTAL_PARTS; i++)	      if (parts[i])		warn = 1;	    if (warn)	      pedwarn ("integer constant out of range");	    /* This is simplified by the fact that our constant	       is always positive.  */	    high = low = 0;	    for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR; i++)	      {		high |= ((HOST_WIDE_INT) parts[i + (HOST_BITS_PER_WIDE_INT						    / HOST_BITS_PER_CHAR)]			 << (i * HOST_BITS_PER_CHAR));		low |= (HOST_WIDE_INT) parts[i] << (i * HOST_BITS_PER_CHAR);	      }	    	    yylval.ttype = build_int_2 (low, high);	    TREE_TYPE (yylval.ttype) = long_long_unsigned_type_node;	    /* If warn_traditional, calculate both the ANSI type and the	       traditional type, then see if they disagree.	       Otherwise, calculate only the type for the dialect in use.  */	    if (warn_traditional || flag_traditional)	      {		/* Calculate the traditional type.  */		/* Traditionally, any constant is signed;		   but if unsigned is specified explicitly, obey that.		   Use the smallest size with the right number of bits,		   except for one special case with decimal constants.  */		if (! spec_long && base != 10		    && int_fits_type_p (yylval.ttype, unsigned_type_node))		  traditional_type = (spec_unsigned ? unsigned_type_node				      : integer_type_node);		/* A decimal constant must be long		   if it does not fit in type int.		   I think this is independent of whether		   the constant is signed.  */		else if (! spec_long && base == 10			 && int_fits_type_p (yylval.ttype, integer_type_node))		  traditional_type = (spec_unsigned ? unsigned_type_node				      : integer_type_node);		else if (! spec_long_long)		  traditional_type = (spec_unsigned ? long_unsigned_type_node				      : long_integer_type_node);		else		  traditional_type = (spec_unsigned				      ? long_long_unsigned_type_node				      : long_long_integer_type_node);	      }	    if (warn_traditional || ! flag_traditional)	      {		/* Calculate the ANSI type.  */		if (! spec_long && ! spec_unsigned		    && int_fits_type_p (yylval.ttype, integer_type_node))		  ansi_type = integer_type_node;		else if (! spec_long && (base != 10 || spec_unsigned)			 && int_fits_type_p (yylval.ttype, unsigned_type_node))		  ansi_type = unsigned_type_node;		else if (! spec_unsigned && !spec_long_long			 && int_fits_type_p (yylval.ttype, long_integer_type_node))		  ansi_type = long_integer_type_node;		else if (! spec_long_long)		  ansi_type = long_unsigned_type_node;		else if (! spec_unsigned			 /* Verify value does not overflow into sign bit.  */			 && TREE_INT_CST_HIGH (yylval.ttype) >= 0			 && int_fits_type_p (yylval.ttype,					     long_long_integer_type_node))		  ansi_type = long_long_integer_type_node;		else		  ansi_type = long_long_unsigned_type_node;	      }	    type = flag_traditional ? traditional_type : ansi_type;	    if (warn_traditional && traditional_type != ansi_type)	      {		if (TYPE_PRECISION (traditional_type)		    != TYPE_PRECISION (ansi_type))		  warning ("width of integer constant changes with -traditional");		else if (TREE_UNSIGNED (traditional_type)			 != TREE_UNSIGNED (ansi_type))		  warning ("integer constant is unsigned in ANSI C, signed with -traditional");		else		  warning ("width of integer constant may change on other systems with -traditional");	      }	    if (!flag_traditional && !int_fits_type_p (yylval.ttype, type)		&& !warn)	      pedwarn ("integer constant out of range");	    if (base == 10 && ! spec_unsigned && TREE_UNSIGNED (type))	      warning ("decimal constant is so large that it is unsigned");	    if (spec_imag)	      {		if (TYPE_PRECISION (type)		    <= TYPE_PRECISION (integer_type_node))		  yylval.ttype		    = build_complex (integer_zero_node,				     convert (integer_type_node, yylval.ttype));		else		  error ("complex integer constant is too wide for `complex int'");	      }	    else if (flag_traditional && !int_fits_type_p (yylval.ttype, type))	      /* The traditional constant 0x80000000 is signed		 but doesn't fit in the range of int.		 This will change it to -0x80000000, which does fit.  */	      {		TREE_TYPE (yylval.ttype) = unsigned_type (type);		yylval.ttype = convert (type, yylval.ttype);		TREE_OVERFLOW (yylval.ttype)		  = TREE_CONSTANT_OVERFLOW (yylval.ttype) = 0;	      }	    else	      TREE_TYPE (yylval.ttype) = type;	    *p = 0;	  }	value = CONSTANT; break;      }    case '\'':    char_constant:      {	register int result = 0;	register int num_chars = 0;	unsigned width = TYPE_PRECISION (char_type_node);	int max_chars;	if (wide_flag)	  {	    width = WCHAR_TYPE_SIZE;#ifdef MULTIBYTE_CHARS	    max_chars = MB_CUR_MAX;#else	    max_chars = 1;#endif	  }	else	  max_chars = TYPE_PRECISION (integer_type_node) / width;	while (1)	  {	  tryagain:	    c = getc (finput);	    if (c == '\'' || c == EOF)	      break;	    if (c == '\\')	      {		int ignore = 0;		c = readescape (&ignore);		if (ignore)		  goto tryagain;		if (width < HOST_BITS_PER_INT		    && (unsigned) c >= (1 << width))		  pedwarn ("escape sequence out of range for character");#ifdef MAP_CHARACTER		if (isprint (c))		  c = MAP_CHARACTER (c);#endif	      }	    else if (c == '\n')	      {		if (pedantic)		  pedwarn ("ANSI C forbids newline in character constant");		lineno++;	      }#ifdef MAP_CHARACTER	    else	      c = MAP_CHARACTER (c);#endif	    num_chars++;	    if (num_chars > maxtoken - 4)	      extend_token_buffer (token_buffer);	    token_buffer[num_chars] = c;	    /* 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] = '\'';	token_buffer[num_chars + 2] = 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 && ! flag_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 (num_bits == 0)	      /* We already got an error; avoid invalid shift.  */	      yylval.ttype = build_int_2 (0, 0);	    else if (TREE_UNSIGNED (char_type_node)		     || ((result >> (num_bits - 1)) & 1) == 0)	      yylval.ttype		= build_int_2 (result & ((unsigned HOST_WIDE_INT) ~0					 >> (HOST_BITS_PER_WIDE_INT - num_bits)),			       0);	    else	      yylval.ttype		= build_int_2 (result | ~((unsigned HOST_WIDE_INT) ~0					  >> (HOST_BITS_PER_WIDE_INT - num_bits)),			       -1);	    TREE_TYPE (yylval.ttype) = integer_type_node;	  }	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[1] != '\0'))	      {		wchar_t wc;		(void) mbtowc (NULL_PTR, NULL_PTR, 0);		if (mbtowc (& wc, token_buffer + 1, num_chars) == num_chars)		  result = wc;		else		  warning ("Ignoring invalid multibyte character");	      }#endif	    yylval.ttype = build_int_2 (result, 0);	    TREE_TYPE (yylval.ttype) = wchar_type_node;	  }	value = CONSTANT;	break;      }    case '"':    string_constant:      {	c = getc (finput);	p = token_buffer + 1;	while (c != '"' && c >= 0)	  {	    if (c == '\\')	      {		int ignore = 0;		c = readescape (&ignore);		if (ignore)		  goto skipnewline;		if (!wide_flag		    && TYPE_PRECISION (char_type_node) < HOST_BITS_PER_INT		    && c >= (1 << TYPE_PRECISION (char_type_node)))		  pedwarn ("escape sequence out of range for character");	      }	    else if (c == '\n')	      {		if (pedantic)		  pedwarn ("ANSI C forbids newline in string constant");		lineno++;	      }	    if (p == token_buffer + maxtoken)	      p = extend_token_buffer (p);	    *p++ = c;	  skipnewline:	    c = getc (finput);	  }	*p = 0;	if (c < 0)	  error ("Unterminated string constant");	/* We have read the entire constant.	   Construct a STRING_CST for the result.  */	if (wide_flag)	  {	    /* If this is a L"..." wide-string, convert the multibyte string	       to a wide character string.  */	    char *widep = (char *) alloca ((p - token_buffer) * WCHAR_BYTES);	    int len;#ifdef MULTIBYTE_CHARS	    len = mbstowcs ((wchar_t *) widep, token_buffer + 1, p - token_buffer);	    if (len < 0 || len >= (p - token_buffer))	      {		warning ("Ignoring invalid multibyte string");		len = 0;	      }	    bzero (widep + (len * WCHAR_BYTES), WCHAR_BYTES);#else	    {	      union { long l; char c[sizeof (long)]; } u;	      int big_endian;	      char *wp, *cp;	      /* Determine whether host is little or big endian.  */	      u.l = 1;	      big_endian = u.c[sizeof (long) - 1];	      wp = widep + (big_endian ? WCHAR_BYTES - 1 : 0);	      bzero (widep, (p - token_buffer) * WCHAR_BYTES);	      for (cp = token_buffer + 1; cp < p; cp++)		*wp = *cp, wp += WCHAR_BYTES;	      len = p - token_buffer - 1;	    }#endif	    yylval.ttype = build_string ((len + 1) * WCHAR_BYTES, widep);	    TREE_TYPE (yylval.ttype) = wchar_array_type_node;	    value = STRING;	  }	else if (objc_flag)	  {	    extern tree build_objc_string();	    /* Return an Objective-C @"..." constant string object.  */	    yylval.ttype = build_objc_string (p - token_buffer,					      token_buffer + 1);	    TREE_TYPE (yylval.ttype) = char_array_type_node;	    value = OBJC_STRING;	  }	else	  {	    yylval.ttype = build_string (p - token_buffer, token_buffer + 1);	    TREE_TYPE (yylval.ttype) = char_array_type_node;	    value = STRING;	  }	*p++ = '"';	*p = 0;	break;      }    case '+':    case '-':    case '&':    case '|':    case ':':    case '<':    case '>':    case '*':    case '/':    case '%':    case '^':    case '!':    case '=':      {	register int c1;      combine:	switch (c)	  {	  case '+':	    yylval.code = PLUS_EXPR; break;	  case '-':	    yylval.code = MINUS_EXPR; break;	  case '&':	    yylval.code = BIT_AND_EXPR; break;	  case '|':	    yylval.code = BIT_IOR_EXPR; break;	  case '*':	    yylval.code = MULT_EXPR; break;	  case '/':	    yylval.code = TRUNC_DIV_EXPR; break;	  case '%':	    yylval.code = TRUNC_MOD_EXPR; break;	  case '^':	    yylval.code = BIT_XOR_EXPR; break;	  case LSHIFT:	    yylval.code = LSHIFT_EXPR; break;	  case RSHIFT:	    yylval.code = RSHIFT_EXPR; break;	  case '<':	    yylval.code = LT_EXPR; break;	  case '>':	    yylval.code = GT_EXPR; break;	  }	token_buffer[1] = c1 = getc (finput);	token_buffer[2] = 0;	if (c1 == '=')	  {	    switch (c)	      {	      case '<':		value = ARITHCOMPARE; yylval.code = LE_EXPR; goto done;	      case '>':		value = ARITHCOMPARE; yylval.code = GE_EXPR; goto done;	      case '!':		value = EQCOMPARE; yylval.code = NE_EXPR; goto done;	      case '=':		value = EQCOMPARE; yylval.code = EQ_EXPR; goto done;	      }	    value = ASSIGN; goto done;	  }	else if (c == c1)	  switch (c)	    {	    case '+':	      value = PLUSPLUS; goto done;	    case '-':	      value = MINUSMINUS; goto done;	    case '&':	      value = ANDAND; goto done;	    case '|':	      value = OROR; goto done;	    case '<':	      c = LSHIFT;	      goto combine;	    case '>':	      c = RSHIFT;	      goto combine;	    }	else	  switch (c)	    {	    case '-':	      if (c1 == '>')		{ value = POINTSAT; goto done; }	      break;	    case ':':	      if (c1 == '>')		{ value = ']'; goto done; }	      break;	    case '<':	      if (c1 == '%')		{ value = '{'; goto done; }	      if (c1 == ':')		{ value = '['; goto done; }	      break;	    case '%':	      if (c1 == '>')		{ value = '}'; goto done; }	      break;	    }	ungetc (c1, finput);	token_buffer[1] = 0;	if ((c == '<') || (c == '>'))	  value = ARITHCOMPARE;	else value = c;	goto done;      }    case 0:      /* Don't make yyparse think this is eof.  */      value = 1;      break;    default:      value = c;    }done:/*  yylloc.last_line = lineno; */  return value;}/* Sets the value of the 'yydebug' variable to VALUE.   This is a function so we don't have to have YYDEBUG defined   in order to build the compiler.  */voidset_yydebug (value)     int value;{#if YYDEBUG != 0  yydebug = value;#else  warning ("YYDEBUG not defined.");#endif}

⌨️ 快捷键说明

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