
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);

       /* make a copy of the other set */
       BitSet copy = (BitSet)other._elements.clone();

       /* xor out our values */
       copy.xor(this._elements);

       /* see if its different */
       return !copy.equals(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;
    }

  /*-----------------------------------------------------------*/

};

