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

📄 cp-spew.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/*  consume_token(); */ /* already eaten by frob_identifier?... */  return yychar;}/* token[0] == AGGR (struct/union/enum) * thus, token[1] is either a TYPENAME or a TYPENAME_DEFN * if token[2] == '{' or ':' then it's TYPENAME_DEFN */static intdo_aggr (){  int yc1, yc2;    scan_tokens (2);  yc1 = nth_token (1)->yychar;  if (yc1 != TYPENAME && yc1 != IDENTIFIER && yc1 != PTYPENAME)    return 0;  yc2 = nth_token (2)->yychar;  if (yc2 == '{' || yc2 == ':')    {      switch (yc1)	{	case TYPENAME:	  nth_token (1)->yychar = TYPENAME_DEFN;	  break;	case PTYPENAME:	  nth_token (1)->yychar = PTYPENAME_DEFN;	  break;	case IDENTIFIER:	  nth_token (1)->yychar = IDENTIFIER_DEFN;	  break;	default:	  my_friendly_abort (102);	}    }  return 0;}  static struct tokenfrob_identifier (){  /* we could have a type, if it is followed by :: (if so, suck it all up); */  /* we could have a ptypename; */  /* we could have a normal identifier. */  tree t1;  struct token rt;    scan_tokens(1);  rt = *nth_token(0);#if 0  if (nth_token(1)->yychar == '<')    {      t1 = hack_ptype();	/* suck up the whole thing */      if (t1)	{	  rt.yylval.ttype = t1;	  rt.yychar = TYPENAME;	  *nth_token(0) = rt;	}      /* else fall out bottom */    }	#endif  if (nth_token(1)->yychar == SCOPE)    {#if 0      t1 = hack_more_ids(0);      if (t1 && TREE_CODE(t1) == SCOPE_REF)#else      t1 = hack_more_ids(0, nth_token (0)->yylval.ttype);      if (t1)#endif	{	  rt.yylval.ttype = t1;	  rt.yychar = SCOPED_TYPENAME ;	  return rt;	}      else	{	  /* deal with types (enums?) in classes... */	  struct token *tok;	  tree ta, tb;	  scan_tokens(3);	  /* Have to check for a type conversion operator	     to a nested type.  */	  if (nth_token (2)->yychar == OPERATOR)	    tok = nth_token (3);	  else	    tok = nth_token(2);	  if (tok->yychar == IDENTIFIER || tok->yychar == TYPENAME)	    {	      ta = build_parse_node (SCOPE_REF,				     nth_token(0)->yylval.ttype,				     tok->yylval.ttype);	      tb = resolve_scope_to_name (NULL_TREE, ta);	      if (tb != NULL_TREE)		{		  if (nth_token (2)->yychar == OPERATOR)		    {		      /* Have to keep these tokens around			 so we can finish parsing the declaration.			 What do we do for			 int foo::operator bar::baz (); 			 where bar is a nested class in foo?  */		      nth_token (3)->yychar = TYPENAME;		      nth_token (3)->yylval.ttype = tb;		    }		  else		    {		      consume_token (); /* base type */		      consume_token (); /* SCOPE */		      consume_token (); /* member type */		      rt.yychar = TYPENAME;		      rt.yylval.ttype = tb;		      rt.end_of_file = tok->end_of_file;		      return rt;		    }		  		}	    }      	  /* else fall out bottom */	}    }	       consume_token();  return rt;}/* When this function is called, nth_token(0) is the current   token we are scanning.  This means that the next token we'll   scan is nth_token (1).  Usually the next token we'll scan   is nth_token (0) (and the current token is in [yylval,yychar]).  */treearbitrate_lookup (name, exp_decl, type_decl)     tree name, exp_decl, type_decl;{  int ch;  scan_tokens (3);  ch = nth_token (1)->yychar;  switch (ch)    {    case '(':    case LEFT_RIGHT:      /* If we guessed wrong here, `build_functional_cast' can fix it.  */      return type_decl;    case '=':      if (global_bindings_p ())	/* Probably a default parameter.  */	return type_decl;      /* Probably not an initialization.  */      return exp_decl;    case '[':      /* This needs special help because an expression inside the	 brackets means nothing.  */      {	int i;	for (i = 0; i < 42; i++)	  {	    int ith_yychar;	    scan_tokens (3+i);	    ith_yychar = nth_token (2+i)->yychar;	    /* If we hit an undefined identifier, assume	       the decl in arbitration is its type specifier.  */	    if (ith_yychar == IDENTIFIER		&& lookup_name (nth_token (2+i)->yylval.ttype, 0) == 0)	      return type_decl;	    else if (ith_yychar == ']')	      {		/* There are only a few things we expect after a ']'		   in a declarator.  */		i += 1;		scan_tokens (4+i);		ith_yychar = nth_token (2+i)->yychar;		/* These are inconclusive.  */		if (ith_yychar == LEFT_RIGHT		    || ith_yychar == '('		    || ith_yychar == '['		    || ith_yychar == ',')		  continue;		/* stmt or decl?  We'll probably never know.  */		else if (ith_yychar == ';')		  goto warn_ambiguous;		if (ith_yychar == '=')		  {		    if (nth_token (3+i)->yychar == '{')		      return type_decl;		    continue;		  }		/* Whatever it is, it looks like we're processing an expr.  */		return exp_decl;	      }	  }	goto warn_ambiguous;      }    case ',':    case ';':    case '&':    case '<':    case '*':    case ']':    case ')':    case '>':      /* see if the next token looks like it wants to be part	 of a declaration list or an expression list.  */      {	int i;	/* Some heuristics: if we are inside a function definition,	   prefer the local declaration.  */	if (! global_bindings_p ())	  {	    if (IDENTIFIER_LOCAL_VALUE (name) == exp_decl)	      return exp_decl;	    if (IDENTIFIER_LOCAL_VALUE (name) != type_decl		&& IDENTIFIER_CLASS_VALUE (name) == exp_decl)	      return exp_decl;	  }	/* If these symbols follow in a list, we know it's a list of	   expressions.  */	if (follows_identifier[nth_token (2)->yychar])	  return exp_decl;	/* If we see a id&, or id&) the we are probably in an argument list. */	if (ch=='&'	    && (nth_token (2)->yychar == ',' || nth_token (2)->yychar == ')'))	  return type_decl;	/* Look for the first identifier or other distinguishing token	   we find in the next several tokens.  */	for (i = 0; i < 42; i++)	  {	    int ith_yychar;	    scan_tokens (3+i);	    ith_yychar = nth_token (2+i)->yychar;	    if (ith_yychar == IDENTIFIER)	      {		tree as_type = lookup_name (nth_token (2+i)->yylval.ttype, 1);		if (as_type && TREE_CODE (as_type) != TYPE_DECL)		  return exp_decl;		/* An undeclared identifier or a typename means we're		   probably looking at a typename.  */		return type_decl;	      }	    else if (ith_yychar == EMPTY		     || follows_identifier[ith_yychar])	      return exp_decl;	    else if (follows_typename[ith_yychar])	      return type_decl;	    /* stmt or decl?  We'll probably never know.  */	    else if (ith_yychar == ';')	      goto warn_ambiguous;	  }	goto warn_ambiguous;      }    default:      if (follows_identifier[ch])	return exp_decl;      if (follows_typename[ch])	return type_decl;      /* Fall through...  */    warn_ambiguous:      warning ("name `%s' could be type or expression; compiler assuming type",	       IDENTIFIER_POINTER (DECL_NAME (type_decl)));      return type_decl;    }}/* now returns decl_node */#if 0static treehack_ptype(){  /* when we get here, we know that [0] is a ptype and [1] is '<'.   * now we loop over simple parameters. */  struct token this_param;  int n = 2;  tree tplist = 0;  tree tc;  scan_tokens(n+1);    while((this_param = *nth_token(n)).yychar != '>')    {      /* if it is a type, add it to the list */      tree thistype;          switch(this_param.yychar)	{	case IDENTIFIER:	case TYPENAME:	case TYPESPEC:	  break;	default:	  return 0;	}      thistype = this_param.yylval.ttype;      thistype = lookup_name(thistype, 1);      thistype = TREE_TYPE (thistype);              if (tplist)	tplist = chainon (tplist, build_tree_list (NULL_TREE, thistype));      else	tplist = build_tree_list(NULL_TREE, thistype);              /* then suck up the comma */      n++;      scan_tokens(n+1);      this_param = *nth_token(n);      if (this_param.yychar == ',')	{	  n++;	  scan_tokens(n+1);	  continue;	}      if (this_param.yychar == '>')	break;      return 0;    }  /* once we're done, lookup_template_class -> identifier */  tc = lookup_template_class (nth_token(0)->yylval.ttype,tplist);  /* then lookup_name on that to get a type, if there is one */  tc = lookup_name (tc, 1);  if (tc)    {      int i;      /* don't actually eat the trailing '>'... we can replace it! */      for (i=0; i<n; i++)	consume_token();      /*    IDENTIFIER_TYPE_VALUE (DECL_NAME (tc)) = */      return DECL_NAME (tc);    }  return NULL_TREE;}#endif#if 0static treehack_more_ids (n)     int n;{  /*   * The recursion should probably do consume_tokens(), since once we've started   * down an IDENTIFIER SCOPE ... chain, we don't need to back-track - we just   * get as much as we can, make SCOPE_REF's out of it, and return it.   */  struct token this_iter, this2_iter;  int tmp_y;    scan_tokens(n+1);  this_iter = *nth_token(n);  tmp_y = nth_token(n)->yychar;  if (tmp_y == IDENTIFIER || tmp_y == TYPENAME)    {      scan_tokens(n+2+2);      if (nth_token(n+1)->yychar == SCOPE)	{	  if (nth_token(n+1+2)->yychar == SCOPE)	    {	      tree hmi;		      consume_token();	/* last IDENTIFIER (this_iter) */	      consume_token();	/* last SCOPE */	      this2_iter = *nth_token(n);		      hmi = hack_more_ids (n);		      if (hmi)		return build_parse_node (SCOPE_REF, this_iter.yylval.ttype, hmi);	      consume_token(); /* last IDENTIFIER (this2_iter) */	      return build_parse_node (SCOPE_REF, this_iter.yylval.ttype,				       this2_iter.yylval.ttype);	    }	  else	    {	      /* consume_token();	*/	/* last IDENTIFIER */	      /* leave whatever else we got */	      /* return this_iter.yylval.ttype; */	      return NULL_TREE;	    }	}    }  return NULL_TREE;		/* @@ may need to backtrack */}#else/* niklas@appli.se says:  I didn't understand how the code above was intended * to work, so I rewrote it (also changed the interface a bit).  This code * dives down an IDENTIFIER/TYPENAME SCOPE ... chain as long as the parsed * type prefix constitutes recognizable (by resolve_scope_to_name) types. * Interface changed like this: * 1. Takes an extra argument containing the name of the the type recognized *    so far. * 2. Now returns the name of the type instead of a SCOPE_REF. */static treehack_more_ids(n, outer)  int n;  tree outer;{  int ch;  tree type, val;  scan_tokens (n + 2);  if (nth_token (n + 1)->yychar != SCOPE      || ((ch = nth_token (n + 2)->yychar) != IDENTIFIER && ch != TYPENAME))    return NULL_TREE;  val = build_parse_node (SCOPE_REF, outer, nth_token (n + 2)->yylval.ttype);  type = resolve_scope_to_name (NULL_TREE, val);  if (type == NULL_TREE)    return NULL_TREE;  consume_token ();  consume_token ();  val = hack_more_ids (n, type);  if (! val)    consume_token ();  return val ? val : type;}#endif#if 0static struct tokenhack_scope (){  /* we've got a :: - what follows is either a global var or a type. */  /* hmm, template names can be in the global scope too... */  tree t1;  struct token rt;    scan_tokens(1);  if (nth_token(1)->yychar == IDENTIFIER)    {      /* @@ this is probably not right, but doesn't get hit yet */      t1 = build_parse_node (SCOPE_REF,			     NULL_TREE, /* to get "global" scope */			     hack_more_ids(0)); /* do some prefetching */      rt.yylval.ttype = t1;      rt.yychar =		/*SCOPED_*/TYPENAME;      return rt;    }  else    {      rt = *nth_token(0);      consume_token();      return rt;    }}#endif  /* * Generations: * 	 * PINST: PTYPE { saved_arg_count = arg_count($1) } *        '<' { arg_c = 0; } PARGS '>' *        ; * PARG: TYPE *       | VALUE *       ; * (of course the arg counting doesn't work for recursion... Do it right.) * PARGS: PARG { assert(arg_c == saved_arg_count); } *        | PARG ',' PARGS	{ arg_c++; } *        ; * ATYPE: PINST *        | TYPEID *        ; * TYPE: ATYPE *       | ATYPE { basetype = $1; } '::' TYPEKIDS *       ; * TYPEKIDS: TYPE { assert ($1 is a member of basetype); } * 	  | TYPEKIDS { basetype += $1} TYPE { assert( $3 is in basetype ); } * 	  ; * * * state0: ; ATYPE * 	TYPE '<': ac = args($0), base = CALL state1, state3	 * 	TYPE '::': base=$0, state3 * 	else return TYPE * state1: ; begin PARGS * 	if(ac < list length) punt * 	PARG ",": add to list, state1 * 	PARG ">": add to list, return * 	else unravel * state3: ; begin TYPEKIDS * 	TYPE:  */    #ifdef SPEW_DEBUG    /* debug_yychar takes a yychar (token number) value and prints its name. */static intdebug_yychar (yy)     int yy;{  /* In cp-parse.y: */  extern char *debug_yytranslate ();    int i;    if(yy<256) {    fprintf (stderr, "<%d: %c >\n", yy, yy);    return 0;  }  fprintf (stderr, "<%d:%s>\n", yy, debug_yytranslate (yy));  return 1;}#endif

⌨️ 快捷键说明

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