• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1ANTLR_BEGIN_NAMESPACE()
2
3template<class ImplTraits>
4CommonTreeNodeStream<ImplTraits>::CommonTreeNodeStream(ANTLR_UINT32 hint)
5{
6	this->init(hint);
7}
8
9template<class ImplTraits>
10void CommonTreeNodeStream<ImplTraits>::init( ANTLR_UINT32 hint )
11{
12	m_root = NULL;
13	m_adaptor = new TreeAdaptorType;
14	// Create the node list map
15	//
16	if	(hint == 0)
17		hint = DEFAULT_INITIAL_BUFFER_SIZE;
18	m_nodes.reserve( DEFAULT_INITIAL_BUFFER_SIZE );
19
20	m_p = -1;
21	m_currentNode = NULL;
22	m_previousNode = NULL;
23	m_currentChildIndex = 0;
24	m_absoluteNodeIndex = 0;
25	m_lookAhead = NULL;
26	m_lookAheadLength = 0;
27	m_head = 0;
28	m_tail = 0;
29	m_uniqueNavigationNodes = false;
30	m_isRewriter = false;
31
32	CommonTokenType* token		= new CommonTokenType(CommonTokenType::TOKEN_UP);
33	token->set_tokText( "UP" );
34	m_UP.set_token( token );
35
36	token		= new CommonTokenType(CommonTokenType::TOKEN_DOWN);
37	token->set_tokText( "DOWN" );
38	m_DOWN.set_token( token );
39
40	token		= new CommonTokenType(CommonTokenType::TOKEN_EOF);
41	token->set_tokText( "EOF" );
42	m_EOF_NODE.set_token( token );
43
44	token		= new CommonTokenType(CommonTokenType::TOKEN_INVALID);
45	token->set_tokText( "INVALID" );
46	m_EOF_NODE.set_token( token );
47}
48
49template<class ImplTraits>
50CommonTreeNodeStream<ImplTraits>::CommonTreeNodeStream( const CommonTreeNodeStream& ctn )
51{
52	m_root = ctn.m_root;
53	m_adaptor = ctn.m_adaptor;
54	m_nodes.reserve( DEFAULT_INITIAL_BUFFER_SIZE );
55	m_nodeStack = ctn.m_nodeStack;
56	m_p = -1;
57	m_currentNode = NULL;
58	m_previousNode = NULL;
59	m_currentChildIndex = 0;
60	m_absoluteNodeIndex = 0;
61	m_lookAhead = NULL;
62	m_lookAheadLength = 0;
63	m_head = 0;
64	m_tail = 0;
65	m_uniqueNavigationNodes = false;
66	m_isRewriter = true;
67
68	m_UP.set_token( ctn.m_UP.get_token() );
69	m_DOWN.set_token( ctn.m_DOWN.get_token() );
70	m_EOF_NODE.set_token( ctn.m_EOF_NODE.get_token() );
71	m_INVALID_NODE.set_token( ctn.m_INVALID_NODE.get_token() );
72}
73
74template<class ImplTraits>
75CommonTreeNodeStream<ImplTraits>::CommonTreeNodeStream( TreeType* tree, ANTLR_UINT32 hint )
76{
77	this->init(hint);
78	m_root = tree;
79}
80
81template<class ImplTraits>
82CommonTreeNodeStream<ImplTraits>::~CommonTreeNodeStream()
83{
84	// If this is a rewrting stream, then certain resources
85	// belong to the originating node stream and we do not
86	// free them here.
87	//
88	if	( m_isRewriter != true)
89	{
90		delete m_adaptor;
91
92		m_nodeStack.clear();
93
94		delete m_INVALID_NODE.get_token();
95		delete m_EOF_NODE.get_token();
96		delete m_DOWN.get_token();
97		delete m_UP.get_token();
98	}
99
100	m_nodes.clear();
101}
102
103template<class ImplTraits>
104typename CommonTreeNodeStream<ImplTraits>::TreeType*	CommonTreeNodeStream<ImplTraits>::_LT(ANTLR_INT32 k)
105{
106	if	( m_p == -1)
107	{
108		this->fillBufferRoot();
109	}
110
111	if	(k < 0)
112	{
113		return this->LB(-k);
114	}
115	else if	(k == 0)
116	{
117		return	&(m_INVALID_NODE);
118	}
119
120	// k was a legitimate request,
121	//
122	if	(( m_p + k - 1) >= (ANTLR_INT32)(m_nodes.size()))
123	{
124		return &(m_EOF_NODE);
125	}
126
127	return	m_nodes[ m_p + k - 1 ];
128}
129
130template<class ImplTraits>
131typename CommonTreeNodeStream<ImplTraits>::TreeType*	CommonTreeNodeStream<ImplTraits>::getTreeSource()
132{
133	return m_root;
134}
135
136template<class ImplTraits>
137typename CommonTreeNodeStream<ImplTraits>::TreeAdaptorType*	CommonTreeNodeStream<ImplTraits>::getTreeAdaptor()
138{
139	return m_adaptor;
140}
141
142template<class ImplTraits>
143void  CommonTreeNodeStream<ImplTraits>::set_uniqueNavigationNodes(bool uniqueNavigationNodes)
144{
145	m_uniqueNavigationNodes = uniqueNavigationNodes;
146}
147
148template<class ImplTraits>
149typename CommonTreeNodeStream<ImplTraits>::StringType  CommonTreeNodeStream<ImplTraits>::toString()
150{
151    return  this->toStringSS(m_root, NULL);
152}
153
154template<class ImplTraits>
155typename CommonTreeNodeStream<ImplTraits>::StringType  CommonTreeNodeStream<ImplTraits>::toStringSS(TreeType* start, TreeType* stop)
156{
157	StringType  buf;
158    this->toStringWork(start, stop, buf);
159    return  buf;
160}
161
162template<class ImplTraits>
163void CommonTreeNodeStream<ImplTraits>::toStringWork(TreeType* start, TreeType* stop, StringType& str)
164{
165	ANTLR_UINT32   n;
166	ANTLR_UINT32   c;
167	StringStreamType buf;
168
169	if	(!start->isNilNode() )
170	{
171		StringType	text;
172
173		text	= start->toString();
174
175		if  (text.empty())
176		{
177			buf << ' ';
178			buf << start->getType();
179		}
180		else
181			buf << text;
182	}
183
184	if	(start == stop)
185	{
186		return;		/* Finished */
187	}
188
189	n = start->getChildCount();
190
191	if	(n > 0 && ! start->isNilNode() )
192	{
193		buf << ' ';
194		buf << CommonTokenType::TOKEN_DOWN;
195	}
196
197	for	(c = 0; c<n ; c++)
198	{
199		TreeType*   child;
200
201		child = start->getChild(c);
202		this->toStringWork(child, stop, buf);
203	}
204
205	if	(n > 0 && ! start->isNilNode() )
206	{
207		buf << ' ';
208		buf << CommonTokenType::TOKEN_UP;
209	}
210	str = buf.str();
211}
212
213template<class ImplTraits>
214typename  CommonTreeNodeStream<ImplTraits>::TreeType*	CommonTreeNodeStream<ImplTraits>::get(ANTLR_INT32 k)
215{
216	if( m_p == -1 )
217	{
218		this->fillBufferRoot();
219	}
220
221	return m_nodes[k];
222}
223
224template<class ImplTraits>
225void	CommonTreeNodeStream<ImplTraits>::replaceChildren(TreeType* parent,
226															ANTLR_INT32 startChildIndex,
227															ANTLR_INT32 stopChildIndex,
228															TreeType* t)
229{
230	if	(parent != NULL)
231	{
232		TreeAdaptorType*	adaptor;
233		adaptor	= this->getTreeAdaptor();
234		adaptor->replaceChildren(parent, startChildIndex, stopChildIndex, t);
235	}
236}
237
238template<class ImplTraits>
239typename CommonTreeNodeStream<ImplTraits>::TreeType* CommonTreeNodeStream<ImplTraits>::LB(ANTLR_INT32 k)
240{
241	if	( k==0)
242	{
243		return	&(m_INVALID_NODE);
244	}
245
246	if	( (m_p - k) < 0)
247	{
248		return	&(m_INVALID_NODE);
249	}
250
251	return m_nodes[ m_p - k ];
252}
253
254template<class ImplTraits>
255void CommonTreeNodeStream<ImplTraits>::addNavigationNode(ANTLR_UINT32 ttype)
256{
257	TreeType*	    node;
258
259	node = NULL;
260
261	if	(ttype == CommonTokenType::TOKEN_DOWN)
262	{
263		if  (this->hasUniqueNavigationNodes() == true)
264		{
265			node    = this->newDownNode();
266		}
267		else
268		{
269			node    = &m_DOWN;
270		}
271	}
272	else
273	{
274		if  (this->hasUniqueNavigationNodes() == true)
275		{
276			node    = this->newUpNode();
277		}
278		else
279		{
280			node    = &m_UP;
281		}
282	}
283
284	// Now add the node we decided upon.
285	//
286	m_nodes.push_back(node);
287}
288
289template<class ImplTraits>
290typename CommonTreeNodeStream<ImplTraits>::TreeType*	CommonTreeNodeStream<ImplTraits>::newDownNode()
291{
292	TreeType*	    dNode;
293    CommonTokenType*    token;
294
295    token					= new CommonTokenType(CommonTokenType::TOKEN_DOWN);
296	token->set_tokText("DOWN");
297    dNode					= new TreeType(token);
298    return  &dNode;
299}
300
301template<class ImplTraits>
302typename CommonTreeNodeStream<ImplTraits>::TreeType*	CommonTreeNodeStream<ImplTraits>::newUpNode()
303{
304	TreeType*	    uNode;
305    CommonTokenType*    token;
306
307    token					= new CommonTokenType(CommonTokenType::TOKEN_UP);
308	token->set_tokText("UP");
309    uNode					= new TreeType(token);
310    return  &uNode;
311
312}
313
314template<class ImplTraits>
315bool  CommonTreeNodeStream<ImplTraits>::hasUniqueNavigationNodes() const
316{
317	 return  m_uniqueNavigationNodes;
318}
319
320template<class ImplTraits>
321ANTLR_UINT32	CommonTreeNodeStream<ImplTraits>::getLookaheadSize()
322{
323	return	m_tail < m_head
324	    ?	(m_lookAheadLength - m_head + m_tail)
325	    :	(m_tail - m_head);
326}
327
328template<class ImplTraits>
329void	CommonTreeNodeStream<ImplTraits>::push(ANTLR_INT32 index)
330{
331	m_nodeStack.push(m_p);	// Save current index
332	this->seek(index);
333}
334
335template<class ImplTraits>
336ANTLR_INT32	CommonTreeNodeStream<ImplTraits>::pop()
337{
338	ANTLR_INT32	retVal;
339
340	retVal = m_nodeStack.top();
341	m_nodeStack.pop();
342	this->seek(retVal);
343	return retVal;
344}
345
346template<class ImplTraits>
347void	CommonTreeNodeStream<ImplTraits>::reset()
348{
349	if	( m_p != -1)
350	{
351		m_p	= 0;
352	}
353	BaseType::m_lastMarker		= 0;
354
355
356	// Free and reset the node stack only if this is not
357	// a rewriter, which is going to reuse the originating
358	// node streams node stack
359	//
360	if  (m_isRewriter != true)
361		m_nodeStack.clear();
362}
363
364template<class ImplTraits>
365void CommonTreeNodeStream<ImplTraits>::fillBufferRoot()
366{
367	// Call the generic buffer routine with the root as the
368	// argument
369	//
370	this->fillBuffer(m_root);
371	m_p = 0;					// Indicate we are at buffer start
372}
373
374template<class ImplTraits>
375void CommonTreeNodeStream<ImplTraits>::fillBuffer(TreeType* t)
376{
377	bool	nilNode;
378	ANTLR_UINT32	nCount;
379	ANTLR_UINT32	c;
380
381	nilNode = m_adaptor->isNilNode(t);
382
383	// If the supplied node is not a nil (list) node then we
384	// add in the node itself to the vector
385	//
386	if	(nilNode == false)
387	{
388		m_nodes.push_back(t);
389	}
390
391	// Only add a DOWN node if the tree is not a nil tree and
392	// the tree does have children.
393	//
394	nCount = t->getChildCount();
395
396	if	(nilNode == false && nCount>0)
397	{
398		this->addNavigationNode( CommonTokenType::TOKEN_DOWN);
399	}
400
401	// We always add any children the tree contains, which is
402	// a recursive call to this function, which will cause similar
403	// recursion and implement a depth first addition
404	//
405	for	(c = 0; c < nCount; c++)
406	{
407		this->fillBuffer( m_adaptor->getChild(t, c));
408	}
409
410	// If the tree had children and was not a nil (list) node, then we
411	// we need to add an UP node here to match the DOWN node
412	//
413	if	(nilNode == false && nCount > 0)
414	{
415		this->addNavigationNode(CommonTokenType::TOKEN_UP);
416	}
417}
418
419
420
421ANTLR_END_NAMESPACE()
422
423