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

📄 c-lex.c

📁 GCC编译器源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
  /* Effectively do c = skip_white_space (c)     but do it faster in the usual cases.  */  while (1)    switch (c)      {      case ' ':      case '\t':      case '\f':      case '\v':      case '\b':	c = GETC();	break;      case '\r':	/* Call skip_white_space so we can warn if appropriate.  */      case '\n':      case '/':      case '\\':	c = skip_white_space (c);      default:	goto found_nonwhite;      } found_nonwhite:  token_buffer[0] = c;  token_buffer[1] = 0;/*  yylloc.first_line = lineno; */  switch (c)    {    case EOF:      end_of_file = 1;      token_buffer[0] = 0;      value = ENDFILE;      break;    case 'L':      /* Capital L may start a wide-string or wide-character constant.  */      {	register int c = GETC();	if (c == '\'')	  {	    wide_flag = 1;	    goto char_constant;	  }	if (c == '"')	  {	    wide_flag = 1;	    goto string_constant;	  }	UNGETC (c);      }      goto letter;    case '@':      if (!doing_objc_thang)	{	  value = c;	  break;	}      else	{	  /* '@' may start a constant string object.  */	  register int c = GETC ();	  if (c == '"')	    {	      objc_flag = 1;	      goto string_constant;	    }	  UNGETC (c);	  /* Fall through to treat '@' as the start of an identifier.  */	}    case 'A':  case 'B':  case 'C':  case 'D':  case 'E':    case 'F':  case 'G':  case 'H':  case 'I':  case 'J':    case 'K':		  case 'M':  case 'N':  case 'O':    case 'P':  case 'Q':  case 'R':  case 'S':  case 'T':    case 'U':  case 'V':  case 'W':  case 'X':  case 'Y':    case 'Z':    case 'a':  case 'b':  case 'c':  case 'd':  case 'e':    case 'f':  case 'g':  case 'h':  case 'i':  case 'j':    case 'k':  case 'l':  case 'm':  case 'n':  case 'o':    case 'p':  case 'q':  case 'r':  case 's':  case 't':    case 'u':  case 'v':  case 'w':  case 'x':  case 'y':    case 'z':    case '_':    case '$':    letter:      p = token_buffer;      while (isalnum (c) || c == '_' || c == '$' || c == '@')	{	  /* Make sure this char really belongs in an identifier.  */	  if (c == '@' && ! doing_objc_thang)	    break;	  if (c == '$')	    {	      if (! dollars_in_ident)		error ("`$' in identifier");	      else if (pedantic)		pedwarn ("`$' in identifier");	    }	  if (p >= token_buffer + maxtoken)	    p = extend_token_buffer (p);	  *p++ = c;	  c = GETC();	}      *p = 0;#if USE_CPPLIB      UNGETC (c);#else      nextchar = c;#endif      value = IDENTIFIER;      yylval.itype = 0;      /* Try to recognize a keyword.  Uses minimum-perfect hash function */      {	register struct resword *ptr;	if (ptr = is_reserved_word (token_buffer, p - token_buffer))	  {	    if (ptr->rid)	      yylval.ttype = ridpointers[(int) ptr->rid];	    value = (int) ptr->token;	    /* Only return OBJECTNAME if it is a typedef.  */	    if (doing_objc_thang && value == OBJECTNAME)	      {		lastiddecl = lookup_name(yylval.ttype);		if (lastiddecl == NULL_TREE		    || TREE_CODE (lastiddecl) != TYPE_DECL)		  value = IDENTIFIER;	      }	    /* Even if we decided to recognize asm, still perhaps warn.  */	    if (pedantic		&& (value == ASM_KEYWORD || value == TYPEOF		    || ptr->rid == RID_INLINE)		&& token_buffer[0] != '_')	      pedwarn ("ANSI does not permit the keyword `%s'",		       token_buffer);	  }      }      /* If we did not find a keyword, look for an identifier	 (or a typename).  */      if (value == IDENTIFIER)	{ 	  if (token_buffer[0] == '@')	    error("invalid identifier `%s'", token_buffer);          yylval.ttype = get_identifier (token_buffer);	  lastiddecl = lookup_name (yylval.ttype);	  if (lastiddecl != 0 && TREE_CODE (lastiddecl) == TYPE_DECL)	    value = TYPENAME;	  /* A user-invisible read-only initialized variable	     should be replaced by its value.	     We handle only strings since that's the only case used in C.  */	  else if (lastiddecl != 0 && TREE_CODE (lastiddecl) == VAR_DECL		   && DECL_IGNORED_P (lastiddecl)		   && TREE_READONLY (lastiddecl)		   && DECL_INITIAL (lastiddecl) != 0		   && TREE_CODE (DECL_INITIAL (lastiddecl)) == STRING_CST)	    {	      tree stringval = DECL_INITIAL (lastiddecl);	      	      /* Copy the string value so that we won't clobber anything		 if we put something in the TREE_CHAIN of this one.  */	      yylval.ttype = build_string (TREE_STRING_LENGTH (stringval),					   TREE_STRING_POINTER (stringval));	      value = STRING;	    }          else if (doing_objc_thang)            {	      tree objc_interface_decl = is_class_name (yylval.ttype);	      if (objc_interface_decl)		{		  value = CLASSNAME;		  yylval.ttype = objc_interface_decl;		}	    }	}      break;    case '0':  case '1':      {	int next_c;	/* Check first for common special case:  single-digit 0 or 1.  */	next_c = GETC ();	UNGETC (next_c);	/* Always undo this lookahead.  */	if (!isalnum (next_c) && next_c != '.')	  {	    token_buffer[0] = (char)c,  token_buffer[1] = '\0';	    yylval.ttype = (c == '0') ? integer_zero_node : integer_one_node;	    value = CONSTANT;	    break;	  }	/*FALLTHRU*/      }    case '2':  case '3':  case '4':    case '5':  case '6':  case '7':  case '8':  case '9':    case '.':      {	int base = 10;	int count = 0;	int largest_digit = 0;	int numdigits = 0;	/* for multi-precision arithmetic,	   we actually store only HOST_BITS_PER_CHAR bits in each part.	   The number of parts is chosen so as to be sufficient to hold	   the enough bits to fit into the two HOST_WIDE_INTs that contain	   the integer value (this is always at least as many bits as are	   in a target `long long' value, but may be wider).  */#define TOTAL_PARTS ((HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR) * 2 + 2)	int parts[TOTAL_PARTS];	int overflow = 0;	enum anon1 { NOT_FLOAT, AFTER_POINT, TOO_MANY_POINTS} floatflag	  = NOT_FLOAT;	for (count = 0; count < TOTAL_PARTS; count++)	  parts[count] = 0;	p = token_buffer;	*p++ = c;	if (c == '0')	  {	    *p++ = (c = GETC());	    if ((c == 'x') || (c == 'X'))	      {		base = 16;		*p++ = (c = GETC());	      }	    /* Leading 0 forces octal unless the 0 is the only digit.  */	    else if (c >= '0' && c <= '9')	      {		base = 8;		numdigits++;	      }	    else	      numdigits++;	  }	/* Read all the digits-and-decimal-points.  */	while (c == '.'	       || (isalnum (c) && c != 'l' && c != 'L'		   && c != 'u' && c != 'U'		   && c != 'i' && c != 'I' && c != 'j' && c != 'J'		   && (floatflag == NOT_FLOAT || ((c != 'f') && (c != 'F')))))	  {	    if (c == '.')	      {		if (base == 16)		  error ("floating constant may not be in radix 16");		if (floatflag == TOO_MANY_POINTS)		  /* We have already emitted an error.  Don't need another.  */		  ;		else if (floatflag == AFTER_POINT)		  {		    error ("malformed floating constant");		    floatflag = TOO_MANY_POINTS;		    /* Avoid another error from atof by forcing all characters		       from here on to be ignored.  */		    p[-1] = '\0';		  }		else		  floatflag = AFTER_POINT;		base = 10;		*p++ = c = GETC();		/* Accept '.' as the start of a floating-point number		   only when it is followed by a digit.		   Otherwise, unread the following non-digit		   and use the '.' as a structural token.  */		if (p == token_buffer + 2 && !isdigit (c))		  {		    if (c == '.')		      {			c = GETC();			if (c == '.')			  {			    *p++ = c;			    *p = 0;			    return ELLIPSIS;			  }			error ("parse error at `..'");		      }		    UNGETC (c);		    token_buffer[1] = 0;		    value = '.';		    goto done;		  }	      }	    else	      {		/* It is not a decimal point.		   It should be a digit (perhaps a hex digit).  */		if (isdigit (c))		  {		    c = c - '0';		  }		else if (base <= 10)		  {		    if (c == 'e' || c == 'E')		      {			base = 10;			floatflag = AFTER_POINT;			break;   /* start of exponent */		      }		    error ("nondigits in number and not hexadecimal");		    c = 0;		  }		else if (c >= 'a')		  {		    c = c - 'a' + 10;		  }		else		  {		    c = c - 'A' + 10;		  }		if (c >= largest_digit)		  largest_digit = c;		numdigits++;		for (count = 0; count < TOTAL_PARTS; count++)		  {		    parts[count] *= base;		    if (count)		      {			parts[count]			  += (parts[count-1] >> HOST_BITS_PER_CHAR);			parts[count-1]			  &= (1 << HOST_BITS_PER_CHAR) - 1;		      }		    else		      parts[0] += c;		  }		/* If the extra highest-order part ever gets anything in it,		   the number is certainly too big.  */		if (parts[TOTAL_PARTS - 1] != 0)		  overflow = 1;		if (p >= token_buffer + maxtoken - 3)		  p = extend_token_buffer (p);		*p++ = (c = GETC());	      }	  }	if (numdigits == 0)	  error ("numeric constant with no digits");	if (largest_digit >= base)	  error ("numeric constant contains digits beyond the radix");	/* Remove terminating char from the token buffer and delimit the string */	*--p = 0;	if (floatflag != NOT_FLOAT)	  {	    tree type = double_type_node;	    int exceeds_double = 0;	    int imag = 0;	    REAL_VALUE_TYPE value;	    jmp_buf handler;	    /* Read explicit exponent if any, and put it in tokenbuf.  */	    if ((c == 'e') || (c == 'E'))	      {		if (p >= token_buffer + maxtoken - 3)		  p = extend_token_buffer (p);		*p++ = c;		c = GETC();		if ((c == '+') || (c == '-'))		  {		    *p++ = c;		    c = GETC();		  }		if (! isdigit (c))		  error ("floating constant exponent has no digits");	        while (isdigit (c))		  {		    if (p >= token_buffer + maxtoken - 3)		      p = extend_token_buffer (p);		    *p++ = c;		    c = GETC();		  }	      }	    *p = 0;	    errno = 0;	    /* Convert string to a double, checking for overflow.  */	    if (setjmp (handler))	      {		error ("floating constant out of range");		value = dconst0;	      }	    else	      {		int fflag = 0, lflag = 0;		/* Copy token_buffer now, while it has just the number		   and not the suffixes; once we add `f' or `i',		   REAL_VALUE_ATOF may not work any more.  */		char *copy = (char *) alloca (p - token_buffer + 1);		bcopy (token_buffer, copy, p - token_buffer + 1);		set_float_handler (handler);		while (1)		  {		    int lose = 0;		    /* Read the suffixes to choose a data type.  */		    switch (c)		      {		      case 'f': case 'F':			if (fflag)			  error ("more than one `f' in numeric constant");			fflag = 1;			break;		      case 'l': case 'L':			if (lflag)			  error ("more than one `l' in numeric constant");			lflag = 1;			break;		      case 'i': case 'I':			if (imag)			  error ("more than one `i' or `j' in numeric constant");			else if (pedantic)			  pedwarn ("ANSI C forbids imaginary numeric constants");			imag = 1;			break;		      default:			lose = 1;		      }		    if (lose)		      break;		    if (p >= token_buffer + maxtoken - 3)		      p = extend_token_buffer (p);		    *p++ = c;		    *p = 0;		    c = GETC();		  }		/* The second argument, machine_mode, of REAL_VALUE_ATOF		   tells the desired precision of the binary result		   of decimal-to-binary conversion.  */		if (fflag)		  {		    if (lflag)		      error ("both `f' and `l' in floating constant");		    type = float_type_node;		    value = REAL_VALUE_ATOF (copy, TYPE_MODE (type));		    /* A diagnostic is required here by some ANSI C testsuites.		       This is not pedwarn, become some people don't want		       an error for this.  */		    if (REAL_VALUE_ISINF (value) && pedantic)		      warning ("floating point number exceeds range of `float'");		  }		else if (lflag)		  {		    type = long_double_type_node;		    value = REAL_VALUE_ATOF (copy, TYPE_MODE (type));		    if (REAL_VALUE_ISINF (value) && pedantic)		      warning ("floating point number exceeds range of `long double'");		  }		else		  {		    value = REAL_VALUE_ATOF (copy, TYPE_MODE (type));		    if (REAL_VALUE_ISINF (value) && pedantic)		      warning ("floating point number exceeds range of `double'");		  }		set_float_handler (NULL_PTR);	    }#ifdef ERANGE	    if (errno == ERANGE && !flag_traditional && pedantic)	      {  		/* ERANGE is also reported for underflow,  		   so test the value to distinguish overflow from that.  */		if (REAL_VALUES_LESS (dconst1, value)		    || REAL_VALUES_LESS (value, dconstm1))		  {		    warning ("floating point number exceeds range of `double'");		    exceeds_double = 1;		  }	      }#endif	    /* If the result is not a number, assume it must have been	       due to some error message above, so silently convert	       it to a zero.  */	    if (REAL_VALUE_ISNAN (value))	      value = dconst0;	    /* Create a node with determined type and value.  */	    if (imag)	      yylval.ttype = build_complex (NULL_TREE,					    convert (type, integer_zero_node),					    build_real (type, value));	    else	      yylval.ttype = build_real (type, value);	  }	else	  {	    tree traditional_type, ansi_type, type;	    HOST_WIDE_INT high, low;	    int spec_unsigned = 0;	    int spec_long = 0;	    int spec_long_long = 0;	    int spec_imag = 0;	    int bytes, warn, i;	    while (1)	      {		if (c == 'u' || c == 'U')		  {		    if (spec_unsigned)		      error ("two `u's in integer constant");		    spec_unsigned = 1;		  }		else if (c == 'l' || c == 'L')		  {

⌨️ 快捷键说明

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