content: 
  package java_cup;
  
  /** The "core" of an LR item.  This includes a production and the position
   *  of a marker (the "dot") within the production.  Typically item cores 
   *  are written using a production with an embedded "dot" to indicate their 
   *  position.  For example: <pre>
   *     A ::= B * C d E
   *  </pre>
   *  This represents a point in a parse where the parser is trying to match
   *  the given production, and has succeeded in matching everything before the 
   *  "dot" (and hence is expecting to see the symbols after the dot next).  See 
   *  lalr_item, lalr_item_set, and lalr_start for full details on the meaning 
   *  and use of items.
   *
   * @see     java_cup.lalr_item
   * @see     java_cup.lalr_item_set
   * @see     java_cup.lalr_state
   * @version last updated: 11/25/95
   * @author  Scott Hudson
  */
  
  public class lr_item_core {
     
    /*-----------------------------------------------------------*/
    /*--- Constructor(s) ----------------------------------------*/
    /*-----------------------------------------------------------*/
  
    /** Full constructor.
     * @param prod production this item uses.
     * @param pos  position of the "dot" within the item.
     */
    public lr_item_core(production prod, int pos) throws internal_error
      {
        symbol          after_dot = null;
        production_part part;
  
        if (prod == null)
  	throw new internal_error(
  	  "Attempt to create an lr_item_core with a null production");
  
        _the_production = prod;
  
        if (pos < 0 || pos > _the_production.rhs_length())
  	throw new internal_error(
  	  "Attempt to create an lr_item_core with a bad dot position");
  
        _dot_pos = pos;
  
        /* compute and cache hash code now */
        _core_hash_cache = 13*_the_production.hashCode() + pos;
  
        /* cache the symbol after the dot */
        if (_dot_pos < _the_production.rhs_length())
  	{
  	  part = _the_production.rhs(_dot_pos);
  	  if (!part.is_action())
  	    _symbol_after_dot = ((symbol_part)part).the_symbol();
  	}
      } 
  
    /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
  
    /** Constructor for dot at start of right hand side. 
     * @param prod production this item uses.
     */
    public lr_item_core(production prod) throws internal_error
      {
        this(prod,0);
      }
  
    /*-----------------------------------------------------------*/
    /*--- (Access to) Instance Variables ------------------------*/
    /*-----------------------------------------------------------*/
  
    /** The production for the item. */
    protected production _the_production;
  
    /** The production for the item. */
    public production the_production() {return _the_production;}
  
    /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
  
    /** The position of the "dot" -- this indicates the part of the production 
     *  that the marker is before, so 0 indicates a dot at the beginning of 
     *  the RHS.
     */
    protected int _dot_pos;
  
    /** The position of the "dot" -- this indicates the part of the production 
     *  that the marker is before, so 0 indicates a dot at the beginning of 
     *  the RHS.
     */
    public int dot_pos() {return _dot_pos;}
  
    /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
  
    /** Cache of the hash code. */
    protected int _core_hash_cache;
  
    /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
  
    /** Cache of symbol after the dot. */
    protected symbol _symbol_after_dot = null;
  
    /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
  
    /** Is the dot at the end of the production? */
    public boolean dot_at_end() 
      {
         return _dot_pos >= _the_production.rhs_length();
      }
  
    /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
  
    /** Return the symbol after the dot.  If there is no symbol after the dot
     *  we return null. */
    public symbol symbol_after_dot()
      {
        /* use the cached symbol */
        return _symbol_after_dot;
      }
  
    /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
  
    /** Determine if we have a dot before a non terminal, and if so which one 
     *  (return null or the non terminal). 
     */
    public non_terminal dot_before_nt()
      {
        symbol sym;
  
        /* get the symbol after the dot */
        sym = symbol_after_dot();
  
        /* if it exists and is a non terminal, return it */
        if (sym != null && sym.is_non_term())
  	return (non_terminal)sym;
        else
  	return null;
      }
  
    /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
  
    /** Produce a new lr_item_core that results from shifting the dot one 
     *  position to the right. 
     */
    public lr_item_core shift_core() throws internal_error
      {
        if (dot_at_end()) 
  	throw new internal_error(
  	  "Attempt to shift past end of an lr_item_core");
  
        return new lr_item_core(_the_production, _dot_pos+1);
      }
  
    /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
  
    /** Equality comparison for the core only.  This is separate out because we 
     *  need separate access in a super class. 
     */
    public boolean core_equals(lr_item_core other)
      {
        return other != null && 
  	     _the_production.equals(other._the_production) && 
  	     _dot_pos == other._dot_pos;
      }
  
    /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
  
    /** Equality comparison. */
    public boolean equals(lr_item_core other) {return core_equals(other);}
  
    /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
  
    /** Generic equality comparison. */
    public boolean equals(Object other)
      {
        if (!(other instanceof lr_item_core))
  	return false;
        else
  	return equals((lr_item_core)other);
      }
  
    /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
  
    /** Hash code for the core (separated so we keep non overridden version). */
    public int core_hashCode()
      {
        return _core_hash_cache;
      }
  
    /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
  
    /** Hash code for the item. */
    public int hashCode() 
      {
        return _core_hash_cache;
      }
  
    /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
  
    /** Return the hash code that object would have provided for us so we have 
     *  a (nearly) unique id for debugging.
     */
    protected int obj_hash()
      {
        return super.hashCode();
      }
  
    /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
  
    /** Convert to a string (separated out from toString() so we can call it
     *  from subclass that overrides toString()).
     */
    public String to_simple_string() throws internal_error
      {
        String result;
        production_part part;
  
        if (_the_production.lhs() != null && 
  	  _the_production.lhs().the_symbol() != null &&
  	  _the_production.lhs().the_symbol().name() != null)
  	result = _the_production.lhs().the_symbol().name();
        else
  	result = "$$NULL$$";
  
        result += " ::= ";
  
        for (int i = 0; i<_the_production.rhs_length(); i++)
  	{
  	  /* do we need the dot before this one? */
  	  if (i == _dot_pos)
  	    result += "(*) ";
  	  
  	  /* print the name of the part */
  	  if (_the_production.rhs(i) == null)
  	    {
  	      result += "$$NULL$$ ";
  	    }
  	  else
  	    {
  	      part = _the_production.rhs(i);
  	      if (part == null)
  		result += "$$NULL$$ ";
  	      else if (part.is_action())
  		result += "{ACTION} ";
  	      else if (((symbol_part)part).the_symbol() != null &&
                         ((symbol_part)part).the_symbol().name() != null)
  		result += ((symbol_part)part).the_symbol().name() + " ";
  	      else
  		result += "$$NULL$$ ";
  	    }
  	}
  
        /* put the dot after if needed */
        if (_dot_pos == _the_production.rhs_length())
  	result += "(*) ";
  
        return result;
      }
  
    /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
  
    /** Convert to a string */
    public String toString() 
      {
        /* can't throw here since super class doesn't, so we crash instead */
        try {
          return to_simple_string();
        } catch(internal_error e) {
  	e.crash();
  	return null;
        }
      }
  
    /*-----------------------------------------------------------*/
  
  }
     
  