xref: /aosp_15_r20/external/antlr/runtime/Cpp/include/antlr3collections.inl (revision 16467b971bd3e2009fad32dd79016f2c7e421deb)
1*16467b97STreehugger RobotANTLR_BEGIN_NAMESPACE()
2*16467b97STreehugger Robot
3*16467b97STreehugger Robottemplate< class ImplTraits, class DataType >
4*16467b97STreehugger RobotANTLR_INLINE TrieEntry<ImplTraits, DataType>::TrieEntry(const DataType& data, TrieEntry* next)
5*16467b97STreehugger Robot	:m_data(data)
6*16467b97STreehugger Robot{
7*16467b97STreehugger Robot	m_next = next;
8*16467b97STreehugger Robot}
9*16467b97STreehugger Robottemplate< class ImplTraits, class DataType >
10*16467b97STreehugger RobotANTLR_INLINE DataType& TrieEntry<ImplTraits, DataType>::get_data()
11*16467b97STreehugger Robot{
12*16467b97STreehugger Robot	return m_data;
13*16467b97STreehugger Robot}
14*16467b97STreehugger Robottemplate< class ImplTraits, class DataType >
15*16467b97STreehugger RobotANTLR_INLINE const DataType& TrieEntry<ImplTraits, DataType>::get_data() const
16*16467b97STreehugger Robot{
17*16467b97STreehugger Robot	return m_data;
18*16467b97STreehugger Robot}
19*16467b97STreehugger Robottemplate< class ImplTraits, class DataType >
20*16467b97STreehugger RobotANTLR_INLINE TrieEntry<ImplTraits, DataType>* TrieEntry<ImplTraits, DataType>::get_next() const
21*16467b97STreehugger Robot{
22*16467b97STreehugger Robot	return m_next;
23*16467b97STreehugger Robot}
24*16467b97STreehugger Robot
25*16467b97STreehugger Robottemplate< class ImplTraits, class DataType >
26*16467b97STreehugger RobotANTLR_INLINE void TrieEntry<ImplTraits, DataType>::set_next( TrieEntry* next )
27*16467b97STreehugger Robot{
28*16467b97STreehugger Robot	m_next = next;
29*16467b97STreehugger Robot}
30*16467b97STreehugger Robot
31*16467b97STreehugger Robottemplate< class ImplTraits, class DataType >
32*16467b97STreehugger RobotANTLR_INLINE ANTLR_UINT32 IntTrieNode<ImplTraits, DataType>::get_bitNum() const
33*16467b97STreehugger Robot{
34*16467b97STreehugger Robot	return m_bitNum;
35*16467b97STreehugger Robot}
36*16467b97STreehugger Robottemplate< class ImplTraits, class DataType >
37*16467b97STreehugger RobotANTLR_INLINE ANTLR_INTKEY IntTrieNode<ImplTraits, DataType>::get_key() const
38*16467b97STreehugger Robot{
39*16467b97STreehugger Robot	return m_key;
40*16467b97STreehugger Robot}
41*16467b97STreehugger Robottemplate< class ImplTraits, class DataType >
42*16467b97STreehugger RobotANTLR_INLINE typename IntTrieNode<ImplTraits, DataType>::BucketsType* IntTrieNode<ImplTraits, DataType>::get_buckets() const
43*16467b97STreehugger Robot{
44*16467b97STreehugger Robot	return m_buckets;
45*16467b97STreehugger Robot}
46*16467b97STreehugger Robottemplate< class ImplTraits, class DataType >
47*16467b97STreehugger RobotANTLR_INLINE IntTrieNode<ImplTraits, DataType>* IntTrieNode<ImplTraits, DataType>::get_leftN() const
48*16467b97STreehugger Robot{
49*16467b97STreehugger Robot	return m_leftN;
50*16467b97STreehugger Robot}
51*16467b97STreehugger Robottemplate< class ImplTraits, class DataType >
52*16467b97STreehugger RobotANTLR_INLINE IntTrieNode<ImplTraits, DataType>* IntTrieNode<ImplTraits, DataType>::get_rightN() const
53*16467b97STreehugger Robot{
54*16467b97STreehugger Robot	return m_rightN;
55*16467b97STreehugger Robot}
56*16467b97STreehugger Robottemplate< class ImplTraits, class DataType >
57*16467b97STreehugger RobotANTLR_INLINE void IntTrieNode<ImplTraits, DataType>::set_bitNum( ANTLR_UINT32 bitNum )
58*16467b97STreehugger Robot{
59*16467b97STreehugger Robot	m_bitNum = bitNum;
60*16467b97STreehugger Robot}
61*16467b97STreehugger Robottemplate< class ImplTraits, class DataType >
62*16467b97STreehugger RobotANTLR_INLINE void IntTrieNode<ImplTraits, DataType>::set_key( ANTLR_INTKEY key )
63*16467b97STreehugger Robot{
64*16467b97STreehugger Robot	m_key = key;
65*16467b97STreehugger Robot}
66*16467b97STreehugger Robottemplate< class ImplTraits, class DataType >
67*16467b97STreehugger RobotANTLR_INLINE void IntTrieNode<ImplTraits, DataType>::set_buckets( BucketsType* buckets )
68*16467b97STreehugger Robot{
69*16467b97STreehugger Robot	m_buckets = buckets;
70*16467b97STreehugger Robot}
71*16467b97STreehugger Robottemplate< class ImplTraits, class DataType >
72*16467b97STreehugger RobotANTLR_INLINE void IntTrieNode<ImplTraits, DataType>::set_leftN( IntTrieNode* leftN )
73*16467b97STreehugger Robot{
74*16467b97STreehugger Robot	m_leftN = leftN;
75*16467b97STreehugger Robot}
76*16467b97STreehugger Robottemplate< class ImplTraits, class DataType >
77*16467b97STreehugger RobotANTLR_INLINE void IntTrieNode<ImplTraits, DataType>::set_rightN( IntTrieNode* rightN )
78*16467b97STreehugger Robot{
79*16467b97STreehugger Robot	m_rightN = rightN;
80*16467b97STreehugger Robot}
81*16467b97STreehugger Robot
82*16467b97STreehugger RobotANTLR_INLINE const ANTLR_UINT8* IntTrieBase::get_bitIndex()
83*16467b97STreehugger Robot{
84*16467b97STreehugger Robot	static ANTLR_UINT8 bitIndex[256] =
85*16467b97STreehugger Robot	{
86*16467b97STreehugger Robot		0,													// 0 - Just for padding
87*16467b97STreehugger Robot		0,													// 1
88*16467b97STreehugger Robot		1, 1,												// 2..3
89*16467b97STreehugger Robot		2, 2, 2, 2,											// 4..7
90*16467b97STreehugger Robot		3, 3, 3, 3, 3, 3, 3, 3,								// 8+
91*16467b97STreehugger Robot		4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,	    // 16+
92*16467b97STreehugger Robot		5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,	    // 32+
93*16467b97STreehugger Robot		5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
94*16467b97STreehugger Robot		6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,	    // 64+
95*16467b97STreehugger Robot		6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
96*16467b97STreehugger Robot		6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
97*16467b97STreehugger Robot		6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
98*16467b97STreehugger Robot		7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,	    // 128+
99*16467b97STreehugger Robot		7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
100*16467b97STreehugger Robot		7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
101*16467b97STreehugger Robot		7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
102*16467b97STreehugger Robot		7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
103*16467b97STreehugger Robot		7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
104*16467b97STreehugger Robot		7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
105*16467b97STreehugger Robot		7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
106*16467b97STreehugger Robot	};
107*16467b97STreehugger Robot	return bitIndex;
108*16467b97STreehugger Robot}
109*16467b97STreehugger Robot
110*16467b97STreehugger RobotANTLR_INLINE const ANTLR_UINT64* IntTrieBase::get_bitMask()
111*16467b97STreehugger Robot{
112*16467b97STreehugger Robot	static ANTLR_UINT64 bitMask[64] =
113*16467b97STreehugger Robot	{
114*16467b97STreehugger Robot		0x0000000000000001ULL, 0x0000000000000002ULL, 0x0000000000000004ULL, 0x0000000000000008ULL,
115*16467b97STreehugger Robot		0x0000000000000010ULL, 0x0000000000000020ULL, 0x0000000000000040ULL, 0x0000000000000080ULL,
116*16467b97STreehugger Robot		0x0000000000000100ULL, 0x0000000000000200ULL, 0x0000000000000400ULL, 0x0000000000000800ULL,
117*16467b97STreehugger Robot		0x0000000000001000ULL, 0x0000000000002000ULL, 0x0000000000004000ULL, 0x0000000000008000ULL,
118*16467b97STreehugger Robot		0x0000000000010000ULL, 0x0000000000020000ULL, 0x0000000000040000ULL, 0x0000000000080000ULL,
119*16467b97STreehugger Robot		0x0000000000100000ULL, 0x0000000000200000ULL, 0x0000000000400000ULL, 0x0000000000800000ULL,
120*16467b97STreehugger Robot		0x0000000001000000ULL, 0x0000000002000000ULL, 0x0000000004000000ULL, 0x0000000008000000ULL,
121*16467b97STreehugger Robot		0x0000000010000000ULL, 0x0000000020000000ULL, 0x0000000040000000ULL, 0x0000000080000000ULL,
122*16467b97STreehugger Robot		0x0000000100000000ULL, 0x0000000200000000ULL, 0x0000000400000000ULL, 0x0000000800000000ULL,
123*16467b97STreehugger Robot		0x0000001000000000ULL, 0x0000002000000000ULL, 0x0000004000000000ULL, 0x0000008000000000ULL,
124*16467b97STreehugger Robot		0x0000010000000000ULL, 0x0000020000000000ULL, 0x0000040000000000ULL, 0x0000080000000000ULL,
125*16467b97STreehugger Robot		0x0000100000000000ULL, 0x0000200000000000ULL, 0x0000400000000000ULL, 0x0000800000000000ULL,
126*16467b97STreehugger Robot		0x0001000000000000ULL, 0x0002000000000000ULL, 0x0004000000000000ULL, 0x0008000000000000ULL,
127*16467b97STreehugger Robot		0x0010000000000000ULL, 0x0020000000000000ULL, 0x0040000000000000ULL, 0x0080000000000000ULL,
128*16467b97STreehugger Robot		0x0100000000000000ULL, 0x0200000000000000ULL, 0x0400000000000000ULL, 0x0800000000000000ULL,
129*16467b97STreehugger Robot		0x1000000000000000ULL, 0x2000000000000000ULL, 0x4000000000000000ULL, 0x8000000000000000ULL
130*16467b97STreehugger Robot	};
131*16467b97STreehugger Robot
132*16467b97STreehugger Robot	return bitMask;
133*16467b97STreehugger Robot}
134*16467b97STreehugger Robot
135*16467b97STreehugger Robottemplate< class ImplTraits, class DataType >
136*16467b97STreehugger RobotIntTrie<ImplTraits, DataType>::IntTrie( ANTLR_UINT32 depth )
137*16467b97STreehugger Robot{
138*16467b97STreehugger Robot	/* Now we need to allocate the root node. This makes it easier
139*16467b97STreehugger Robot	 * to use the tree as we don't have to do anything special
140*16467b97STreehugger Robot	 * for the root node.
141*16467b97STreehugger Robot	 */
142*16467b97STreehugger Robot	m_root	= new IntTrieNodeType;
143*16467b97STreehugger Robot
144*16467b97STreehugger Robot	/* Now we seed the root node with the index being the
145*16467b97STreehugger Robot	 * highest left most bit we want to test, which limits the
146*16467b97STreehugger Robot	 * keys in the trie. This is the trie 'depth'. The limit for
147*16467b97STreehugger Robot	 * this implementation is 63 (bits 0..63).
148*16467b97STreehugger Robot	 */
149*16467b97STreehugger Robot	m_root->set_bitNum( depth );
150*16467b97STreehugger Robot
151*16467b97STreehugger Robot	/* And as we have nothing in here yet, we set both child pointers
152*16467b97STreehugger Robot	 * of the root node to point back to itself.
153*16467b97STreehugger Robot	 */
154*16467b97STreehugger Robot	m_root->set_leftN( m_root );
155*16467b97STreehugger Robot	m_root->set_rightN( m_root );
156*16467b97STreehugger Robot	m_count			= 0;
157*16467b97STreehugger Robot
158*16467b97STreehugger Robot	/* Finally, note that the key for this root node is 0 because
159*16467b97STreehugger Robot	 * we use calloc() to initialise it.
160*16467b97STreehugger Robot	 */
161*16467b97STreehugger Robot	m_allowDups = false;
162*16467b97STreehugger Robot	m_current   = NULL;
163*16467b97STreehugger Robot}
164*16467b97STreehugger Robot
165*16467b97STreehugger Robottemplate< class ImplTraits, class DataType >
166*16467b97STreehugger RobotIntTrie<ImplTraits, DataType>::~IntTrie()
167*16467b97STreehugger Robot{
168*16467b97STreehugger Robot    /* Descend from the root and free all the nodes
169*16467b97STreehugger Robot     */
170*16467b97STreehugger Robot    delete m_root;
171*16467b97STreehugger Robot
172*16467b97STreehugger Robot    /* the nodes are all gone now, so we need only free the memory
173*16467b97STreehugger Robot     * for the structure itself
174*16467b97STreehugger Robot     */
175*16467b97STreehugger Robot}
176*16467b97STreehugger Robot
177*16467b97STreehugger Robottemplate< class ImplTraits, class DataType >
178*16467b97STreehugger Robottypename IntTrie<ImplTraits, DataType>::TrieEntryType*	IntTrie<ImplTraits, DataType>::get( ANTLR_INTKEY key)
179*16467b97STreehugger Robot{
180*16467b97STreehugger Robot	IntTrieNodeType*    thisNode;
181*16467b97STreehugger Robot	IntTrieNodeType*    nextNode;
182*16467b97STreehugger Robot
183*16467b97STreehugger Robot	if (m_count == 0)
184*16467b97STreehugger Robot		return NULL;	    /* Nothing in this trie yet	*/
185*16467b97STreehugger Robot
186*16467b97STreehugger Robot	/* Starting at the root node in the trie, compare the bit index
187*16467b97STreehugger Robot	 * of the current node with its next child node (starts left from root).
188*16467b97STreehugger Robot	 * When the bit index of the child node is greater than the bit index of the current node
189*16467b97STreehugger Robot	 * then by definition (as the bit index decreases as we descent the trie)
190*16467b97STreehugger Robot	 * we have reached a 'backward' pointer. A backward pointer means we
191*16467b97STreehugger Robot	 * have reached the only node that can be reached by the bits given us so far
192*16467b97STreehugger Robot	 * and it must either be the key we are looking for, or if not then it
193*16467b97STreehugger Robot	 * means the entry was not in the trie, and we return NULL. A backward pointer
194*16467b97STreehugger Robot	 * points back in to the tree structure rather than down (deeper) within the
195*16467b97STreehugger Robot	 * tree branches.
196*16467b97STreehugger Robot	 */
197*16467b97STreehugger Robot	thisNode	= m_root;		/* Start at the root node		*/
198*16467b97STreehugger Robot	nextNode	= thisNode->get_leftN();	/* Examine the left node from the root	*/
199*16467b97STreehugger Robot
200*16467b97STreehugger Robot	/* While we are descending the tree nodes...
201*16467b97STreehugger Robot	 */
202*16467b97STreehugger Robot	const ANTLR_UINT64* bitMask = this->get_bitMask();
203*16467b97STreehugger Robot	while( thisNode->get_bitNum() > nextNode->get_bitNum() )
204*16467b97STreehugger Robot	{
205*16467b97STreehugger Robot		/* Next node now becomes the new 'current' node
206*16467b97STreehugger Robot		 */
207*16467b97STreehugger Robot		thisNode    = nextNode;
208*16467b97STreehugger Robot
209*16467b97STreehugger Robot		/* We now test the bit indicated by the bitmap in the next node
210*16467b97STreehugger Robot		 * in the key we are searching for. The new next node is the
211*16467b97STreehugger Robot		 * right node if that bit is set and the left node it is not.
212*16467b97STreehugger Robot		 */
213*16467b97STreehugger Robot		if (key & bitMask[nextNode->get_bitNum()])
214*16467b97STreehugger Robot		{
215*16467b97STreehugger Robot			nextNode = nextNode->get_rightN();	/* 1 is right	*/
216*16467b97STreehugger Robot		}
217*16467b97STreehugger Robot		else
218*16467b97STreehugger Robot		{
219*16467b97STreehugger Robot			nextNode = nextNode->get_leftN();		/* 0 is left	*/
220*16467b97STreehugger Robot		}
221*16467b97STreehugger Robot	}
222*16467b97STreehugger Robot
223*16467b97STreehugger Robot	/* Here we have reached a node where the bitMap index is lower than
224*16467b97STreehugger Robot	 * its parent. This means it is pointing backward in the tree and
225*16467b97STreehugger Robot	 * must therefore be a terminal node, being the only point than can
226*16467b97STreehugger Robot	 * be reached with the bits seen so far. It is either the actual key
227*16467b97STreehugger Robot	 * we wanted, or if that key is not in the trie it is another key
228*16467b97STreehugger Robot	 * that is currently the only one that can be reached by those bits.
229*16467b97STreehugger Robot	 * That situation would obviously change if the key was to be added
230*16467b97STreehugger Robot	 * to the trie.
231*16467b97STreehugger Robot	 *
232*16467b97STreehugger Robot	 * Hence it only remains to test whether this is actually the key or not.
233*16467b97STreehugger Robot	 */
234*16467b97STreehugger Robot	if (nextNode->get_key() == key)
235*16467b97STreehugger Robot	{
236*16467b97STreehugger Robot		/* This was the key, so return the entry pointer
237*16467b97STreehugger Robot		 */
238*16467b97STreehugger Robot		return	nextNode->get_buckets();
239*16467b97STreehugger Robot	}
240*16467b97STreehugger Robot	else
241*16467b97STreehugger Robot	{
242*16467b97STreehugger Robot		return	NULL;	/* That key is not in the trie (note that we set the pointer to -1 if no payload) */
243*16467b97STreehugger Robot	}
244*16467b97STreehugger Robot}
245*16467b97STreehugger Robot
246*16467b97STreehugger Robottemplate< class ImplTraits, class DataType >
247*16467b97STreehugger Robotbool	IntTrie<ImplTraits, DataType>::del( ANTLR_INTKEY key)
248*16467b97STreehugger Robot{
249*16467b97STreehugger Robot    IntTrieNodeType*   p;
250*16467b97STreehugger Robot
251*16467b97STreehugger Robot    p = m_root;
252*16467b97STreehugger Robot
253*16467b97STreehugger Robot    return false;
254*16467b97STreehugger Robot
255*16467b97STreehugger Robot}
256*16467b97STreehugger Robot
257*16467b97STreehugger Robottemplate< class ImplTraits, class DataType >
258*16467b97STreehugger Robotbool	IntTrie<ImplTraits, DataType>::add( ANTLR_INTKEY key, const DataType& data  )
259*16467b97STreehugger Robot{
260*16467b97STreehugger Robot	IntTrieNodeType*   thisNode;
261*16467b97STreehugger Robot	IntTrieNodeType*   nextNode;
262*16467b97STreehugger Robot	IntTrieNodeType*   entNode;
263*16467b97STreehugger Robot	ANTLR_UINT32	depth;
264*16467b97STreehugger Robot	TrieEntryType*	    newEnt;
265*16467b97STreehugger Robot	TrieEntryType*	    nextEnt;
266*16467b97STreehugger Robot	ANTLR_INTKEY		    xorKey;
267*16467b97STreehugger Robot
268*16467b97STreehugger Robot	/* Cache the bit depth of this trie, which is always the highest index,
269*16467b97STreehugger Robot	 * which is in the root node
270*16467b97STreehugger Robot	 */
271*16467b97STreehugger Robot	depth   = m_root->get_bitNum();
272*16467b97STreehugger Robot
273*16467b97STreehugger Robot	thisNode	= m_root;		/* Start with the root node	    */
274*16467b97STreehugger Robot	nextNode	= m_root->get_leftN();	/* And assume we start to the left  */
275*16467b97STreehugger Robot
276*16467b97STreehugger Robot	/* Now find the only node that can be currently reached by the bits in the
277*16467b97STreehugger Robot	 * key we are being asked to insert.
278*16467b97STreehugger Robot	 */
279*16467b97STreehugger Robot	const ANTLR_UINT64* bitMask = this->get_bitMask();
280*16467b97STreehugger Robot	while (thisNode->get_bitNum()  > nextNode->get_bitNum() )
281*16467b97STreehugger Robot	{
282*16467b97STreehugger Robot		/* Still descending the structure, next node becomes current.
283*16467b97STreehugger Robot		 */
284*16467b97STreehugger Robot		thisNode = nextNode;
285*16467b97STreehugger Robot
286*16467b97STreehugger Robot		if (key & bitMask[nextNode->get_bitNum()])
287*16467b97STreehugger Robot		{
288*16467b97STreehugger Robot			/* Bit at the required index was 1, so travers the right node from here
289*16467b97STreehugger Robot			 */
290*16467b97STreehugger Robot			nextNode = nextNode->get_rightN();
291*16467b97STreehugger Robot		}
292*16467b97STreehugger Robot		else
293*16467b97STreehugger Robot		{
294*16467b97STreehugger Robot			/* Bit at the required index was 0, so we traverse to the left
295*16467b97STreehugger Robot			 */
296*16467b97STreehugger Robot			nextNode = nextNode->get_leftN();
297*16467b97STreehugger Robot		}
298*16467b97STreehugger Robot	}
299*16467b97STreehugger Robot	/* Here we have located the only node that can be reached by the
300*16467b97STreehugger Robot	 * bits in the requested key. It could in fact be that key or the node
301*16467b97STreehugger Robot	 * we need to use to insert the new key.
302*16467b97STreehugger Robot	 */
303*16467b97STreehugger Robot	if (nextNode->get_key() == key)
304*16467b97STreehugger Robot	{
305*16467b97STreehugger Robot		/* We have located an exact match, but we will only append to the bucket chain
306*16467b97STreehugger Robot		 * if this trie accepts duplicate keys.
307*16467b97STreehugger Robot		 */
308*16467b97STreehugger Robot		if (m_allowDups ==true)
309*16467b97STreehugger Robot		{
310*16467b97STreehugger Robot			/* Yes, we are accepting duplicates
311*16467b97STreehugger Robot			 */
312*16467b97STreehugger Robot			newEnt = new TrieEntryType(data, NULL);
313*16467b97STreehugger Robot
314*16467b97STreehugger Robot			/* We want to be able to traverse the stored elements in the order that they were
315*16467b97STreehugger Robot			 * added as duplicate keys. We might need to revise this opinion if we end up having many duplicate keys
316*16467b97STreehugger Robot			 * as perhaps reverse order is just as good, so long as it is ordered.
317*16467b97STreehugger Robot			 */
318*16467b97STreehugger Robot			nextEnt = nextNode->get_buckets();
319*16467b97STreehugger Robot			while (nextEnt->get_next() != NULL)
320*16467b97STreehugger Robot			{
321*16467b97STreehugger Robot				nextEnt = nextEnt->get_next();
322*16467b97STreehugger Robot			}
323*16467b97STreehugger Robot			nextEnt->set_next(newEnt);
324*16467b97STreehugger Robot
325*16467b97STreehugger Robot			m_count++;
326*16467b97STreehugger Robot			return  true;
327*16467b97STreehugger Robot		}
328*16467b97STreehugger Robot		else
329*16467b97STreehugger Robot		{
330*16467b97STreehugger Robot			/* We found the key is already there and we are not allowed duplicates in this
331*16467b97STreehugger Robot			 * trie.
332*16467b97STreehugger Robot			 */
333*16467b97STreehugger Robot			return  false;
334*16467b97STreehugger Robot		}
335*16467b97STreehugger Robot	}
336*16467b97STreehugger Robot
337*16467b97STreehugger Robot	/* Here we have discovered the only node that can be reached by the bits in the key
338*16467b97STreehugger Robot	 * but we have found that this node is not the key we need to insert. We must find the
339*16467b97STreehugger Robot	 * the leftmost bit by which the current key for that node and the new key we are going
340*16467b97STreehugger Robot	 * to insert, differ. While this nested series of ifs may look a bit strange, experimentation
341*16467b97STreehugger Robot	 * showed that it allows a machine code path that works well with predicated execution
342*16467b97STreehugger Robot	 */
343*16467b97STreehugger Robot	xorKey = (key ^ nextNode->get_key() );   /* Gives 1 bits only where they differ then we find the left most 1 bit*/
344*16467b97STreehugger Robot
345*16467b97STreehugger Robot	/* Most common case is a 32 bit key really
346*16467b97STreehugger Robot	 */
347*16467b97STreehugger Robot	const ANTLR_UINT8* bitIndex = this->get_bitIndex();
348*16467b97STreehugger Robot#ifdef	ANTLR_USE_64BIT
349*16467b97STreehugger Robot	if	(xorKey & 0xFFFFFFFF00000000)
350*16467b97STreehugger Robot	{
351*16467b97STreehugger Robot		if  (xorKey & 0xFFFF000000000000)
352*16467b97STreehugger Robot		{
353*16467b97STreehugger Robot			if	(xorKey & 0xFF00000000000000)
354*16467b97STreehugger Robot			{
355*16467b97STreehugger Robot				depth = 56 + bitIndex[((xorKey & 0xFF00000000000000)>>56)];
356*16467b97STreehugger Robot			}
357*16467b97STreehugger Robot			else
358*16467b97STreehugger Robot			{
359*16467b97STreehugger Robot				depth = 48 + bitIndex[((xorKey & 0x00FF000000000000)>>48)];
360*16467b97STreehugger Robot			}
361*16467b97STreehugger Robot		}
362*16467b97STreehugger Robot		else
363*16467b97STreehugger Robot		{
364*16467b97STreehugger Robot			if	(xorKey & 0x0000FF0000000000)
365*16467b97STreehugger Robot			{
366*16467b97STreehugger Robot				depth = 40 + bitIndex[((xorKey & 0x0000FF0000000000)>>40)];
367*16467b97STreehugger Robot			}
368*16467b97STreehugger Robot			else
369*16467b97STreehugger Robot			{
370*16467b97STreehugger Robot				depth = 32 + bitIndex[((xorKey & 0x000000FF00000000)>>32)];
371*16467b97STreehugger Robot			}
372*16467b97STreehugger Robot		}
373*16467b97STreehugger Robot	}
374*16467b97STreehugger Robot	else
375*16467b97STreehugger Robot#endif
376*16467b97STreehugger Robot	{
377*16467b97STreehugger Robot		if  (xorKey & 0x00000000FFFF0000)
378*16467b97STreehugger Robot		{
379*16467b97STreehugger Robot			if	(xorKey & 0x00000000FF000000)
380*16467b97STreehugger Robot			{
381*16467b97STreehugger Robot				depth = 24 + bitIndex[((xorKey & 0x00000000FF000000)>>24)];
382*16467b97STreehugger Robot			}
383*16467b97STreehugger Robot			else
384*16467b97STreehugger Robot			{
385*16467b97STreehugger Robot				depth = 16 + bitIndex[((xorKey & 0x0000000000FF0000)>>16)];
386*16467b97STreehugger Robot			}
387*16467b97STreehugger Robot		}
388*16467b97STreehugger Robot		else
389*16467b97STreehugger Robot		{
390*16467b97STreehugger Robot			if	(xorKey & 0x000000000000FF00)
391*16467b97STreehugger Robot			{
392*16467b97STreehugger Robot				depth = 8 + bitIndex[((xorKey & 0x0000000000000FF00)>>8)];
393*16467b97STreehugger Robot			}
394*16467b97STreehugger Robot			else
395*16467b97STreehugger Robot			{
396*16467b97STreehugger Robot				depth = bitIndex[xorKey & 0x00000000000000FF];
397*16467b97STreehugger Robot			}
398*16467b97STreehugger Robot		}
399*16467b97STreehugger Robot	}
400*16467b97STreehugger Robot
401*16467b97STreehugger Robot    /* We have located the leftmost differing bit, indicated by the depth variable. So, we know what
402*16467b97STreehugger Robot     * bit index we are to insert the new entry at. There are two cases, being where the two keys
403*16467b97STreehugger Robot     * differ at a bit position that is not currently part of the bit testing, where they differ on a bit
404*16467b97STreehugger Robot     * that is currently being skipped in the indexed comparisons, and where they differ on a bit
405*16467b97STreehugger Robot     * that is merely lower down in the current bit search. If the bit index went bit 4, bit 2 and they differ
406*16467b97STreehugger Robot     * at bit 3, then we have the "skipped" bit case. But if that chain was Bit 4, Bit 2 and they differ at bit 1
407*16467b97STreehugger Robot     * then we have the easy bit <pun>.
408*16467b97STreehugger Robot     *
409*16467b97STreehugger Robot     * So, set up to descend the tree again, but this time looking for the insert point
410*16467b97STreehugger Robot     * according to whether we skip the bit that differs or not.
411*16467b97STreehugger Robot     */
412*16467b97STreehugger Robot    thisNode	= m_root;
413*16467b97STreehugger Robot    entNode	= m_root->get_leftN();
414*16467b97STreehugger Robot
415*16467b97STreehugger Robot    /* Note the slight difference in the checks here to cover both cases
416*16467b97STreehugger Robot     */
417*16467b97STreehugger Robot    while (thisNode->get_bitNum() > entNode->get_bitNum() && entNode->get_bitNum() > depth)
418*16467b97STreehugger Robot    {
419*16467b97STreehugger Robot		/* Still descending the structure, next node becomes current.
420*16467b97STreehugger Robot		 */
421*16467b97STreehugger Robot		thisNode = entNode;
422*16467b97STreehugger Robot
423*16467b97STreehugger Robot		if (key & bitMask[entNode->get_bitNum()])
424*16467b97STreehugger Robot		{
425*16467b97STreehugger Robot			/* Bit at the required index was 1, so traverse the right node from here
426*16467b97STreehugger Robot			 */
427*16467b97STreehugger Robot			entNode = entNode->get_rightN();
428*16467b97STreehugger Robot		}
429*16467b97STreehugger Robot		else
430*16467b97STreehugger Robot		{
431*16467b97STreehugger Robot			/* Bit at the required index was 0, so we traverse to the left
432*16467b97STreehugger Robot			 */
433*16467b97STreehugger Robot			entNode = entNode->get_leftN();
434*16467b97STreehugger Robot		}
435*16467b97STreehugger Robot    }
436*16467b97STreehugger Robot
437*16467b97STreehugger Robot    /* We have located the correct insert point for this new key, so we need
438*16467b97STreehugger Robot     * to allocate our entry and insert it etc.
439*16467b97STreehugger Robot     */
440*16467b97STreehugger Robot    nextNode	= new IntTrieNodeType();
441*16467b97STreehugger Robot
442*16467b97STreehugger Robot    /* Build a new entry block for the new node
443*16467b97STreehugger Robot     */
444*16467b97STreehugger Robot    newEnt = new TrieEntryType(data, NULL);
445*16467b97STreehugger Robot
446*16467b97STreehugger Robot	/* Install it
447*16467b97STreehugger Robot     */
448*16467b97STreehugger Robot    nextNode->set_buckets(newEnt);
449*16467b97STreehugger Robot    nextNode->set_key(key);
450*16467b97STreehugger Robot    nextNode->set_bitNum( depth );
451*16467b97STreehugger Robot
452*16467b97STreehugger Robot    /* Work out the right and left pointers for this new node, which involve
453*16467b97STreehugger Robot     * terminating with the current found node either right or left according
454*16467b97STreehugger Robot     * to whether the current index bit is 1 or 0
455*16467b97STreehugger Robot     */
456*16467b97STreehugger Robot    if (key & bitMask[depth])
457*16467b97STreehugger Robot    {
458*16467b97STreehugger Robot		nextNode->set_leftN(entNode);	    /* Terminates at previous position	*/
459*16467b97STreehugger Robot		nextNode->set_rightN(nextNode);	    /* Terminates with itself		*/
460*16467b97STreehugger Robot    }
461*16467b97STreehugger Robot    else
462*16467b97STreehugger Robot    {
463*16467b97STreehugger Robot		nextNode->set_rightN(entNode);	    /* Terminates at previous position	*/
464*16467b97STreehugger Robot		nextNode->set_leftN(nextNode);	    /* Terminates with itself		*/
465*16467b97STreehugger Robot    }
466*16467b97STreehugger Robot
467*16467b97STreehugger Robot    /* Finally, we need to change the pointers at the node we located
468*16467b97STreehugger Robot     * for inserting. If the key bit at its index is set then the right
469*16467b97STreehugger Robot     * pointer for that node becomes the newly created node, otherwise the left
470*16467b97STreehugger Robot     * pointer does.
471*16467b97STreehugger Robot     */
472*16467b97STreehugger Robot    if (key & bitMask[thisNode->get_bitNum()] )
473*16467b97STreehugger Robot    {
474*16467b97STreehugger Robot		thisNode->set_rightN( nextNode );
475*16467b97STreehugger Robot    }
476*16467b97STreehugger Robot    else
477*16467b97STreehugger Robot    {
478*16467b97STreehugger Robot		thisNode->set_leftN(nextNode);
479*16467b97STreehugger Robot    }
480*16467b97STreehugger Robot
481*16467b97STreehugger Robot    /* Et voila
482*16467b97STreehugger Robot     */
483*16467b97STreehugger Robot    m_count++;
484*16467b97STreehugger Robot    return  true;
485*16467b97STreehugger Robot}
486*16467b97STreehugger Robot
487*16467b97STreehugger Robottemplate< class ImplTraits, class DataType >
488*16467b97STreehugger RobotIntTrieNode<ImplTraits, DataType>::IntTrieNode()
489*16467b97STreehugger Robot{
490*16467b97STreehugger Robot	m_bitNum = 0;
491*16467b97STreehugger Robot	m_key = 0;
492*16467b97STreehugger Robot	m_buckets = NULL;
493*16467b97STreehugger Robot	m_leftN = NULL;
494*16467b97STreehugger Robot	m_rightN = NULL;
495*16467b97STreehugger Robot}
496*16467b97STreehugger Robot
497*16467b97STreehugger Robottemplate< class ImplTraits, class DataType >
498*16467b97STreehugger RobotIntTrieNode<ImplTraits, DataType>::~IntTrieNode()
499*16467b97STreehugger Robot{
500*16467b97STreehugger Robot	TrieEntryType*	thisEntry;
501*16467b97STreehugger Robot    TrieEntryType*	nextEntry;
502*16467b97STreehugger Robot
503*16467b97STreehugger Robot    /* If this node has a left pointer that is not a back pointer
504*16467b97STreehugger Robot     * then recursively call to free this
505*16467b97STreehugger Robot     */
506*16467b97STreehugger Robot    if ( m_bitNum > m_leftN->get_bitNum())
507*16467b97STreehugger Robot    {
508*16467b97STreehugger Robot		/* We have a left node that needs descending, so do it.
509*16467b97STreehugger Robot		 */
510*16467b97STreehugger Robot		delete m_leftN;
511*16467b97STreehugger Robot    }
512*16467b97STreehugger Robot
513*16467b97STreehugger Robot    /* The left nodes from here should now be dealt with, so
514*16467b97STreehugger Robot     * we need to descend any right nodes that are not back pointers
515*16467b97STreehugger Robot     */
516*16467b97STreehugger Robot    if ( m_bitNum > m_rightN->get_bitNum() )
517*16467b97STreehugger Robot    {
518*16467b97STreehugger Robot		/* There are some right nodes to descend and deal with.
519*16467b97STreehugger Robot		 */
520*16467b97STreehugger Robot		delete m_rightN;
521*16467b97STreehugger Robot    }
522*16467b97STreehugger Robot
523*16467b97STreehugger Robot    /* Now all the children are dealt with, we can destroy
524*16467b97STreehugger Robot     * this node too
525*16467b97STreehugger Robot     */
526*16467b97STreehugger Robot    thisEntry	= m_buckets;
527*16467b97STreehugger Robot
528*16467b97STreehugger Robot    while (thisEntry != NULL)
529*16467b97STreehugger Robot    {
530*16467b97STreehugger Robot		nextEntry   = thisEntry->get_next();
531*16467b97STreehugger Robot
532*16467b97STreehugger Robot		/* Now free the data for this bucket entry
533*16467b97STreehugger Robot		 */
534*16467b97STreehugger Robot		delete thisEntry;
535*16467b97STreehugger Robot		thisEntry = nextEntry;	    /* See if there are any more to free    */
536*16467b97STreehugger Robot    }
537*16467b97STreehugger Robot
538*16467b97STreehugger Robot    /* The bucket entry is now gone, so we can free the memory for
539*16467b97STreehugger Robot     * the entry itself.
540*16467b97STreehugger Robot     */
541*16467b97STreehugger Robot
542*16467b97STreehugger Robot    /* And that should be it for everything under this node and itself
543*16467b97STreehugger Robot     */
544*16467b97STreehugger Robot}
545*16467b97STreehugger Robot
546*16467b97STreehugger Robot/**
547*16467b97STreehugger Robot * Allocate and initialize a new ANTLR3 topological sorter, which can be
548*16467b97STreehugger Robot * used to define edges that identify numerical node indexes that depend on other
549*16467b97STreehugger Robot * numerical node indexes, which can then be sorted topologically such that
550*16467b97STreehugger Robot * any node is sorted after all its dependent nodes.
551*16467b97STreehugger Robot *
552*16467b97STreehugger Robot * Use:
553*16467b97STreehugger Robot *
554*16467b97STreehugger Robot * /verbatim
555*16467b97STreehugger Robot
556*16467b97STreehugger Robot  pANTLR3_TOPO topo;
557*16467b97STreehugger Robot  topo = antlr3NewTopo();
558*16467b97STreehugger Robot
559*16467b97STreehugger Robot  if (topo == NULL) { out of memory }
560*16467b97STreehugger Robot
561*16467b97STreehugger Robot  topo->addEdge(topo, 3, 0); // Node 3 depends on node 0
562*16467b97STreehugger Robot  topo->addEdge(topo, 0, 1); // Node - depends on node 1
563*16467b97STreehugger Robot  topo->sortVector(topo, myVector); // Sort the vector in place (node numbers are the vector entry numbers)
564*16467b97STreehugger Robot
565*16467b97STreehugger Robot * /verbatim
566*16467b97STreehugger Robot */
567*16467b97STreehugger Robottemplate<class ImplTraits>
568*16467b97STreehugger RobotTopo<ImplTraits>::Topo()
569*16467b97STreehugger Robot{
570*16467b97STreehugger Robot    // Initialize variables
571*16467b97STreehugger Robot    //
572*16467b97STreehugger Robot    m_visited   = NULL;                 // Don't know how big it is yet
573*16467b97STreehugger Robot    m_limit     = 1;                    // No edges added yet
574*16467b97STreehugger Robot    m_edges     = NULL;                 // No edges added yet
575*16467b97STreehugger Robot    m_sorted    = NULL;                 // Nothing sorted at the start
576*16467b97STreehugger Robot    m_cycle     = NULL;                 // No cycles at the start
577*16467b97STreehugger Robot    m_cycleMark = 0;                    // No cycles at the start
578*16467b97STreehugger Robot    m_hasCycle  = false;         // No cycle at the start
579*16467b97STreehugger Robot}
580*16467b97STreehugger Robot
581*16467b97STreehugger Robot// Topological sorter
582*16467b97STreehugger Robot//
583*16467b97STreehugger Robottemplate<class ImplTraits>
584*16467b97STreehugger Robotvoid Topo<ImplTraits>::addEdge(ANTLR_UINT32 edge, ANTLR_UINT32 dependency)
585*16467b97STreehugger Robot{
586*16467b97STreehugger Robot	ANTLR_UINT32   i;
587*16467b97STreehugger Robot    ANTLR_UINT32   maxEdge;
588*16467b97STreehugger Robot    BitsetType*  edgeDeps;
589*16467b97STreehugger Robot
590*16467b97STreehugger Robot    if (edge>dependency)
591*16467b97STreehugger Robot    {
592*16467b97STreehugger Robot        maxEdge = edge;
593*16467b97STreehugger Robot    }
594*16467b97STreehugger Robot    else
595*16467b97STreehugger Robot    {
596*16467b97STreehugger Robot        maxEdge = dependency;
597*16467b97STreehugger Robot    }
598*16467b97STreehugger Robot    // We need to add an edge to says that the node indexed by 'edge' is
599*16467b97STreehugger Robot    // dependent on the node indexed by 'dependency'
600*16467b97STreehugger Robot    //
601*16467b97STreehugger Robot
602*16467b97STreehugger Robot    // First see if we have enough room in the edges array to add the edge?
603*16467b97STreehugger Robot    //
604*16467b97STreehugger Robot    if ( m_edges == NULL)
605*16467b97STreehugger Robot    {
606*16467b97STreehugger Robot        // We don't have any edges yet, so create an array to hold them
607*16467b97STreehugger Robot        //
608*16467b97STreehugger Robot        m_edges = AllocPolicyType::alloc0(sizeof(BitsetType*) * (maxEdge + 1));
609*16467b97STreehugger Robot
610*16467b97STreehugger Robot        // Set the limit to what we have now
611*16467b97STreehugger Robot        //
612*16467b97STreehugger Robot        m_limit = maxEdge + 1;
613*16467b97STreehugger Robot    }
614*16467b97STreehugger Robot    else if (m_limit <= maxEdge)
615*16467b97STreehugger Robot    {
616*16467b97STreehugger Robot        // WE have some edges but not enough
617*16467b97STreehugger Robot        //
618*16467b97STreehugger Robot        m_edges = AllocPolicyType::realloc(m_edges, sizeof(BitsetType*) * (maxEdge + 1));
619*16467b97STreehugger Robot
620*16467b97STreehugger Robot        // Initialize the new bitmaps to ;indicate we have no edges defined yet
621*16467b97STreehugger Robot        //
622*16467b97STreehugger Robot        for (i = m_limit; i <= maxEdge; i++)
623*16467b97STreehugger Robot        {
624*16467b97STreehugger Robot            *((m_edges) + i) = NULL;
625*16467b97STreehugger Robot        }
626*16467b97STreehugger Robot
627*16467b97STreehugger Robot        // Set the limit to what we have now
628*16467b97STreehugger Robot        //
629*16467b97STreehugger Robot        m_limit = maxEdge + 1;
630*16467b97STreehugger Robot    }
631*16467b97STreehugger Robot
632*16467b97STreehugger Robot    // If the edge was flagged as depending on itself, then we just
633*16467b97STreehugger Robot    // do nothing as it means this routine was just called to add it
634*16467b97STreehugger Robot    // in to the list of nodes.
635*16467b97STreehugger Robot    //
636*16467b97STreehugger Robot    if  (edge == dependency)
637*16467b97STreehugger Robot    {
638*16467b97STreehugger Robot        return;
639*16467b97STreehugger Robot    }
640*16467b97STreehugger Robot
641*16467b97STreehugger Robot    // Pick up the bit map for the requested edge
642*16467b97STreehugger Robot    //
643*16467b97STreehugger Robot    edgeDeps = *((m_edges) + edge);
644*16467b97STreehugger Robot
645*16467b97STreehugger Robot    if  (edgeDeps == NULL)
646*16467b97STreehugger Robot    {
647*16467b97STreehugger Robot        // No edges are defined yet for this node
648*16467b97STreehugger Robot        //
649*16467b97STreehugger Robot        edgeDeps                = new BitsetType(0);
650*16467b97STreehugger Robot        *((m_edges) + edge) = edgeDeps;
651*16467b97STreehugger Robot    }
652*16467b97STreehugger Robot
653*16467b97STreehugger Robot    // Set the bit in the bitmap that corresponds to the requested
654*16467b97STreehugger Robot    // dependency.
655*16467b97STreehugger Robot    //
656*16467b97STreehugger Robot    edgeDeps->add(dependency);
657*16467b97STreehugger Robot
658*16467b97STreehugger Robot    // And we are all set
659*16467b97STreehugger Robot    //
660*16467b97STreehugger Robot    return;
661*16467b97STreehugger Robot
662*16467b97STreehugger Robot}
663*16467b97STreehugger Robot
664*16467b97STreehugger Robot/**
665*16467b97STreehugger Robot * Given a starting node, descend its dependent nodes (ones that it has edges
666*16467b97STreehugger Robot * to) until we find one without edges. Having found a node without edges, we have
667*16467b97STreehugger Robot * discovered the bottom of a depth first search, which we can then ascend, adding
668*16467b97STreehugger Robot * the nodes in order from the bottom, which gives us the dependency order.
669*16467b97STreehugger Robot */
670*16467b97STreehugger Robottemplate<class ImplTraits>
671*16467b97STreehugger Robotvoid Topo<ImplTraits>::DFS(ANTLR_UINT32 node)
672*16467b97STreehugger Robot{
673*16467b97STreehugger Robot	BitsetType* edges;
674*16467b97STreehugger Robot
675*16467b97STreehugger Robot    // Guard against a revisit and check for cycles
676*16467b97STreehugger Robot    //
677*16467b97STreehugger Robot    if  (m_hasCycle == true)
678*16467b97STreehugger Robot    {
679*16467b97STreehugger Robot        return; // We don't do anything else if we found a cycle
680*16467b97STreehugger Robot    }
681*16467b97STreehugger Robot
682*16467b97STreehugger Robot    if  ( m_visited->isMember(node))
683*16467b97STreehugger Robot    {
684*16467b97STreehugger Robot        // Check to see if we found a cycle. To do this we search the
685*16467b97STreehugger Robot        // current cycle stack and see if we find this node already in the stack.
686*16467b97STreehugger Robot        //
687*16467b97STreehugger Robot        ANTLR_UINT32   i;
688*16467b97STreehugger Robot
689*16467b97STreehugger Robot        for (i=0; i< m_cycleMark; i++)
690*16467b97STreehugger Robot        {
691*16467b97STreehugger Robot            if  ( m_cycle[i] == node)
692*16467b97STreehugger Robot            {
693*16467b97STreehugger Robot                // Stop! We found a cycle in the input, so rejig the cycle
694*16467b97STreehugger Robot                // stack so that it only contains the cycle and set the cycle flag
695*16467b97STreehugger Robot                // which will tell the caller what happened
696*16467b97STreehugger Robot                //
697*16467b97STreehugger Robot                ANTLR_UINT32 l;
698*16467b97STreehugger Robot
699*16467b97STreehugger Robot                for (l = i; l < m_cycleMark; l++)
700*16467b97STreehugger Robot                {
701*16467b97STreehugger Robot                    m_cycle[l - i] = m_cycle[l];    // Move to zero base in the cycle list
702*16467b97STreehugger Robot                }
703*16467b97STreehugger Robot
704*16467b97STreehugger Robot                // Recalculate the limit
705*16467b97STreehugger Robot                //
706*16467b97STreehugger Robot                m_cycleMark -= i;
707*16467b97STreehugger Robot
708*16467b97STreehugger Robot                // Signal disaster
709*16467b97STreehugger Robot                //
710*16467b97STreehugger Robot                m_hasCycle = true;
711*16467b97STreehugger Robot            }
712*16467b97STreehugger Robot        }
713*16467b97STreehugger Robot        return;
714*16467b97STreehugger Robot    }
715*16467b97STreehugger Robot
716*16467b97STreehugger Robot    // So far, no cycles have been found and we have not visited this node yet,
717*16467b97STreehugger Robot    // so this node needs to go into the cycle stack before we continue
718*16467b97STreehugger Robot    // then we will take it out of the stack once we have descended all its
719*16467b97STreehugger Robot    // dependencies.
720*16467b97STreehugger Robot    //
721*16467b97STreehugger Robot    m_cycle[m_cycleMark++] = node;
722*16467b97STreehugger Robot
723*16467b97STreehugger Robot    // First flag that we have visited this node
724*16467b97STreehugger Robot    //
725*16467b97STreehugger Robot    m_visited->add(node);
726*16467b97STreehugger Robot
727*16467b97STreehugger Robot    // Now, if this node has edges, then we want to ensure we visit
728*16467b97STreehugger Robot    // them all before we drop through and add this node into the sorted
729*16467b97STreehugger Robot    // list.
730*16467b97STreehugger Robot    //
731*16467b97STreehugger Robot    edges = *((m_edges) + node);
732*16467b97STreehugger Robot    if  (edges != NULL)
733*16467b97STreehugger Robot    {
734*16467b97STreehugger Robot        // We have some edges, so visit each of the edge nodes
735*16467b97STreehugger Robot        // that have not already been visited.
736*16467b97STreehugger Robot        //
737*16467b97STreehugger Robot        ANTLR_UINT32   numBits;	    // How many bits are in the set
738*16467b97STreehugger Robot        ANTLR_UINT32   i;
739*16467b97STreehugger Robot        ANTLR_UINT32   range;
740*16467b97STreehugger Robot
741*16467b97STreehugger Robot        numBits = edges->numBits();
742*16467b97STreehugger Robot        range   = edges->size();   // Number of set bits
743*16467b97STreehugger Robot
744*16467b97STreehugger Robot        // Stop if we exahust the bit list or have checked the
745*16467b97STreehugger Robot        // number of edges that this node refers to (so we don't
746*16467b97STreehugger Robot        // check bits at the end that cannot possibly be set).
747*16467b97STreehugger Robot        //
748*16467b97STreehugger Robot        for (i=0; i<= numBits && range > 0; i++)
749*16467b97STreehugger Robot        {
750*16467b97STreehugger Robot            if  (edges->isMember(i))
751*16467b97STreehugger Robot            {
752*16467b97STreehugger Robot                range--;        // About to check another one
753*16467b97STreehugger Robot
754*16467b97STreehugger Robot                // Found an edge, make sure we visit and descend it
755*16467b97STreehugger Robot                //
756*16467b97STreehugger Robot                this->DFS(i);
757*16467b97STreehugger Robot            }
758*16467b97STreehugger Robot        }
759*16467b97STreehugger Robot    }
760*16467b97STreehugger Robot
761*16467b97STreehugger Robot    // At this point we will have visited all the dependencies
762*16467b97STreehugger Robot    // of this node and they will be ordered (even if there are cycles)
763*16467b97STreehugger Robot    // So we just add the node into the sorted list at the
764*16467b97STreehugger Robot    // current index position.
765*16467b97STreehugger Robot    //
766*16467b97STreehugger Robot    m_sorted[m_limit++] = node;
767*16467b97STreehugger Robot
768*16467b97STreehugger Robot    // Remove this node from the cycle list if we have not detected a cycle
769*16467b97STreehugger Robot    //
770*16467b97STreehugger Robot    if  (m_hasCycle == false)
771*16467b97STreehugger Robot    {
772*16467b97STreehugger Robot        m_cycleMark--;
773*16467b97STreehugger Robot    }
774*16467b97STreehugger Robot
775*16467b97STreehugger Robot    return;
776*16467b97STreehugger Robot}
777*16467b97STreehugger Robot
778*16467b97STreehugger Robottemplate<class ImplTraits>
779*16467b97STreehugger RobotANTLR_UINT32*  Topo<ImplTraits>::sortToArray()
780*16467b97STreehugger Robot{
781*16467b97STreehugger Robot	ANTLR_UINT32 v;
782*16467b97STreehugger Robot    ANTLR_UINT32 oldLimit;
783*16467b97STreehugger Robot
784*16467b97STreehugger Robot    // Guard against being called with no edges defined
785*16467b97STreehugger Robot    //
786*16467b97STreehugger Robot    if  (m_edges == NULL)
787*16467b97STreehugger Robot    {
788*16467b97STreehugger Robot        return 0;
789*16467b97STreehugger Robot    }
790*16467b97STreehugger Robot    // First we need a vector to populate with enough
791*16467b97STreehugger Robot    // entries to accomodate the sorted list and another to accomodate
792*16467b97STreehugger Robot    // the maximum cycle we could detect which is all nodes such as 0->1->2->3->0
793*16467b97STreehugger Robot    //
794*16467b97STreehugger Robot    m_sorted    = AllocPolicyType::alloc( m_limit * sizeof(ANTLR_UINT32) );
795*16467b97STreehugger Robot    m_cycle     = AllocPolicyType::alloc( m_limit * sizeof(ANTLR_UINT32));
796*16467b97STreehugger Robot
797*16467b97STreehugger Robot    // Next we need an empty bitset to show whether we have visited a node
798*16467b97STreehugger Robot    // or not. This is the bit that gives us linear time of course as we are essentially
799*16467b97STreehugger Robot    // dropping through the nodes in depth first order and when we get to a node that
800*16467b97STreehugger Robot    // has no edges, we pop back up the stack adding the nodes we traversed in reverse
801*16467b97STreehugger Robot    // order.
802*16467b97STreehugger Robot    //
803*16467b97STreehugger Robot    m_visited   = new BitsetType(0);
804*16467b97STreehugger Robot
805*16467b97STreehugger Robot    // Now traverse the nodes as if we were just going left to right, but
806*16467b97STreehugger Robot    // then descend each node unless it has already been visited.
807*16467b97STreehugger Robot    //
808*16467b97STreehugger Robot    oldLimit    = m_limit;     // Number of nodes to traverse linearly
809*16467b97STreehugger Robot    m_limit = 0;               // Next entry in the sorted table
810*16467b97STreehugger Robot
811*16467b97STreehugger Robot    for (v = 0; v < oldLimit; v++)
812*16467b97STreehugger Robot    {
813*16467b97STreehugger Robot        // If we did not already visit this node, then descend it until we
814*16467b97STreehugger Robot        // get a node without edges or arrive at a node we have already visited.
815*16467b97STreehugger Robot        //
816*16467b97STreehugger Robot        if  (m_visited->isMember(v) == false)
817*16467b97STreehugger Robot        {
818*16467b97STreehugger Robot            // We have not visited this one so descend it
819*16467b97STreehugger Robot            //
820*16467b97STreehugger Robot            this->DFS(v);
821*16467b97STreehugger Robot        }
822*16467b97STreehugger Robot
823*16467b97STreehugger Robot        // Break the loop if we detect a cycle as we have no need to go any
824*16467b97STreehugger Robot        // further
825*16467b97STreehugger Robot        //
826*16467b97STreehugger Robot        if  (m_hasCycle == true)
827*16467b97STreehugger Robot        {
828*16467b97STreehugger Robot            break;
829*16467b97STreehugger Robot        }
830*16467b97STreehugger Robot    }
831*16467b97STreehugger Robot
832*16467b97STreehugger Robot    // Reset the limit to the number we recorded as if we hit a
833*16467b97STreehugger Robot    // cycle, then limit will have stopped at the node where we
834*16467b97STreehugger Robot    // discovered the cycle, but in order to free the edge bitmaps
835*16467b97STreehugger Robot    // we need to know how many we may have allocated and traverse them all.
836*16467b97STreehugger Robot    //
837*16467b97STreehugger Robot    m_limit = oldLimit;
838*16467b97STreehugger Robot
839*16467b97STreehugger Robot    // Having traversed all the nodes we were given, we
840*16467b97STreehugger Robot    // are guaranteed to have ordered all the nodes or detected a
841*16467b97STreehugger Robot    // cycle.
842*16467b97STreehugger Robot    //
843*16467b97STreehugger Robot    return m_sorted;
844*16467b97STreehugger Robot}
845*16467b97STreehugger Robot
846*16467b97STreehugger Robottemplate<class ImplTraits>
847*16467b97STreehugger Robot	template<typename DataType>
848*16467b97STreehugger Robotvoid   Topo<ImplTraits>::sortVector(  typename ImplTraits::template VectorType<DataType>& v )
849*16467b97STreehugger Robot{
850*16467b97STreehugger Robot    // To sort a vector, we first perform the
851*16467b97STreehugger Robot    // sort to an array, then use the results to reorder the vector
852*16467b97STreehugger Robot    // we are given. This is just a convenience routine that allows you to
853*16467b97STreehugger Robot    // sort the children of a tree node into topological order before or
854*16467b97STreehugger Robot    // during an AST walk. This can be useful for optimizations that require
855*16467b97STreehugger Robot    // dag reorders and also when the input stream defines thigns that are
856*16467b97STreehugger Robot    // interdependent and you want to walk the list of the generated trees
857*16467b97STreehugger Robot    // for those things in topological order so you can ignore the interdependencies
858*16467b97STreehugger Robot    // at that point.
859*16467b97STreehugger Robot    //
860*16467b97STreehugger Robot    ANTLR_UINT32 i;
861*16467b97STreehugger Robot
862*16467b97STreehugger Robot    // Used as a lookup index to find the current location in the vector of
863*16467b97STreehugger Robot    // the vector entry that was originally at position [0], [1], [2] etc
864*16467b97STreehugger Robot    //
865*16467b97STreehugger Robot    ANTLR_UINT32*  vIndex;
866*16467b97STreehugger Robot
867*16467b97STreehugger Robot    // Sort into an array, then we can use the array that is
868*16467b97STreehugger Robot    // stored in the topo
869*16467b97STreehugger Robot    //
870*16467b97STreehugger Robot    if  (this->sortToArray() == 0)
871*16467b97STreehugger Robot    {
872*16467b97STreehugger Robot        return;     // There were no edges
873*16467b97STreehugger Robot    }
874*16467b97STreehugger Robot
875*16467b97STreehugger Robot    if  (m_hasCycle == true)
876*16467b97STreehugger Robot    {
877*16467b97STreehugger Robot        return;  // Do nothing if we detected a cycle
878*16467b97STreehugger Robot    }
879*16467b97STreehugger Robot
880*16467b97STreehugger Robot    // Ensure that the vector we are sorting is at least as big as the
881*16467b97STreehugger Robot    // the input sequence we were adsked to sort. It does not matter if it is
882*16467b97STreehugger Robot    // bigger as thaat probably just means that nodes numbered higher than the
883*16467b97STreehugger Robot    // limit had no dependencies and so can be left alone.
884*16467b97STreehugger Robot    //
885*16467b97STreehugger Robot    if  (m_limit > v.size() )
886*16467b97STreehugger Robot    {
887*16467b97STreehugger Robot        // We can only sort the entries that we have dude! The caller is
888*16467b97STreehugger Robot        // responsible for ensuring the vector is the correct one and is the
889*16467b97STreehugger Robot        // correct size etc.
890*16467b97STreehugger Robot        //
891*16467b97STreehugger Robot        m_limit = v.size();
892*16467b97STreehugger Robot    }
893*16467b97STreehugger Robot    // We need to know the locations of each of the entries
894*16467b97STreehugger Robot    // in the vector as we don't want to duplicate them in a new vector. We
895*16467b97STreehugger Robot    // just use an indirection table to get the vector entry for a particular sequence
896*16467b97STreehugger Robot    // acording to where we moved it last. Then we can just swap vector entries until
897*16467b97STreehugger Robot    // we are done :-)
898*16467b97STreehugger Robot    //
899*16467b97STreehugger Robot    vIndex = AllocPolicyType::alloc(m_limit * sizeof(ANTLR_UINT32));
900*16467b97STreehugger Robot
901*16467b97STreehugger Robot    // Start index, each vector entry is located where you think it is
902*16467b97STreehugger Robot    //
903*16467b97STreehugger Robot    for (i = 0; i < m_limit; i++)
904*16467b97STreehugger Robot    {
905*16467b97STreehugger Robot        vIndex[i] = i;
906*16467b97STreehugger Robot    }
907*16467b97STreehugger Robot
908*16467b97STreehugger Robot    // Now we traverse the sorted array and moved the entries of
909*16467b97STreehugger Robot    // the vector around according to the sort order and the indirection
910*16467b97STreehugger Robot    // table we just created. The index telsl us where in the vector the
911*16467b97STreehugger Robot    // original element entry n is now located via vIndex[n].
912*16467b97STreehugger Robot    //
913*16467b97STreehugger Robot    for (i=0; i < m_limit; i++)
914*16467b97STreehugger Robot    {
915*16467b97STreehugger Robot        ANTLR_UINT32   ind;
916*16467b97STreehugger Robot
917*16467b97STreehugger Robot        // If the vector entry at i is already the one that it
918*16467b97STreehugger Robot        // should be, then we skip moving it of course.
919*16467b97STreehugger Robot        //
920*16467b97STreehugger Robot        if  (vIndex[m_sorted[i]] == i)
921*16467b97STreehugger Robot        {
922*16467b97STreehugger Robot            continue;
923*16467b97STreehugger Robot        }
924*16467b97STreehugger Robot
925*16467b97STreehugger Robot        // The vector entry at i, should be replaced with the
926*16467b97STreehugger Robot        // vector entry indicated by topo->sorted[i]. The vector entry
927*16467b97STreehugger Robot        // at topo->sorted[i] may have already been swapped out though, so we
928*16467b97STreehugger Robot        // find where it is now and move it from there to i.
929*16467b97STreehugger Robot        //
930*16467b97STreehugger Robot        ind     = vIndex[m_sorted[i]];
931*16467b97STreehugger Robot		std::swap( v[i], v[ind] );
932*16467b97STreehugger Robot
933*16467b97STreehugger Robot        // Update our index. The element at i is now the one we wanted
934*16467b97STreehugger Robot        // to be sorted here and the element we swapped out is now the
935*16467b97STreehugger Robot        // element that was at i just before we swapped it. If you are lost now
936*16467b97STreehugger Robot        // don't worry about it, we are just reindexing on the fly is all.
937*16467b97STreehugger Robot        //
938*16467b97STreehugger Robot        vIndex[m_sorted[i]] = i;
939*16467b97STreehugger Robot        vIndex[i] = ind;
940*16467b97STreehugger Robot    }
941*16467b97STreehugger Robot
942*16467b97STreehugger Robot    // Having traversed all the entries, we have sorted the vector in place.
943*16467b97STreehugger Robot    //
944*16467b97STreehugger Robot    AllocPolicyType::free(vIndex);
945*16467b97STreehugger Robot    return;
946*16467b97STreehugger Robot}
947*16467b97STreehugger Robot
948*16467b97STreehugger Robottemplate<class ImplTraits>
949*16467b97STreehugger RobotTopo<ImplTraits>::~Topo()
950*16467b97STreehugger Robot{
951*16467b97STreehugger Robot    ANTLR_UINT32   i;
952*16467b97STreehugger Robot
953*16467b97STreehugger Robot    // Free the result vector
954*16467b97STreehugger Robot    //
955*16467b97STreehugger Robot    if  (m_sorted != NULL)
956*16467b97STreehugger Robot    {
957*16467b97STreehugger Robot        AllocPolicyType::free(m_sorted);
958*16467b97STreehugger Robot    }
959*16467b97STreehugger Robot
960*16467b97STreehugger Robot    // Free the visited map
961*16467b97STreehugger Robot    //
962*16467b97STreehugger Robot    if  (m_visited != NULL)
963*16467b97STreehugger Robot    {
964*16467b97STreehugger Robot		delete m_visited;
965*16467b97STreehugger Robot    }
966*16467b97STreehugger Robot
967*16467b97STreehugger Robot    // Free any edgemaps
968*16467b97STreehugger Robot    //
969*16467b97STreehugger Robot    if  (m_edges != NULL)
970*16467b97STreehugger Robot    {
971*16467b97STreehugger Robot        Bitset<AllocPolicyType>* edgeList;
972*16467b97STreehugger Robot
973*16467b97STreehugger Robot        for (i=0; i<m_limit; i++)
974*16467b97STreehugger Robot        {
975*16467b97STreehugger Robot            edgeList = *((m_edges) + i);
976*16467b97STreehugger Robot            if  (edgeList != NULL)
977*16467b97STreehugger Robot            {
978*16467b97STreehugger Robot				delete edgeList;
979*16467b97STreehugger Robot            }
980*16467b97STreehugger Robot        }
981*16467b97STreehugger Robot
982*16467b97STreehugger Robot        AllocPolicyType::free( m_edges );
983*16467b97STreehugger Robot    }
984*16467b97STreehugger Robot    m_edges = NULL;
985*16467b97STreehugger Robot
986*16467b97STreehugger Robot    // Free any cycle map
987*16467b97STreehugger Robot    //
988*16467b97STreehugger Robot    if  (m_cycle != NULL)
989*16467b97STreehugger Robot    {
990*16467b97STreehugger Robot        AllocPolicyType::free(m_cycle);
991*16467b97STreehugger Robot    }
992*16467b97STreehugger Robot}
993*16467b97STreehugger Robot
994*16467b97STreehugger Robot
995*16467b97STreehugger RobotANTLR_END_NAMESPACE()
996