Home | History | Annotate | Download | only in java_cup
      1 
      2 package java_cup;
      3 
      4 import java.util.Enumeration;
      5 import java.util.Hashtable;
      6 
      7 /** This class represents a set of symbols and provides a series of
      8  *  set operations to manipulate them.
      9  *
     10  * @see     java_cup.symbol
     11  * @version last updated: 11/25/95
     12  * @author  Scott Hudson
     13  */
     14 public class symbol_set {
     15 
     16   /*-----------------------------------------------------------*/
     17   /*--- Constructor(s) ----------------------------------------*/
     18   /*-----------------------------------------------------------*/
     19 
     20   /** Constructor for an empty set. */
     21   public symbol_set() { };
     22 
     23   /** Constructor for cloning from another set.
     24    * @param other the set we are cloning from.
     25    */
     26   public symbol_set(symbol_set other) throws internal_error
     27     {
     28       not_null(other);
     29       _all = (Hashtable)other._all.clone();
     30     };
     31 
     32   /*-----------------------------------------------------------*/
     33   /*--- (Access to) Instance Variables ------------------------*/
     34   /*-----------------------------------------------------------*/
     35 
     36   /** A hash table to hold the set. Symbols are keyed using their name string.
     37    */
     38   protected Hashtable _all = new Hashtable(11);
     39 
     40   /** Access to all elements of the set. */
     41   public Enumeration all() {return _all.elements();};
     42 
     43   /** size of the set */
     44   public int size() {return _all.size();};
     45 
     46   /*-----------------------------------------------------------*/
     47   /*--- (Access to) Instance Variables ------------------------*/
     48   /*-----------------------------------------------------------*/
     49 
     50   /** Helper function to test for a null object and throw an exception
     51    *  if one is found.
     52    * @param obj the object we are testing.
     53    */
     54   protected void not_null(Object obj) throws internal_error
     55     {
     56       if (obj == null)
     57     throw new internal_error("Null object used in set operation");
     58     }
     59 
     60   /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
     61 
     62   /** Determine if the set contains a particular symbol.
     63    * @param sym the symbol we are looking for.
     64    */
     65   public boolean contains(symbol sym) {return _all.containsKey(sym.name());};
     66 
     67   /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
     68 
     69   /** Determine if this set is an (improper) subset of another.
     70    * @param other the set we are testing against.
     71    */
     72   public boolean is_subset_of(symbol_set other) throws internal_error
     73     {
     74       not_null(other);
     75 
     76       /* walk down our set and make sure every element is in the other */
     77       for (Enumeration e = all(); e.hasMoreElements(); )
     78     if (!other.contains((symbol)e.nextElement()))
     79       return false;
     80 
     81       /* they were all there */
     82       return true;
     83     }
     84 
     85   /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
     86 
     87   /** Determine if this set is an (improper) superset of another.
     88    * @param other the set we are are testing against.
     89    */
     90   public boolean is_superset_of(symbol_set other) throws internal_error
     91     {
     92       not_null(other);
     93       return other.is_subset_of(this);
     94     }
     95 
     96   /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
     97 
     98   /** Add a single symbol to the set.
     99    * @param sym the symbol we are adding.
    100    * @return true if this changes the set.
    101    */
    102   public boolean add(symbol sym) throws internal_error
    103     {
    104       Object previous;
    105 
    106       not_null(sym);
    107 
    108       /* put the object in */
    109       previous = _all.put(sym.name(),sym);
    110 
    111       /* if we had a previous, this is no change */
    112       return previous == null;
    113     };
    114 
    115   /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
    116 
    117   /** Remove a single symbol if it is in the set.
    118    * @param sym the symbol we are removing.
    119    */
    120   public void remove(symbol sym) throws internal_error
    121     {
    122       not_null(sym);
    123       _all.remove(sym.name());
    124     };
    125 
    126   /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
    127 
    128   /** Add (union) in a complete set.
    129    * @param other the set we are adding in.
    130    * @return true if this changes the set.
    131    */
    132   public boolean add(symbol_set other) throws internal_error
    133     {
    134       boolean result = false;
    135 
    136       not_null(other);
    137 
    138       /* walk down the other set and do the adds individually */
    139       for (Enumeration e = other.all(); e.hasMoreElements(); )
    140     result = add((symbol)e.nextElement()) || result;
    141 
    142       return result;
    143     };
    144 
    145   /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
    146 
    147   /** Remove (set subtract) a complete set.
    148    * @param other the set we are removing.
    149    */
    150   public void remove(symbol_set other) throws internal_error
    151     {
    152       not_null(other);
    153 
    154       /* walk down the other set and do the removes individually */
    155       for (Enumeration e = other.all(); e.hasMoreElements(); )
    156     remove((symbol)e.nextElement());
    157     };
    158 
    159   /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
    160 
    161   /** Equality comparison. */
    162   public boolean equals(symbol_set other)
    163     {
    164       if (other == null || other.size() != size()) return false;
    165 
    166       /* once we know they are the same size, then improper subset does test */
    167       try {
    168         return is_subset_of(other);
    169       } catch (internal_error e) {
    170     /* can't throw the error (because super class doesn't), so we crash */
    171     e.crash();
    172     return false;
    173       }
    174     }
    175 
    176   /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
    177 
    178   /** Generic equality comparison. */
    179   public boolean equals(Object other)
    180     {
    181       if (!(other instanceof symbol_set))
    182     return false;
    183       else
    184     return equals((symbol_set)other);
    185     }
    186 
    187   /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
    188 
    189   /** Compute a hash code. */
    190   public int hashCode()
    191     {
    192       int result = 0;
    193       int cnt;
    194       Enumeration e;
    195 
    196       /* hash together codes from at most first 5 elements */
    197       for (e = all(), cnt=0 ; e.hasMoreElements() && cnt<5; cnt++)
    198     result ^= ((symbol)e.nextElement()).hashCode();
    199 
    200       return result;
    201     }
    202 
    203   /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
    204 
    205   /** Convert to a string. */
    206   public String toString()
    207     {
    208       String result;
    209       boolean comma_flag;
    210 
    211       result = "{";
    212       comma_flag = false;
    213       for (Enumeration e = all(); e.hasMoreElements(); )
    214     {
    215       if (comma_flag)
    216         result += ", ";
    217       else
    218         comma_flag = true;
    219 
    220       result += ((symbol)e.nextElement()).name();
    221     }
    222       result += "}";
    223 
    224       return result;
    225     }
    226 
    227   /*-----------------------------------------------------------*/
    228 
    229 };
    230 
    231 
    232