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

📄 c-lex.c

📁 gcc库的原代码,对编程有很大帮助.
💻 C
📖 第 1 页 / 共 4 页
字号:
  if (c == '\n')    return c;  /* Something follows the #; read a token.  */  ungetc (c, finput);  token = yylex ();  if (token == CONSTANT      && TREE_CODE (yylval.ttype) == INTEGER_CST)    {      int old_lineno = lineno;      int used_up = 0;      /* subtract one, because it is the following line that	 gets the specified number */      int l = TREE_INT_CST_LOW (yylval.ttype) - 1;      /* Is this the last nonwhite stuff on the line?  */      c = getc (finput);      while (c == ' ' || c == '\t')	c = getc (finput);      if (c == '\n')	{	  /* No more: store the line number and check following line.  */	  lineno = l;	  return c;	}      ungetc (c, finput);      /* More follows: it must be a string constant (filename).  */      /* Read the string constant.  */      token = yylex ();      if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)	{	  error ("invalid #line");	  goto skipline;	}      input_filename	= (char *) permalloc (TREE_STRING_LENGTH (yylval.ttype) + 1);      strcpy (input_filename, TREE_STRING_POINTER (yylval.ttype));      lineno = l;      /* Each change of file name	 reinitializes whether we are now in a system header.  */      in_system_header = 0;      if (main_input_filename == 0)	main_input_filename = input_filename;      /* Is this the last nonwhite stuff on the line?  */      c = getc (finput);      while (c == ' ' || c == '\t')	c = getc (finput);      if (c == '\n')	{	  /* Update the name in the top element of input_file_stack.  */	  if (input_file_stack)	    input_file_stack->name = input_filename;	  return c;	}      ungetc (c, finput);      token = yylex ();      used_up = 0;      /* `1' after file name means entering new file.	 `2' after file name means just left a file.  */      if (token == CONSTANT	  && TREE_CODE (yylval.ttype) == INTEGER_CST)	{	  if (TREE_INT_CST_LOW (yylval.ttype) == 1)	    {	      /* Pushing to a new file.  */	      struct file_stack *p		= (struct file_stack *) xmalloc (sizeof (struct file_stack));	      input_file_stack->line = old_lineno;	      p->next = input_file_stack;	      p->name = input_filename;	      input_file_stack = p;	      input_file_stack_tick++;#ifdef DWARF_DEBUGGING_INFO	      if (debug_info_level == DINFO_LEVEL_VERBOSE		  && write_symbols == DWARF_DEBUG)		dwarfout_start_new_source_file (input_filename);#endif /* DWARF_DEBUGGING_INFO */	      used_up = 1;	    }	  else if (TREE_INT_CST_LOW (yylval.ttype) == 2)	    {	      /* Popping out of a file.  */	      if (input_file_stack->next)		{		  struct file_stack *p = input_file_stack;		  input_file_stack = p->next;		  free (p);		  input_file_stack_tick++;#ifdef DWARF_DEBUGGING_INFO		  if (debug_info_level == DINFO_LEVEL_VERBOSE		      && write_symbols == DWARF_DEBUG)		    dwarfout_resume_previous_source_file (input_file_stack->line);#endif /* DWARF_DEBUGGING_INFO */		}	      else		error ("#-lines for entering and leaving files don't match");	      used_up = 1;	    }	}      /* Now that we've pushed or popped the input stack,	 update the name in the top element.  */      if (input_file_stack)	input_file_stack->name = input_filename;      /* If we have handled a `1' or a `2',	 see if there is another number to read.  */      if (used_up)	{	  /* Is this the last nonwhite stuff on the line?  */	  c = getc (finput);	  while (c == ' ' || c == '\t')	    c = getc (finput);	  if (c == '\n')	    return c;	  ungetc (c, finput);	  token = yylex ();	  used_up = 0;	}      /* `3' after file name means this is a system header file.  */      if (token == CONSTANT	  && TREE_CODE (yylval.ttype) == INTEGER_CST	  && TREE_INT_CST_LOW (yylval.ttype) == 3)	in_system_header = 1, used_up = 1;      if (used_up)	{	  /* Is this the last nonwhite stuff on the line?  */	  c = getc (finput);	  while (c == ' ' || c == '\t')	    c = getc (finput);	  if (c == '\n')	    return c;	  ungetc (c, finput);	}      warning ("unrecognized text at end of #line");    }  else    error ("invalid #-line");  /* skip the rest of this line.  */ skipline:  if (c == '\n')    return c;  while ((c = getc (finput)) != EOF && c != '\n');  return c;}#ifdef HANDLE_SYSV_PRAGMA/* Handle a #pragma directive.  INPUT is the current input stream,   and C is a character to reread.  Processes the entire input line   and returns a character for the caller to reread: either \n or EOF.  *//* This function has to be in this file, in order to get at   the token types.  */inthandle_sysv_pragma (input, c)     FILE *input;     int c;{  for (;;)    {      while (c == ' ' || c == '\t')	c = getc (input);      if (c == '\n' || c == EOF)	{	  handle_pragma_token (0, 0);	  return c;	}      ungetc (c, input);      switch (yylex ())	{	case IDENTIFIER:	case TYPENAME:	case STRING:	case CONSTANT:	  handle_pragma_token (token_buffer, yylval.ttype);	  break;	default:	  handle_pragma_token (token_buffer, 0);	}      if (nextchar >= 0)	c = nextchar, nextchar = -1;      else	c = getc (input);    }}#endif /* HANDLE_SYSV_PRAGMA */#define ENDFILE -1  /* token that represents end-of-file *//* Read an escape sequence, returning its equivalent as a character,   or store 1 in *ignore_ptr if it is backslash-newline.  */static intreadescape (ignore_ptr)     int *ignore_ptr;{  register int c = getc (finput);  register int code;  register unsigned count;  unsigned firstdig = 0;  int nonnull;  switch (c)    {    case 'x':      if (warn_traditional)	warning ("the meaning of `\\x' varies with -traditional");      if (flag_traditional)	return c;      code = 0;      count = 0;      nonnull = 0;      while (1)	{	  c = getc (finput);	  if (!(c >= 'a' && c <= 'f')	      && !(c >= 'A' && c <= 'F')	      && !(c >= '0' && c <= '9'))	    {	      ungetc (c, finput);	      break;	    }	  code *= 16;	  if (c >= 'a' && c <= 'f')	    code += c - 'a' + 10;	  if (c >= 'A' && c <= 'F')	    code += c - 'A' + 10;	  if (c >= '0' && c <= '9')	    code += c - '0';	  if (code != 0 || count != 0)	    {	      if (count == 0)		firstdig = code;	      count++;	    }	  nonnull = 1;	}      if (! nonnull)	error ("\\x used with no following hex digits");      else if (count == 0)	/* Digits are all 0's.  Ok.  */	;      else if ((count - 1) * 4 >= TYPE_PRECISION (integer_type_node)	       || (count > 1		   && ((1 << (TYPE_PRECISION (integer_type_node) - (count - 1) * 4))		       <= firstdig)))	pedwarn ("hex escape out of range");      return code;    case '0':  case '1':  case '2':  case '3':  case '4':    case '5':  case '6':  case '7':      code = 0;      count = 0;      while ((c <= '7') && (c >= '0') && (count++ < 3))	{	  code = (code * 8) + (c - '0');	  c = getc (finput);	}      ungetc (c, finput);      return code;    case '\\': case '\'': case '"':      return c;    case '\n':      lineno++;      *ignore_ptr = 1;      return 0;    case 'n':      return TARGET_NEWLINE;    case 't':      return TARGET_TAB;    case 'r':      return TARGET_CR;    case 'f':      return TARGET_FF;    case 'b':      return TARGET_BS;    case 'a':      if (warn_traditional)	warning ("the meaning of `\\a' varies with -traditional");      if (flag_traditional)	return c;      return TARGET_BELL;    case 'v':#if 0 /* Vertical tab is present in common usage compilers.  */      if (flag_traditional)	return c;#endif      return TARGET_VT;    case 'e':    case 'E':      if (pedantic)	pedwarn ("non-ANSI-standard escape sequence, `\\%c'", c);      return 033;    case '?':      return c;      /* `\(', etc, are used at beginning of line to avoid confusing Emacs.  */    case '(':    case '{':    case '[':      /* `\%' is used to prevent SCCS from getting confused.  */    case '%':      if (pedantic)	pedwarn ("non-ANSI escape sequence `\\%c'", c);      return c;    }  if (c >= 040 && c < 0177)    pedwarn ("unknown escape sequence `\\%c'", c);  else    pedwarn ("unknown escape sequence: `\\' followed by char code 0x%x", c);  return c;}voidyyerror (string)     char *string;{  char buf[200];  strcpy (buf, string);  /* We can't print string and character constants well     because the token_buffer contains the result of processing escapes.  */  if (end_of_file)    strcat (buf, " at end of input");  else if (token_buffer[0] == 0)    strcat (buf, " at null character");  else if (token_buffer[0] == '"')    strcat (buf, " before string constant");  else if (token_buffer[0] == '\'')    strcat (buf, " before character constant");  else if (token_buffer[0] < 040 || (unsigned char) token_buffer[0] >= 0177)    sprintf (buf + strlen (buf), " before character 0%o",	     (unsigned char) token_buffer[0]);  else    strcat (buf, " before `%s'");  error (buf, token_buffer);}#if 0struct try_type{  tree *node_var;  char unsigned_flag;  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;  int objc_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;	}      else	{	  /* '@' may start a constant string object.  */	  register int c = getc(finput);	  if (c == '"')	    {	      objc_flag = 1;	      goto string_constant;	    }	  ungetc(c, finput);	  /* 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':

⌨️ 快捷键说明

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