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

📄 production.java

📁 我开发的一个用java语言实现的编译器,内含词法分析器,语法分析器,而且可以实现中间代码生成.用到了SLR算法和LR(1)算法
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
   * @param labelname    the label name   * @param stack_type   the stack type of label?   * @author frankf   */   protected String make_declaration(				    String  labelname,				    String  stack_type,				    int     offset)    {      String ret;      /* Put in the left/right value labels */      if (emit.lr_values())        ret = "\t\tint " + labelname + "left = ((java_cup.runtime.Symbol)" + 	  emit.pre("stack") + ".elementAt(" + emit.pre("top") + 	  "-" + offset + ")).left;\n" +	  "\t\tint " + labelname + "right = ((java_cup.runtime.Symbol)" + 	  emit.pre("stack") + ".elementAt(" + emit.pre("top") +	  "-" + offset + ")).right;\n";      else ret = "";      /* otherwise, just declare label. */	return ret + "\t\t" + stack_type + " " + labelname + " = (" + stack_type + 	  ")((" + "java_cup.runtime.Symbol) " + emit.pre("stack") + ".elementAt(" + emit.pre("top") 	  + "-" + offset + ")).value;\n";    }  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/  /** Declare label names as valid variables within the action string   * @param rhs          array of RHS parts.   * @param rhs_len      how much of rhs to consider valid.   * @param final_action the final action string of the production.    * @param lhs_type     the object type associated with the LHS symbol.   */   protected String declare_labels(    production_part  rhs[],     int              rhs_len,     String           final_action)    {      String declaration = "";      symbol_part part;      action_part act_part;      int         pos;      /* walk down the parts and extract the labels */      for (pos = 0; pos < rhs_len; pos++)	{	  if (!rhs[pos].is_action())	    {	      part = (symbol_part)rhs[pos];	      /* if it has a label, make declaration! */	      if (part.label() != null)		{		  declaration = declaration + 		    make_declaration(part.label(), part.the_symbol().stack_type(), 				     rhs_len-pos-1);		}	    }	}      return declaration;    }  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/  /** Helper routine to merge adjacent actions in a set of RHS parts    * @param rhs_parts array of RHS parts.   * @param len       amount of that array that is valid.   * @return          remaining valid length.   */  protected int merge_adjacent_actions(production_part rhs_parts[], int len)    {      int from_loc, to_loc, merge_cnt;      /* bail out early if we have no work to do */      if (rhs_parts == null || len == 0) return 0;      merge_cnt = 0;      to_loc = -1;      for (from_loc=0; from_loc<len; from_loc++)	{	  /* do we go in the current position or one further */	  if (to_loc < 0 || !rhs_parts[to_loc].is_action() 			 || !rhs_parts[from_loc].is_action())	    {	      /* next one */	      to_loc++;	      /* clear the way for it */	      if (to_loc != from_loc) rhs_parts[to_loc] = null;	    }	  /* if this is not trivial? */	  if (to_loc != from_loc)	    {	      /* do we merge or copy? */	      if (rhs_parts[to_loc] != null && rhs_parts[to_loc].is_action() && 		  rhs_parts[from_loc].is_action())	      {	        /* merge */	        rhs_parts[to_loc] = new action_part(		  ((action_part)rhs_parts[to_loc]).code_string() +		  ((action_part)rhs_parts[from_loc]).code_string());	        merge_cnt++;	      }	    else	      {	        /* copy */	        rhs_parts[to_loc] = rhs_parts[from_loc];	      }	    }	}      /* return the used length */      return len - merge_cnt;    }  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/  /** Helper routine to strip a trailing action off rhs and return it   * @param rhs_parts array of RHS parts.   * @param len       how many of those are valid.   * @return          the removed action part.   */  protected action_part strip_trailing_action(    production_part rhs_parts[],    int             len)    {      action_part result;      /* bail out early if we have nothing to do */      if (rhs_parts == null || len == 0) return null;      /* see if we have a trailing action */      if (rhs_parts[len-1].is_action())	{	  /* snip it out and return it */	  result = (action_part)rhs_parts[len-1];	  rhs_parts[len-1] = null;	  return result;	}      else	return null;    }  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/  /** Remove all embedded actions from a production by factoring them    *  out into individual action production using new non terminals.   *  if the original production was:  <pre>   *    A ::= B {action1} C {action2} D    *  </pre>   *  then it will be factored into: <pre>   *    A ::= B NT$1 C NT$2 D   *    NT$1 ::= {action1}   *    NT$2 ::= {action2}   *  </pre>   *  where NT$1 and NT$2 are new system created non terminals.   */  /* the declarations added to the parent production are also passed along,     as they should be perfectly valid in this code string, since it     was originally a code string in the parent, not on its own.     frank 6/20/96 */  protected void remove_embedded_actions(	               ) throws internal_error    {      non_terminal new_nt;      production   new_prod;      String declare_str;            /* walk over the production and process each action */      for (int act_loc = 0; act_loc < rhs_length(); act_loc++)	if (rhs(act_loc).is_action())	  {	    	    	    declare_str = declare_labels(		      _rhs, act_loc, "");	    /* create a new non terminal for the action production */	    new_nt = non_terminal.create_new();	    new_nt.is_embedded_action = true; /* 24-Mar-1998, CSA */	    /* create a new production with just the action */	    new_prod = new action_production(this, new_nt, null, 0, 		declare_str + ((action_part)rhs(act_loc)).code_string());	    /* replace the action with the generated non terminal */	    _rhs[act_loc] = new symbol_part(new_nt);	  }    }  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/  /** Check to see if the production (now) appears to be nullable.   *  A production is nullable if its RHS could derive the empty string.   *  This results when the RHS is empty or contains only non terminals   *  which themselves are nullable.   */  public boolean check_nullable() throws internal_error    {      production_part part;      symbol          sym;      int             pos;      /* if we already know bail out early */      if (nullable_known()) return nullable();      /* if we have a zero size RHS we are directly nullable */      if (rhs_length() == 0)	{	  /* stash and return the result */	  return set_nullable(true);	}      /* otherwise we need to test all of our parts */      for (pos=0; pos<rhs_length(); pos++)	{	  part = rhs(pos);	  /* only look at non-actions */	  if (!part.is_action())	    {	      sym = ((symbol_part)part).the_symbol();	      /* if its a terminal we are definitely not nullable */	      if (!sym.is_non_term()) 		return set_nullable(false);	      /* its a non-term, is it marked nullable */	      else if (!((non_terminal)sym).nullable())		/* this one not (yet) nullable, so we aren't */	        return false;	    }	}      /* if we make it here all parts are nullable */      return set_nullable(true);    }  /** set (and return) nullability */  boolean set_nullable(boolean v)    {      _nullable_known = true;      _nullable = v;      return v;    }  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/  /** Update (and return) the first set based on current NT firsts.    *  This assumes that nullability has already been computed for all non    *  terminals and productions.    */  public terminal_set check_first_set() throws internal_error    {      int    part;      symbol sym;      /* walk down the right hand side till we get past all nullables */      for (part=0; part<rhs_length(); part++)	{	  /* only look at non-actions */	  if (!rhs(part).is_action())	    {	      sym = ((symbol_part)rhs(part)).the_symbol();	      /* is it a non-terminal?*/	      if (sym.is_non_term())		{		  /* add in current firsts from that NT */		  _first_set.add(((non_terminal)sym).first_set());		  /* if its not nullable, we are done */		  if (!((non_terminal)sym).nullable())		    break;		}	      else		{	          /* its a terminal -- add that to the set */		  _first_set.add((terminal)sym);		  /* we are done */		  break;		}	    }	}      /* return our updated first set */      return first_set();    }  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/  /** Equality comparison. */  public boolean equals(production other)    {      if (other == null) return false;      return other._index == _index;    }  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/  /** Generic equality comparison. */  public boolean equals(Object other)    {      if (!(other instanceof production))	return false;      else	return equals((production)other);    }  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/  /** Produce a hash code. */  public int hashCode()    {      /* just use a simple function of the index */      return _index*13;    }  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/  /** Convert to a string. */  public String toString()     {      String result;            /* catch any internal errors */      try {        result = "production [" + index() + "]: ";         result += ((lhs() != null) ? lhs().toString() : "$$NULL-LHS$$");        result += " :: = ";        for (int i = 0; i<rhs_length(); i++)	  result += rhs(i) + " ";        result += ";";        if (action()  != null && action().code_string() != null) 	  result += " {" + action().code_string() + "}";        if (nullable_known())	  if (nullable())	    result += "[NULLABLE]";	  else	    result += "[NOT NULLABLE]";      } catch (internal_error e) {	/* crash on internal error since we can't throw it from here (because	   superclass does not throw anything. */	e.crash();	result = null;      }      return result;    }  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/  /** Convert to a simpler string. */  public String to_simple_string() throws internal_error    {      String result;      result = ((lhs() != null) ? lhs().the_symbol().name() : "NULL_LHS");      result += " ::= ";      for (int i = 0; i < rhs_length(); i++)	if (!rhs(i).is_action())	  result += ((symbol_part)rhs(i)).the_symbol().name() + " ";      return result;    }  /*-----------------------------------------------------------*/}

⌨️ 快捷键说明

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