4 import java.util.BitSet;
6 /** A set of terminals implemented as a bitset.
7 * @version last updated: 11/25/95
10 public class terminal_set {
12 /*-----------------------------------------------------------*/
13 /*--- Constructor(s) ----------------------------------------*/
14 /*-----------------------------------------------------------*/
16 /** Constructor for an empty set. */
19 /* allocate the bitset at what is probably the right size */
20 _elements = new BitSet(terminal.number());
23 /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
25 /** Constructor for cloning from another set.
26 * @param other the set we are cloning from.
28 public terminal_set(terminal_set other)
32 _elements = (BitSet)other._elements.clone();
35 /*-----------------------------------------------------------*/
36 /*--- (Access to) Static (Class) Variables ------------------*/
37 /*-----------------------------------------------------------*/
39 /** Constant for the empty set. */
40 public static final terminal_set EMPTY = new terminal_set();
42 /*-----------------------------------------------------------*/
43 /*--- (Access to) Instance Variables ------------------------*/
44 /*-----------------------------------------------------------*/
46 /** Bitset to implement the actual set. */
47 protected BitSet _elements;
49 /*-----------------------------------------------------------*/
50 /*--- General Methods ----------------------------------------*/
51 /*-----------------------------------------------------------*/
53 /** Helper function to test for a null object and throw an exception if
55 * @param obj the object we are testing.
57 protected void not_null(Object obj) throws internal_error
60 throw new internal_error("Null object used in set operation");
63 /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
65 /** Determine if the set is empty. */
66 public boolean empty()
71 /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
73 /** Determine if the set contains a particular terminal.
74 * @param sym the terminal symbol we are looking for.
76 public boolean contains(terminal sym)
80 return _elements.get(sym.index());
83 /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
85 /** Given its index determine if the set contains a particular terminal.
86 * @param indx the index of the terminal in question.
88 public boolean contains(int indx)
90 return _elements.get(indx);
93 /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
95 /** Determine if this set is an (improper) subset of another.
96 * @param other the set we are testing against.
98 public boolean is_subset_of(terminal_set other)
103 /* make a copy of the other set */
104 BitSet copy_other = (BitSet)other._elements.clone();
107 copy_other.or(_elements);
109 /* if it hasn't changed, we were a subset */
110 return copy_other.equals(other._elements);
113 /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
115 /** Determine if this set is an (improper) superset of another.
116 * @param other the set we are testing against.
118 public boolean is_superset_of(terminal_set other)
119 throws internal_error
122 return other.is_subset_of(this);
125 /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
127 /** Add a single terminal to the set.
128 * @param sym the terminal being added.
129 * @return true if this changes the set.
131 public boolean add(terminal sym)
132 throws internal_error
138 /* see if we already have this */
139 result = _elements.get(sym.index());
141 /* if not we add it */
143 _elements.set(sym.index());
148 /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
150 /** Remove a terminal if it is in the set.
151 * @param sym the terminal being removed.
153 public void remove(terminal sym)
154 throws internal_error
157 _elements.clear(sym.index());
160 /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
162 /** Add (union) in a complete set.
163 * @param other the set being added.
164 * @return true if this changes the set.
166 public boolean add(terminal_set other)
167 throws internal_error
172 BitSet copy = (BitSet)_elements.clone();
174 /* or in the other set */
175 _elements.or(other._elements);
177 /* changed if we are not the same as the copy */
178 return !_elements.equals(copy);
181 /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
183 /** Determine if this set intersects another.
184 * @param other the other set in question.
186 public boolean intersects(terminal_set other)
187 throws internal_error
191 /* make a copy of the other set */
192 BitSet copy = (BitSet)other._elements.clone();
194 /* xor out our values */
195 copy.xor(this._elements);
197 /* see if its different */
198 return !copy.equals(other._elements);
201 /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
203 /** Equality comparison. */
204 public boolean equals(terminal_set other)
209 return _elements.equals(other._elements);
212 /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
214 /** Generic equality comparison. */
215 public boolean equals(Object other)
217 if (!(other instanceof terminal_set))
220 return equals((terminal_set)other);
223 /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
225 /** Convert to string. */
226 public String toString()
233 for (int t = 0; t < terminal.number(); t++)
235 if (_elements.get(t))
242 result += terminal.find(t).name();
250 /*-----------------------------------------------------------*/