Source code: org/sablecc/sablecc/SymbolSet.java
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * This file is part of SableCC. *
3 * See the file "LICENSE" for copyright information and the *
4 * terms and conditions for copying, distribution and *
5 * modification of SableCC. *
6 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
7
8 package org.sablecc.sablecc;
9
10 import java.util.*;
11 import com.sun.java.util.collections.*;
12 import java.util.Vector;
13
14 final class SymbolSet implements Cloneable
15 {
16 private final IntSet terminals;
17 private final IntSet nonterminals;
18 private boolean empty;
19
20 private boolean modified = true;
21 private Symbol[] symbols;
22
23 private void computeArray()
24 {
25 Vector symbols = new Vector(0);
26
27 int[] elements = terminals.elements();
28 for(int i = 0; i < elements.length; i++)
29 {
30 symbols.addElement(Symbol.symbol(elements[i], true));
31 }
32
33 elements = nonterminals.elements();
34 for(int i = 0; i < elements.length; i++)
35 {
36 symbols.addElement(Symbol.symbol(elements[i], false));
37 }
38
39 this.symbols = new Symbol[symbols.size()];
40 symbols.copyInto(this.symbols);
41
42 modified = false;
43 }
44
45 SymbolSet()
46 {
47 this.terminals = new IntSet();
48 this.nonterminals= new IntSet();
49 }
50
51 private SymbolSet(SymbolSet set)
52 {
53 this.terminals = (IntSet) set.terminals.clone();
54 this.nonterminals = (IntSet) set.nonterminals.clone();
55 this.empty = set.empty;
56 }
57
58 void setTerminal(int terminal)
59 {
60 terminals.set(terminal);
61 modified = true;
62 }
63
64 void clearTerminal(int terminal)
65 {
66 terminals.clear(terminal);
67 modified = true;
68 }
69
70 boolean getTerminal(int terminal)
71 {
72 return terminals.get(terminal);
73 }
74
75 void setNonterminal(int nonterminal)
76 {
77 nonterminals.set(nonterminal);
78 modified = true;
79 }
80
81 void clearNonterminal(int nonterminal)
82 {
83 nonterminals.clear(nonterminal);
84 modified = true;
85 }
86
87 boolean getNonterminal(int nonterminal)
88 {
89 return nonterminals.get(nonterminal);
90 }
91
92 void setEmpty()
93 {
94 empty = true;
95 modified = true;
96 }
97
98 void clearEmpty()
99 {
100 empty = false;
101 modified = true;
102 }
103
104 boolean getEmpty()
105 {
106 return empty;
107 }
108
109 void and(SymbolSet s)
110 {
111 terminals.and(s.terminals);
112 nonterminals.and(s.nonterminals);
113 empty &= s.empty;
114 modified = true;
115 }
116
117 void or(SymbolSet s)
118 {
119 terminals.or(s.terminals);
120 nonterminals.or(s.nonterminals);
121 empty |= s.empty;
122 modified = true;
123 }
124
125 void xor(SymbolSet s)
126 {
127 terminals.xor(s.terminals);
128 nonterminals.xor(s.nonterminals);
129 empty ^= s.empty;
130 modified = true;
131 }
132
133 public int hashCode()
134 {
135 return terminals.hashCode() + nonterminals.hashCode() + new Boolean(empty).hashCode();
136 }
137
138 public boolean equals(Object obj)
139 {
140 if((obj == null) ||
141 (obj.getClass() != this.getClass()))
142 {
143 return false;
144 }
145
146 SymbolSet s = (SymbolSet) obj;
147
148 return terminals.equals(s.terminals) &&
149 nonterminals.equals(s.nonterminals) &&
150 (empty == s.empty);
151 }
152
153 Symbol[] getSymbols()
154 {
155 if(modified)
156 {
157 computeArray();
158 }
159
160 return symbols;
161 }
162
163 public String toString()
164 {
165 StringBuffer result = new StringBuffer();
166 result.append("{");
167
168 Symbol[] symbols = getSymbols();
169 boolean comma = false;
170 for(int i = 0; i < symbols.length; i++)
171 {
172 if(comma)
173 {
174 result.append(",");
175 }
176 else
177 {
178 comma = true;
179 }
180
181 result.append(symbols[i]);
182 }
183
184 if(empty)
185 {
186 if(comma)
187 {
188 result.append(",");
189 }
190 else
191 {
192 comma = true;
193 }
194
195 result.append("*empty*");
196 }
197
198 result.append("}");
199
200 return result.toString();
201 }
202
203 public Object clone()
204 {
205 return new SymbolSet(this);
206 }
207 }
208