public production()

in util/src/main/java/java_cup/production.java [71:176]


  public production(
    non_terminal    lhs_sym, 
    production_part rhs_parts[], 
    int             rhs_l,
    String          action_str)
    throws internal_error
    {
      int         i;
      action_part tail_action;
      String declare_str;
      int rightlen = rhs_l;

      /* remember the length */
      if (rhs_l >= 0)
	_rhs_length = rhs_l;
      else if (rhs_parts != null)
	_rhs_length = rhs_parts.length;
      else
	_rhs_length = 0;
	
      /* make sure we have a valid left-hand-side */
      if (lhs_sym == null) 
	throw new internal_error(
	  "Attempt to construct a production with a null LHS");

      /* I'm not translating labels anymore, I'm adding code to declare
	 labels as valid variables.  This way, the users code string is
	 untouched 
	 6/96 frankf */

      /* check if the last part of the right hand side is an action.  If
         it is, it won't be on the stack, so we don't want to count it 
	 in the rightlen.  Then when we search down the stack for a
         Symbol, we don't try to search past action */

      if (rhs_l > 0) {
	if (rhs_parts[rhs_l - 1].is_action()) {
	  rightlen = rhs_l - 1;
	} else {
	  rightlen = rhs_l;
	}
      }

      /* get the generated declaration code for the necessary labels. */
      declare_str = declare_labels(
		    rhs_parts, rightlen, action_str);

      if (action_str == null) 
	action_str = declare_str;
      else 
	action_str = declare_str + action_str;	 	  

      /* count use of lhs */
      lhs_sym.note_use();

      /* create the part for left-hand-side */
      _lhs = new symbol_part(lhs_sym);

      /* merge adjacent actions (if any) */
      _rhs_length = merge_adjacent_actions(rhs_parts, _rhs_length);

      /* strip off any trailing action */
      tail_action = strip_trailing_action(rhs_parts, _rhs_length);
      if (tail_action != null) _rhs_length--;

      /* Why does this run through the right hand side happen
	 over and over?  here a quick combination of two 
	 prior runs plus one I wanted of my own
	 frankf 6/25/96 */
      /* allocate and copy over the right-hand-side */
      /* count use of each rhs symbol */
      _rhs = new production_part[_rhs_length];
      for (i=0; i<_rhs_length; i++) {
	_rhs[i] = rhs_parts[i];
	if (!_rhs[i].is_action()) {
	  ((symbol_part)_rhs[i]).the_symbol().note_use();
	  if (((symbol_part)_rhs[i]).the_symbol() instanceof terminal) {
	    _rhs_prec = 
	      ((terminal)((symbol_part)_rhs[i]).the_symbol()).precedence_num();
	    _rhs_assoc = 
	      ((terminal)((symbol_part)_rhs[i]).the_symbol()).precedence_side();
	  }
	}
      }

      /*now action string is really declaration string, so put it in front!
	6/14/96 frankf */
      if (action_str == null) action_str = "";
      if (tail_action != null && tail_action.code_string() != null)
	action_str = action_str + "\t\t" +  tail_action.code_string();

      /* stash the action */
      _action = new action_part(action_str);

      /* rewrite production to remove any embedded actions */
      remove_embedded_actions();

      /* assign an index */
      _index = next_index++;

      /* put us in the global collection of productions */
      _all.put(new Integer(_index),this);

      /* put us in the production list of the lhs non terminal */
      lhs_sym.add_production(this);
    }