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

📄 cp-lex.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
	case '\r':	case '\v':	case '\b':	  do	    c = getch ();	  while (c == ' ' || c == '\t');	  break;	case '\\':	  c = getch ();	  if (c == '\n')	    lineno++;	  else	    error ("stray '\\' in program");	  c = getch ();	  break;	default:	  return (c);	}    }}/* Make the token buffer longer, preserving the data in it.   P should point to just beyond the last valid character in the old buffer.   The value we return is a pointer to the new buffer   at a place corresponding to P.  */static char *extend_token_buffer (p)     char *p;{  int offset = p - token_buffer;  maxtoken = maxtoken * 2 + 10;  token_buffer = (char *) xrealloc (token_buffer, maxtoken + 2);  return token_buffer + offset;}static intget_last_nonwhite_on_line (){  register int c;  /* Is this the last nonwhite stuff on the line?  */  if (nextchar >= 0)    c = nextchar, nextchar = -1;  else    c = getch ();  while (c == ' ' || c == '\t')    c = getch ();  return c;}/* At the beginning of a line, increment the line number   and process any #-directive on this line.   If the line is a #-directive, read the entire line and return a newline.   Otherwise, return the line's first non-whitespace character.  */intcheck_newline (){  register int c;  register int token;  lineno++;  /* Read first nonwhite char on the line.  */  do    c = getch ();  while (c == ' ' || c == '\t');  if (c != '#')    {      /* If not #, return it so caller will use it.  */      return c;    }  /* Read first nonwhite char after the `#'.  */  do    c = getch ();  while (c == ' ' || c == '\t');  /* If a letter follows, then if the word here is `line', skip     it and ignore it; otherwise, ignore the line, with an error     if the word isn't `pragma'.  */  if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))    {      if (c == 'p')	{	  if (getch () == 'r'	      && getch () == 'a'	      && getch () == 'g'	      && getch () == 'm'	      && getch () == 'a')	    {	      /* Read first nonwhite char after the `#pragma'.  */	      do		c = getch ();	      while (c == ' ' || c == '\t');	      if (c == 'v'		  && getch () == 't'		  && getch () == 'a'		  && getch () == 'b'		  && getch () == 'l'		  && getch () == 'e'		  && ((c = getch ()) == ' ' || c == '\t' || c == '\n'))		{		  extern tree pending_vtables;		  /* More follows: it must be a string constant (class name).  */		  token = real_yylex ();		  if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)		    {		      error ("invalid #pragma vtable");		      goto skipline;		    }		  if (write_virtuals != 2)		    {		      warning ("use `+e2' option to enable #pragma vtable");		      goto skipline;		    }		  pending_vtables = perm_tree_cons (NULL_TREE, get_identifier (TREE_STRING_POINTER (yylval.ttype)), pending_vtables);		  if (nextchar < 0)		    nextchar = getch ();		  c = nextchar;		  if (c != '\n')		    warning ("trailing characters ignored");		}	      else if (c == 'u'		       && getch () == 'n'		       && getch () == 'i'		       && getch () == 't'		       && ((c = getch ()) == ' ' || c == '\t' || c == '\n'))		{		  /* More follows: it must be a string constant (unit name).  */		  token = real_yylex ();		  if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)		    {		      error ("invalid #pragma unit");		      goto skipline;		    }		  current_unit_name = get_identifier (TREE_STRING_POINTER (yylval.ttype));		  current_unit_language = current_lang_name;		  if (nextchar < 0)		    nextchar = getch ();		  c = nextchar;		  if (c != '\n')		    warning ("trailing characters ignored");		}	      else if (c == 'i')		{		  tree fileinfo = IDENTIFIER_CLASS_VALUE (get_time_identifier (input_filename));		  c = getch ();		  if (c == 'n'		      && getch () == 't'		      && getch () == 'e'		      && getch () == 'r'		      && getch () == 'f'		      && getch () == 'a'		      && getch () == 'c'		      && getch () == 'e'		      && ((c = getch ()) == ' ' || c == '\t' || c == '\n'))		    {		      /* read to newline.  */		      while (c != '\n')			c = getch ();		      write_virtuals = 3;		      if (impl_file_chain == 0)			{			  char *filename;			  tree fi;			  /* If this is zero at this point, then we are			     auto-implementing.  */			  if (main_input_filename == 0)			    main_input_filename = input_filename;			  filename = FILE_NAME_NONDIRECTORY (main_input_filename);			  fi = get_time_identifier (filename);			  fi = IDENTIFIER_CLASS_VALUE (fi);			  TREE_INT_CST_LOW (fi) = 0;			  TREE_INT_CST_HIGH (fi) = 1;			  /* Get default.  */			  impl_file_chain = (struct impl_files *)permalloc (sizeof (struct impl_files));			  impl_file_chain->filename = filename;			  impl_file_chain->next = 0;			}		      interface_only = interface_strcmp (input_filename);		      interface_unknown = 0;		      TREE_INT_CST_LOW (fileinfo) = interface_only;		      TREE_INT_CST_HIGH (fileinfo) = interface_unknown;		    }		  else if (c == 'm'			   && getch () == 'p'			   && getch () == 'l'			   && getch () == 'e'			   && getch () == 'm'			   && getch () == 'e'			   && getch () == 'n'			   && getch () == 't'			   && getch () == 'a'			   && getch () == 't'			   && getch () == 'i'			   && getch () == 'o'			   && getch () == 'n'			   && ((c = getch ()) == ' ' || c == '\t' || c == '\n'))		    {		      char *main_filename = main_input_filename ? main_input_filename : input_filename;		      while (c == ' ' || c == '\t')			c = getch ();		      if (c != '\n')			{			  put_back (c);			  token = real_yylex ();			  if (token != STRING			      || TREE_CODE (yylval.ttype) != STRING_CST)			    {			      error ("invalid `#pragma implementation'");			      goto skipline;			    }			  main_filename = TREE_STRING_POINTER (yylval.ttype);			}		      main_filename = FILE_NAME_NONDIRECTORY (main_filename);		      /* read to newline.  */		      while (c != '\n')			c = getch ();		      if (write_virtuals == 3)			{			  struct impl_files *ifiles = impl_file_chain;			  while (ifiles)			    {			      if (! strcmp (ifiles->filename, main_filename))				break;			      ifiles = ifiles->next;			    }			  if (ifiles == 0)			    {			      ifiles = (struct impl_files*) permalloc (sizeof (struct impl_files));			      ifiles->filename = main_filename;			      ifiles->next = impl_file_chain;			      impl_file_chain = ifiles;			    }			}		      else if ((main_input_filename != 0				&& ! strcmp (main_input_filename, input_filename))			       || ! strcmp (input_filename, main_filename))			{			  write_virtuals = 3;			  if (impl_file_chain == 0)			    {			      impl_file_chain = (struct impl_files*) permalloc (sizeof (struct impl_files));			      impl_file_chain->filename = main_filename;			      impl_file_chain->next = 0;			    }			}		      else			error ("`#pragma implementation' can only appear at top-level");		      interface_only = 0;		      /* We make this non-zero so that we infer decl linkage			 in the impl file only for variables first declared			 in the interface file.  */		      interface_unknown = 1;		      TREE_INT_CST_LOW (fileinfo) = interface_only;		      TREE_INT_CST_HIGH (fileinfo) = interface_unknown;		    }		}	    }	  goto skipline;	}      else if (c == 'd')	{	  if (getch () == 'e'	      && getch () == 'f'	      && getch () == 'i'	      && getch () == 'n'	      && getch () == 'e'	      && ((c = getch ()) == ' ' || 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 (getch () == 'n'	      && getch () == 'd'	      && getch () == 'e'	      && getch () == 'f'	      && ((c = getch ()) == ' ' || 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 (getch () == 'i'	      && getch () == 'n'	      && getch () == 'e'	      && ((c = getch ()) == ' ' || c == '\t'))	    goto linenum;	}      else if (c == 'i')	{	  if (getch () == 'd'	      && getch () == 'e'	      && getch () == 'n'	      && getch () == 't'	      && ((c = getch ()) == ' ' || c == '\t'))	    {#ifdef ASM_OUTPUT_IDENT              extern FILE *asm_out_file;#endif	      /* #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 = getch ();	      /* If no argument, ignore the line.  */	      if (c == '\n')		return c;	      put_back (c);	      token = real_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;	    }	}      else if (c == 'n')	{	  if (getch () == 'e'	      && getch () == 'w'	      && getch () == 'w'	      && getch () == 'o'	      && getch () == 'r'	      && getch () == 'l'	      && getch () == 'd'	      && ((c = getch ()) == ' ' || c == '\t'))	    {	      /* Used to test incremental compilation.  */	      sorry ("#pragma newworld");	      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 = getch ();  /* 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.  */  put_back (c);  token = real_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;      c = get_last_nonwhite_on_line ();      if (c == '\n')	{	  /* No more: store the line number and check following line.  */	  lineno = l;	  return c;	}      put_back (c);      /* More follows: it must be a string constant (filename).  */      /* Read the string constant, but don't treat \ as special.  */      ignore_escape_flag = 1;      token = real_yylex ();      ignore_escape_flag = 0;      if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)	{	  error ("invalid #line");	  goto skipline;	}      /* Changing files again.  This means currently collected 

⌨️ 快捷键说明

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