• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1ANTLR_BEGIN_NAMESPACE()
2
3template<class ImplTraits>
4CommonTree<ImplTraits>::CommonTree()
5{
6	m_savedIndex = 0;
7	m_startIndex = 0;
8	m_stopIndex  = 0;
9	m_token		 = NULL;
10	m_parent     = NULL;
11	m_childIndex = 0;
12}
13
14template<class ImplTraits>
15CommonTree<ImplTraits>::CommonTree( const CommonTree& ctree )
16	:m_children( ctree.m_children)
17{
18	m_savedIndex = ctree.m_savedIndex;
19	m_startIndex = ctree.m_startIndex;
20	m_stopIndex  = ctree.m_stopIndex;
21	m_token		 = ctree.m_token;
22	m_parent     = ctree.m_parent;
23	m_childIndex = ctree.m_childIndex;
24}
25
26template<class ImplTraits>
27CommonTree<ImplTraits>::CommonTree( CommonTokenType* token )
28{
29	m_savedIndex = 0;
30	m_startIndex = 0;
31	m_stopIndex  = 0;
32	m_token		 = token;
33	m_parent     = NULL;
34	m_childIndex = 0;
35}
36
37template<class ImplTraits>
38CommonTree<ImplTraits>::CommonTree( CommonTree* tree )
39{
40	m_savedIndex = 0;
41	m_startIndex = 0;
42	m_stopIndex  = 0;
43	m_token		 = tree->get_token();
44	m_parent     = NULL;
45	m_childIndex = 0;
46}
47
48template<class ImplTraits>
49typename CommonTree<ImplTraits>::TokenType*   CommonTree<ImplTraits>::get_token() const
50{
51	return m_token;
52}
53
54template<class ImplTraits>
55typename CommonTree<ImplTraits>::ChildrenType& CommonTree<ImplTraits>::get_children()
56{
57	return m_children;
58}
59
60template<class ImplTraits>
61const typename CommonTree<ImplTraits>::ChildrenType& CommonTree<ImplTraits>::get_children() const
62{
63	return m_children;
64}
65
66template<class ImplTraits>
67typename CommonTree<ImplTraits>::ChildrenType* CommonTree<ImplTraits>::get_children_p()
68{
69	return &m_children;
70}
71
72template<class ImplTraits>
73void	CommonTree<ImplTraits>::addChild(TreeType* child)
74{
75	ANTLR_UINT32   n;
76	ANTLR_UINT32   i;
77
78	if	(child == NULL)
79		return;
80
81	ChildrenType& child_children = child->get_children();
82	ChildrenType& tree_children  = this->get_children();
83
84	if	(child->isNilNode() == true)
85	{
86		if ( !child_children.empty() && child_children == tree_children )
87		{
88			// TODO: Change to exception rather than ANTLR3_FPRINTF?
89			//
90			fprintf(stderr, "ANTLR3: An attempt was made to add a child list to itself!\n");
91			return;
92		}
93
94        // Add all of the children's children to this list
95        //
96        if ( !child_children.empty() )
97        {
98            if (tree_children.empty())
99            {
100                // We are build ing the tree structure here, so we need not
101                // worry about duplication of pointers as the tree node
102                // factory will only clean up each node once. So we just
103                // copy in the child's children pointer as the child is
104                // a nil node (has not root itself).
105                //
106                tree_children.swap( child_children );
107                this->freshenPACIndexesAll();
108            }
109            else
110            {
111                // Need to copy the children
112                //
113                n = child_children.size();
114
115                for (i = 0; i < n; i++)
116                {
117                    TreeType* entry;
118                    entry = child_children[i];
119
120                    // ANTLR3 lists can be sparse, unlike Array Lists
121                    //
122                    if (entry != NULL)
123                    {
124                        tree_children.push_back(entry);
125                    }
126                }
127            }
128		}
129	}
130	else
131	{
132		// Tree we are adding is not a Nil and might have children to copy
133		//
134		if  (tree_children.empty())
135		{
136			// No children in the tree we are adding to, so create a new list on
137			// the fly to hold them.
138			//
139			this->createChildrenList();
140		}
141		tree_children.push_back( child );
142	}
143}
144
145template<class ImplTraits>
146void	CommonTree<ImplTraits>::addChildren(const ChildListType& kids)
147{
148	for( typename ChildListType::const_iterator iter = kids.begin();
149		 iter != kids.end(); ++iter )
150	{
151		this->addChild( *iter );
152	}
153}
154
155//dummy one, as vector is always there
156template<class ImplTraits>
157void    CommonTree<ImplTraits>::createChildrenList()
158{
159}
160
161template<class ImplTraits>
162typename CommonTree<ImplTraits>::TreeType*	CommonTree<ImplTraits>::deleteChild(ANTLR_UINT32 i)
163{
164	if( m_children.empty() )
165		return	NULL;
166
167	return  m_children.erase( m_children.begin() + i);
168}
169
170template<class ImplTraits>
171void	CommonTree<ImplTraits>::replaceChildren(ANTLR_INT32 startChildIndex, ANTLR_INT32 stopChildIndex, TreeType* newTree)
172{
173	ANTLR_INT32	replacingHowMany;		// How many nodes will go away
174	ANTLR_INT32	replacingWithHowMany;	// How many nodes will replace them
175	ANTLR_INT32	numNewChildren;			// Tracking variable
176	ANTLR_INT32	delta;					// Difference in new vs existing count
177
178	ANTLR_INT32	i;
179	ANTLR_INT32	j;
180
181	if	( m_children.empty() )
182	{
183		fprintf(stderr, "replaceChildren call: Indexes are invalid; no children in list for %s", this->getText().c_str() );
184		return;
185	}
186
187	// Either use the existing list of children in the supplied nil node, or build a vector of the
188	// tree we were given if it is not a nil node, then we treat both situations exactly the same
189	//
190	ChildrenType newChildren_temp;
191	ChildrenType*	newChildren;			// Iterator for whatever we are going to add in
192
193	if	(newTree->isNilNode())
194	{
195		newChildren = newTree->get_children_p();
196	}
197	else
198	{
199		newChildren = &newChildren_temp;
200		newChildren->push_back(newTree);
201	}
202
203	// Initialize
204	//
205	replacingHowMany		= stopChildIndex - startChildIndex + 1;
206	replacingWithHowMany	= newChildren->size();
207	delta					= replacingHowMany - replacingWithHowMany;
208	numNewChildren			= newChildren->size();
209
210	// If it is the same number of nodes, then do a direct replacement
211	//
212	if	(delta == 0)
213	{
214		TreeType*	child;
215
216		// Same number of nodes
217		//
218		j	= 0;
219		for	(i = startChildIndex; i <= stopChildIndex; i++)
220		{
221			child = newChildren->at(j);
222			ChildrenType& parent_children = this->get_children();
223			parent_children[i] = child;
224			child->setParent(this);
225			child->setChildIndex(i);
226		}
227	}
228	else if (delta > 0)
229	{
230		ANTLR_UINT32	indexToDelete;
231
232		// Less nodes than there were before
233		// reuse what we have then delete the rest
234		//
235		ChildrenType& parent_children = this->get_children();
236		for	(j = 0; j < numNewChildren; j++)
237		{
238			parent_children[ startChildIndex + j ] = newChildren->at(j);
239		}
240
241		// We just delete the same index position until done
242		//
243		indexToDelete = startChildIndex + numNewChildren;
244
245		for	(j = indexToDelete; j <= stopChildIndex; j++)
246		{
247			parent_children.erase( parent_children.begin() + indexToDelete);
248		}
249
250		this->freshenPACIndexes(startChildIndex);
251	}
252	else
253	{
254		ChildrenType& parent_children = this->get_children();
255		ANTLR_UINT32 numToInsert;
256
257		// More nodes than there were before
258		// Use what we can, then start adding
259		//
260		for	(j = 0; j < replacingHowMany; j++)
261		{
262			parent_children[ startChildIndex + j ] = newChildren->at(j);
263		}
264
265		numToInsert = replacingWithHowMany - replacingHowMany;
266
267		for	(j = replacingHowMany; j < replacingWithHowMany; j++)
268		{
269			parent_children.push_back( newChildren->at(j) );
270		}
271
272		this->freshenPACIndexes(startChildIndex);
273	}
274}
275
276template<class ImplTraits>
277CommonTree<ImplTraits>*	CommonTree<ImplTraits>::dupNode() const
278{
279	// The node we are duplicating is in fact the common tree (that's why we are here)
280    // so we use the super pointer to duplicate.
281    //
282    TreeType*   clone = new TreeType();
283
284	// The pointer we return is the base implementation of course
285    //
286	clone->set_token( m_token );
287	return  clone;
288}
289
290template<class ImplTraits>
291typename CommonTree<ImplTraits>::TreeType*	CommonTree<ImplTraits>::dupTree()
292{
293	TreeType*	newTree;
294	ANTLR_UINT32	i;
295	ANTLR_UINT32	s;
296
297	newTree = this->dupNode();
298
299	if	( !m_children.empty() )
300	{
301		s	    = m_children.size();
302
303		for	(i = 0; i < s; i++)
304		{
305			TreeType*    t;
306			TreeType*    newNode;
307
308			t   = m_children[i];
309
310			if  (t!= NULL)
311			{
312				newNode	    = t->dupTree();
313				newTree->addChild(newNode);
314			}
315		}
316	}
317
318	return newTree;
319}
320
321template<class ImplTraits>
322ANTLR_UINT32	CommonTree<ImplTraits>::getCharPositionInLine()
323{
324	CommonTokenType*    token;
325	token   = m_token;
326
327	if	(token == NULL || (token->getCharPositionInLine() == -1) )
328	{
329		if  (this->getChildCount() > 0)
330		{
331			TreeType*	child;
332
333			child   = this->getChild(0);
334
335			return child->getCharPositionInLine();
336		}
337		return 0;
338	}
339	return  token->getCharPositionInLine();
340}
341
342template<class ImplTraits>
343typename CommonTree<ImplTraits>::TreeType*	CommonTree<ImplTraits>::getChild(ANTLR_UINT32 i)
344{
345	if	(  m_children.empty()
346		|| i >= m_children.size() )
347	{
348		return NULL;
349	}
350	return  m_children[i];
351
352}
353
354template<class ImplTraits>
355void    CommonTree<ImplTraits>::set_childIndex( ANTLR_INT32 i)
356{
357	m_childIndex = i;
358}
359
360template<class ImplTraits>
361ANTLR_INT32	CommonTree<ImplTraits>::get_childIndex() const
362{
363	return m_childIndex;
364}
365
366template<class ImplTraits>
367ANTLR_UINT32	CommonTree<ImplTraits>::getChildCount() const
368{
369	return static_cast<ANTLR_UINT32>( m_children.size() );
370}
371
372template<class ImplTraits>
373typename CommonTree<ImplTraits>::TreeType* CommonTree<ImplTraits>::get_parent() const
374{
375	return m_parent;
376}
377
378template<class ImplTraits>
379void     CommonTree<ImplTraits>::set_parent( TreeType* parent)
380{
381	m_parent = parent;
382}
383
384template<class ImplTraits>
385ANTLR_UINT32	CommonTree<ImplTraits>::getType()
386{
387	if	(this == NULL)
388	{
389		return	0;
390	}
391	else
392	{
393		return	m_token->getType();
394	}
395}
396
397template<class ImplTraits>
398typename CommonTree<ImplTraits>::TreeType*	CommonTree<ImplTraits>::getFirstChildWithType(ANTLR_UINT32 type)
399{
400	ANTLR_UINT32   i;
401	std::size_t   cs;
402
403	TreeType*	t;
404	if	( !m_children.empty() )
405	{
406		cs	= m_children.size();
407		for	(i = 0; i < cs; i++)
408		{
409			t = m_children[i];
410			if  (t->getType() == type)
411			{
412				return  t;
413			}
414		}
415	}
416	return  NULL;
417}
418
419template<class ImplTraits>
420ANTLR_UINT32	CommonTree<ImplTraits>::getLine()
421{
422	TreeType*	    cTree = this;
423	CommonTokenType* token;
424	token   = cTree->get_token();
425
426	if	(token == NULL || token->getLine() == 0)
427	{
428		if  ( this->getChildCount() > 0)
429		{
430			TreeType*	child;
431			child   = this->getChild(0);
432			return child->getLine();
433		}
434		return 0;
435	}
436	return  token->getLine();
437}
438
439template<class ImplTraits>
440typename CommonTree<ImplTraits>::StringType	CommonTree<ImplTraits>::getText()
441{
442	return this->toString();
443}
444
445template<class ImplTraits>
446bool	CommonTree<ImplTraits>::isNilNode()
447{
448	// This is a Nil tree if it has no payload (Token in our case)
449	//
450	if(m_token == NULL)
451	{
452		return true;
453	}
454	else
455	{
456		return false;
457	}
458}
459
460template<class ImplTraits>
461void	CommonTree<ImplTraits>::setChild(ANTLR_UINT32 i, TreeType* child)
462{
463	if( m_children.size() >= i )
464		m_children.resize(i+1);
465	m_children[i] = child;
466}
467
468template<class ImplTraits>
469typename CommonTree<ImplTraits>::StringType	CommonTree<ImplTraits>::toStringTree()
470{
471	StringType  string;
472	ANTLR_UINT32   i;
473	ANTLR_UINT32   n;
474	TreeType*   t;
475
476	if( m_children.empty() )
477	{
478		return	this->toString();
479	}
480
481	/* Need a new string with nothing at all in it.
482	*/
483	if	(this->isNilNode() == false)
484	{
485		string.append("(");
486		string.append(this->toString());
487		string.append(" ");
488	}
489	if	( m_children != NULL)
490	{
491		n = m_children.size();
492
493		for	(i = 0; i < n; i++)
494		{
495			t   = m_children[i];
496
497			if  (i > 0)
498			{
499				string.append(" ");
500			}
501			string.append(t->toStringTree());
502		}
503	}
504	if	(this->isNilNode() == false)
505	{
506		string.append(")");
507	}
508
509	return  string;
510}
511
512template<class ImplTraits>
513typename CommonTree<ImplTraits>::StringType	CommonTree<ImplTraits>::toString()
514{
515	if  (this->isNilNode() )
516	{
517		StringType  nilNode;
518
519		nilNode	= "nil";
520
521		return nilNode;
522	}
523
524	return	m_token->getText();
525}
526
527template<class ImplTraits>
528void	CommonTree<ImplTraits>::freshenPACIndexesAll()
529{
530	this->freshenPACIndexes(0);
531}
532
533template<class ImplTraits>
534void	CommonTree<ImplTraits>::freshenPACIndexes(ANTLR_UINT32 offset)
535{
536	ANTLR_UINT32	count;
537	ANTLR_UINT32	c;
538
539	count	= this->getChildCount();		// How many children do we have
540
541	// Loop from the supplied index and set the indexes and parent
542	//
543	for	(c = offset; c < count; c++)
544	{
545		TreeType*	child;
546
547		child = this->getChild(c);
548
549		child->setChildIndex(c);
550		child->setParent(this);
551	}
552}
553
554template<class ImplTraits>
555void    CommonTree<ImplTraits>::reuse()
556{
557	delete this; //memory re-use should be taken by the library user
558}
559
560template<class ImplTraits>
561CommonTree<ImplTraits>::~CommonTree()
562{
563}
564
565ANTLR_END_NAMESPACE()
566