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

📄 c-lex.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 4 页
字号:
  char long_flag;  char long_long_flag;};struct try_type type_sequence[] = {  { &integer_type_node, 0, 0, 0},  { &unsigned_type_node, 1, 0, 0},  { &long_integer_type_node, 0, 1, 0},  { &long_unsigned_type_node, 1, 1, 0},  { &long_long_integer_type_node, 0, 1, 1},  { &long_long_unsigned_type_node, 1, 1, 1}};#endif /* 0 */intyylex (){  register int c;  register char *p;  register int value;  int wide_flag = 0;  if (nextchar >= 0)    c = nextchar, nextchar = -1;  else    c = getc (finput);  /* 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 (finput);	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 '$':      if (dollars_in_ident)	goto letter;      return '$';    case 'L':      /* Capital L may start a wide-string or wide-character constant.  */      {	register int c = getc (finput);	if (c == '\'')	  {	    wide_flag = 1;	    goto char_constant;	  }	if (c == '"')	  {	    wide_flag = 1;	    goto string_constant;	  }	ungetc (c, finput);      }      goto letter;    case '@':      if (!doing_objc_thang)	{	  value = c;	  break;	}      p = token_buffer;      *p++ = '@';      c = getc (finput);      while (isalnum (c) || c == '_')	{	  if (p >= token_buffer + maxtoken)	    p = extend_token_buffer (p);	  *p++ = c;	  c = getc (finput);	}      *p = 0;      nextchar = c;      value = recognize_objc_keyword (token_buffer + 1);      if (value != 0)	break;      error ("invalid Objective C keyword `%s'", token_buffer);      /* Cause a syntax error--1 is not a valid token type.  */      value = 1;      break;    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 '_':    letter:      p = token_buffer;      while (isalnum (c) || c == '_' || c == '$' || c == '@')	{	  if (p >= token_buffer + maxtoken)	    p = extend_token_buffer (p);	  if (c == '$' && ! dollars_in_ident)	    break;	  *p++ = c;	  c = getc (finput);	}      *p = 0;      nextchar = c;      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;	    /* 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)	{          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)	    {	      yylval.ttype = DECL_INITIAL (lastiddecl);	      value = STRING;	    }          else if (doing_objc_thang)            {	      tree objc_interface_decl = lookup_interface (yylval.ttype);	      if (objc_interface_decl)		{		  value = CLASSNAME;		  yylval.ttype = objc_interface_decl;		}	    }	}      break;    case '0':  case '1':  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 (finput));	    if ((c == 'x') || (c == 'X'))	      {		base = 16;		*p++ = (c = getc (finput));	      }	    /* 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')		   && (floatflag == NOT_FLOAT || ((c != 'f') && (c != 'F')))))	  {	    if (c == '.')	      {		if (base == 16)		  error ("floating constant may not be in radix 16");		if (floatflag == AFTER_POINT)		  {		    error ("malformed floating constant");		    floatflag = TOO_MANY_POINTS;		  }		else		  floatflag = AFTER_POINT;		base = 10;		*p++ = c = getc (finput);		/* 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 (finput);			if (c == '.')			  {			    *p++ = c;			    *p = 0;			    return ELLIPSIS;			  }			error ("parse error at `..'");		      }		    ungetc (c, finput);		    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&~040) == '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 (finput));	      }	  }	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 garbage_chars = 0, exceeds_double = 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 (finput);		if ((c == '+') || (c == '-'))		  {		    *p++ = c;		    c = getc (finput);		  }		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 (finput);		  }	      }	    *p = 0;	    errno = 0;	    /* Convert string to a double, checking for overflow.  */	    if (setjmp (handler))	      {		error ("floating constant out of range");		value = dconst0;	      }	    else	      {		set_float_handler (handler);		value = REAL_VALUE_ATOF (token_buffer);		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))		  {		    pedwarn ("floating point number exceeds range of `double'");		    exceeds_double = 1;		  }	      }#endif	    /* Read the suffixes to choose a data type.  */	    switch (c)	      {	      case 'f': case 'F':		type = float_type_node;		value = REAL_VALUE_TRUNCATE (TYPE_MODE (type), value);		if (REAL_VALUE_ISINF (value) && ! exceeds_double && pedantic)		  pedwarn ("floating point number exceeds range of `float'");		garbage_chars = -1;		break;	      case 'l': case 'L':		type = long_double_type_node;		garbage_chars = -1;		break;	      }	    /* Note: garbage_chars is -1 if first char is *not* garbage.  */	    while (isalnum (c))	      {		if (p >= token_buffer + maxtoken - 3)		  p = extend_token_buffer (p);		*p++ = c;		c = getc (finput);		garbage_chars++;	      }	    if (garbage_chars > 0)	      error ("garbage at end of number");	    /* Create a node with determined type and value.  */	    yylval.ttype = build_real (type, value);	    ungetc (c, finput);	    *p = 0;	  }	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 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')		  {		    if (spec_long)		      {			if (spec_long_long)			  error ("three `l's in integer constant");			else if (pedantic)			  pedwarn ("ANSI C forbids long long integer constants");			spec_long_long = 1;		      }

⌨️ 快捷键说明

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