xref: /aosp_15_r20/external/antlr/runtime/C/src/antlr3basetree.c (revision 16467b971bd3e2009fad32dd79016f2c7e421deb)
1*16467b97STreehugger Robot #include    <antlr3basetree.h>
2*16467b97STreehugger Robot 
3*16467b97STreehugger Robot #ifdef	ANTLR3_WINDOWS
4*16467b97STreehugger Robot #pragma warning( disable : 4100 )
5*16467b97STreehugger Robot #endif
6*16467b97STreehugger Robot 
7*16467b97STreehugger Robot // [The "BSD licence"]
8*16467b97STreehugger Robot // Copyright (c) 2005-2009 Jim Idle, Temporal Wave LLC
9*16467b97STreehugger Robot // http://www.temporal-wave.com
10*16467b97STreehugger Robot // http://www.linkedin.com/in/jimidle
11*16467b97STreehugger Robot //
12*16467b97STreehugger Robot // All rights reserved.
13*16467b97STreehugger Robot //
14*16467b97STreehugger Robot // Redistribution and use in source and binary forms, with or without
15*16467b97STreehugger Robot // modification, are permitted provided that the following conditions
16*16467b97STreehugger Robot // are met:
17*16467b97STreehugger Robot // 1. Redistributions of source code must retain the above copyright
18*16467b97STreehugger Robot //    notice, this list of conditions and the following disclaimer.
19*16467b97STreehugger Robot // 2. Redistributions in binary form must reproduce the above copyright
20*16467b97STreehugger Robot //    notice, this list of conditions and the following disclaimer in the
21*16467b97STreehugger Robot //    documentation and/or other materials provided with the distribution.
22*16467b97STreehugger Robot // 3. The name of the author may not be used to endorse or promote products
23*16467b97STreehugger Robot //    derived from this software without specific prior written permission.
24*16467b97STreehugger Robot //
25*16467b97STreehugger Robot // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
26*16467b97STreehugger Robot // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
27*16467b97STreehugger Robot // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
28*16467b97STreehugger Robot // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
29*16467b97STreehugger Robot // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30*16467b97STreehugger Robot // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31*16467b97STreehugger Robot // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32*16467b97STreehugger Robot // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33*16467b97STreehugger Robot // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34*16467b97STreehugger Robot // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35*16467b97STreehugger Robot 
36*16467b97STreehugger Robot static void				*	getChild			(pANTLR3_BASE_TREE tree, ANTLR3_UINT32 i);
37*16467b97STreehugger Robot static ANTLR3_UINT32		getChildCount		(pANTLR3_BASE_TREE tree);
38*16467b97STreehugger Robot static ANTLR3_UINT32		getCharPositionInLine
39*16467b97STreehugger Robot (pANTLR3_BASE_TREE tree);
40*16467b97STreehugger Robot static ANTLR3_UINT32		getLine				(pANTLR3_BASE_TREE tree);
41*16467b97STreehugger Robot static pANTLR3_BASE_TREE
42*16467b97STreehugger Robot getFirstChildWithType
43*16467b97STreehugger Robot (pANTLR3_BASE_TREE tree, ANTLR3_UINT32 type);
44*16467b97STreehugger Robot static void					addChild			(pANTLR3_BASE_TREE tree, pANTLR3_BASE_TREE child);
45*16467b97STreehugger Robot static void					addChildren			(pANTLR3_BASE_TREE tree, pANTLR3_LIST kids);
46*16467b97STreehugger Robot static void					replaceChildren		(pANTLR3_BASE_TREE parent, ANTLR3_INT32 startChildIndex, ANTLR3_INT32 stopChildIndex, pANTLR3_BASE_TREE t);
47*16467b97STreehugger Robot 
48*16467b97STreehugger Robot static	void				freshenPACIndexesAll(pANTLR3_BASE_TREE tree);
49*16467b97STreehugger Robot static	void				freshenPACIndexes	(pANTLR3_BASE_TREE tree, ANTLR3_UINT32 offset);
50*16467b97STreehugger Robot 
51*16467b97STreehugger Robot static void					setChild			(pANTLR3_BASE_TREE tree, ANTLR3_UINT32 i, void * child);
52*16467b97STreehugger Robot static void				*	deleteChild			(pANTLR3_BASE_TREE tree, ANTLR3_UINT32 i);
53*16467b97STreehugger Robot static void				*	dupTree				(pANTLR3_BASE_TREE tree);
54*16467b97STreehugger Robot static pANTLR3_STRING		toStringTree		(pANTLR3_BASE_TREE tree);
55*16467b97STreehugger Robot 
56*16467b97STreehugger Robot 
57*16467b97STreehugger Robot ANTLR3_API pANTLR3_BASE_TREE
antlr3BaseTreeNew(pANTLR3_BASE_TREE tree)58*16467b97STreehugger Robot antlr3BaseTreeNew(pANTLR3_BASE_TREE  tree)
59*16467b97STreehugger Robot {
60*16467b97STreehugger Robot 	/* api */
61*16467b97STreehugger Robot 	tree->getChild				= getChild;
62*16467b97STreehugger Robot 	tree->getChildCount			= getChildCount;
63*16467b97STreehugger Robot 	tree->addChild				= (void (*)(pANTLR3_BASE_TREE, void *))(addChild);
64*16467b97STreehugger Robot 	tree->addChildren			= addChildren;
65*16467b97STreehugger Robot 	tree->setChild				= setChild;
66*16467b97STreehugger Robot 	tree->deleteChild			= deleteChild;
67*16467b97STreehugger Robot 	tree->dupTree				= dupTree;
68*16467b97STreehugger Robot 	tree->toStringTree			= toStringTree;
69*16467b97STreehugger Robot 	tree->getCharPositionInLine	= getCharPositionInLine;
70*16467b97STreehugger Robot 	tree->getLine				= getLine;
71*16467b97STreehugger Robot 	tree->replaceChildren		= replaceChildren;
72*16467b97STreehugger Robot 	tree->freshenPACIndexesAll	= freshenPACIndexesAll;
73*16467b97STreehugger Robot 	tree->freshenPACIndexes		= freshenPACIndexes;
74*16467b97STreehugger Robot 	tree->getFirstChildWithType	= (void *(*)(pANTLR3_BASE_TREE, ANTLR3_UINT32))(getFirstChildWithType);
75*16467b97STreehugger Robot 	tree->children				= NULL;
76*16467b97STreehugger Robot 	tree->strFactory			= NULL;
77*16467b97STreehugger Robot 
78*16467b97STreehugger Robot 	/* Rest must be filled in by caller.
79*16467b97STreehugger Robot 	*/
80*16467b97STreehugger Robot 	return  tree;
81*16467b97STreehugger Robot }
82*16467b97STreehugger Robot 
83*16467b97STreehugger Robot static ANTLR3_UINT32
getCharPositionInLine(pANTLR3_BASE_TREE tree)84*16467b97STreehugger Robot getCharPositionInLine	(pANTLR3_BASE_TREE tree)
85*16467b97STreehugger Robot {
86*16467b97STreehugger Robot 	return  0;
87*16467b97STreehugger Robot }
88*16467b97STreehugger Robot 
89*16467b97STreehugger Robot static ANTLR3_UINT32
getLine(pANTLR3_BASE_TREE tree)90*16467b97STreehugger Robot getLine	(pANTLR3_BASE_TREE tree)
91*16467b97STreehugger Robot {
92*16467b97STreehugger Robot 	return  0;
93*16467b97STreehugger Robot }
94*16467b97STreehugger Robot static pANTLR3_BASE_TREE
getFirstChildWithType(pANTLR3_BASE_TREE tree,ANTLR3_UINT32 type)95*16467b97STreehugger Robot getFirstChildWithType	(pANTLR3_BASE_TREE tree, ANTLR3_UINT32 type)
96*16467b97STreehugger Robot {
97*16467b97STreehugger Robot 	ANTLR3_UINT32   i;
98*16467b97STreehugger Robot 	ANTLR3_UINT32   cs;
99*16467b97STreehugger Robot 
100*16467b97STreehugger Robot 	pANTLR3_BASE_TREE	t;
101*16467b97STreehugger Robot 	if	(tree->children != NULL)
102*16467b97STreehugger Robot 	{
103*16467b97STreehugger Robot 		cs	= tree->children->size(tree->children);
104*16467b97STreehugger Robot 		for	(i = 0; i < cs; i++)
105*16467b97STreehugger Robot 		{
106*16467b97STreehugger Robot 			t = (pANTLR3_BASE_TREE) (tree->children->get(tree->children, i));
107*16467b97STreehugger Robot 			if  (tree->getType(t) == type)
108*16467b97STreehugger Robot 			{
109*16467b97STreehugger Robot 				return  (pANTLR3_BASE_TREE)t;
110*16467b97STreehugger Robot 			}
111*16467b97STreehugger Robot 		}
112*16467b97STreehugger Robot 	}
113*16467b97STreehugger Robot 	return  NULL;
114*16467b97STreehugger Robot }
115*16467b97STreehugger Robot 
116*16467b97STreehugger Robot 
117*16467b97STreehugger Robot 
118*16467b97STreehugger Robot static void    *
getChild(pANTLR3_BASE_TREE tree,ANTLR3_UINT32 i)119*16467b97STreehugger Robot getChild		(pANTLR3_BASE_TREE tree, ANTLR3_UINT32 i)
120*16467b97STreehugger Robot {
121*16467b97STreehugger Robot 	if	(      tree->children == NULL
122*16467b97STreehugger Robot 		|| i >= tree->children->size(tree->children))
123*16467b97STreehugger Robot 	{
124*16467b97STreehugger Robot 		return NULL;
125*16467b97STreehugger Robot 	}
126*16467b97STreehugger Robot 	return  tree->children->get(tree->children, i);
127*16467b97STreehugger Robot }
128*16467b97STreehugger Robot 
129*16467b97STreehugger Robot 
130*16467b97STreehugger Robot static ANTLR3_UINT32
getChildCount(pANTLR3_BASE_TREE tree)131*16467b97STreehugger Robot getChildCount	(pANTLR3_BASE_TREE tree)
132*16467b97STreehugger Robot {
133*16467b97STreehugger Robot 	if	(tree->children == NULL)
134*16467b97STreehugger Robot 	{
135*16467b97STreehugger Robot 		return 0;
136*16467b97STreehugger Robot 	}
137*16467b97STreehugger Robot 	else
138*16467b97STreehugger Robot 	{
139*16467b97STreehugger Robot 		return	tree->children->size(tree->children);
140*16467b97STreehugger Robot 	}
141*16467b97STreehugger Robot }
142*16467b97STreehugger Robot 
143*16467b97STreehugger Robot void
addChild(pANTLR3_BASE_TREE tree,pANTLR3_BASE_TREE child)144*16467b97STreehugger Robot addChild (pANTLR3_BASE_TREE tree, pANTLR3_BASE_TREE child)
145*16467b97STreehugger Robot {
146*16467b97STreehugger Robot 	ANTLR3_UINT32   n;
147*16467b97STreehugger Robot 	ANTLR3_UINT32   i;
148*16467b97STreehugger Robot 
149*16467b97STreehugger Robot 	if	(child == NULL)
150*16467b97STreehugger Robot 	{
151*16467b97STreehugger Robot 		return;
152*16467b97STreehugger Robot 	}
153*16467b97STreehugger Robot 
154*16467b97STreehugger Robot 	if	(child->isNilNode(child) == ANTLR3_TRUE)
155*16467b97STreehugger Robot 	{
156*16467b97STreehugger Robot 		if  (child->children != NULL && child->children == tree->children)
157*16467b97STreehugger Robot 		{
158*16467b97STreehugger Robot 			// TODO: Change to exception rather than ANTLR3_FPRINTF?
159*16467b97STreehugger Robot 			//
160*16467b97STreehugger Robot 			ANTLR3_FPRINTF(stderr, "ANTLR3: An attempt was made to add a child list to itself!\n");
161*16467b97STreehugger Robot 			return;
162*16467b97STreehugger Robot 		}
163*16467b97STreehugger Robot 
164*16467b97STreehugger Robot         // Add all of the children's children to this list
165*16467b97STreehugger Robot         //
166*16467b97STreehugger Robot         if (child->children != NULL)
167*16467b97STreehugger Robot         {
168*16467b97STreehugger Robot             if (tree->children == NULL)
169*16467b97STreehugger Robot             {
170*16467b97STreehugger Robot                 // We are build ing the tree structure here, so we need not
171*16467b97STreehugger Robot                 // worry about duplication of pointers as the tree node
172*16467b97STreehugger Robot                 // factory will only clean up each node once. So we just
173*16467b97STreehugger Robot                 // copy in the child's children pointer as the child is
174*16467b97STreehugger Robot                 // a nil node (has not root itself).
175*16467b97STreehugger Robot                 //
176*16467b97STreehugger Robot                 tree->children = child->children;
177*16467b97STreehugger Robot                 child->children = NULL;
178*16467b97STreehugger Robot                 freshenPACIndexesAll(tree);
179*16467b97STreehugger Robot 
180*16467b97STreehugger Robot             }
181*16467b97STreehugger Robot             else
182*16467b97STreehugger Robot             {
183*16467b97STreehugger Robot                 // Need to copy the children
184*16467b97STreehugger Robot                 //
185*16467b97STreehugger Robot                 n = child->children->size(child->children);
186*16467b97STreehugger Robot 
187*16467b97STreehugger Robot                 for (i = 0; i < n; i++)
188*16467b97STreehugger Robot                 {
189*16467b97STreehugger Robot                     pANTLR3_BASE_TREE entry;
190*16467b97STreehugger Robot                     entry = (pANTLR3_BASE_TREE)child->children->get(child->children, i);
191*16467b97STreehugger Robot 
192*16467b97STreehugger Robot                     // ANTLR3 lists can be sparse, unlike Array Lists
193*16467b97STreehugger Robot                     //
194*16467b97STreehugger Robot                     if (entry != NULL)
195*16467b97STreehugger Robot                     {
196*16467b97STreehugger Robot                         ANTLR3_UINT32 count = tree->children->add(tree->children, entry, (void (ANTLR3_CDECL *) (void *))child->free);
197*16467b97STreehugger Robot 
198*16467b97STreehugger Robot                         entry->setChildIndex(entry, count - 1);
199*16467b97STreehugger Robot                         entry->setParent(entry, tree);
200*16467b97STreehugger Robot                     }
201*16467b97STreehugger Robot                 }
202*16467b97STreehugger Robot             }
203*16467b97STreehugger Robot 		}
204*16467b97STreehugger Robot 	}
205*16467b97STreehugger Robot 	else
206*16467b97STreehugger Robot 	{
207*16467b97STreehugger Robot 		// Tree we are adding is not a Nil and might have children to copy
208*16467b97STreehugger Robot 		//
209*16467b97STreehugger Robot 		if  (tree->children == NULL)
210*16467b97STreehugger Robot 		{
211*16467b97STreehugger Robot 			// No children in the tree we are adding to, so create a new list on
212*16467b97STreehugger Robot 			// the fly to hold them.
213*16467b97STreehugger Robot 			//
214*16467b97STreehugger Robot 			tree->createChildrenList(tree);
215*16467b97STreehugger Robot 		}
216*16467b97STreehugger Robot 
217*16467b97STreehugger Robot 		ANTLR3_UINT32 count = tree->children->add(tree->children, child, (void (ANTLR3_CDECL *)(void *))child->free);
218*16467b97STreehugger Robot 		child->setChildIndex(child, count - 1);
219*16467b97STreehugger Robot 		child->setParent(child, tree);
220*16467b97STreehugger Robot 	}
221*16467b97STreehugger Robot }
222*16467b97STreehugger Robot 
223*16467b97STreehugger Robot /// Add all elements of the supplied list as children of this node
224*16467b97STreehugger Robot ///
225*16467b97STreehugger Robot static void
addChildren(pANTLR3_BASE_TREE tree,pANTLR3_LIST kids)226*16467b97STreehugger Robot addChildren	(pANTLR3_BASE_TREE tree, pANTLR3_LIST kids)
227*16467b97STreehugger Robot {
228*16467b97STreehugger Robot 	ANTLR3_UINT32    i;
229*16467b97STreehugger Robot 	ANTLR3_UINT32    s;
230*16467b97STreehugger Robot 
231*16467b97STreehugger Robot 	s = kids->size(kids);
232*16467b97STreehugger Robot 	for	(i = 0; i<s; i++)
233*16467b97STreehugger Robot 	{
234*16467b97STreehugger Robot 		tree->addChild(tree, (pANTLR3_BASE_TREE)(kids->get(kids, i+1)));
235*16467b97STreehugger Robot 	}
236*16467b97STreehugger Robot }
237*16467b97STreehugger Robot 
238*16467b97STreehugger Robot 
239*16467b97STreehugger Robot static    void
setChild(pANTLR3_BASE_TREE tree,ANTLR3_UINT32 i,void * child)240*16467b97STreehugger Robot setChild	(pANTLR3_BASE_TREE tree, ANTLR3_UINT32 i, void * child)
241*16467b97STreehugger Robot {
242*16467b97STreehugger Robot 	if	(tree->children == NULL)
243*16467b97STreehugger Robot 	{
244*16467b97STreehugger Robot 		tree->createChildrenList(tree);
245*16467b97STreehugger Robot 	}
246*16467b97STreehugger Robot 	tree->children->set(tree->children, i, child, NULL, ANTLR3_FALSE);
247*16467b97STreehugger Robot }
248*16467b97STreehugger Robot 
249*16467b97STreehugger Robot static void    *
deleteChild(pANTLR3_BASE_TREE tree,ANTLR3_UINT32 i)250*16467b97STreehugger Robot deleteChild	(pANTLR3_BASE_TREE tree, ANTLR3_UINT32 i)
251*16467b97STreehugger Robot {
252*16467b97STreehugger Robot 	if	( tree->children == NULL)
253*16467b97STreehugger Robot 	{
254*16467b97STreehugger Robot 		return	NULL;
255*16467b97STreehugger Robot 	}
256*16467b97STreehugger Robot 
257*16467b97STreehugger Robot 	return  tree->children->remove(tree->children, i);
258*16467b97STreehugger Robot }
259*16467b97STreehugger Robot 
260*16467b97STreehugger Robot static void    *
dupTree(pANTLR3_BASE_TREE tree)261*16467b97STreehugger Robot dupTree		(pANTLR3_BASE_TREE tree)
262*16467b97STreehugger Robot {
263*16467b97STreehugger Robot 	pANTLR3_BASE_TREE	newTree;
264*16467b97STreehugger Robot 	ANTLR3_UINT32	i;
265*16467b97STreehugger Robot 	ANTLR3_UINT32	s;
266*16467b97STreehugger Robot 
267*16467b97STreehugger Robot 	newTree = (pANTLR3_BASE_TREE)tree->dupNode	    (tree);
268*16467b97STreehugger Robot 
269*16467b97STreehugger Robot 	if	(tree->children != NULL)
270*16467b97STreehugger Robot 	{
271*16467b97STreehugger Robot 		s	    = tree->children->size  (tree->children);
272*16467b97STreehugger Robot 
273*16467b97STreehugger Robot 		for	(i = 0; i < s; i++)
274*16467b97STreehugger Robot 		{
275*16467b97STreehugger Robot 			pANTLR3_BASE_TREE    t;
276*16467b97STreehugger Robot 			pANTLR3_BASE_TREE    newNode;
277*16467b97STreehugger Robot 
278*16467b97STreehugger Robot 			t   = (pANTLR3_BASE_TREE) tree->children->get(tree->children, i);
279*16467b97STreehugger Robot 
280*16467b97STreehugger Robot 			if  (t!= NULL)
281*16467b97STreehugger Robot 			{
282*16467b97STreehugger Robot 				newNode	    = (pANTLR3_BASE_TREE)t->dupTree(t);
283*16467b97STreehugger Robot 				newTree->addChild(newTree, newNode);
284*16467b97STreehugger Robot 			}
285*16467b97STreehugger Robot 		}
286*16467b97STreehugger Robot 	}
287*16467b97STreehugger Robot 
288*16467b97STreehugger Robot 	return newTree;
289*16467b97STreehugger Robot }
290*16467b97STreehugger Robot 
291*16467b97STreehugger Robot static pANTLR3_STRING
toStringTree(pANTLR3_BASE_TREE tree)292*16467b97STreehugger Robot toStringTree	(pANTLR3_BASE_TREE tree)
293*16467b97STreehugger Robot {
294*16467b97STreehugger Robot 	pANTLR3_STRING  string;
295*16467b97STreehugger Robot 	ANTLR3_UINT32   i;
296*16467b97STreehugger Robot 	ANTLR3_UINT32   n;
297*16467b97STreehugger Robot 	pANTLR3_BASE_TREE   t;
298*16467b97STreehugger Robot 
299*16467b97STreehugger Robot 	if	(tree->children == NULL || tree->children->size(tree->children) == 0)
300*16467b97STreehugger Robot 	{
301*16467b97STreehugger Robot 		return	tree->toString(tree);
302*16467b97STreehugger Robot 	}
303*16467b97STreehugger Robot 
304*16467b97STreehugger Robot 	/* Need a new string with nothing at all in it.
305*16467b97STreehugger Robot 	*/
306*16467b97STreehugger Robot 	string	= tree->strFactory->newRaw(tree->strFactory);
307*16467b97STreehugger Robot 
308*16467b97STreehugger Robot 	if	(tree->isNilNode(tree) == ANTLR3_FALSE)
309*16467b97STreehugger Robot 	{
310*16467b97STreehugger Robot 		string->append8	(string, "(");
311*16467b97STreehugger Robot 		string->appendS	(string, tree->toString(tree));
312*16467b97STreehugger Robot 		string->append8	(string, " ");
313*16467b97STreehugger Robot 	}
314*16467b97STreehugger Robot 	if	(tree->children != NULL)
315*16467b97STreehugger Robot 	{
316*16467b97STreehugger Robot 		n = tree->children->size(tree->children);
317*16467b97STreehugger Robot 
318*16467b97STreehugger Robot 		for	(i = 0; i < n; i++)
319*16467b97STreehugger Robot 		{
320*16467b97STreehugger Robot 			t   = (pANTLR3_BASE_TREE) tree->children->get(tree->children, i);
321*16467b97STreehugger Robot 
322*16467b97STreehugger Robot 			if  (i > 0)
323*16467b97STreehugger Robot 			{
324*16467b97STreehugger Robot 				string->append8(string, " ");
325*16467b97STreehugger Robot 			}
326*16467b97STreehugger Robot 			string->appendS(string, t->toStringTree(t));
327*16467b97STreehugger Robot 		}
328*16467b97STreehugger Robot 	}
329*16467b97STreehugger Robot 	if	(tree->isNilNode(tree) == ANTLR3_FALSE)
330*16467b97STreehugger Robot 	{
331*16467b97STreehugger Robot 		string->append8(string,")");
332*16467b97STreehugger Robot 	}
333*16467b97STreehugger Robot 
334*16467b97STreehugger Robot 	return  string;
335*16467b97STreehugger Robot }
336*16467b97STreehugger Robot 
337*16467b97STreehugger Robot /// Delete children from start to stop and replace with t even if t is
338*16467b97STreehugger Robot /// a list (nil-root tree). Num of children can increase or decrease.
339*16467b97STreehugger Robot /// For huge child lists, inserting children can force walking rest of
340*16467b97STreehugger Robot /// children to set their child index; could be slow.
341*16467b97STreehugger Robot ///
342*16467b97STreehugger Robot static void
replaceChildren(pANTLR3_BASE_TREE parent,ANTLR3_INT32 startChildIndex,ANTLR3_INT32 stopChildIndex,pANTLR3_BASE_TREE newTree)343*16467b97STreehugger Robot replaceChildren		(pANTLR3_BASE_TREE parent, ANTLR3_INT32 startChildIndex, ANTLR3_INT32 stopChildIndex, pANTLR3_BASE_TREE newTree)
344*16467b97STreehugger Robot {
345*16467b97STreehugger Robot 	ANTLR3_INT32	replacingHowMany;		// How many nodes will go away
346*16467b97STreehugger Robot 	ANTLR3_INT32	replacingWithHowMany;	// How many nodes will replace them
347*16467b97STreehugger Robot 	ANTLR3_INT32	numNewChildren;			// Tracking variable
348*16467b97STreehugger Robot 	ANTLR3_INT32	delta;					// Difference in new vs existing count
349*16467b97STreehugger Robot 
350*16467b97STreehugger Robot 	ANTLR3_INT32	i;
351*16467b97STreehugger Robot 	ANTLR3_INT32	j;
352*16467b97STreehugger Robot 
353*16467b97STreehugger Robot 	pANTLR3_VECTOR	newChildren;			// Iterator for whatever we are going to add in
354*16467b97STreehugger Robot 	ANTLR3_BOOLEAN	freeNewChildren;		// Whether we created the iterator locally or reused it
355*16467b97STreehugger Robot 
356*16467b97STreehugger Robot 	if	(parent->children == NULL)
357*16467b97STreehugger Robot 	{
358*16467b97STreehugger Robot 		ANTLR3_FPRINTF(stderr, "replaceChildren call: Indexes are invalid; no children in list for %s", parent->getText(parent)->chars);
359*16467b97STreehugger Robot 		return;
360*16467b97STreehugger Robot 	}
361*16467b97STreehugger Robot 
362*16467b97STreehugger Robot 	// Either use the existing list of children in the supplied nil node, or build a vector of the
363*16467b97STreehugger Robot 	// tree we were given if it is not a nil node, then we treat both situations exactly the same
364*16467b97STreehugger Robot 	//
365*16467b97STreehugger Robot 	if	(newTree->isNilNode(newTree))
366*16467b97STreehugger Robot 	{
367*16467b97STreehugger Robot 		newChildren = newTree->children;
368*16467b97STreehugger Robot 		freeNewChildren = ANTLR3_FALSE;		// We must NO free this memory
369*16467b97STreehugger Robot 	}
370*16467b97STreehugger Robot 	else
371*16467b97STreehugger Robot 	{
372*16467b97STreehugger Robot 		newChildren = antlr3VectorNew(1);
373*16467b97STreehugger Robot 		if	(newChildren == NULL)
374*16467b97STreehugger Robot 		{
375*16467b97STreehugger Robot 			ANTLR3_FPRINTF(stderr, "replaceChildren: out of memory!!");
376*16467b97STreehugger Robot 			exit(1);
377*16467b97STreehugger Robot 		}
378*16467b97STreehugger Robot 		newChildren->add(newChildren, (void *)newTree, NULL);
379*16467b97STreehugger Robot 
380*16467b97STreehugger Robot 		freeNewChildren = ANTLR3_TRUE;		// We must free this memory
381*16467b97STreehugger Robot 	}
382*16467b97STreehugger Robot 
383*16467b97STreehugger Robot 	// Initialize
384*16467b97STreehugger Robot 	//
385*16467b97STreehugger Robot 	replacingHowMany		= stopChildIndex - startChildIndex + 1;
386*16467b97STreehugger Robot 	replacingWithHowMany	= newChildren->size(newChildren);
387*16467b97STreehugger Robot 	delta					= replacingHowMany - replacingWithHowMany;
388*16467b97STreehugger Robot 	numNewChildren			= newChildren->size(newChildren);
389*16467b97STreehugger Robot 
390*16467b97STreehugger Robot 	// If it is the same number of nodes, then do a direct replacement
391*16467b97STreehugger Robot 	//
392*16467b97STreehugger Robot 	if	(delta == 0)
393*16467b97STreehugger Robot 	{
394*16467b97STreehugger Robot 		pANTLR3_BASE_TREE	child;
395*16467b97STreehugger Robot 
396*16467b97STreehugger Robot 		// Same number of nodes
397*16467b97STreehugger Robot 		//
398*16467b97STreehugger Robot 		j	= 0;
399*16467b97STreehugger Robot 		for	(i = startChildIndex; i <= stopChildIndex; i++)
400*16467b97STreehugger Robot 		{
401*16467b97STreehugger Robot 			child = (pANTLR3_BASE_TREE) newChildren->get(newChildren, j);
402*16467b97STreehugger Robot 			parent->children->set(parent->children, i, child, NULL, ANTLR3_FALSE);
403*16467b97STreehugger Robot 			child->setParent(child, parent);
404*16467b97STreehugger Robot 			child->setChildIndex(child, i);
405*16467b97STreehugger Robot 		}
406*16467b97STreehugger Robot 	}
407*16467b97STreehugger Robot 	else if (delta > 0)
408*16467b97STreehugger Robot 	{
409*16467b97STreehugger Robot 		ANTLR3_UINT32	indexToDelete;
410*16467b97STreehugger Robot 
411*16467b97STreehugger Robot 		// Less nodes than there were before
412*16467b97STreehugger Robot 		// reuse what we have then delete the rest
413*16467b97STreehugger Robot 		//
414*16467b97STreehugger Robot 		for	(j = 0; j < numNewChildren; j++)
415*16467b97STreehugger Robot 		{
416*16467b97STreehugger Robot 			parent->children->set(parent->children, startChildIndex + j, newChildren->get(newChildren, j), NULL, ANTLR3_FALSE);
417*16467b97STreehugger Robot 		}
418*16467b97STreehugger Robot 
419*16467b97STreehugger Robot 		// We just delete the same index position until done
420*16467b97STreehugger Robot 		//
421*16467b97STreehugger Robot 		indexToDelete = startChildIndex + numNewChildren;
422*16467b97STreehugger Robot 
423*16467b97STreehugger Robot 		for	(j = indexToDelete; j <= (ANTLR3_INT32)stopChildIndex; j++)
424*16467b97STreehugger Robot 		{
425*16467b97STreehugger Robot 			parent->children->remove(parent->children, indexToDelete);
426*16467b97STreehugger Robot 		}
427*16467b97STreehugger Robot 
428*16467b97STreehugger Robot 		parent->freshenPACIndexes(parent, startChildIndex);
429*16467b97STreehugger Robot 	}
430*16467b97STreehugger Robot 	else
431*16467b97STreehugger Robot 	{
432*16467b97STreehugger Robot 		ANTLR3_UINT32 numToInsert;
433*16467b97STreehugger Robot 
434*16467b97STreehugger Robot 		// More nodes than there were before
435*16467b97STreehugger Robot 		// Use what we can, then start adding
436*16467b97STreehugger Robot 		//
437*16467b97STreehugger Robot 		for	(j = 0; j < replacingHowMany; j++)
438*16467b97STreehugger Robot 		{
439*16467b97STreehugger Robot 			parent->children->set(parent->children, startChildIndex + j, newChildren->get(newChildren, j), NULL, ANTLR3_FALSE);
440*16467b97STreehugger Robot 		}
441*16467b97STreehugger Robot 
442*16467b97STreehugger Robot 		numToInsert = replacingWithHowMany - replacingHowMany;
443*16467b97STreehugger Robot 
444*16467b97STreehugger Robot 		for	(j = replacingHowMany; j < replacingWithHowMany; j++)
445*16467b97STreehugger Robot 		{
446*16467b97STreehugger Robot 			parent->children->add(parent->children, newChildren->get(newChildren, j), NULL);
447*16467b97STreehugger Robot 		}
448*16467b97STreehugger Robot 
449*16467b97STreehugger Robot 		parent->freshenPACIndexes(parent, startChildIndex);
450*16467b97STreehugger Robot 	}
451*16467b97STreehugger Robot 
452*16467b97STreehugger Robot 	if	(freeNewChildren == ANTLR3_TRUE)
453*16467b97STreehugger Robot 	{
454*16467b97STreehugger Robot 		ANTLR3_FREE(newChildren->elements);
455*16467b97STreehugger Robot 		newChildren->elements = NULL;
456*16467b97STreehugger Robot 		newChildren->size = 0;
457*16467b97STreehugger Robot 		ANTLR3_FREE(newChildren);		// Will not free the nodes
458*16467b97STreehugger Robot 	}
459*16467b97STreehugger Robot }
460*16467b97STreehugger Robot 
461*16467b97STreehugger Robot /// Set the parent and child indexes for all children of the
462*16467b97STreehugger Robot /// supplied tree.
463*16467b97STreehugger Robot ///
464*16467b97STreehugger Robot static	void
freshenPACIndexesAll(pANTLR3_BASE_TREE tree)465*16467b97STreehugger Robot freshenPACIndexesAll(pANTLR3_BASE_TREE tree)
466*16467b97STreehugger Robot {
467*16467b97STreehugger Robot 	tree->freshenPACIndexes(tree, 0);
468*16467b97STreehugger Robot }
469*16467b97STreehugger Robot 
470*16467b97STreehugger Robot /// Set the parent and child indexes for some of the children of the
471*16467b97STreehugger Robot /// supplied tree, starting with the child at the supplied index.
472*16467b97STreehugger Robot ///
473*16467b97STreehugger Robot static	void
freshenPACIndexes(pANTLR3_BASE_TREE tree,ANTLR3_UINT32 offset)474*16467b97STreehugger Robot freshenPACIndexes	(pANTLR3_BASE_TREE tree, ANTLR3_UINT32 offset)
475*16467b97STreehugger Robot {
476*16467b97STreehugger Robot 	ANTLR3_UINT32	count;
477*16467b97STreehugger Robot 	ANTLR3_UINT32	c;
478*16467b97STreehugger Robot 
479*16467b97STreehugger Robot 	count	= tree->getChildCount(tree);		// How many children do we have
480*16467b97STreehugger Robot 
481*16467b97STreehugger Robot 	// Loop from the supplied index and set the indexes and parent
482*16467b97STreehugger Robot 	//
483*16467b97STreehugger Robot 	for	(c = offset; c < count; c++)
484*16467b97STreehugger Robot 	{
485*16467b97STreehugger Robot 		pANTLR3_BASE_TREE	child;
486*16467b97STreehugger Robot 
487*16467b97STreehugger Robot 		child = (pANTLR3_BASE_TREE)tree->getChild(tree, c);
488*16467b97STreehugger Robot 
489*16467b97STreehugger Robot 		child->setChildIndex(child, c);
490*16467b97STreehugger Robot 		child->setParent(child, tree);
491*16467b97STreehugger Robot 	}
492*16467b97STreehugger Robot }
493*16467b97STreehugger Robot 
494