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

📄 c-lex.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 4 页
字号:
     it and ignore it; otherwise, ignore the line, with an error     if the word isn't `pragma', `ident', `define', or `undef'.  */  if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))    {      if (c == 'p')	{	  if (getc (finput) == 'r'	      && getc (finput) == 'a'	      && getc (finput) == 'g'	      && getc (finput) == 'm'	      && getc (finput) == 'a'	      && ((c = getc (finput)) == ' ' || c == '\t' || c == '\n'))	    {#ifdef HANDLE_SYSV_PRAGMA	      return handle_sysv_pragma (finput, c);#endif /* HANDLE_SYSV_PRAGMA */#ifdef HANDLE_PRAGMA	      HANDLE_PRAGMA (finput);#endif /* HANDLE_PRAGMA */	      goto skipline;	    }	}      else if (c == 'd')	{	  if (getc (finput) == 'e'	      && getc (finput) == 'f'	      && getc (finput) == 'i'	      && getc (finput) == 'n'	      && getc (finput) == 'e'	      && ((c = getc (finput)) == ' ' || c == '\t' || c == '\n'))	    {#ifdef DWARF_DEBUGGING_INFO	      if ((debug_info_level == DINFO_LEVEL_VERBOSE)		  && (write_symbols == DWARF_DEBUG))	        dwarfout_define (lineno, get_directive_line (finput));#endif /* DWARF_DEBUGGING_INFO */	      goto skipline;	    }	}      else if (c == 'u')	{	  if (getc (finput) == 'n'	      && getc (finput) == 'd'	      && getc (finput) == 'e'	      && getc (finput) == 'f'	      && ((c = getc (finput)) == ' ' || c == '\t' || c == '\n'))	    {#ifdef DWARF_DEBUGGING_INFO	      if ((debug_info_level == DINFO_LEVEL_VERBOSE)		  && (write_symbols == DWARF_DEBUG))	        dwarfout_undef (lineno, get_directive_line (finput));#endif /* DWARF_DEBUGGING_INFO */	      goto skipline;	    }	}      else if (c == 'l')	{	  if (getc (finput) == 'i'	      && getc (finput) == 'n'	      && getc (finput) == 'e'	      && ((c = getc (finput)) == ' ' || c == '\t'))	    goto linenum;	}      else if (c == 'i')	{	  if (getc (finput) == 'd'	      && getc (finput) == 'e'	      && getc (finput) == 'n'	      && getc (finput) == 't'	      && ((c = getc (finput)) == ' ' || c == '\t'))	    {	      /* #ident.  The pedantic warning is now in cccp.c.  */	      /* Here we have just seen `#ident '.		 A string constant should follow.  */	      while (c == ' ' || c == '\t')		c = getc (finput);	      /* If no argument, ignore the line.  */	      if (c == '\n')		return c;	      ungetc (c, finput);	      token = yylex ();	      if (token != STRING		  || TREE_CODE (yylval.ttype) != STRING_CST)		{		  error ("invalid #ident");		  goto skipline;		}	      if (!flag_no_ident)		{#ifdef ASM_OUTPUT_IDENT		  ASM_OUTPUT_IDENT (asm_out_file, TREE_STRING_POINTER (yylval.ttype));#endif		}	      /* Skip the rest of this line.  */	      goto skipline;	    }	}      error ("undefined or invalid # directive");      goto skipline;    }linenum:  /* Here we have either `#line' or `# <nonletter>'.     In either case, it should be a line number; a digit should follow.  */  while (c == ' ' || c == '\t')    c = getc (finput);  /* If the # is the only nonwhite char on the line,     just ignore it.  Check the new newline.  */  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, but don't treat \ as special.  */      ignore_escape_flag = 1;      token = yylex ();      ignore_escape_flag = 0;      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')	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;	    }	}      /* 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;    }  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 isalnum(char) ((char >= 'a' && char <= 'z') || (char >= 'A' && char <= 'Z') || (char >= '0' && char <= '9'))#define isdigit(char) (char >= '0' && char <= '9')#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;  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 '[':      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;

⌨️ 快捷键说明

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