xref: /aosp_15_r20/external/antlr/runtime/C/src/antlr3commontreenodestream.c (revision 16467b971bd3e2009fad32dd79016f2c7e421deb)
1*16467b97STreehugger Robot /// \file
2*16467b97STreehugger Robot /// Defines the implementation of the common node stream the default
3*16467b97STreehugger Robot /// tree node stream used by ANTLR.
4*16467b97STreehugger Robot ///
5*16467b97STreehugger Robot 
6*16467b97STreehugger Robot // [The "BSD licence"]
7*16467b97STreehugger Robot // Copyright (c) 2005-2009 Jim Idle, Temporal Wave LLC
8*16467b97STreehugger Robot // http://www.temporal-wave.com
9*16467b97STreehugger Robot // http://www.linkedin.com/in/jimidle
10*16467b97STreehugger Robot //
11*16467b97STreehugger Robot // All rights reserved.
12*16467b97STreehugger Robot //
13*16467b97STreehugger Robot // Redistribution and use in source and binary forms, with or without
14*16467b97STreehugger Robot // modification, are permitted provided that the following conditions
15*16467b97STreehugger Robot // are met:
16*16467b97STreehugger Robot // 1. Redistributions of source code must retain the above copyright
17*16467b97STreehugger Robot //    notice, this list of conditions and the following disclaimer.
18*16467b97STreehugger Robot // 2. Redistributions in binary form must reproduce the above copyright
19*16467b97STreehugger Robot //    notice, this list of conditions and the following disclaimer in the
20*16467b97STreehugger Robot //    documentation and/or other materials provided with the distribution.
21*16467b97STreehugger Robot // 3. The name of the author may not be used to endorse or promote products
22*16467b97STreehugger Robot //    derived from this software without specific prior written permission.
23*16467b97STreehugger Robot //
24*16467b97STreehugger Robot // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
25*16467b97STreehugger Robot // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26*16467b97STreehugger Robot // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27*16467b97STreehugger Robot // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
28*16467b97STreehugger Robot // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29*16467b97STreehugger Robot // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30*16467b97STreehugger Robot // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31*16467b97STreehugger Robot // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32*16467b97STreehugger Robot // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33*16467b97STreehugger Robot // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34*16467b97STreehugger Robot 
35*16467b97STreehugger Robot #include    <antlr3commontreenodestream.h>
36*16467b97STreehugger Robot 
37*16467b97STreehugger Robot #ifdef	ANTLR3_WINDOWS
38*16467b97STreehugger Robot #pragma warning( disable : 4100 )
39*16467b97STreehugger Robot #endif
40*16467b97STreehugger Robot 
41*16467b97STreehugger Robot // COMMON TREE STREAM API
42*16467b97STreehugger Robot //
43*16467b97STreehugger Robot static	void						addNavigationNode			(pANTLR3_COMMON_TREE_NODE_STREAM ctns, ANTLR3_UINT32 ttype);
44*16467b97STreehugger Robot static	ANTLR3_BOOLEAN				hasUniqueNavigationNodes	(pANTLR3_COMMON_TREE_NODE_STREAM ctns);
45*16467b97STreehugger Robot static	pANTLR3_BASE_TREE			newDownNode					(pANTLR3_COMMON_TREE_NODE_STREAM ctns);
46*16467b97STreehugger Robot static	pANTLR3_BASE_TREE			newUpNode					(pANTLR3_COMMON_TREE_NODE_STREAM ctns);
47*16467b97STreehugger Robot static	void						reset						(pANTLR3_COMMON_TREE_NODE_STREAM ctns);
48*16467b97STreehugger Robot static	void						push						(pANTLR3_COMMON_TREE_NODE_STREAM ctns, ANTLR3_INT32 index);
49*16467b97STreehugger Robot static	ANTLR3_INT32				pop							(pANTLR3_COMMON_TREE_NODE_STREAM ctns);
50*16467b97STreehugger Robot //static	ANTLR3_INT32				index						(pANTLR3_COMMON_TREE_NODE_STREAM ctns);
51*16467b97STreehugger Robot static	ANTLR3_UINT32				getLookaheadSize			(pANTLR3_COMMON_TREE_NODE_STREAM ctns);
52*16467b97STreehugger Robot // TREE NODE STREAM API
53*16467b97STreehugger Robot //
54*16467b97STreehugger Robot static	pANTLR3_BASE_TREE_ADAPTOR   getTreeAdaptor				(pANTLR3_TREE_NODE_STREAM tns);
55*16467b97STreehugger Robot static	pANTLR3_BASE_TREE			getTreeSource				(pANTLR3_TREE_NODE_STREAM tns);
56*16467b97STreehugger Robot static	pANTLR3_BASE_TREE			_LT							(pANTLR3_TREE_NODE_STREAM tns, ANTLR3_INT32 k);
57*16467b97STreehugger Robot static	pANTLR3_BASE_TREE			get							(pANTLR3_TREE_NODE_STREAM tns, ANTLR3_INT32 k);
58*16467b97STreehugger Robot static	void						setUniqueNavigationNodes	(pANTLR3_TREE_NODE_STREAM tns, ANTLR3_BOOLEAN uniqueNavigationNodes);
59*16467b97STreehugger Robot static	pANTLR3_STRING				toString					(pANTLR3_TREE_NODE_STREAM tns);
60*16467b97STreehugger Robot static	pANTLR3_STRING				toStringSS					(pANTLR3_TREE_NODE_STREAM tns, pANTLR3_BASE_TREE start, pANTLR3_BASE_TREE stop);
61*16467b97STreehugger Robot static	void						toStringWork				(pANTLR3_TREE_NODE_STREAM tns, pANTLR3_BASE_TREE start, pANTLR3_BASE_TREE stop, pANTLR3_STRING buf);
62*16467b97STreehugger Robot static	void						replaceChildren				(pANTLR3_TREE_NODE_STREAM tns, pANTLR3_BASE_TREE parent, ANTLR3_INT32 startChildIndex, ANTLR3_INT32 stopChildIndex, pANTLR3_BASE_TREE t);
63*16467b97STreehugger Robot 
64*16467b97STreehugger Robot // INT STREAM API
65*16467b97STreehugger Robot //
66*16467b97STreehugger Robot static	void						consume						(pANTLR3_INT_STREAM is);
67*16467b97STreehugger Robot static	ANTLR3_MARKER				tindex						(pANTLR3_INT_STREAM is);
68*16467b97STreehugger Robot static	ANTLR3_UINT32				_LA							(pANTLR3_INT_STREAM is, ANTLR3_INT32 i);
69*16467b97STreehugger Robot static	ANTLR3_MARKER				mark						(pANTLR3_INT_STREAM is);
70*16467b97STreehugger Robot static	void						release						(pANTLR3_INT_STREAM is, ANTLR3_MARKER marker);
71*16467b97STreehugger Robot static	void						rewindMark					(pANTLR3_INT_STREAM is, ANTLR3_MARKER marker);
72*16467b97STreehugger Robot static	void						rewindLast					(pANTLR3_INT_STREAM is);
73*16467b97STreehugger Robot static	void						seek						(pANTLR3_INT_STREAM is, ANTLR3_MARKER index);
74*16467b97STreehugger Robot static	ANTLR3_UINT32				size						(pANTLR3_INT_STREAM is);
75*16467b97STreehugger Robot 
76*16467b97STreehugger Robot 
77*16467b97STreehugger Robot // Helper functions
78*16467b97STreehugger Robot //
79*16467b97STreehugger Robot static	void						fillBuffer					(pANTLR3_COMMON_TREE_NODE_STREAM ctns, pANTLR3_BASE_TREE t);
80*16467b97STreehugger Robot static	void						fillBufferRoot				(pANTLR3_COMMON_TREE_NODE_STREAM ctns);
81*16467b97STreehugger Robot 
82*16467b97STreehugger Robot // Constructors
83*16467b97STreehugger Robot //
84*16467b97STreehugger Robot static	void						antlr3TreeNodeStreamFree			(pANTLR3_TREE_NODE_STREAM tns);
85*16467b97STreehugger Robot static	void						antlr3CommonTreeNodeStreamFree		(pANTLR3_COMMON_TREE_NODE_STREAM ctns);
86*16467b97STreehugger Robot 
87*16467b97STreehugger Robot ANTLR3_API pANTLR3_TREE_NODE_STREAM
antlr3TreeNodeStreamNew()88*16467b97STreehugger Robot antlr3TreeNodeStreamNew()
89*16467b97STreehugger Robot {
90*16467b97STreehugger Robot     pANTLR3_TREE_NODE_STREAM stream;
91*16467b97STreehugger Robot 
92*16467b97STreehugger Robot     // Memory for the interface structure
93*16467b97STreehugger Robot     //
94*16467b97STreehugger Robot     stream  = (pANTLR3_TREE_NODE_STREAM) ANTLR3_CALLOC(1, sizeof(ANTLR3_TREE_NODE_STREAM));
95*16467b97STreehugger Robot 
96*16467b97STreehugger Robot     if	(stream == NULL)
97*16467b97STreehugger Robot     {
98*16467b97STreehugger Robot 		return	NULL;
99*16467b97STreehugger Robot     }
100*16467b97STreehugger Robot 
101*16467b97STreehugger Robot     // Install basic API
102*16467b97STreehugger Robot     //
103*16467b97STreehugger Robot 	stream->replaceChildren = replaceChildren;
104*16467b97STreehugger Robot     stream->free			= antlr3TreeNodeStreamFree;
105*16467b97STreehugger Robot 
106*16467b97STreehugger Robot     return stream;
107*16467b97STreehugger Robot }
108*16467b97STreehugger Robot 
109*16467b97STreehugger Robot static void
antlr3TreeNodeStreamFree(pANTLR3_TREE_NODE_STREAM stream)110*16467b97STreehugger Robot antlr3TreeNodeStreamFree(pANTLR3_TREE_NODE_STREAM stream)
111*16467b97STreehugger Robot {
112*16467b97STreehugger Robot     ANTLR3_FREE(stream);
113*16467b97STreehugger Robot }
114*16467b97STreehugger Robot 
115*16467b97STreehugger Robot ANTLR3_API pANTLR3_COMMON_TREE_NODE_STREAM
antlr3CommonTreeNodeStreamNewTree(pANTLR3_BASE_TREE tree,ANTLR3_UINT32 hint)116*16467b97STreehugger Robot antlr3CommonTreeNodeStreamNewTree(pANTLR3_BASE_TREE tree, ANTLR3_UINT32 hint)
117*16467b97STreehugger Robot {
118*16467b97STreehugger Robot 	pANTLR3_COMMON_TREE_NODE_STREAM stream;
119*16467b97STreehugger Robot 
120*16467b97STreehugger Robot 	stream = antlr3CommonTreeNodeStreamNew(tree->strFactory, hint);
121*16467b97STreehugger Robot 
122*16467b97STreehugger Robot 	if	(stream == NULL)
123*16467b97STreehugger Robot 	{
124*16467b97STreehugger Robot 		return	NULL;
125*16467b97STreehugger Robot 	}
126*16467b97STreehugger Robot 	stream->root    = tree;
127*16467b97STreehugger Robot 
128*16467b97STreehugger Robot 	return stream;
129*16467b97STreehugger Robot }
130*16467b97STreehugger Robot 
131*16467b97STreehugger Robot ANTLR3_API pANTLR3_COMMON_TREE_NODE_STREAM
antlr3CommonTreeNodeStreamNewStream(pANTLR3_COMMON_TREE_NODE_STREAM inStream)132*16467b97STreehugger Robot antlr3CommonTreeNodeStreamNewStream(pANTLR3_COMMON_TREE_NODE_STREAM inStream)
133*16467b97STreehugger Robot {
134*16467b97STreehugger Robot 	pANTLR3_COMMON_TREE_NODE_STREAM stream;
135*16467b97STreehugger Robot 
136*16467b97STreehugger Robot 	// Memory for the interface structure
137*16467b97STreehugger Robot 	//
138*16467b97STreehugger Robot 	stream  = (pANTLR3_COMMON_TREE_NODE_STREAM) ANTLR3_CALLOC(1, sizeof(ANTLR3_COMMON_TREE_NODE_STREAM));
139*16467b97STreehugger Robot 
140*16467b97STreehugger Robot 	if	(stream == NULL)
141*16467b97STreehugger Robot 	{
142*16467b97STreehugger Robot 		return	NULL;
143*16467b97STreehugger Robot 	}
144*16467b97STreehugger Robot 
145*16467b97STreehugger Robot 	// Copy in all the reusable parts of the originating stream and create new
146*16467b97STreehugger Robot 	// pieces where necessary.
147*16467b97STreehugger Robot 	//
148*16467b97STreehugger Robot 
149*16467b97STreehugger Robot 	// String factory for tree walker
150*16467b97STreehugger Robot 	//
151*16467b97STreehugger Robot 	stream->stringFactory		= inStream->stringFactory;
152*16467b97STreehugger Robot 
153*16467b97STreehugger Robot 	// Create an adaptor for the common tree node stream
154*16467b97STreehugger Robot 	//
155*16467b97STreehugger Robot 	stream->adaptor				= inStream->adaptor;
156*16467b97STreehugger Robot 
157*16467b97STreehugger Robot 	// Create space for the tree node stream interface
158*16467b97STreehugger Robot 	//
159*16467b97STreehugger Robot 	stream->tnstream	    = antlr3TreeNodeStreamNew();
160*16467b97STreehugger Robot 
161*16467b97STreehugger Robot 	if	(stream->tnstream == NULL)
162*16467b97STreehugger Robot 	{
163*16467b97STreehugger Robot 		stream->free				(stream);
164*16467b97STreehugger Robot 
165*16467b97STreehugger Robot 		return	NULL;
166*16467b97STreehugger Robot 	}
167*16467b97STreehugger Robot 
168*16467b97STreehugger Robot 	// Create space for the INT_STREAM interface
169*16467b97STreehugger Robot 	//
170*16467b97STreehugger Robot 	stream->tnstream->istream		    =  antlr3IntStreamNew();
171*16467b97STreehugger Robot 
172*16467b97STreehugger Robot 	if	(stream->tnstream->istream == NULL)
173*16467b97STreehugger Robot 	{
174*16467b97STreehugger Robot 		stream->tnstream->free		(stream->tnstream);
175*16467b97STreehugger Robot 		stream->free				(stream);
176*16467b97STreehugger Robot 
177*16467b97STreehugger Robot 		return	NULL;
178*16467b97STreehugger Robot 	}
179*16467b97STreehugger Robot 
180*16467b97STreehugger Robot 	// Install the common tree node stream API
181*16467b97STreehugger Robot 	//
182*16467b97STreehugger Robot 	stream->addNavigationNode		    =  addNavigationNode;
183*16467b97STreehugger Robot 	stream->hasUniqueNavigationNodes    =  hasUniqueNavigationNodes;
184*16467b97STreehugger Robot 	stream->newDownNode					=  newDownNode;
185*16467b97STreehugger Robot 	stream->newUpNode					=  newUpNode;
186*16467b97STreehugger Robot 	stream->reset						=  reset;
187*16467b97STreehugger Robot 	stream->push						=  push;
188*16467b97STreehugger Robot 	stream->pop							=  pop;
189*16467b97STreehugger Robot 	stream->getLookaheadSize			=  getLookaheadSize;
190*16467b97STreehugger Robot 
191*16467b97STreehugger Robot 	stream->free			    =  antlr3CommonTreeNodeStreamFree;
192*16467b97STreehugger Robot 
193*16467b97STreehugger Robot 	// Install the tree node stream API
194*16467b97STreehugger Robot 	//
195*16467b97STreehugger Robot 	stream->tnstream->getTreeAdaptor			=  getTreeAdaptor;
196*16467b97STreehugger Robot 	stream->tnstream->getTreeSource				=  getTreeSource;
197*16467b97STreehugger Robot 	stream->tnstream->_LT						=  _LT;
198*16467b97STreehugger Robot 	stream->tnstream->setUniqueNavigationNodes	=  setUniqueNavigationNodes;
199*16467b97STreehugger Robot 	stream->tnstream->toString					=  toString;
200*16467b97STreehugger Robot 	stream->tnstream->toStringSS				=  toStringSS;
201*16467b97STreehugger Robot 	stream->tnstream->toStringWork				=  toStringWork;
202*16467b97STreehugger Robot 	stream->tnstream->get						=  get;
203*16467b97STreehugger Robot 
204*16467b97STreehugger Robot 	// Install INT_STREAM interface
205*16467b97STreehugger Robot 	//
206*16467b97STreehugger Robot 	stream->tnstream->istream->consume	    =  consume;
207*16467b97STreehugger Robot 	stream->tnstream->istream->index	    =  tindex;
208*16467b97STreehugger Robot 	stream->tnstream->istream->_LA			=  _LA;
209*16467b97STreehugger Robot 	stream->tnstream->istream->mark			=  mark;
210*16467b97STreehugger Robot 	stream->tnstream->istream->release	    =  release;
211*16467b97STreehugger Robot 	stream->tnstream->istream->rewind	    =  rewindMark;
212*16467b97STreehugger Robot 	stream->tnstream->istream->rewindLast   =  rewindLast;
213*16467b97STreehugger Robot 	stream->tnstream->istream->seek			=  seek;
214*16467b97STreehugger Robot 	stream->tnstream->istream->size			=  size;
215*16467b97STreehugger Robot 
216*16467b97STreehugger Robot 	// Initialize data elements of INT stream
217*16467b97STreehugger Robot 	//
218*16467b97STreehugger Robot 	stream->tnstream->istream->type			= ANTLR3_COMMONTREENODE;
219*16467b97STreehugger Robot 	stream->tnstream->istream->super	    =  (stream->tnstream);
220*16467b97STreehugger Robot 
221*16467b97STreehugger Robot 	// Initialize data elements of TREE stream
222*16467b97STreehugger Robot 	//
223*16467b97STreehugger Robot 	stream->tnstream->ctns =  stream;
224*16467b97STreehugger Robot 
225*16467b97STreehugger Robot 	// Initialize data elements of the COMMON TREE NODE stream
226*16467b97STreehugger Robot 	//
227*16467b97STreehugger Robot 	stream->super					= NULL;
228*16467b97STreehugger Robot 	stream->uniqueNavigationNodes	= ANTLR3_FALSE;
229*16467b97STreehugger Robot 	stream->markers					= NULL;
230*16467b97STreehugger Robot 	stream->nodeStack				= inStream->nodeStack;
231*16467b97STreehugger Robot 
232*16467b97STreehugger Robot 	// Create the node list map
233*16467b97STreehugger Robot 	//
234*16467b97STreehugger Robot 	stream->nodes	= antlr3VectorNew(DEFAULT_INITIAL_BUFFER_SIZE);
235*16467b97STreehugger Robot 	stream->p		= -1;
236*16467b97STreehugger Robot 
237*16467b97STreehugger Robot 	// Install the navigation nodes
238*16467b97STreehugger Robot 	//
239*16467b97STreehugger Robot 
240*16467b97STreehugger Robot 	// Install the navigation nodes
241*16467b97STreehugger Robot 	//
242*16467b97STreehugger Robot 	antlr3SetCTAPI(&(stream->UP));
243*16467b97STreehugger Robot 	antlr3SetCTAPI(&(stream->DOWN));
244*16467b97STreehugger Robot 	antlr3SetCTAPI(&(stream->EOF_NODE));
245*16467b97STreehugger Robot 	antlr3SetCTAPI(&(stream->INVALID_NODE));
246*16467b97STreehugger Robot 
247*16467b97STreehugger Robot 	stream->UP.token						= inStream->UP.token;
248*16467b97STreehugger Robot 	inStream->UP.token->strFactory			= stream->stringFactory;
249*16467b97STreehugger Robot 	stream->DOWN.token						= inStream->DOWN.token;
250*16467b97STreehugger Robot 	inStream->DOWN.token->strFactory		= stream->stringFactory;
251*16467b97STreehugger Robot 	stream->EOF_NODE.token					= inStream->EOF_NODE.token;
252*16467b97STreehugger Robot 	inStream->EOF_NODE.token->strFactory	= stream->stringFactory;
253*16467b97STreehugger Robot 	stream->INVALID_NODE.token				= inStream->INVALID_NODE.token;
254*16467b97STreehugger Robot 	inStream->INVALID_NODE.token->strFactory= stream->stringFactory;
255*16467b97STreehugger Robot 
256*16467b97STreehugger Robot 	// Reuse the root tree of the originating stream
257*16467b97STreehugger Robot 	//
258*16467b97STreehugger Robot 	stream->root		= inStream->root;
259*16467b97STreehugger Robot 
260*16467b97STreehugger Robot 	// Signal that this is a rewriting stream so we don't
261*16467b97STreehugger Robot 	// free the originating tree. Anything that we rewrite or
262*16467b97STreehugger Robot 	// duplicate here will be done through the adaptor or
263*16467b97STreehugger Robot 	// the original tree factory.
264*16467b97STreehugger Robot 	//
265*16467b97STreehugger Robot 	stream->isRewriter	= ANTLR3_TRUE;
266*16467b97STreehugger Robot 	return stream;
267*16467b97STreehugger Robot }
268*16467b97STreehugger Robot 
269*16467b97STreehugger Robot ANTLR3_API pANTLR3_COMMON_TREE_NODE_STREAM
antlr3CommonTreeNodeStreamNew(pANTLR3_STRING_FACTORY strFactory,ANTLR3_UINT32 hint)270*16467b97STreehugger Robot antlr3CommonTreeNodeStreamNew(pANTLR3_STRING_FACTORY strFactory, ANTLR3_UINT32 hint)
271*16467b97STreehugger Robot {
272*16467b97STreehugger Robot 	pANTLR3_COMMON_TREE_NODE_STREAM stream;
273*16467b97STreehugger Robot 	pANTLR3_COMMON_TOKEN			token;
274*16467b97STreehugger Robot 
275*16467b97STreehugger Robot 	// Memory for the interface structure
276*16467b97STreehugger Robot 	//
277*16467b97STreehugger Robot 	stream  = (pANTLR3_COMMON_TREE_NODE_STREAM) ANTLR3_CALLOC(1, sizeof(ANTLR3_COMMON_TREE_NODE_STREAM));
278*16467b97STreehugger Robot 
279*16467b97STreehugger Robot 	if	(stream == NULL)
280*16467b97STreehugger Robot 	{
281*16467b97STreehugger Robot 		return	NULL;
282*16467b97STreehugger Robot 	}
283*16467b97STreehugger Robot 
284*16467b97STreehugger Robot 	// String factory for tree walker
285*16467b97STreehugger Robot 	//
286*16467b97STreehugger Robot 	stream->stringFactory		= strFactory;
287*16467b97STreehugger Robot 
288*16467b97STreehugger Robot 	// Create an adaptor for the common tree node stream
289*16467b97STreehugger Robot 	//
290*16467b97STreehugger Robot 	stream->adaptor				= ANTLR3_TREE_ADAPTORNew(strFactory);
291*16467b97STreehugger Robot 
292*16467b97STreehugger Robot 	if	(stream->adaptor == NULL)
293*16467b97STreehugger Robot 	{
294*16467b97STreehugger Robot 		stream->free(stream);
295*16467b97STreehugger Robot 		return	NULL;
296*16467b97STreehugger Robot 	}
297*16467b97STreehugger Robot 
298*16467b97STreehugger Robot 	// Create space for the tree node stream interface
299*16467b97STreehugger Robot 	//
300*16467b97STreehugger Robot 	stream->tnstream	    = antlr3TreeNodeStreamNew();
301*16467b97STreehugger Robot 
302*16467b97STreehugger Robot 	if	(stream->tnstream == NULL)
303*16467b97STreehugger Robot 	{
304*16467b97STreehugger Robot 		stream->adaptor->free		(stream->adaptor);
305*16467b97STreehugger Robot 		stream->free				(stream);
306*16467b97STreehugger Robot 
307*16467b97STreehugger Robot 		return	NULL;
308*16467b97STreehugger Robot 	}
309*16467b97STreehugger Robot 
310*16467b97STreehugger Robot 	// Create space for the INT_STREAM interface
311*16467b97STreehugger Robot 	//
312*16467b97STreehugger Robot 	stream->tnstream->istream		    =  antlr3IntStreamNew();
313*16467b97STreehugger Robot 
314*16467b97STreehugger Robot 	if	(stream->tnstream->istream == NULL)
315*16467b97STreehugger Robot 	{
316*16467b97STreehugger Robot 		stream->adaptor->free		(stream->adaptor);
317*16467b97STreehugger Robot 		stream->tnstream->free		(stream->tnstream);
318*16467b97STreehugger Robot 		stream->free				(stream);
319*16467b97STreehugger Robot 
320*16467b97STreehugger Robot 		return	NULL;
321*16467b97STreehugger Robot 	}
322*16467b97STreehugger Robot 
323*16467b97STreehugger Robot 	// Install the common tree node stream API
324*16467b97STreehugger Robot 	//
325*16467b97STreehugger Robot 	stream->addNavigationNode		    =  addNavigationNode;
326*16467b97STreehugger Robot 	stream->hasUniqueNavigationNodes    =  hasUniqueNavigationNodes;
327*16467b97STreehugger Robot 	stream->newDownNode					=  newDownNode;
328*16467b97STreehugger Robot 	stream->newUpNode					=  newUpNode;
329*16467b97STreehugger Robot 	stream->reset						=  reset;
330*16467b97STreehugger Robot 	stream->push						=  push;
331*16467b97STreehugger Robot 	stream->pop							=  pop;
332*16467b97STreehugger Robot 
333*16467b97STreehugger Robot 	stream->free			    =  antlr3CommonTreeNodeStreamFree;
334*16467b97STreehugger Robot 
335*16467b97STreehugger Robot 	// Install the tree node stream API
336*16467b97STreehugger Robot 	//
337*16467b97STreehugger Robot 	stream->tnstream->getTreeAdaptor			=  getTreeAdaptor;
338*16467b97STreehugger Robot 	stream->tnstream->getTreeSource				=  getTreeSource;
339*16467b97STreehugger Robot 	stream->tnstream->_LT						=  _LT;
340*16467b97STreehugger Robot 	stream->tnstream->setUniqueNavigationNodes	=  setUniqueNavigationNodes;
341*16467b97STreehugger Robot 	stream->tnstream->toString					=  toString;
342*16467b97STreehugger Robot 	stream->tnstream->toStringSS				=  toStringSS;
343*16467b97STreehugger Robot 	stream->tnstream->toStringWork				=  toStringWork;
344*16467b97STreehugger Robot 	stream->tnstream->get						=  get;
345*16467b97STreehugger Robot 
346*16467b97STreehugger Robot 	// Install INT_STREAM interface
347*16467b97STreehugger Robot 	//
348*16467b97STreehugger Robot 	stream->tnstream->istream->consume	    =  consume;
349*16467b97STreehugger Robot 	stream->tnstream->istream->index	    =  tindex;
350*16467b97STreehugger Robot 	stream->tnstream->istream->_LA			=  _LA;
351*16467b97STreehugger Robot 	stream->tnstream->istream->mark			=  mark;
352*16467b97STreehugger Robot 	stream->tnstream->istream->release	    =  release;
353*16467b97STreehugger Robot 	stream->tnstream->istream->rewind	    =  rewindMark;
354*16467b97STreehugger Robot 	stream->tnstream->istream->rewindLast   =  rewindLast;
355*16467b97STreehugger Robot 	stream->tnstream->istream->seek			=  seek;
356*16467b97STreehugger Robot 	stream->tnstream->istream->size			=  size;
357*16467b97STreehugger Robot 
358*16467b97STreehugger Robot 	// Initialize data elements of INT stream
359*16467b97STreehugger Robot 	//
360*16467b97STreehugger Robot 	stream->tnstream->istream->type			= ANTLR3_COMMONTREENODE;
361*16467b97STreehugger Robot 	stream->tnstream->istream->super	    =  (stream->tnstream);
362*16467b97STreehugger Robot 
363*16467b97STreehugger Robot 	// Initialize data elements of TREE stream
364*16467b97STreehugger Robot 	//
365*16467b97STreehugger Robot 	stream->tnstream->ctns =  stream;
366*16467b97STreehugger Robot 
367*16467b97STreehugger Robot 	// Initialize data elements of the COMMON TREE NODE stream
368*16467b97STreehugger Robot 	//
369*16467b97STreehugger Robot 	stream->super					= NULL;
370*16467b97STreehugger Robot 	stream->uniqueNavigationNodes	= ANTLR3_FALSE;
371*16467b97STreehugger Robot 	stream->markers					= NULL;
372*16467b97STreehugger Robot 	stream->nodeStack				= antlr3StackNew(INITIAL_CALL_STACK_SIZE);
373*16467b97STreehugger Robot 
374*16467b97STreehugger Robot 	// Create the node list map
375*16467b97STreehugger Robot 	//
376*16467b97STreehugger Robot 	if	(hint == 0)
377*16467b97STreehugger Robot 	{
378*16467b97STreehugger Robot 		hint = DEFAULT_INITIAL_BUFFER_SIZE;
379*16467b97STreehugger Robot 	}
380*16467b97STreehugger Robot 	stream->nodes	= antlr3VectorNew(hint);
381*16467b97STreehugger Robot 	stream->p		= -1;
382*16467b97STreehugger Robot 
383*16467b97STreehugger Robot 	// Install the navigation nodes
384*16467b97STreehugger Robot 	//
385*16467b97STreehugger Robot 	antlr3SetCTAPI(&(stream->UP));
386*16467b97STreehugger Robot 	antlr3SetCTAPI(&(stream->DOWN));
387*16467b97STreehugger Robot 	antlr3SetCTAPI(&(stream->EOF_NODE));
388*16467b97STreehugger Robot 	antlr3SetCTAPI(&(stream->INVALID_NODE));
389*16467b97STreehugger Robot 
390*16467b97STreehugger Robot 	token						= antlr3CommonTokenNew(ANTLR3_TOKEN_UP);
391*16467b97STreehugger Robot 	token->strFactory			= strFactory;
392*16467b97STreehugger Robot 	token->textState			= ANTLR3_TEXT_CHARP;
393*16467b97STreehugger Robot 	token->tokText.chars		= (pANTLR3_UCHAR)"UP";
394*16467b97STreehugger Robot 	stream->UP.token			= token;
395*16467b97STreehugger Robot 
396*16467b97STreehugger Robot 	token						= antlr3CommonTokenNew(ANTLR3_TOKEN_DOWN);
397*16467b97STreehugger Robot 	token->strFactory			= strFactory;
398*16467b97STreehugger Robot 	token->textState			= ANTLR3_TEXT_CHARP;
399*16467b97STreehugger Robot 	token->tokText.chars		= (pANTLR3_UCHAR)"DOWN";
400*16467b97STreehugger Robot 	stream->DOWN.token			= token;
401*16467b97STreehugger Robot 
402*16467b97STreehugger Robot 	token						= antlr3CommonTokenNew(ANTLR3_TOKEN_EOF);
403*16467b97STreehugger Robot 	token->strFactory			= strFactory;
404*16467b97STreehugger Robot 	token->textState			= ANTLR3_TEXT_CHARP;
405*16467b97STreehugger Robot 	token->tokText.chars		= (pANTLR3_UCHAR)"EOF";
406*16467b97STreehugger Robot 	stream->EOF_NODE.token		= token;
407*16467b97STreehugger Robot 
408*16467b97STreehugger Robot 	token						= antlr3CommonTokenNew(ANTLR3_TOKEN_INVALID);
409*16467b97STreehugger Robot 	token->strFactory			= strFactory;
410*16467b97STreehugger Robot 	token->textState			= ANTLR3_TEXT_CHARP;
411*16467b97STreehugger Robot 	token->tokText.chars		= (pANTLR3_UCHAR)"INVALID";
412*16467b97STreehugger Robot 	stream->INVALID_NODE.token	= token;
413*16467b97STreehugger Robot 
414*16467b97STreehugger Robot 
415*16467b97STreehugger Robot 	return  stream;
416*16467b97STreehugger Robot }
417*16467b97STreehugger Robot 
418*16467b97STreehugger Robot /// Free up any resources that belong to this common tree node stream.
419*16467b97STreehugger Robot ///
antlr3CommonTreeNodeStreamFree(pANTLR3_COMMON_TREE_NODE_STREAM ctns)420*16467b97STreehugger Robot static	void			    antlr3CommonTreeNodeStreamFree  (pANTLR3_COMMON_TREE_NODE_STREAM ctns)
421*16467b97STreehugger Robot {
422*16467b97STreehugger Robot 
423*16467b97STreehugger Robot 	// If this is a rewrting stream, then certain resources
424*16467b97STreehugger Robot 	// belong to the originating node stream and we do not
425*16467b97STreehugger Robot 	// free them here.
426*16467b97STreehugger Robot 	//
427*16467b97STreehugger Robot 	if	(ctns->isRewriter != ANTLR3_TRUE)
428*16467b97STreehugger Robot 	{
429*16467b97STreehugger Robot 		ctns->adaptor			->free  (ctns->adaptor);
430*16467b97STreehugger Robot 
431*16467b97STreehugger Robot 		if	(ctns->nodeStack != NULL)
432*16467b97STreehugger Robot 		{
433*16467b97STreehugger Robot 			ctns->nodeStack->free(ctns->nodeStack);
434*16467b97STreehugger Robot 		}
435*16467b97STreehugger Robot 
436*16467b97STreehugger Robot 		ANTLR3_FREE(ctns->INVALID_NODE.token);
437*16467b97STreehugger Robot 		ANTLR3_FREE(ctns->EOF_NODE.token);
438*16467b97STreehugger Robot 		ANTLR3_FREE(ctns->DOWN.token);
439*16467b97STreehugger Robot 		ANTLR3_FREE(ctns->UP.token);
440*16467b97STreehugger Robot 	}
441*16467b97STreehugger Robot 
442*16467b97STreehugger Robot 	if	(ctns->nodes != NULL)
443*16467b97STreehugger Robot 	{
444*16467b97STreehugger Robot 		ctns->nodes			->free  (ctns->nodes);
445*16467b97STreehugger Robot 	}
446*16467b97STreehugger Robot 	ctns->tnstream->istream ->free  (ctns->tnstream->istream);
447*16467b97STreehugger Robot     ctns->tnstream			->free  (ctns->tnstream);
448*16467b97STreehugger Robot 
449*16467b97STreehugger Robot 
450*16467b97STreehugger Robot     ANTLR3_FREE(ctns);
451*16467b97STreehugger Robot }
452*16467b97STreehugger Robot 
453*16467b97STreehugger Robot // ------------------------------------------------------------------------------
454*16467b97STreehugger Robot // Local helpers
455*16467b97STreehugger Robot //
456*16467b97STreehugger Robot 
457*16467b97STreehugger Robot /// Walk and fill the tree node buffer from the root tree
458*16467b97STreehugger Robot ///
459*16467b97STreehugger Robot static void
fillBufferRoot(pANTLR3_COMMON_TREE_NODE_STREAM ctns)460*16467b97STreehugger Robot fillBufferRoot(pANTLR3_COMMON_TREE_NODE_STREAM ctns)
461*16467b97STreehugger Robot {
462*16467b97STreehugger Robot 	// Call the generic buffer routine with the root as the
463*16467b97STreehugger Robot 	// argument
464*16467b97STreehugger Robot 	//
465*16467b97STreehugger Robot 	fillBuffer(ctns, ctns->root);
466*16467b97STreehugger Robot 	ctns->p = 0;					// Indicate we are at buffer start
467*16467b97STreehugger Robot }
468*16467b97STreehugger Robot 
469*16467b97STreehugger Robot /// Walk tree with depth-first-search and fill nodes buffer.
470*16467b97STreehugger Robot /// Don't add in DOWN, UP nodes if the supplied tree is a list (t is isNilNode)
471*16467b97STreehugger Robot // such as the root tree is.
472*16467b97STreehugger Robot ///
473*16467b97STreehugger Robot static void
fillBuffer(pANTLR3_COMMON_TREE_NODE_STREAM ctns,pANTLR3_BASE_TREE t)474*16467b97STreehugger Robot fillBuffer(pANTLR3_COMMON_TREE_NODE_STREAM ctns, pANTLR3_BASE_TREE t)
475*16467b97STreehugger Robot {
476*16467b97STreehugger Robot 	ANTLR3_BOOLEAN	nilNode;
477*16467b97STreehugger Robot 	ANTLR3_UINT32	nCount;
478*16467b97STreehugger Robot 	ANTLR3_UINT32	c;
479*16467b97STreehugger Robot 
480*16467b97STreehugger Robot 	nilNode = ctns->adaptor->isNilNode(ctns->adaptor, t);
481*16467b97STreehugger Robot 
482*16467b97STreehugger Robot 	// If the supplied node is not a nil (list) node then we
483*16467b97STreehugger Robot 	// add in the node itself to the vector
484*16467b97STreehugger Robot 	//
485*16467b97STreehugger Robot 	if	(nilNode == ANTLR3_FALSE)
486*16467b97STreehugger Robot 	{
487*16467b97STreehugger Robot 		ctns->nodes->add(ctns->nodes, t, NULL);
488*16467b97STreehugger Robot 	}
489*16467b97STreehugger Robot 
490*16467b97STreehugger Robot 	// Only add a DOWN node if the tree is not a nil tree and
491*16467b97STreehugger Robot 	// the tree does have children.
492*16467b97STreehugger Robot 	//
493*16467b97STreehugger Robot 	nCount = t->getChildCount(t);
494*16467b97STreehugger Robot 
495*16467b97STreehugger Robot 	if	(nilNode == ANTLR3_FALSE && nCount>0)
496*16467b97STreehugger Robot 	{
497*16467b97STreehugger Robot 		ctns->addNavigationNode(ctns, ANTLR3_TOKEN_DOWN);
498*16467b97STreehugger Robot 	}
499*16467b97STreehugger Robot 
500*16467b97STreehugger Robot 	// We always add any children the tree contains, which is
501*16467b97STreehugger Robot 	// a recursive call to this function, which will cause similar
502*16467b97STreehugger Robot 	// recursion and implement a depth first addition
503*16467b97STreehugger Robot 	//
504*16467b97STreehugger Robot 	for	(c = 0; c < nCount; c++)
505*16467b97STreehugger Robot 	{
506*16467b97STreehugger Robot 		fillBuffer(ctns, (pANTLR3_BASE_TREE)ctns->adaptor->getChild(ctns->adaptor, t, c));
507*16467b97STreehugger Robot 	}
508*16467b97STreehugger Robot 
509*16467b97STreehugger Robot 	// If the tree had children and was not a nil (list) node, then we
510*16467b97STreehugger Robot 	// we need to add an UP node here to match the DOWN node
511*16467b97STreehugger Robot 	//
512*16467b97STreehugger Robot 	if	(nilNode == ANTLR3_FALSE && nCount > 0)
513*16467b97STreehugger Robot 	{
514*16467b97STreehugger Robot 		ctns->addNavigationNode(ctns, ANTLR3_TOKEN_UP);
515*16467b97STreehugger Robot 	}
516*16467b97STreehugger Robot }
517*16467b97STreehugger Robot 
518*16467b97STreehugger Robot 
519*16467b97STreehugger Robot // ------------------------------------------------------------------------------
520*16467b97STreehugger Robot // Interface functions
521*16467b97STreehugger Robot //
522*16467b97STreehugger Robot 
523*16467b97STreehugger Robot /// Reset the input stream to the start of the input nodes.
524*16467b97STreehugger Robot ///
525*16467b97STreehugger Robot static	void
reset(pANTLR3_COMMON_TREE_NODE_STREAM ctns)526*16467b97STreehugger Robot reset	    (pANTLR3_COMMON_TREE_NODE_STREAM ctns)
527*16467b97STreehugger Robot {
528*16467b97STreehugger Robot 	if	(ctns->p != -1)
529*16467b97STreehugger Robot 	{
530*16467b97STreehugger Robot 		ctns->p									= 0;
531*16467b97STreehugger Robot 	}
532*16467b97STreehugger Robot 	ctns->tnstream->istream->lastMarker		= 0;
533*16467b97STreehugger Robot 
534*16467b97STreehugger Robot 
535*16467b97STreehugger Robot 	// Free and reset the node stack only if this is not
536*16467b97STreehugger Robot 	// a rewriter, which is going to reuse the originating
537*16467b97STreehugger Robot 	// node streams node stack
538*16467b97STreehugger Robot 	//
539*16467b97STreehugger Robot 	if  (ctns->isRewriter != ANTLR3_TRUE)
540*16467b97STreehugger Robot     {
541*16467b97STreehugger Robot 		if	(ctns->nodeStack != NULL)
542*16467b97STreehugger Robot 		{
543*16467b97STreehugger Robot 			ctns->nodeStack->free(ctns->nodeStack);
544*16467b97STreehugger Robot 			ctns->nodeStack = antlr3StackNew(INITIAL_CALL_STACK_SIZE);
545*16467b97STreehugger Robot 		}
546*16467b97STreehugger Robot 	}
547*16467b97STreehugger Robot }
548*16467b97STreehugger Robot 
549*16467b97STreehugger Robot 
550*16467b97STreehugger Robot static pANTLR3_BASE_TREE
LB(pANTLR3_TREE_NODE_STREAM tns,ANTLR3_INT32 k)551*16467b97STreehugger Robot LB(pANTLR3_TREE_NODE_STREAM tns, ANTLR3_INT32 k)
552*16467b97STreehugger Robot {
553*16467b97STreehugger Robot 	if	( k==0)
554*16467b97STreehugger Robot 	{
555*16467b97STreehugger Robot 		return	&(tns->ctns->INVALID_NODE.baseTree);
556*16467b97STreehugger Robot 	}
557*16467b97STreehugger Robot 
558*16467b97STreehugger Robot 	if	( (tns->ctns->p - k) < 0)
559*16467b97STreehugger Robot 	{
560*16467b97STreehugger Robot 		return	&(tns->ctns->INVALID_NODE.baseTree);
561*16467b97STreehugger Robot 	}
562*16467b97STreehugger Robot 
563*16467b97STreehugger Robot 	return (pANTLR3_BASE_TREE)tns->ctns->nodes->get(tns->ctns->nodes, tns->ctns->p - k);
564*16467b97STreehugger Robot }
565*16467b97STreehugger Robot 
566*16467b97STreehugger Robot /// Get tree node at current input pointer + i ahead where i=1 is next node.
567*16467b97STreehugger Robot /// i<0 indicates nodes in the past.  So -1 is previous node and -2 is
568*16467b97STreehugger Robot /// two nodes ago. LT(0) is undefined.  For i>=n, return null.
569*16467b97STreehugger Robot /// Return null for LT(0) and any index that results in an absolute address
570*16467b97STreehugger Robot /// that is negative.
571*16467b97STreehugger Robot ///
572*16467b97STreehugger Robot /// This is analogous to the _LT() method of the TokenStream, but this
573*16467b97STreehugger Robot /// returns a tree node instead of a token.  Makes code gen identical
574*16467b97STreehugger Robot /// for both parser and tree grammars. :)
575*16467b97STreehugger Robot ///
576*16467b97STreehugger Robot static	pANTLR3_BASE_TREE
_LT(pANTLR3_TREE_NODE_STREAM tns,ANTLR3_INT32 k)577*16467b97STreehugger Robot _LT	    (pANTLR3_TREE_NODE_STREAM tns, ANTLR3_INT32 k)
578*16467b97STreehugger Robot {
579*16467b97STreehugger Robot 	if	(tns->ctns->p == -1)
580*16467b97STreehugger Robot 	{
581*16467b97STreehugger Robot 		fillBufferRoot(tns->ctns);
582*16467b97STreehugger Robot 	}
583*16467b97STreehugger Robot 
584*16467b97STreehugger Robot 	if	(k < 0)
585*16467b97STreehugger Robot 	{
586*16467b97STreehugger Robot 		return LB(tns, -k);
587*16467b97STreehugger Robot 	}
588*16467b97STreehugger Robot 	else if	(k == 0)
589*16467b97STreehugger Robot 	{
590*16467b97STreehugger Robot 		return	&(tns->ctns->INVALID_NODE.baseTree);
591*16467b97STreehugger Robot 	}
592*16467b97STreehugger Robot 
593*16467b97STreehugger Robot 	// k was a legitimate request,
594*16467b97STreehugger Robot 	//
595*16467b97STreehugger Robot 	if	(( tns->ctns->p + k - 1) >= (ANTLR3_INT32)(tns->ctns->nodes->count))
596*16467b97STreehugger Robot 	{
597*16467b97STreehugger Robot 		return &(tns->ctns->EOF_NODE.baseTree);
598*16467b97STreehugger Robot 	}
599*16467b97STreehugger Robot 
600*16467b97STreehugger Robot 	return	(pANTLR3_BASE_TREE)tns->ctns->nodes->get(tns->ctns->nodes, tns->ctns->p + k - 1);
601*16467b97STreehugger Robot }
602*16467b97STreehugger Robot 
603*16467b97STreehugger Robot /// Where is this stream pulling nodes from?  This is not the name, but
604*16467b97STreehugger Robot /// the object that provides node objects.
605*16467b97STreehugger Robot ///
606*16467b97STreehugger Robot static	pANTLR3_BASE_TREE
getTreeSource(pANTLR3_TREE_NODE_STREAM tns)607*16467b97STreehugger Robot getTreeSource	(pANTLR3_TREE_NODE_STREAM tns)
608*16467b97STreehugger Robot {
609*16467b97STreehugger Robot     return  tns->ctns->root;
610*16467b97STreehugger Robot }
611*16467b97STreehugger Robot 
612*16467b97STreehugger Robot /// Consume the next node from the input stream
613*16467b97STreehugger Robot ///
614*16467b97STreehugger Robot static	void
consume(pANTLR3_INT_STREAM is)615*16467b97STreehugger Robot consume	(pANTLR3_INT_STREAM is)
616*16467b97STreehugger Robot {
617*16467b97STreehugger Robot     pANTLR3_TREE_NODE_STREAM		tns;
618*16467b97STreehugger Robot     pANTLR3_COMMON_TREE_NODE_STREAM	ctns;
619*16467b97STreehugger Robot 
620*16467b97STreehugger Robot     tns	    = (pANTLR3_TREE_NODE_STREAM)(is->super);
621*16467b97STreehugger Robot     ctns    = tns->ctns;
622*16467b97STreehugger Robot 
623*16467b97STreehugger Robot 	if	(ctns->p == -1)
624*16467b97STreehugger Robot 	{
625*16467b97STreehugger Robot 		fillBufferRoot(ctns);
626*16467b97STreehugger Robot 	}
627*16467b97STreehugger Robot 	ctns->p++;
628*16467b97STreehugger Robot }
629*16467b97STreehugger Robot 
630*16467b97STreehugger Robot static	ANTLR3_UINT32
_LA(pANTLR3_INT_STREAM is,ANTLR3_INT32 i)631*16467b97STreehugger Robot _LA	    (pANTLR3_INT_STREAM is, ANTLR3_INT32 i)
632*16467b97STreehugger Robot {
633*16467b97STreehugger Robot 	pANTLR3_TREE_NODE_STREAM		tns;
634*16467b97STreehugger Robot 	pANTLR3_BASE_TREE				t;
635*16467b97STreehugger Robot 
636*16467b97STreehugger Robot 	tns	    = (pANTLR3_TREE_NODE_STREAM)(is->super);
637*16467b97STreehugger Robot 
638*16467b97STreehugger Robot 	// Ask LT for the 'token' at that position
639*16467b97STreehugger Robot 	//
640*16467b97STreehugger Robot 	t = tns->_LT(tns, i);
641*16467b97STreehugger Robot 
642*16467b97STreehugger Robot 	if	(t == NULL)
643*16467b97STreehugger Robot 	{
644*16467b97STreehugger Robot 		return	ANTLR3_TOKEN_INVALID;
645*16467b97STreehugger Robot 	}
646*16467b97STreehugger Robot 
647*16467b97STreehugger Robot 	// Token node was there so return the type of it
648*16467b97STreehugger Robot 	//
649*16467b97STreehugger Robot 	return  t->getType(t);
650*16467b97STreehugger Robot }
651*16467b97STreehugger Robot 
652*16467b97STreehugger Robot /// Mark the state of the input stream so that we can come back to it
653*16467b97STreehugger Robot /// after a syntactic predicate and so on.
654*16467b97STreehugger Robot ///
655*16467b97STreehugger Robot static	ANTLR3_MARKER
mark(pANTLR3_INT_STREAM is)656*16467b97STreehugger Robot mark	(pANTLR3_INT_STREAM is)
657*16467b97STreehugger Robot {
658*16467b97STreehugger Robot 	pANTLR3_TREE_NODE_STREAM		tns;
659*16467b97STreehugger Robot 	pANTLR3_COMMON_TREE_NODE_STREAM	ctns;
660*16467b97STreehugger Robot 
661*16467b97STreehugger Robot 	tns	    = (pANTLR3_TREE_NODE_STREAM)(is->super);
662*16467b97STreehugger Robot 	ctns    = tns->ctns;
663*16467b97STreehugger Robot 
664*16467b97STreehugger Robot 	if	(tns->ctns->p == -1)
665*16467b97STreehugger Robot 	{
666*16467b97STreehugger Robot 		fillBufferRoot(tns->ctns);
667*16467b97STreehugger Robot 	}
668*16467b97STreehugger Robot 
669*16467b97STreehugger Robot 	// Return the current mark point
670*16467b97STreehugger Robot 	//
671*16467b97STreehugger Robot 	ctns->tnstream->istream->lastMarker = ctns->tnstream->istream->index(ctns->tnstream->istream);
672*16467b97STreehugger Robot 
673*16467b97STreehugger Robot 	return ctns->tnstream->istream->lastMarker;
674*16467b97STreehugger Robot }
675*16467b97STreehugger Robot 
676*16467b97STreehugger Robot static	void
release(pANTLR3_INT_STREAM is,ANTLR3_MARKER marker)677*16467b97STreehugger Robot release	(pANTLR3_INT_STREAM is, ANTLR3_MARKER marker)
678*16467b97STreehugger Robot {
679*16467b97STreehugger Robot }
680*16467b97STreehugger Robot 
681*16467b97STreehugger Robot /// Rewind the current state of the tree walk to the state it
682*16467b97STreehugger Robot /// was in when mark() was called and it returned marker.  Also,
683*16467b97STreehugger Robot /// wipe out the lookahead which will force reloading a few nodes
684*16467b97STreehugger Robot /// but it is better than making a copy of the lookahead buffer
685*16467b97STreehugger Robot /// upon mark().
686*16467b97STreehugger Robot ///
687*16467b97STreehugger Robot static	void
rewindMark(pANTLR3_INT_STREAM is,ANTLR3_MARKER marker)688*16467b97STreehugger Robot rewindMark	    (pANTLR3_INT_STREAM is, ANTLR3_MARKER marker)
689*16467b97STreehugger Robot {
690*16467b97STreehugger Robot 	is->seek(is, marker);
691*16467b97STreehugger Robot }
692*16467b97STreehugger Robot 
693*16467b97STreehugger Robot static	void
rewindLast(pANTLR3_INT_STREAM is)694*16467b97STreehugger Robot rewindLast	(pANTLR3_INT_STREAM is)
695*16467b97STreehugger Robot {
696*16467b97STreehugger Robot    is->seek(is, is->lastMarker);
697*16467b97STreehugger Robot }
698*16467b97STreehugger Robot 
699*16467b97STreehugger Robot /// consume() ahead until we hit index.  Can't just jump ahead--must
700*16467b97STreehugger Robot /// spit out the navigation nodes.
701*16467b97STreehugger Robot ///
702*16467b97STreehugger Robot static	void
seek(pANTLR3_INT_STREAM is,ANTLR3_MARKER index)703*16467b97STreehugger Robot seek	(pANTLR3_INT_STREAM is, ANTLR3_MARKER index)
704*16467b97STreehugger Robot {
705*16467b97STreehugger Robot     pANTLR3_TREE_NODE_STREAM		tns;
706*16467b97STreehugger Robot     pANTLR3_COMMON_TREE_NODE_STREAM	ctns;
707*16467b97STreehugger Robot 
708*16467b97STreehugger Robot     tns	    = (pANTLR3_TREE_NODE_STREAM)(is->super);
709*16467b97STreehugger Robot     ctns    = tns->ctns;
710*16467b97STreehugger Robot 
711*16467b97STreehugger Robot 	ctns->p = ANTLR3_UINT32_CAST(index);
712*16467b97STreehugger Robot }
713*16467b97STreehugger Robot 
714*16467b97STreehugger Robot static	ANTLR3_MARKER
tindex(pANTLR3_INT_STREAM is)715*16467b97STreehugger Robot tindex	(pANTLR3_INT_STREAM is)
716*16467b97STreehugger Robot {
717*16467b97STreehugger Robot     pANTLR3_TREE_NODE_STREAM		tns;
718*16467b97STreehugger Robot     pANTLR3_COMMON_TREE_NODE_STREAM	ctns;
719*16467b97STreehugger Robot 
720*16467b97STreehugger Robot     tns	    = (pANTLR3_TREE_NODE_STREAM)(is->super);
721*16467b97STreehugger Robot     ctns    = tns->ctns;
722*16467b97STreehugger Robot 
723*16467b97STreehugger Robot 	return (ANTLR3_MARKER)(ctns->p);
724*16467b97STreehugger Robot }
725*16467b97STreehugger Robot 
726*16467b97STreehugger Robot /// Expensive to compute the size of the whole tree while parsing.
727*16467b97STreehugger Robot /// This method only returns how much input has been seen so far.  So
728*16467b97STreehugger Robot /// after parsing it returns true size.
729*16467b97STreehugger Robot ///
730*16467b97STreehugger Robot static	ANTLR3_UINT32
size(pANTLR3_INT_STREAM is)731*16467b97STreehugger Robot size	(pANTLR3_INT_STREAM is)
732*16467b97STreehugger Robot {
733*16467b97STreehugger Robot     pANTLR3_TREE_NODE_STREAM		tns;
734*16467b97STreehugger Robot     pANTLR3_COMMON_TREE_NODE_STREAM	ctns;
735*16467b97STreehugger Robot 
736*16467b97STreehugger Robot     tns	    = (pANTLR3_TREE_NODE_STREAM)(is->super);
737*16467b97STreehugger Robot     ctns    = tns->ctns;
738*16467b97STreehugger Robot 
739*16467b97STreehugger Robot 	if	(ctns->p == -1)
740*16467b97STreehugger Robot 	{
741*16467b97STreehugger Robot 		fillBufferRoot(ctns);
742*16467b97STreehugger Robot 	}
743*16467b97STreehugger Robot 
744*16467b97STreehugger Robot 	return ctns->nodes->size(ctns->nodes);
745*16467b97STreehugger Robot }
746*16467b97STreehugger Robot 
747*16467b97STreehugger Robot /// As we flatten the tree, we use UP, DOWN nodes to represent
748*16467b97STreehugger Robot /// the tree structure.  When debugging we need unique nodes
749*16467b97STreehugger Robot /// so instantiate new ones when uniqueNavigationNodes is true.
750*16467b97STreehugger Robot ///
751*16467b97STreehugger Robot static	void
addNavigationNode(pANTLR3_COMMON_TREE_NODE_STREAM ctns,ANTLR3_UINT32 ttype)752*16467b97STreehugger Robot addNavigationNode	    (pANTLR3_COMMON_TREE_NODE_STREAM ctns, ANTLR3_UINT32 ttype)
753*16467b97STreehugger Robot {
754*16467b97STreehugger Robot 	pANTLR3_BASE_TREE	    node;
755*16467b97STreehugger Robot 
756*16467b97STreehugger Robot 	node = NULL;
757*16467b97STreehugger Robot 
758*16467b97STreehugger Robot 	if	(ttype == ANTLR3_TOKEN_DOWN)
759*16467b97STreehugger Robot 	{
760*16467b97STreehugger Robot 		if  (ctns->hasUniqueNavigationNodes(ctns) == ANTLR3_TRUE)
761*16467b97STreehugger Robot 		{
762*16467b97STreehugger Robot 			node    = ctns->newDownNode(ctns);
763*16467b97STreehugger Robot 		}
764*16467b97STreehugger Robot 		else
765*16467b97STreehugger Robot 		{
766*16467b97STreehugger Robot 			node    = &(ctns->DOWN.baseTree);
767*16467b97STreehugger Robot 		}
768*16467b97STreehugger Robot 	}
769*16467b97STreehugger Robot 	else
770*16467b97STreehugger Robot 	{
771*16467b97STreehugger Robot 		if  (ctns->hasUniqueNavigationNodes(ctns) == ANTLR3_TRUE)
772*16467b97STreehugger Robot 		{
773*16467b97STreehugger Robot 			node    = ctns->newUpNode(ctns);
774*16467b97STreehugger Robot 		}
775*16467b97STreehugger Robot 		else
776*16467b97STreehugger Robot 		{
777*16467b97STreehugger Robot 			node    = &(ctns->UP.baseTree);
778*16467b97STreehugger Robot 		}
779*16467b97STreehugger Robot 	}
780*16467b97STreehugger Robot 
781*16467b97STreehugger Robot 	// Now add the node we decided upon.
782*16467b97STreehugger Robot 	//
783*16467b97STreehugger Robot 	ctns->nodes->add(ctns->nodes, node, NULL);
784*16467b97STreehugger Robot }
785*16467b97STreehugger Robot 
786*16467b97STreehugger Robot 
787*16467b97STreehugger Robot static	pANTLR3_BASE_TREE_ADAPTOR
getTreeAdaptor(pANTLR3_TREE_NODE_STREAM tns)788*16467b97STreehugger Robot getTreeAdaptor	(pANTLR3_TREE_NODE_STREAM tns)
789*16467b97STreehugger Robot {
790*16467b97STreehugger Robot     return  tns->ctns->adaptor;
791*16467b97STreehugger Robot }
792*16467b97STreehugger Robot 
793*16467b97STreehugger Robot static	ANTLR3_BOOLEAN
hasUniqueNavigationNodes(pANTLR3_COMMON_TREE_NODE_STREAM ctns)794*16467b97STreehugger Robot hasUniqueNavigationNodes	    (pANTLR3_COMMON_TREE_NODE_STREAM ctns)
795*16467b97STreehugger Robot {
796*16467b97STreehugger Robot     return  ctns->uniqueNavigationNodes;
797*16467b97STreehugger Robot }
798*16467b97STreehugger Robot 
799*16467b97STreehugger Robot static	void
setUniqueNavigationNodes(pANTLR3_TREE_NODE_STREAM tns,ANTLR3_BOOLEAN uniqueNavigationNodes)800*16467b97STreehugger Robot setUniqueNavigationNodes	    (pANTLR3_TREE_NODE_STREAM tns, ANTLR3_BOOLEAN uniqueNavigationNodes)
801*16467b97STreehugger Robot {
802*16467b97STreehugger Robot     tns->ctns->uniqueNavigationNodes = uniqueNavigationNodes;
803*16467b97STreehugger Robot }
804*16467b97STreehugger Robot 
805*16467b97STreehugger Robot 
806*16467b97STreehugger Robot /// Print out the entire tree including DOWN/UP nodes.  Uses
807*16467b97STreehugger Robot /// a recursive walk.  Mostly useful for testing as it yields
808*16467b97STreehugger Robot /// the token types not text.
809*16467b97STreehugger Robot ///
810*16467b97STreehugger Robot static	pANTLR3_STRING
toString(pANTLR3_TREE_NODE_STREAM tns)811*16467b97STreehugger Robot toString	    (pANTLR3_TREE_NODE_STREAM tns)
812*16467b97STreehugger Robot {
813*16467b97STreehugger Robot 
814*16467b97STreehugger Robot     return  tns->toStringSS(tns, tns->ctns->root, NULL);
815*16467b97STreehugger Robot }
816*16467b97STreehugger Robot 
817*16467b97STreehugger Robot static	pANTLR3_STRING
toStringSS(pANTLR3_TREE_NODE_STREAM tns,pANTLR3_BASE_TREE start,pANTLR3_BASE_TREE stop)818*16467b97STreehugger Robot toStringSS	    (pANTLR3_TREE_NODE_STREAM tns, pANTLR3_BASE_TREE start, pANTLR3_BASE_TREE stop)
819*16467b97STreehugger Robot {
820*16467b97STreehugger Robot     pANTLR3_STRING  buf;
821*16467b97STreehugger Robot 
822*16467b97STreehugger Robot     buf = tns->ctns->stringFactory->newRaw(tns->ctns->stringFactory);
823*16467b97STreehugger Robot 
824*16467b97STreehugger Robot     tns->toStringWork(tns, start, stop, buf);
825*16467b97STreehugger Robot 
826*16467b97STreehugger Robot     return  buf;
827*16467b97STreehugger Robot }
828*16467b97STreehugger Robot 
829*16467b97STreehugger Robot static	void
toStringWork(pANTLR3_TREE_NODE_STREAM tns,pANTLR3_BASE_TREE p,pANTLR3_BASE_TREE stop,pANTLR3_STRING buf)830*16467b97STreehugger Robot toStringWork	(pANTLR3_TREE_NODE_STREAM tns, pANTLR3_BASE_TREE p, pANTLR3_BASE_TREE stop, pANTLR3_STRING buf)
831*16467b97STreehugger Robot {
832*16467b97STreehugger Robot 
833*16467b97STreehugger Robot 	ANTLR3_UINT32   n;
834*16467b97STreehugger Robot 	ANTLR3_UINT32   c;
835*16467b97STreehugger Robot 
836*16467b97STreehugger Robot 	if	(!p->isNilNode(p) )
837*16467b97STreehugger Robot 	{
838*16467b97STreehugger Robot 		pANTLR3_STRING	text;
839*16467b97STreehugger Robot 
840*16467b97STreehugger Robot 		text	= p->toString(p);
841*16467b97STreehugger Robot 
842*16467b97STreehugger Robot 		if  (text == NULL)
843*16467b97STreehugger Robot 		{
844*16467b97STreehugger Robot 			text = tns->ctns->stringFactory->newRaw(tns->ctns->stringFactory);
845*16467b97STreehugger Robot 
846*16467b97STreehugger Robot 			text->addc	(text, ' ');
847*16467b97STreehugger Robot 			text->addi	(text, p->getType(p));
848*16467b97STreehugger Robot 		}
849*16467b97STreehugger Robot 
850*16467b97STreehugger Robot 		buf->appendS(buf, text);
851*16467b97STreehugger Robot 	}
852*16467b97STreehugger Robot 
853*16467b97STreehugger Robot 	if	(p == stop)
854*16467b97STreehugger Robot 	{
855*16467b97STreehugger Robot 		return;		/* Finished */
856*16467b97STreehugger Robot 	}
857*16467b97STreehugger Robot 
858*16467b97STreehugger Robot 	n = p->getChildCount(p);
859*16467b97STreehugger Robot 
860*16467b97STreehugger Robot 	if	(n > 0 && ! p->isNilNode(p) )
861*16467b97STreehugger Robot 	{
862*16467b97STreehugger Robot 		buf->addc   (buf, ' ');
863*16467b97STreehugger Robot 		buf->addi   (buf, ANTLR3_TOKEN_DOWN);
864*16467b97STreehugger Robot 	}
865*16467b97STreehugger Robot 
866*16467b97STreehugger Robot 	for	(c = 0; c<n ; c++)
867*16467b97STreehugger Robot 	{
868*16467b97STreehugger Robot 		pANTLR3_BASE_TREE   child;
869*16467b97STreehugger Robot 
870*16467b97STreehugger Robot 		child = (pANTLR3_BASE_TREE)p->getChild(p, c);
871*16467b97STreehugger Robot 		tns->toStringWork(tns, child, stop, buf);
872*16467b97STreehugger Robot 	}
873*16467b97STreehugger Robot 
874*16467b97STreehugger Robot 	if	(n > 0 && ! p->isNilNode(p) )
875*16467b97STreehugger Robot 	{
876*16467b97STreehugger Robot 		buf->addc   (buf, ' ');
877*16467b97STreehugger Robot 		buf->addi   (buf, ANTLR3_TOKEN_UP);
878*16467b97STreehugger Robot 	}
879*16467b97STreehugger Robot }
880*16467b97STreehugger Robot 
881*16467b97STreehugger Robot static	ANTLR3_UINT32
getLookaheadSize(pANTLR3_COMMON_TREE_NODE_STREAM ctns)882*16467b97STreehugger Robot getLookaheadSize	(pANTLR3_COMMON_TREE_NODE_STREAM ctns)
883*16467b97STreehugger Robot {
884*16467b97STreehugger Robot     return	ctns->tail < ctns->head
885*16467b97STreehugger Robot 	    ?	(ctns->lookAheadLength - ctns->head + ctns->tail)
886*16467b97STreehugger Robot 	    :	(ctns->tail - ctns->head);
887*16467b97STreehugger Robot }
888*16467b97STreehugger Robot 
889*16467b97STreehugger Robot static	pANTLR3_BASE_TREE
newDownNode(pANTLR3_COMMON_TREE_NODE_STREAM ctns)890*16467b97STreehugger Robot newDownNode		(pANTLR3_COMMON_TREE_NODE_STREAM ctns)
891*16467b97STreehugger Robot {
892*16467b97STreehugger Robot     pANTLR3_COMMON_TREE	    dNode;
893*16467b97STreehugger Robot     pANTLR3_COMMON_TOKEN    token;
894*16467b97STreehugger Robot 
895*16467b97STreehugger Robot     token					= antlr3CommonTokenNew(ANTLR3_TOKEN_DOWN);
896*16467b97STreehugger Robot 	token->textState		= ANTLR3_TEXT_CHARP;
897*16467b97STreehugger Robot 	token->tokText.chars	= (pANTLR3_UCHAR)"DOWN";
898*16467b97STreehugger Robot     dNode					= antlr3CommonTreeNewFromToken(token);
899*16467b97STreehugger Robot 
900*16467b97STreehugger Robot     return  &(dNode->baseTree);
901*16467b97STreehugger Robot }
902*16467b97STreehugger Robot 
903*16467b97STreehugger Robot static	pANTLR3_BASE_TREE
newUpNode(pANTLR3_COMMON_TREE_NODE_STREAM ctns)904*16467b97STreehugger Robot newUpNode		(pANTLR3_COMMON_TREE_NODE_STREAM ctns)
905*16467b97STreehugger Robot {
906*16467b97STreehugger Robot     pANTLR3_COMMON_TREE	    uNode;
907*16467b97STreehugger Robot     pANTLR3_COMMON_TOKEN    token;
908*16467b97STreehugger Robot 
909*16467b97STreehugger Robot     token					= antlr3CommonTokenNew(ANTLR3_TOKEN_UP);
910*16467b97STreehugger Robot 	token->textState		= ANTLR3_TEXT_CHARP;
911*16467b97STreehugger Robot 	token->tokText.chars	= (pANTLR3_UCHAR)"UP";
912*16467b97STreehugger Robot     uNode					= antlr3CommonTreeNewFromToken(token);
913*16467b97STreehugger Robot 
914*16467b97STreehugger Robot     return  &(uNode->baseTree);
915*16467b97STreehugger Robot }
916*16467b97STreehugger Robot 
917*16467b97STreehugger Robot /// Replace from start to stop child index of parent with t, which might
918*16467b97STreehugger Robot /// be a list.  Number of children may be different
919*16467b97STreehugger Robot /// after this call.  The stream is notified because it is walking the
920*16467b97STreehugger Robot /// tree and might need to know you are monkey-ing with the underlying
921*16467b97STreehugger Robot /// tree.  Also, it might be able to modify the node stream to avoid
922*16467b97STreehugger Robot /// re-streaming for future phases.
923*16467b97STreehugger Robot ///
924*16467b97STreehugger Robot /// If parent is null, don't do anything; must be at root of overall tree.
925*16467b97STreehugger Robot /// Can't replace whatever points to the parent externally.  Do nothing.
926*16467b97STreehugger Robot ///
927*16467b97STreehugger Robot static	void
replaceChildren(pANTLR3_TREE_NODE_STREAM tns,pANTLR3_BASE_TREE parent,ANTLR3_INT32 startChildIndex,ANTLR3_INT32 stopChildIndex,pANTLR3_BASE_TREE t)928*16467b97STreehugger Robot replaceChildren				(pANTLR3_TREE_NODE_STREAM tns, pANTLR3_BASE_TREE parent, ANTLR3_INT32 startChildIndex, ANTLR3_INT32 stopChildIndex, pANTLR3_BASE_TREE t)
929*16467b97STreehugger Robot {
930*16467b97STreehugger Robot 	if	(parent != NULL)
931*16467b97STreehugger Robot 	{
932*16467b97STreehugger Robot 		pANTLR3_BASE_TREE_ADAPTOR	adaptor;
933*16467b97STreehugger Robot 		pANTLR3_COMMON_TREE_ADAPTOR	cta;
934*16467b97STreehugger Robot 
935*16467b97STreehugger Robot 		adaptor	= tns->getTreeAdaptor(tns);
936*16467b97STreehugger Robot 		cta		= (pANTLR3_COMMON_TREE_ADAPTOR)(adaptor->super);
937*16467b97STreehugger Robot 
938*16467b97STreehugger Robot 		adaptor->replaceChildren(adaptor, parent, startChildIndex, stopChildIndex, t);
939*16467b97STreehugger Robot 	}
940*16467b97STreehugger Robot }
941*16467b97STreehugger Robot 
942*16467b97STreehugger Robot static	pANTLR3_BASE_TREE
get(pANTLR3_TREE_NODE_STREAM tns,ANTLR3_INT32 k)943*16467b97STreehugger Robot get							(pANTLR3_TREE_NODE_STREAM tns, ANTLR3_INT32 k)
944*16467b97STreehugger Robot {
945*16467b97STreehugger Robot 	if	(tns->ctns->p == -1)
946*16467b97STreehugger Robot 	{
947*16467b97STreehugger Robot 		fillBufferRoot(tns->ctns);
948*16467b97STreehugger Robot 	}
949*16467b97STreehugger Robot 
950*16467b97STreehugger Robot 	return (pANTLR3_BASE_TREE)tns->ctns->nodes->get(tns->ctns->nodes, k);
951*16467b97STreehugger Robot }
952*16467b97STreehugger Robot 
953*16467b97STreehugger Robot static	void
push(pANTLR3_COMMON_TREE_NODE_STREAM ctns,ANTLR3_INT32 index)954*16467b97STreehugger Robot push						(pANTLR3_COMMON_TREE_NODE_STREAM ctns, ANTLR3_INT32 index)
955*16467b97STreehugger Robot {
956*16467b97STreehugger Robot 	ctns->nodeStack->push(ctns->nodeStack, ANTLR3_FUNC_PTR(ctns->p), NULL);	// Save current index
957*16467b97STreehugger Robot 	ctns->tnstream->istream->seek(ctns->tnstream->istream, index);
958*16467b97STreehugger Robot }
959*16467b97STreehugger Robot 
960*16467b97STreehugger Robot static	ANTLR3_INT32
pop(pANTLR3_COMMON_TREE_NODE_STREAM ctns)961*16467b97STreehugger Robot pop							(pANTLR3_COMMON_TREE_NODE_STREAM ctns)
962*16467b97STreehugger Robot {
963*16467b97STreehugger Robot 	ANTLR3_INT32	retVal;
964*16467b97STreehugger Robot 
965*16467b97STreehugger Robot 	retVal = ANTLR3_UINT32_CAST(ctns->nodeStack->pop(ctns->nodeStack));
966*16467b97STreehugger Robot 	ctns->tnstream->istream->seek(ctns->tnstream->istream, retVal);
967*16467b97STreehugger Robot 	return retVal;
968*16467b97STreehugger Robot }
969