Added support for dynamically allocated arrays.
[repair.git] / Repair / RepairCompiler / java_cup / terminal_set.java
1
2 package java_cup;
3
4 import java.util.BitSet;
5
6 /** A set of terminals implemented as a bitset. 
7  * @version last updated: 11/25/95
8  * @author  Scott Hudson
9  */
10 public class terminal_set {
11
12   /*-----------------------------------------------------------*/
13   /*--- Constructor(s) ----------------------------------------*/
14   /*-----------------------------------------------------------*/
15
16   /** Constructor for an empty set. */
17   public terminal_set() 
18     { 
19       /* allocate the bitset at what is probably the right size */
20       _elements = new BitSet(terminal.number());
21     }
22
23   /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
24
25   /** Constructor for cloning from another set. 
26    * @param other the set we are cloning from.
27    */
28   public terminal_set(terminal_set other) 
29     throws internal_error
30     {
31       not_null(other);
32       _elements = (BitSet)other._elements.clone();
33     }
34
35   /*-----------------------------------------------------------*/
36   /*--- (Access to) Static (Class) Variables ------------------*/
37   /*-----------------------------------------------------------*/
38
39   /** Constant for the empty set. */
40   public static final terminal_set EMPTY = new terminal_set();
41
42   /*-----------------------------------------------------------*/
43   /*--- (Access to) Instance Variables ------------------------*/
44   /*-----------------------------------------------------------*/
45
46   /** Bitset to implement the actual set. */
47   protected BitSet _elements;
48
49   /*-----------------------------------------------------------*/
50   /*--- General Methods ----------------------------------------*/
51   /*-----------------------------------------------------------*/
52
53   /** Helper function to test for a null object and throw an exception if
54    *  one is found. 
55    * @param obj the object we are testing.
56    */
57   protected void not_null(Object obj) throws internal_error
58     {
59       if (obj == null) 
60         throw new internal_error("Null object used in set operation");
61     }
62
63   /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
64
65   /** Determine if the set is empty. */
66   public boolean empty()
67     {
68       return equals(EMPTY);
69     }
70
71   /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
72
73   /** Determine if the set contains a particular terminal. 
74    * @param sym the terminal symbol we are looking for.
75    */
76   public boolean contains(terminal sym) 
77     throws internal_error
78     {
79       not_null(sym); 
80       return _elements.get(sym.index());
81     }
82
83   /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
84
85   /** Given its index determine if the set contains a particular terminal. 
86    * @param indx the index of the terminal in question.
87    */
88   public boolean contains(int indx) 
89     {
90       return _elements.get(indx);
91     }
92
93   /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
94
95   /** Determine if this set is an (improper) subset of another.
96    * @param other the set we are testing against.
97    */
98   public boolean is_subset_of(terminal_set other)
99     throws internal_error
100     {
101       not_null(other);
102
103       /* make a copy of the other set */
104       BitSet copy_other = (BitSet)other._elements.clone();
105
106       /* and or in */
107       copy_other.or(_elements);
108
109       /* if it hasn't changed, we were a subset */
110       return copy_other.equals(other._elements);
111     }
112
113   /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
114
115   /** Determine if this set is an (improper) superset of another.
116    * @param other the set we are testing against.
117    */
118   public boolean is_superset_of(terminal_set other)
119     throws internal_error
120     {
121       not_null(other);
122       return other.is_subset_of(this);
123     }
124
125   /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
126
127   /** Add a single terminal to the set.  
128    * @param sym the terminal being added.
129    * @return true if this changes the set.
130    */
131   public boolean add(terminal sym) 
132     throws internal_error
133     {
134       boolean result;
135
136       not_null(sym); 
137
138       /* see if we already have this */ 
139       result = _elements.get(sym.index());
140
141       /* if not we add it */
142       if (!result)
143         _elements.set(sym.index());
144
145       return result;
146     }
147
148   /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
149
150   /** Remove a terminal if it is in the set.
151    * @param sym the terminal being removed.
152    */
153   public void remove(terminal sym) 
154     throws internal_error
155     {
156       not_null(sym); 
157       _elements.clear(sym.index());
158     }
159
160   /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
161
162   /** Add (union) in a complete set.  
163    * @param other the set being added.
164    * @return true if this changes the set.
165    */
166   public boolean add(terminal_set other)
167     throws internal_error
168     {
169       not_null(other);
170
171       /* make a copy */
172       BitSet copy = (BitSet)_elements.clone();
173
174       /* or in the other set */
175       _elements.or(other._elements);
176
177       /* changed if we are not the same as the copy */
178       return !_elements.equals(copy);
179     }
180
181   /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
182
183   /** Determine if this set intersects another.
184    * @param other the other set in question.
185    */
186    public boolean intersects(terminal_set other)
187      throws internal_error
188      {
189        not_null(other);
190
191        /* make a copy of the other set */
192        BitSet copy = (BitSet)other._elements.clone();
193
194        /* xor out our values */
195        copy.xor(this._elements);
196
197        /* see if its different */
198        return !copy.equals(other._elements);
199      }
200
201   /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
202
203   /** Equality comparison. */
204   public boolean equals(terminal_set other)
205     {
206       if (other == null) 
207         return false;
208       else
209         return _elements.equals(other._elements);
210     }
211
212   /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
213
214   /** Generic equality comparison. */
215   public boolean equals(Object other)
216     {
217       if (!(other instanceof terminal_set))
218         return false;
219       else
220         return equals((terminal_set)other);
221     }
222
223   /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
224
225   /** Convert to string. */
226   public String toString()
227     {
228       String result;
229       boolean comma_flag;
230       
231       result = "{";
232       comma_flag = false;
233       for (int t = 0; t < terminal.number(); t++)
234         {
235           if (_elements.get(t))
236             {
237               if (comma_flag)
238                 result += ", ";
239               else
240                 comma_flag = true;
241
242               result += terminal.find(t).name();
243             }
244         }
245       result += "}";
246
247       return result;
248     }
249
250   /*-----------------------------------------------------------*/
251
252 }
253