content: 
  package java_cup;
  
  import java.util.BitSet;
  
  /** A set of terminals implemented as a bitset. 
   * @version last updated: 11/25/95
   * @author  Scott Hudson
   */
  public class terminal_set {
  
    /*-----------------------------------------------------------*/
    /*--- Constructor(s) ----------------------------------------*/
    /*-----------------------------------------------------------*/
  
    /** Constructor for an empty set. */
    public terminal_set() 
      { 
        /* allocate the bitset at what is probably the right size */
        _elements = new BitSet(terminal.number());
      }
  
    /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
  
    /** Constructor for cloning from another set. 
     * @param other the set we are cloning from.
     */
    public terminal_set(terminal_set other) 
      throws internal_error
      {
        not_null(other);
        _elements = (BitSet)other._elements.clone();
      }
  
    /*-----------------------------------------------------------*/
    /*--- (Access to) Static (Class) Variables ------------------*/
    /*-----------------------------------------------------------*/
  
    /** Constant for the empty set. */
    public static final terminal_set EMPTY = new terminal_set();
  
    /*-----------------------------------------------------------*/
    /*--- (Access to) Instance Variables ------------------------*/
    /*-----------------------------------------------------------*/
  
    /** Bitset to implement the actual set. */
    protected BitSet _elements;
  
    /*-----------------------------------------------------------*/
    /*--- General Methods ----------------------------------------*/
    /*-----------------------------------------------------------*/
  
    /** Helper function to test for a null object and throw an exception if
     *  one is found. 
     * @param obj the object we are testing.
     */
    protected void not_null(Object obj) throws internal_error
      {
        if (obj == null) 
  	throw new internal_error("Null object used in set operation");
      }
  
    /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
  
    /** Determine if the set is empty. */
    public boolean empty()
      {
        return equals(EMPTY);
      }
  
    /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
  
    /** Determine if the set contains a particular terminal. 
     * @param sym the terminal symbol we are looking for.
     */
    public boolean contains(terminal sym) 
      throws internal_error
      {
        not_null(sym); 
        return _elements.get(sym.index());
      }
  
    /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
  
    /** Given its index determine if the set contains a particular terminal. 
     * @param indx the index of the terminal in question.
     */
    public boolean contains(int indx) 
      {
        return _elements.get(indx);
      }
  
    /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
  
    /** Determine if this set is an (improper) subset of another.
     * @param other the set we are testing against.
     */
    public boolean is_subset_of(terminal_set other)
      throws internal_error
      {
        not_null(other);
  
        /* make a copy of the other set */
        BitSet copy_other = (BitSet)other._elements.clone();
  
        /* and or in */
        copy_other.or(_elements);
  
        /* if it hasn't changed, we were a subset */
        return copy_other.equals(other._elements);
      }
  
    /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
  
    /** Determine if this set is an (improper) superset of another.
     * @param other the set we are testing against.
     */
    public boolean is_superset_of(terminal_set other)
      throws internal_error
      {
        not_null(other);
        return other.is_subset_of(this);
      }
  
    /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
  
    /** Add a single terminal to the set.  
     * @param sym the terminal being added.
     * @return true if this changes the set.
     */
    public boolean add(terminal sym) 
      throws internal_error
      {
        boolean result;
  
        not_null(sym); 
  
        /* see if we already have this */ 
        result = _elements.get(sym.index());
  
        /* if not we add it */
        if (!result)
  	_elements.set(sym.index());
  
        return result;
      }
  
    /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
  
    /** Remove a terminal if it is in the set.
     * @param sym the terminal being removed.
     */
    public void remove(terminal sym) 
      throws internal_error
      {
        not_null(sym); 
        _elements.clear(sym.index());
      }
  
    /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
  
    /** Add (union) in a complete set.  
     * @param other the set being added.
     * @return true if this changes the set.
     */
    public boolean add(terminal_set other)
      throws internal_error
      {
        not_null(other);
  
        /* make a copy */
        BitSet copy = (BitSet)_elements.clone();
  
        /* or in the other set */
        _elements.or(other._elements);
  
        /* changed if we are not the same as the copy */
        return !_elements.equals(copy);
      }
  
    /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
  
    /** Determine if this set intersects another.
     * @param other the other set in question.
     */
     public boolean intersects(terminal_set other)
       throws internal_error
       {
         not_null(other);
         return _elements.intersects(other._elements);
       }
  
    /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
  
    /** Equality comparison. */
    public boolean equals(terminal_set other)
      {
        if (other == null) 
  	return false;
        else
  	return _elements.equals(other._elements);
      }
  
    /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
  
    /** Generic equality comparison. */
    public boolean equals(Object other)
      {
        if (!(other instanceof terminal_set))
  	return false;
        else
  	return equals((terminal_set)other);
      }
  
    /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
  
    /** Convert to string. */
    public String toString()
      {
        String result;
        boolean comma_flag;
        
        result = "{";
        comma_flag = false;
        for (int t = 0; t < terminal.number(); t++)
  	{
  	  if (_elements.get(t))
  	    {
  	      if (comma_flag)
  	        result += ", ";
  	      else
  	        comma_flag = true;
  
  	      result += terminal.find(t).name();
  	    }
  	}
        result += "}";
  
        return result;
      }
  
    /*-----------------------------------------------------------*/
  
  }
  
  