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

📄 tree.c

📁 使用yacc和lex编写的cmm语言的词法分析和语法分析程序.
💻 C
📖 第 1 页 / 共 5 页
字号:
rtl_in_current_obstack (){  rtl_obstack = current_obstack;}/* Temporarily allocate rtl from saveable_obstack.  Return 1 if we were   previously allocating it from current_obstack.  */intrtl_in_saveable_obstack (){  if (rtl_obstack == current_obstack)    {      rtl_obstack = saveable_obstack;      return 1;    }  else    return 0;}/* Allocate SIZE bytes in the current obstack   and return a pointer to them.   In practice the current obstack is always the temporary one.  */char *oballoc (size)     int size;{  return (char *) obstack_alloc (current_obstack, size);}/* Free the object PTR in the current obstack   as well as everything allocated since PTR.   In practice the current obstack is always the temporary one.  */voidobfree (ptr)     char *ptr;{  obstack_free (current_obstack, ptr);}/* Allocate SIZE bytes in the permanent obstack   and return a pointer to them.  */char *permalloc (size)     long size;{  return (char *) obstack_alloc (&permanent_obstack, size);}/* Allocate NELEM items of SIZE bytes in the permanent obstack   and return a pointer to them.  The storage is cleared before   returning the value.  */char *perm_calloc (nelem, size)     int nelem;     long size;{  char *rval = (char *) obstack_alloc (&permanent_obstack, nelem * size);  bzero (rval, nelem * size);  return rval;}/* Allocate SIZE bytes in the saveable obstack   and return a pointer to them.  */char *savealloc (size)     int size;{  return (char *) obstack_alloc (saveable_obstack, size);}/* Print out which obstack an object is in.  */voiddebug_obstack (object)     char *object;{  struct obstack *obstack = NULL;  char *obstack_name = NULL;  struct function *p;  for (p = outer_function_chain; p; p = p->next)    {      if (_obstack_allocated_p (p->function_obstack, object))	{	  obstack = p->function_obstack;	  obstack_name = "containing function obstack";	}      if (_obstack_allocated_p (p->function_maybepermanent_obstack, object))	{	  obstack = p->function_maybepermanent_obstack;	  obstack_name = "containing function maybepermanent obstack";	}    }  if (_obstack_allocated_p (&obstack_stack_obstack, object))    {      obstack = &obstack_stack_obstack;      obstack_name = "obstack_stack_obstack";    }  else if (_obstack_allocated_p (function_obstack, object))    {      obstack = function_obstack;      obstack_name = "function obstack";    }  else if (_obstack_allocated_p (&permanent_obstack, object))    {      obstack = &permanent_obstack;      obstack_name = "permanent_obstack";    }  else if (_obstack_allocated_p (&momentary_obstack, object))    {      obstack = &momentary_obstack;      obstack_name = "momentary_obstack";    }  else if (_obstack_allocated_p (function_maybepermanent_obstack, object))    {      obstack = function_maybepermanent_obstack;      obstack_name = "function maybepermanent obstack";    }  else if (_obstack_allocated_p (&temp_decl_obstack, object))    {      obstack = &temp_decl_obstack;      obstack_name = "temp_decl_obstack";    }  /* Check to see if the object is in the free area of the obstack. */  if (obstack != NULL)    {      if (object >= obstack->next_free	  && object < obstack->chunk_limit)	fprintf (stderr, "object in free portion of obstack %s.\n",		 obstack_name);      else	fprintf (stderr, "object allocated from %s.\n", obstack_name);    }  else    fprintf (stderr, "object not allocated from any obstack.\n");}/* Return 1 if OBJ is in the permanent obstack.   This is slow, and should be used only for debugging.   Use TREE_PERMANENT for other purposes.  */intobject_permanent_p (obj)     tree obj;{  return _obstack_allocated_p (&permanent_obstack, obj);}/* Start a level of momentary allocation.   In C, each compound statement has its own level   and that level is freed at the end of each statement.   All expression nodes are allocated in the momentary allocation level.  */voidpush_momentary (){  struct momentary_level *tem    = (struct momentary_level *) obstack_alloc (&momentary_obstack,						sizeof (struct momentary_level));  tem->prev = momentary_stack;  tem->base = (char *) obstack_base (&momentary_obstack);  tem->obstack = expression_obstack;  momentary_stack = tem;  expression_obstack = &momentary_obstack;}/* Free all the storage in the current momentary-allocation level.   In C, this happens at the end of each statement.  */voidclear_momentary (){  obstack_free (&momentary_obstack, momentary_stack->base);}/* Discard a level of momentary allocation.   In C, this happens at the end of each compound statement.   Restore the status of expression node allocation   that was in effect before this level was created.  */voidpop_momentary (){  struct momentary_level *tem = momentary_stack;  momentary_stack = tem->prev;  expression_obstack = tem->obstack;  obstack_free (&momentary_obstack, tem);}/* Call when starting to parse a declaration:   make expressions in the declaration last the length of the function.   Returns an argument that should be passed to resume_momentary later.  */intsuspend_momentary (){  register int tem = expression_obstack == &momentary_obstack;  expression_obstack = saveable_obstack;  return tem;}/* Call when finished parsing a declaration:   restore the treatment of node-allocation that was   in effect before the suspension.   YES should be the value previously returned by suspend_momentary.  */voidresume_momentary (yes)     int yes;{  if (yes)    expression_obstack = &momentary_obstack;}/* Init the tables indexed by tree code.   Note that languages can add to these tables to define their own codes.  */voidinit_tree_codes (){  tree_code_type = (char **) xmalloc (sizeof (standard_tree_code_type));  tree_code_length = (int *) xmalloc (sizeof (standard_tree_code_length));  tree_code_name = (char **) xmalloc (sizeof (standard_tree_code_name));  bcopy (standard_tree_code_type, tree_code_type,	 sizeof (standard_tree_code_type));  bcopy (standard_tree_code_length, tree_code_length,	 sizeof (standard_tree_code_length));  bcopy (standard_tree_code_name, tree_code_name,	 sizeof (standard_tree_code_name));}/* Return a newly allocated node of code CODE.   Initialize the node's unique id and its TREE_PERMANENT flag.   For decl and type nodes, some other fields are initialized.   The rest of the node is initialized to zero.   Achoo!  I got a code in the node.  */treemake_node (code)     enum tree_code code;{  register tree t;  register int type = TREE_CODE_CLASS (code);  register int length;  register struct obstack *obstack = current_obstack;  register int i;  register tree_node_kind kind;  switch (type)    {    case 'd':  /* A decl node */#ifdef GATHER_STATISTICS      kind = d_kind;#endif      length = sizeof (struct tree_decl);      /* All decls in an inline function need to be saved.  */      if (obstack != &permanent_obstack)	obstack = saveable_obstack;      /* PARM_DECLs always go on saveable_obstack, not permanent,	 even though we may make them before the function turns	 on temporary allocation.  */      else if (code == PARM_DECL)	obstack = function_maybepermanent_obstack;      break;    case 't':  /* a type node */#ifdef GATHER_STATISTICS      kind = t_kind;#endif      length = sizeof (struct tree_type);      /* All data types are put where we can preserve them if nec.  */      if (obstack != &permanent_obstack)	obstack = all_types_permanent ? &permanent_obstack : saveable_obstack;      break;    case 's':  /* an expression with side effects */#ifdef GATHER_STATISTICS      kind = s_kind;      goto usual_kind;#endif    case 'r':  /* a reference */#ifdef GATHER_STATISTICS      kind = r_kind;      goto usual_kind;#endif    case 'e':  /* an expression */    case '<':  /* a comparison expression */    case '1':  /* a unary arithmetic expression */    case '2':  /* a binary arithmetic expression */#ifdef GATHER_STATISTICS      kind = e_kind;    usual_kind:#endif      obstack = expression_obstack;      /* All BLOCK nodes are put where we can preserve them if nec.	 Also their potential controllers.  */      if ((code == BLOCK || code == BIND_EXPR)	  && obstack != &permanent_obstack)	obstack = saveable_obstack;      length = sizeof (struct tree_exp)	+ (tree_code_length[(int) code] - 1) * sizeof (char *);      break;    case 'c':  /* a constant */#ifdef GATHER_STATISTICS      kind = c_kind;#endif      obstack = expression_obstack;      /* We can't use tree_code_length for this, since the number of words	 is machine-dependent due to varying alignment of `double'.  */      if (code == REAL_CST)	{	  length = sizeof (struct tree_real_cst);	  break;	}    case 'x':  /* something random, like an identifier.  */#ifdef GATHER_STATISTICS      if (code == IDENTIFIER_NODE)	kind = id_kind;      else if (code == OP_IDENTIFIER)	kind = op_id_kind;      else if (code == TREE_VEC)	kind = vec_kind;      else	kind = x_kind;#endif      length = sizeof (struct tree_common)	+ tree_code_length[(int) code] * sizeof (char *);      /* Identifier nodes are always permanent since they are	 unique in a compiler run.  */      if (code == IDENTIFIER_NODE) obstack = &permanent_obstack;    }  t = (tree) obstack_alloc (obstack, length);#ifdef GATHER_STATISTICS  tree_node_counts[(int)kind]++;  tree_node_sizes[(int)kind] += length;#endif  TREE_TYPE (t) = 0;  TREE_CHAIN (t) = 0;  for (i = (length / sizeof (int)) - 1;       i >= sizeof (struct tree_common) / sizeof (int) - 1;       i--)    ((int *) t)[i] = 0;  TREE_SET_CODE (t, code);  if (obstack == &permanent_obstack)    TREE_PERMANENT (t) = 1;  switch (type)    {    case 's':      TREE_SIDE_EFFECTS (t) = 1;      TREE_TYPE (t) = void_type_node;      break;    case 'd':      DECL_ALIGN (t) = 1;      DECL_SOURCE_LINE (t) = lineno;      DECL_SOURCE_FILE (t) = (input_filename) ? input_filename : "<built-in>";      break;    case 't':      {	static unsigned next_type_uid = 1;	TYPE_UID (t) = next_type_uid++;      }      TYPE_ALIGN (t) = 1;      TYPE_MAIN_VARIANT (t) = t;      break;    case 'c':      TREE_CONSTANT (t) = 1;      break;    }  return t;}/* Return a new node with the same contents as NODE   except that its TREE_CHAIN is zero and it has a fresh uid.  */treecopy_node (node)     tree node;{  register tree t;  register enum tree_code code = TREE_CODE (node);  register int length;  register int i;  switch (TREE_CODE_CLASS (code))    {    case 'd':  /* A decl node */      length = sizeof (struct tree_decl);      break;    case 't':  /* a type node */      length = sizeof (struct tree_type);      break;    case 'r':  /* a reference */    case 'e':  /* a expression */    case 's':  /* an expression with side effects */    case '<':  /* a comparison expression */    case '1':  /* a unary arithmetic expression */    case '2':  /* a binary arithmetic expression */      length = sizeof (struct tree_exp)	+ (tree_code_length[(int) code] - 1) * sizeof (char *);      break;    case 'c':  /* a constant */      /* We can't use tree_code_length for this, since the number of words	 is machine-dependent due to varying alignment of `double'.  */      if (code == REAL_CST)	{	  length = sizeof (struct tree_real_cst);	  break;	}    case 'x':  /* something random, like an identifier.  */      length = sizeof (struct tree_common)	+ tree_code_length[(int) code] * sizeof (char *);      if (code == TREE_VEC)	length += (TREE_VEC_LENGTH (node) - 1) * sizeof (char *);    }  t = (tree) obstack_alloc (current_obstack, length);  for (i = ((length + sizeof (int) - 1) / sizeof (int)) - 1;       i >= 0;       i--)    ((int *) t)[i] = ((int *) node)[i];  TREE_CHAIN (t) = 0;  TREE_PERMANENT (t) = (current_obstack == &permanent_obstack);  return t;}/* Return a copy of a chain of nodes, chained through the TREE_CHAIN field.   For example, this can copy a list made of TREE_LIST nodes.  */treecopy_list (list)     tree list;{  tree head;  register tree prev, next;  if (list == 0)    return 0;  head = prev = copy_node (list);  next = TREE_CHAIN (list);  while (next)    {      TREE_CHAIN (prev) = copy_node (next);      prev = TREE_CHAIN (prev);      next = TREE_CHAIN (next);    }  return head;}#define HASHBITS 30/* Return an IDENTIFIER_NODE whose name is TEXT (a null-terminated string).   If an identifier with that name has previously been referred to,   the same node is returned this time.  */treeget_identifier (text)     register char *text;{  register int hi;  register int i;  register tree idp;  register int len, hash_len;

⌨️ 快捷键说明

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