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

📄 lex.c

📁 GCC编译器源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    case TYPENAME_ELLIPSIS:    case SCSPEC:    case PRE_PARSED_CLASS_DECL:      t = yylval.ttype;      if (TREE_CODE (t) == TYPE_DECL)	{	  fprintf (file, " `%s'", DECL_NAME (t));	  break;	}      my_friendly_assert (TREE_CODE (t) == IDENTIFIER_NODE, 224);      if (IDENTIFIER_POINTER (t))	  fprintf (file, " `%s'", IDENTIFIER_POINTER (t));      break;    case AGGR:      if (yylval.ttype == class_type_node)	fprintf (file, " `class'");      else if (yylval.ttype == record_type_node)	fprintf (file, " `struct'");      else if (yylval.ttype == union_type_node)	fprintf (file, " `union'");      else if (yylval.ttype == enum_type_node)	fprintf (file, " `enum'");      else if (yylval.ttype == signature_type_node)	fprintf (file, " `signature'");      else	my_friendly_abort (80);      break;    }}#if defined(GATHER_STATISTICS) && defined(REDUCE_LENGTH)static int *reduce_count;#endifint *token_count;#if 0#define REDUCE_LENGTH (sizeof (yyr2) / sizeof (yyr2[0]))#define TOKEN_LENGTH (256 + sizeof (yytname) / sizeof (yytname[0]))#endifint *init_parse (){#ifdef GATHER_STATISTICS#ifdef REDUCE_LENGTH  reduce_count = (int *)malloc (sizeof (int) * (REDUCE_LENGTH + 1));  bzero (reduce_count, sizeof (int) * (REDUCE_LENGTH + 1));  reduce_count += 1;  token_count = (int *)malloc (sizeof (int) * (TOKEN_LENGTH + 1));  bzero (token_count, sizeof (int) * (TOKEN_LENGTH + 1));  token_count += 1;#endif#endif  return token_count;}#ifdef GATHER_STATISTICS#ifdef REDUCE_LENGTHvoidyyhook (yyn)     int yyn;{  reduce_count[yyn] += 1;}static intreduce_cmp (p, q)     int *p, *q;{  return reduce_count[*q] - reduce_count[*p];}static inttoken_cmp (p, q)     int *p, *q;{  return token_count[*q] - token_count[*p];}#endif#endifvoidprint_parse_statistics (){#ifdef GATHER_STATISTICS#ifdef REDUCE_LENGTH#if YYDEBUG != 0  int i;  int maxlen = REDUCE_LENGTH;  unsigned *sorted;    if (reduce_count[-1] == 0)    return;  if (TOKEN_LENGTH > REDUCE_LENGTH)    maxlen = TOKEN_LENGTH;  sorted = (unsigned *) alloca (sizeof (int) * maxlen);  for (i = 0; i < TOKEN_LENGTH; i++)    sorted[i] = i;  qsort (sorted, TOKEN_LENGTH, sizeof (int), token_cmp);  for (i = 0; i < TOKEN_LENGTH; i++)    {      int idx = sorted[i];      if (token_count[idx] == 0)	break;      if (token_count[idx] < token_count[-1])	break;      fprintf (stderr, "token %d, `%s', count = %d\n",	       idx, yytname[YYTRANSLATE (idx)], token_count[idx]);    }  fprintf (stderr, "\n");  for (i = 0; i < REDUCE_LENGTH; i++)    sorted[i] = i;  qsort (sorted, REDUCE_LENGTH, sizeof (int), reduce_cmp);  for (i = 0; i < REDUCE_LENGTH; i++)    {      int idx = sorted[i];      if (reduce_count[idx] == 0)	break;      if (reduce_count[idx] < reduce_count[-1])	break;      fprintf (stderr, "rule %d, line %d, count = %d\n",	       idx, yyrline[idx], reduce_count[idx]);    }  fprintf (stderr, "\n");#endif#endif#endif}/* Sets the value of the 'yydebug' variable to VALUE.   This is a function so we don't have to have YYDEBUG defined   in order to build the compiler.  */voidset_yydebug (value)     int value;{#if YYDEBUG != 0  extern int yydebug;  yydebug = value;#else  warning ("YYDEBUG not defined.");#endif}/* Functions and data structures for #pragma interface.   `#pragma implementation' means that the main file being compiled   is considered to implement (provide) the classes that appear in   its main body.  I.e., if this is file "foo.cc", and class `bar'   is defined in "foo.cc", then we say that "foo.cc implements bar".   All main input files "implement" themselves automagically.   `#pragma interface' means that unless this file (of the form "foo.h"   is not presently being included by file "foo.cc", the   CLASSTYPE_INTERFACE_ONLY bit gets set.  The effect is that none   of the vtables nor any of the inline functions defined in foo.h   will ever be output.   There are cases when we want to link files such as "defs.h" and   "main.cc".  In this case, we give "defs.h" a `#pragma interface',   and "main.cc" has `#pragma implementation "defs.h"'.  */struct impl_files{  char *filename;  struct impl_files *next;};static struct impl_files *impl_file_chain;/* Helper function to load global variables with interface   information.  */voidextract_interface_info (){  tree fileinfo = 0;  if (flag_alt_external_templates)    {      struct tinst_level *til = tinst_for_decl ();        if (til)	fileinfo = get_time_identifier (til->file);    }  if (!fileinfo)    fileinfo = get_time_identifier (input_filename);  fileinfo = IDENTIFIER_CLASS_VALUE (fileinfo);  interface_only = TREE_INT_CST_LOW (fileinfo);  interface_unknown = TREE_INT_CST_HIGH (fileinfo);}/* Return nonzero if S is not considered part of an   INTERFACE/IMPLEMENTATION pair.  Otherwise, return 0.  */static intinterface_strcmp (s)     char *s;{  /* Set the interface/implementation bits for this scope.  */  struct impl_files *ifiles;  char *s1;  for (ifiles = impl_file_chain; ifiles; ifiles = ifiles->next)    {      char *t1 = ifiles->filename;      s1 = s;      if (*s1 != *t1 || *s1 == 0)	continue;      while (*s1 == *t1 && *s1 != 0)	s1++, t1++;      /* A match.  */      if (*s1 == *t1)	return 0;      /* Don't get faked out by xxx.yyy.cc vs xxx.zzz.cc.  */      if (index (s1, '.') || index (t1, '.'))	continue;      if (*s1 == '\0' || s1[-1] != '.' || t1[-1] != '.')	continue;      /* A match.  */      return 0;    }  /* No matches.  */  return 1;}static voidset_typedecl_interface_info (prev, vars)     tree prev, vars;{  tree id = get_time_identifier (DECL_SOURCE_FILE (vars));  tree fileinfo = IDENTIFIER_CLASS_VALUE (id);  tree type = TREE_TYPE (vars);  CLASSTYPE_INTERFACE_ONLY (type) = TREE_INT_CST_LOW (fileinfo)    = interface_strcmp (file_name_nondirectory (DECL_SOURCE_FILE (vars)));}static intset_vardecl_interface_info (prev, vars)     tree prev, vars;{  tree type = DECL_CONTEXT (vars);  if (CLASSTYPE_INTERFACE_KNOWN (type))    {      if (CLASSTYPE_INTERFACE_ONLY (type))	set_typedecl_interface_info (prev, TYPE_MAIN_DECL (type));      else	CLASSTYPE_VTABLE_NEEDS_WRITING (type) = 1;      DECL_EXTERNAL (vars) = CLASSTYPE_INTERFACE_ONLY (type);      TREE_PUBLIC (vars) = 1;      return 1;    }  return 0;}/* Called from the top level: if there are any pending inlines to   do, set up to process them now.  This function sets up the first function   to be parsed; after it has been, the rule for fndef in parse.y will   call process_next_inline to start working on the next one.  */voiddo_pending_inlines (){  struct pending_inline *t;  tree context;  /* Oops, we're still dealing with the last batch.  */  if (yychar == PRE_PARSED_FUNCTION_DECL)    return;  /* Reverse the pending inline functions, since     they were cons'd instead of appended.  */  {    struct pending_inline *prev = 0, *tail;    t = pending_inlines;    pending_inlines = 0;    for (; t; t = tail)      {	tail = t->next;	t->next = prev;	t->deja_vu = 1;	prev = t;      }    t = prev;  }  if (t == 0)    return;	      /* Now start processing the first inline function.  */  context = hack_decl_function_context (t->fndecl);  if (context)    push_cp_function_context (context);  if (is_member_template (t->fndecl))    begin_member_template_processing (t->fndecl);  if (t->len > 0)    {      feed_input (t->buf, t->len);      lineno = t->lineno;#if 0      if (input_filename != t->filename)	{	  input_filename = t->filename;	  /* Get interface/implementation back in sync.  */	  extract_interface_info ();	}#else      input_filename = t->filename;      interface_unknown = t->interface == 1;      interface_only = t->interface == 0;#endif      yychar = PRE_PARSED_FUNCTION_DECL;    }  /* Pass back a handle on the rest of the inline functions, so that they     can be processed later.  */  yylval.ttype = build_tree_list ((tree) t, t->fndecl);  DECL_PENDING_INLINE_INFO (t->fndecl) = 0;}static int nextchar = -1;/* Called from the fndecl rule in the parser when the function just parsed   was declared using a PRE_PARSED_FUNCTION_DECL (i.e. came from   do_pending_inlines).  */voidprocess_next_inline (t)     tree t;{  tree context;  struct pending_inline *i = (struct pending_inline *) TREE_PURPOSE (t);  context = hack_decl_function_context (i->fndecl);    if (is_member_template (i->fndecl))    end_member_template_processing ();  if (context)    pop_cp_function_context (context);  i = i->next;  if (yychar == YYEMPTY)    yychar = yylex ();  if (yychar != END_OF_SAVED_INPUT)    {      error ("parse error at end of saved function text");      /* restore_pending_input will abort unless yychar is either         END_OF_SAVED_INPUT or YYEMPTY; since we already know we're         hosed, feed back YYEMPTY.  We also need to discard nextchar,         since that may have gotten set as well.  */      nextchar = -1;    }  yychar = YYEMPTY;  end_input ();  if (i && i->fndecl != NULL_TREE)    {      context = hack_decl_function_context (i->fndecl);      if (context)	push_cp_function_context (context);      if (is_member_template (i->fndecl))	begin_member_template_processing (i->fndecl);      feed_input (i->buf, i->len);      lineno = i->lineno;      input_filename = i->filename;      yychar = PRE_PARSED_FUNCTION_DECL;      yylval.ttype = build_tree_list ((tree) i, i->fndecl);      DECL_PENDING_INLINE_INFO (i->fndecl) = 0;    }  if (i)    {      interface_unknown = i->interface == 1;      interface_only = i->interface == 0;    }  else    extract_interface_info ();}/* Since inline methods can refer to text which has not yet been seen,   we store the text of the method in a structure which is placed in the   DECL_PENDING_INLINE_INFO field of the FUNCTION_DECL.   After parsing the body of the class definition, the FUNCTION_DECL's are   scanned to see which ones have this field set.  Those are then digested   one at a time.   This function's FUNCTION_DECL will have a bit set in its common so   that we know to watch out for it.  */static voidconsume_string (this_obstack, matching_char)     register struct obstack *this_obstack;     int matching_char;{  register int c;  int starting_lineno = lineno;  do    {      c = getch ();      if (c == EOF)	{	  int save_lineno = lineno;	  lineno = starting_lineno;	  if (matching_char == '"')	    error ("end of file encountered inside string constant");	  else	    error ("end of file encountered inside character constant");	  lineno = save_lineno;	  return;	}      if (c == '\\')	{	  obstack_1grow (this_obstack, c);	  c = getch ();	  obstack_1grow (this_obstack, c);	  /* Make sure we continue the loop */	  c = 0;	  continue;	}      if (c == '\n')	{	  if (pedantic)	    pedwarn ("ANSI C++ forbids newline in string constant");	  lineno++;	}      obstack_1grow (this_obstack, c);    }  while (c != matching_char);}static int nextyychar = YYEMPTY;static YYSTYPE nextyylval;struct pending_input {  int nextchar, yychar, nextyychar, eof;  YYSTYPE yylval, nextyylval;  struct obstack token_obstack;  int first_token;

⌨️ 快捷键说明

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