1*16467b97STreehugger Robot /// \file
2*16467b97STreehugger Robot /// Default implementation of CommonTokenStream
3*16467b97STreehugger Robot ///
4*16467b97STreehugger Robot
5*16467b97STreehugger Robot // [The "BSD licence"]
6*16467b97STreehugger Robot // Copyright (c) 2005-2009 Jim Idle, Temporal Wave LLC
7*16467b97STreehugger Robot // http://www.temporal-wave.com
8*16467b97STreehugger Robot // http://www.linkedin.com/in/jimidle
9*16467b97STreehugger Robot //
10*16467b97STreehugger Robot // All rights reserved.
11*16467b97STreehugger Robot //
12*16467b97STreehugger Robot // Redistribution and use in source and binary forms, with or without
13*16467b97STreehugger Robot // modification, are permitted provided that the following conditions
14*16467b97STreehugger Robot // are met:
15*16467b97STreehugger Robot // 1. Redistributions of source code must retain the above copyright
16*16467b97STreehugger Robot // notice, this list of conditions and the following disclaimer.
17*16467b97STreehugger Robot // 2. Redistributions in binary form must reproduce the above copyright
18*16467b97STreehugger Robot // notice, this list of conditions and the following disclaimer in the
19*16467b97STreehugger Robot // documentation and/or other materials provided with the distribution.
20*16467b97STreehugger Robot // 3. The name of the author may not be used to endorse or promote products
21*16467b97STreehugger Robot // derived from this software without specific prior written permission.
22*16467b97STreehugger Robot //
23*16467b97STreehugger Robot // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24*16467b97STreehugger Robot // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25*16467b97STreehugger Robot // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26*16467b97STreehugger Robot // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27*16467b97STreehugger Robot // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28*16467b97STreehugger Robot // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29*16467b97STreehugger Robot // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30*16467b97STreehugger Robot // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31*16467b97STreehugger Robot // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32*16467b97STreehugger Robot // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33*16467b97STreehugger Robot
34*16467b97STreehugger Robot #include <antlr3tokenstream.h>
35*16467b97STreehugger Robot
36*16467b97STreehugger Robot #ifdef ANTLR3_WINDOWS
37*16467b97STreehugger Robot #pragma warning( disable : 4100 )
38*16467b97STreehugger Robot #endif
39*16467b97STreehugger Robot
40*16467b97STreehugger Robot // COMMON_TOKEN_STREAM API
41*16467b97STreehugger Robot //
42*16467b97STreehugger Robot static void setTokenTypeChannel (pANTLR3_COMMON_TOKEN_STREAM cts, ANTLR3_UINT32 ttype, ANTLR3_UINT32 channel);
43*16467b97STreehugger Robot static void discardTokenType (pANTLR3_COMMON_TOKEN_STREAM cts, ANTLR3_INT32 ttype);
44*16467b97STreehugger Robot static void discardOffChannel (pANTLR3_COMMON_TOKEN_STREAM cts, ANTLR3_BOOLEAN discard);
45*16467b97STreehugger Robot static pANTLR3_VECTOR getTokens (pANTLR3_COMMON_TOKEN_STREAM cts);
46*16467b97STreehugger Robot static pANTLR3_LIST getTokenRange (pANTLR3_COMMON_TOKEN_STREAM cts, ANTLR3_UINT32 start, ANTLR3_UINT32 stop);
47*16467b97STreehugger Robot static pANTLR3_LIST getTokensSet (pANTLR3_COMMON_TOKEN_STREAM cts, ANTLR3_UINT32 start, ANTLR3_UINT32 stop, pANTLR3_BITSET types);
48*16467b97STreehugger Robot static pANTLR3_LIST getTokensList (pANTLR3_COMMON_TOKEN_STREAM cts, ANTLR3_UINT32 start, ANTLR3_UINT32 stop, pANTLR3_LIST list);
49*16467b97STreehugger Robot static pANTLR3_LIST getTokensType (pANTLR3_COMMON_TOKEN_STREAM cts, ANTLR3_UINT32 start, ANTLR3_UINT32 stop, ANTLR3_UINT32 type);
50*16467b97STreehugger Robot static void reset (pANTLR3_COMMON_TOKEN_STREAM cts);
51*16467b97STreehugger Robot
52*16467b97STreehugger Robot // TOKEN_STREAM API
53*16467b97STreehugger Robot //
54*16467b97STreehugger Robot static pANTLR3_COMMON_TOKEN tokLT (pANTLR3_TOKEN_STREAM ts, ANTLR3_INT32 k);
55*16467b97STreehugger Robot static pANTLR3_COMMON_TOKEN dbgTokLT (pANTLR3_TOKEN_STREAM ts, ANTLR3_INT32 k);
56*16467b97STreehugger Robot static pANTLR3_COMMON_TOKEN get (pANTLR3_TOKEN_STREAM ts, ANTLR3_UINT32 i);
57*16467b97STreehugger Robot static pANTLR3_TOKEN_SOURCE getTokenSource (pANTLR3_TOKEN_STREAM ts);
58*16467b97STreehugger Robot static void setTokenSource (pANTLR3_TOKEN_STREAM ts, pANTLR3_TOKEN_SOURCE tokenSource);
59*16467b97STreehugger Robot static pANTLR3_STRING toString (pANTLR3_TOKEN_STREAM ts);
60*16467b97STreehugger Robot static pANTLR3_STRING toStringSS (pANTLR3_TOKEN_STREAM ts, ANTLR3_UINT32 start, ANTLR3_UINT32 stop);
61*16467b97STreehugger Robot static pANTLR3_STRING toStringTT (pANTLR3_TOKEN_STREAM ts, pANTLR3_COMMON_TOKEN start, pANTLR3_COMMON_TOKEN stop);
62*16467b97STreehugger Robot static void setDebugListener (pANTLR3_TOKEN_STREAM ts, pANTLR3_DEBUG_EVENT_LISTENER debugger);
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 void dbgConsume (pANTLR3_INT_STREAM is);
68*16467b97STreehugger Robot static ANTLR3_UINT32 _LA (pANTLR3_INT_STREAM is, ANTLR3_INT32 i);
69*16467b97STreehugger Robot static ANTLR3_UINT32 dbgLA (pANTLR3_INT_STREAM is, ANTLR3_INT32 i);
70*16467b97STreehugger Robot static ANTLR3_MARKER mark (pANTLR3_INT_STREAM is);
71*16467b97STreehugger Robot static ANTLR3_MARKER dbgMark (pANTLR3_INT_STREAM is);
72*16467b97STreehugger Robot static void release (pANTLR3_INT_STREAM is, ANTLR3_MARKER mark);
73*16467b97STreehugger Robot static ANTLR3_UINT32 size (pANTLR3_INT_STREAM is);
74*16467b97STreehugger Robot static ANTLR3_MARKER tindex (pANTLR3_INT_STREAM is);
75*16467b97STreehugger Robot static void rewindStream (pANTLR3_INT_STREAM is, ANTLR3_MARKER marker);
76*16467b97STreehugger Robot static void dbgRewindStream (pANTLR3_INT_STREAM is, ANTLR3_MARKER marker);
77*16467b97STreehugger Robot static void rewindLast (pANTLR3_INT_STREAM is);
78*16467b97STreehugger Robot static void dbgRewindLast (pANTLR3_INT_STREAM is);
79*16467b97STreehugger Robot static void seek (pANTLR3_INT_STREAM is, ANTLR3_MARKER index);
80*16467b97STreehugger Robot static void dbgSeek (pANTLR3_INT_STREAM is, ANTLR3_MARKER index);
81*16467b97STreehugger Robot static pANTLR3_STRING getSourceName (pANTLR3_INT_STREAM is);
82*16467b97STreehugger Robot static void antlr3TokenStreamFree (pANTLR3_TOKEN_STREAM stream);
83*16467b97STreehugger Robot static void antlr3CTSFree (pANTLR3_COMMON_TOKEN_STREAM stream);
84*16467b97STreehugger Robot
85*16467b97STreehugger Robot // Helpers
86*16467b97STreehugger Robot //
87*16467b97STreehugger Robot static void fillBuffer (pANTLR3_COMMON_TOKEN_STREAM tokenStream);
88*16467b97STreehugger Robot static ANTLR3_UINT32 skipOffTokenChannels (pANTLR3_COMMON_TOKEN_STREAM tokenStream, ANTLR3_INT32 i);
89*16467b97STreehugger Robot static ANTLR3_UINT32 skipOffTokenChannelsReverse (pANTLR3_COMMON_TOKEN_STREAM tokenStream, ANTLR3_INT32 i);
90*16467b97STreehugger Robot static pANTLR3_COMMON_TOKEN LB (pANTLR3_COMMON_TOKEN_STREAM tokenStream, ANTLR3_INT32 i);
91*16467b97STreehugger Robot
92*16467b97STreehugger Robot ANTLR3_API pANTLR3_TOKEN_STREAM
antlr3TokenStreamNew()93*16467b97STreehugger Robot antlr3TokenStreamNew()
94*16467b97STreehugger Robot {
95*16467b97STreehugger Robot pANTLR3_TOKEN_STREAM stream;
96*16467b97STreehugger Robot
97*16467b97STreehugger Robot // Memory for the interface structure
98*16467b97STreehugger Robot //
99*16467b97STreehugger Robot stream = (pANTLR3_TOKEN_STREAM) ANTLR3_MALLOC(sizeof(ANTLR3_TOKEN_STREAM));
100*16467b97STreehugger Robot
101*16467b97STreehugger Robot if (stream == NULL)
102*16467b97STreehugger Robot {
103*16467b97STreehugger Robot return NULL;
104*16467b97STreehugger Robot }
105*16467b97STreehugger Robot
106*16467b97STreehugger Robot // Install basic API
107*16467b97STreehugger Robot //
108*16467b97STreehugger Robot stream->free = antlr3TokenStreamFree;
109*16467b97STreehugger Robot
110*16467b97STreehugger Robot
111*16467b97STreehugger Robot return stream;
112*16467b97STreehugger Robot }
113*16467b97STreehugger Robot
114*16467b97STreehugger Robot static void
antlr3TokenStreamFree(pANTLR3_TOKEN_STREAM stream)115*16467b97STreehugger Robot antlr3TokenStreamFree(pANTLR3_TOKEN_STREAM stream)
116*16467b97STreehugger Robot {
117*16467b97STreehugger Robot ANTLR3_FREE(stream);
118*16467b97STreehugger Robot }
119*16467b97STreehugger Robot
120*16467b97STreehugger Robot static void
antlr3CTSFree(pANTLR3_COMMON_TOKEN_STREAM stream)121*16467b97STreehugger Robot antlr3CTSFree (pANTLR3_COMMON_TOKEN_STREAM stream)
122*16467b97STreehugger Robot {
123*16467b97STreehugger Robot // We only free up our subordinate interfaces if they belong
124*16467b97STreehugger Robot // to us, otherwise we let whoever owns them deal with them.
125*16467b97STreehugger Robot //
126*16467b97STreehugger Robot if (stream->tstream->super == stream)
127*16467b97STreehugger Robot {
128*16467b97STreehugger Robot if (stream->tstream->istream->super == stream->tstream)
129*16467b97STreehugger Robot {
130*16467b97STreehugger Robot stream->tstream->istream->free(stream->tstream->istream);
131*16467b97STreehugger Robot stream->tstream->istream = NULL;
132*16467b97STreehugger Robot }
133*16467b97STreehugger Robot stream->tstream->free(stream->tstream);
134*16467b97STreehugger Robot }
135*16467b97STreehugger Robot
136*16467b97STreehugger Robot // Now we free our own resources
137*16467b97STreehugger Robot //
138*16467b97STreehugger Robot if (stream->tokens != NULL)
139*16467b97STreehugger Robot {
140*16467b97STreehugger Robot stream->tokens->free(stream->tokens);
141*16467b97STreehugger Robot stream->tokens = NULL;
142*16467b97STreehugger Robot }
143*16467b97STreehugger Robot if (stream->discardSet != NULL)
144*16467b97STreehugger Robot {
145*16467b97STreehugger Robot stream->discardSet->free(stream->discardSet);
146*16467b97STreehugger Robot stream->discardSet = NULL;
147*16467b97STreehugger Robot }
148*16467b97STreehugger Robot if (stream->channelOverrides != NULL)
149*16467b97STreehugger Robot {
150*16467b97STreehugger Robot stream->channelOverrides->free(stream->channelOverrides);
151*16467b97STreehugger Robot stream->channelOverrides = NULL;
152*16467b97STreehugger Robot }
153*16467b97STreehugger Robot
154*16467b97STreehugger Robot // Free our memory now
155*16467b97STreehugger Robot //
156*16467b97STreehugger Robot ANTLR3_FREE(stream);
157*16467b97STreehugger Robot }
158*16467b97STreehugger Robot
159*16467b97STreehugger Robot // Reset a token stream so it can be used again and can reuse it's
160*16467b97STreehugger Robot // resources.
161*16467b97STreehugger Robot //
162*16467b97STreehugger Robot static void
reset(pANTLR3_COMMON_TOKEN_STREAM cts)163*16467b97STreehugger Robot reset (pANTLR3_COMMON_TOKEN_STREAM cts)
164*16467b97STreehugger Robot {
165*16467b97STreehugger Robot
166*16467b97STreehugger Robot // Free any resources that ar most like specifc to the
167*16467b97STreehugger Robot // run we just did.
168*16467b97STreehugger Robot //
169*16467b97STreehugger Robot if (cts->discardSet != NULL)
170*16467b97STreehugger Robot {
171*16467b97STreehugger Robot cts->discardSet->free(cts->discardSet);
172*16467b97STreehugger Robot cts->discardSet = NULL;
173*16467b97STreehugger Robot }
174*16467b97STreehugger Robot if (cts->channelOverrides != NULL)
175*16467b97STreehugger Robot {
176*16467b97STreehugger Robot cts->channelOverrides->free(cts->channelOverrides);
177*16467b97STreehugger Robot cts->channelOverrides = NULL;
178*16467b97STreehugger Robot }
179*16467b97STreehugger Robot
180*16467b97STreehugger Robot // Now, if there were any existing tokens in the stream,
181*16467b97STreehugger Robot // then we just reset the vector count so that it starts
182*16467b97STreehugger Robot // again. We must traverse the entries unfortunately as
183*16467b97STreehugger Robot // there may be free pointers for custom token types and
184*16467b97STreehugger Robot // so on. However that is just a quick NULL check on the
185*16467b97STreehugger Robot // vector entries.
186*16467b97STreehugger Robot //
187*16467b97STreehugger Robot if (cts->tokens != NULL)
188*16467b97STreehugger Robot {
189*16467b97STreehugger Robot cts->tokens->clear(cts->tokens);
190*16467b97STreehugger Robot }
191*16467b97STreehugger Robot else
192*16467b97STreehugger Robot {
193*16467b97STreehugger Robot /* Install the token tracking tables
194*16467b97STreehugger Robot */
195*16467b97STreehugger Robot cts->tokens = antlr3VectorNew(0);
196*16467b97STreehugger Robot }
197*16467b97STreehugger Robot
198*16467b97STreehugger Robot // Reset to defaults
199*16467b97STreehugger Robot //
200*16467b97STreehugger Robot cts->discardOffChannel = ANTLR3_FALSE;
201*16467b97STreehugger Robot cts->channel = ANTLR3_TOKEN_DEFAULT_CHANNEL;
202*16467b97STreehugger Robot cts->p = -1;
203*16467b97STreehugger Robot }
204*16467b97STreehugger Robot
205*16467b97STreehugger Robot ANTLR3_API pANTLR3_COMMON_TOKEN_STREAM
antlr3CommonTokenDebugStreamSourceNew(ANTLR3_UINT32 hint,pANTLR3_TOKEN_SOURCE source,pANTLR3_DEBUG_EVENT_LISTENER debugger)206*16467b97STreehugger Robot antlr3CommonTokenDebugStreamSourceNew(ANTLR3_UINT32 hint, pANTLR3_TOKEN_SOURCE source, pANTLR3_DEBUG_EVENT_LISTENER debugger)
207*16467b97STreehugger Robot {
208*16467b97STreehugger Robot pANTLR3_COMMON_TOKEN_STREAM stream;
209*16467b97STreehugger Robot
210*16467b97STreehugger Robot // Create a standard token stream
211*16467b97STreehugger Robot //
212*16467b97STreehugger Robot stream = antlr3CommonTokenStreamSourceNew(hint, source);
213*16467b97STreehugger Robot
214*16467b97STreehugger Robot // Install the debugger object
215*16467b97STreehugger Robot //
216*16467b97STreehugger Robot stream->tstream->debugger = debugger;
217*16467b97STreehugger Robot
218*16467b97STreehugger Robot // Override standard token stream methods with debugging versions
219*16467b97STreehugger Robot //
220*16467b97STreehugger Robot stream->tstream->initialStreamState = ANTLR3_FALSE;
221*16467b97STreehugger Robot
222*16467b97STreehugger Robot stream->tstream->_LT = dbgTokLT;
223*16467b97STreehugger Robot
224*16467b97STreehugger Robot stream->tstream->istream->consume = dbgConsume;
225*16467b97STreehugger Robot stream->tstream->istream->_LA = dbgLA;
226*16467b97STreehugger Robot stream->tstream->istream->mark = dbgMark;
227*16467b97STreehugger Robot stream->tstream->istream->rewind = dbgRewindStream;
228*16467b97STreehugger Robot stream->tstream->istream->rewindLast = dbgRewindLast;
229*16467b97STreehugger Robot stream->tstream->istream->seek = dbgSeek;
230*16467b97STreehugger Robot
231*16467b97STreehugger Robot return stream;
232*16467b97STreehugger Robot }
233*16467b97STreehugger Robot
234*16467b97STreehugger Robot ANTLR3_API pANTLR3_COMMON_TOKEN_STREAM
antlr3CommonTokenStreamSourceNew(ANTLR3_UINT32 hint,pANTLR3_TOKEN_SOURCE source)235*16467b97STreehugger Robot antlr3CommonTokenStreamSourceNew(ANTLR3_UINT32 hint, pANTLR3_TOKEN_SOURCE source)
236*16467b97STreehugger Robot {
237*16467b97STreehugger Robot pANTLR3_COMMON_TOKEN_STREAM stream;
238*16467b97STreehugger Robot
239*16467b97STreehugger Robot stream = antlr3CommonTokenStreamNew(hint);
240*16467b97STreehugger Robot
241*16467b97STreehugger Robot stream->channel = ANTLR3_TOKEN_DEFAULT_CHANNEL;
242*16467b97STreehugger Robot
243*16467b97STreehugger Robot stream->channelOverrides = NULL;
244*16467b97STreehugger Robot stream->discardSet = NULL;
245*16467b97STreehugger Robot stream->discardOffChannel = ANTLR3_FALSE;
246*16467b97STreehugger Robot
247*16467b97STreehugger Robot stream->tstream->setTokenSource(stream->tstream, source);
248*16467b97STreehugger Robot
249*16467b97STreehugger Robot stream->free = antlr3CTSFree;
250*16467b97STreehugger Robot return stream;
251*16467b97STreehugger Robot }
252*16467b97STreehugger Robot
253*16467b97STreehugger Robot ANTLR3_API pANTLR3_COMMON_TOKEN_STREAM
antlr3CommonTokenStreamNew(ANTLR3_UINT32 hint)254*16467b97STreehugger Robot antlr3CommonTokenStreamNew(ANTLR3_UINT32 hint)
255*16467b97STreehugger Robot {
256*16467b97STreehugger Robot pANTLR3_COMMON_TOKEN_STREAM stream;
257*16467b97STreehugger Robot
258*16467b97STreehugger Robot /* Memory for the interface structure
259*16467b97STreehugger Robot */
260*16467b97STreehugger Robot stream = (pANTLR3_COMMON_TOKEN_STREAM) ANTLR3_MALLOC(sizeof(ANTLR3_COMMON_TOKEN_STREAM));
261*16467b97STreehugger Robot
262*16467b97STreehugger Robot if (stream == NULL)
263*16467b97STreehugger Robot {
264*16467b97STreehugger Robot return NULL;
265*16467b97STreehugger Robot }
266*16467b97STreehugger Robot
267*16467b97STreehugger Robot /* Create space for the token stream interface
268*16467b97STreehugger Robot */
269*16467b97STreehugger Robot stream->tstream = antlr3TokenStreamNew();
270*16467b97STreehugger Robot stream->tstream->super = stream;
271*16467b97STreehugger Robot
272*16467b97STreehugger Robot /* Create space for the INT_STREAM interfacce
273*16467b97STreehugger Robot */
274*16467b97STreehugger Robot stream->tstream->istream = antlr3IntStreamNew();
275*16467b97STreehugger Robot stream->tstream->istream->super = (stream->tstream);
276*16467b97STreehugger Robot stream->tstream->istream->type = ANTLR3_TOKENSTREAM;
277*16467b97STreehugger Robot
278*16467b97STreehugger Robot /* Install the token tracking tables
279*16467b97STreehugger Robot */
280*16467b97STreehugger Robot stream->tokens = antlr3VectorNew(0);
281*16467b97STreehugger Robot
282*16467b97STreehugger Robot /* Defaults
283*16467b97STreehugger Robot */
284*16467b97STreehugger Robot stream->p = -1;
285*16467b97STreehugger Robot
286*16467b97STreehugger Robot /* Install the common token stream API
287*16467b97STreehugger Robot */
288*16467b97STreehugger Robot stream->setTokenTypeChannel = setTokenTypeChannel;
289*16467b97STreehugger Robot stream->discardTokenType = discardTokenType;
290*16467b97STreehugger Robot stream->discardOffChannelToks = discardOffChannel;
291*16467b97STreehugger Robot stream->getTokens = getTokens;
292*16467b97STreehugger Robot stream->getTokenRange = getTokenRange;
293*16467b97STreehugger Robot stream->getTokensSet = getTokensSet;
294*16467b97STreehugger Robot stream->getTokensList = getTokensList;
295*16467b97STreehugger Robot stream->getTokensType = getTokensType;
296*16467b97STreehugger Robot stream->reset = reset;
297*16467b97STreehugger Robot
298*16467b97STreehugger Robot /* Install the token stream API
299*16467b97STreehugger Robot */
300*16467b97STreehugger Robot stream->tstream->_LT = tokLT;
301*16467b97STreehugger Robot stream->tstream->get = get;
302*16467b97STreehugger Robot stream->tstream->getTokenSource = getTokenSource;
303*16467b97STreehugger Robot stream->tstream->setTokenSource = setTokenSource;
304*16467b97STreehugger Robot stream->tstream->toString = toString;
305*16467b97STreehugger Robot stream->tstream->toStringSS = toStringSS;
306*16467b97STreehugger Robot stream->tstream->toStringTT = toStringTT;
307*16467b97STreehugger Robot stream->tstream->setDebugListener = setDebugListener;
308*16467b97STreehugger Robot
309*16467b97STreehugger Robot /* Install INT_STREAM interface
310*16467b97STreehugger Robot */
311*16467b97STreehugger Robot stream->tstream->istream->_LA = _LA;
312*16467b97STreehugger Robot stream->tstream->istream->mark = mark;
313*16467b97STreehugger Robot stream->tstream->istream->release = release;
314*16467b97STreehugger Robot stream->tstream->istream->size = size;
315*16467b97STreehugger Robot stream->tstream->istream->index = tindex;
316*16467b97STreehugger Robot stream->tstream->istream->rewind = rewindStream;
317*16467b97STreehugger Robot stream->tstream->istream->rewindLast= rewindLast;
318*16467b97STreehugger Robot stream->tstream->istream->seek = seek;
319*16467b97STreehugger Robot stream->tstream->istream->consume = consume;
320*16467b97STreehugger Robot stream->tstream->istream->getSourceName = getSourceName;
321*16467b97STreehugger Robot
322*16467b97STreehugger Robot return stream;
323*16467b97STreehugger Robot }
324*16467b97STreehugger Robot
325*16467b97STreehugger Robot // Install a debug listener adn switch to debug mode methods
326*16467b97STreehugger Robot //
327*16467b97STreehugger Robot static void
setDebugListener(pANTLR3_TOKEN_STREAM ts,pANTLR3_DEBUG_EVENT_LISTENER debugger)328*16467b97STreehugger Robot setDebugListener (pANTLR3_TOKEN_STREAM ts, pANTLR3_DEBUG_EVENT_LISTENER debugger)
329*16467b97STreehugger Robot {
330*16467b97STreehugger Robot // Install the debugger object
331*16467b97STreehugger Robot //
332*16467b97STreehugger Robot ts->debugger = debugger;
333*16467b97STreehugger Robot
334*16467b97STreehugger Robot // Override standard token stream methods with debugging versions
335*16467b97STreehugger Robot //
336*16467b97STreehugger Robot ts->initialStreamState = ANTLR3_FALSE;
337*16467b97STreehugger Robot
338*16467b97STreehugger Robot ts->_LT = dbgTokLT;
339*16467b97STreehugger Robot
340*16467b97STreehugger Robot ts->istream->consume = dbgConsume;
341*16467b97STreehugger Robot ts->istream->_LA = dbgLA;
342*16467b97STreehugger Robot ts->istream->mark = dbgMark;
343*16467b97STreehugger Robot ts->istream->rewind = dbgRewindStream;
344*16467b97STreehugger Robot ts->istream->rewindLast = dbgRewindLast;
345*16467b97STreehugger Robot ts->istream->seek = dbgSeek;
346*16467b97STreehugger Robot }
347*16467b97STreehugger Robot
348*16467b97STreehugger Robot /** Get the ith token from the current position 1..n where k=1 is the
349*16467b97STreehugger Robot * first symbol of lookahead.
350*16467b97STreehugger Robot */
351*16467b97STreehugger Robot static pANTLR3_COMMON_TOKEN
tokLT(pANTLR3_TOKEN_STREAM ts,ANTLR3_INT32 k)352*16467b97STreehugger Robot tokLT (pANTLR3_TOKEN_STREAM ts, ANTLR3_INT32 k)
353*16467b97STreehugger Robot {
354*16467b97STreehugger Robot ANTLR3_INT32 i;
355*16467b97STreehugger Robot ANTLR3_INT32 n;
356*16467b97STreehugger Robot pANTLR3_COMMON_TOKEN_STREAM cts;
357*16467b97STreehugger Robot
358*16467b97STreehugger Robot cts = (pANTLR3_COMMON_TOKEN_STREAM)ts->super;
359*16467b97STreehugger Robot
360*16467b97STreehugger Robot if (k < 0)
361*16467b97STreehugger Robot {
362*16467b97STreehugger Robot return LB(cts, -k);
363*16467b97STreehugger Robot }
364*16467b97STreehugger Robot
365*16467b97STreehugger Robot if (cts->p == -1)
366*16467b97STreehugger Robot {
367*16467b97STreehugger Robot fillBuffer(cts);
368*16467b97STreehugger Robot }
369*16467b97STreehugger Robot
370*16467b97STreehugger Robot // Here we used to check for k == 0 and return 0, but this seems
371*16467b97STreehugger Robot // a superfluous check to me. LT(k=0) is therefore just undefined
372*16467b97STreehugger Robot // and we won't waste the clock cycles on the check
373*16467b97STreehugger Robot //
374*16467b97STreehugger Robot
375*16467b97STreehugger Robot if ((cts->p + k - 1) >= (ANTLR3_INT32)ts->istream->cachedSize)
376*16467b97STreehugger Robot {
377*16467b97STreehugger Robot pANTLR3_COMMON_TOKEN teof = &(ts->tokenSource->eofToken);
378*16467b97STreehugger Robot
379*16467b97STreehugger Robot teof->setStartIndex (teof, ts->istream->index (ts->istream));
380*16467b97STreehugger Robot teof->setStopIndex (teof, ts->istream->index (ts->istream));
381*16467b97STreehugger Robot return teof;
382*16467b97STreehugger Robot }
383*16467b97STreehugger Robot
384*16467b97STreehugger Robot i = cts->p;
385*16467b97STreehugger Robot n = 1;
386*16467b97STreehugger Robot
387*16467b97STreehugger Robot /* Need to find k good tokens, skipping ones that are off channel
388*16467b97STreehugger Robot */
389*16467b97STreehugger Robot while ( n < k)
390*16467b97STreehugger Robot {
391*16467b97STreehugger Robot /* Skip off-channel tokens */
392*16467b97STreehugger Robot i = skipOffTokenChannels(cts, i+1); /* leave p on valid token */
393*16467b97STreehugger Robot n++;
394*16467b97STreehugger Robot }
395*16467b97STreehugger Robot if ( (ANTLR3_UINT32) i >= ts->istream->cachedSize)
396*16467b97STreehugger Robot {
397*16467b97STreehugger Robot pANTLR3_COMMON_TOKEN teof = &(ts->tokenSource->eofToken);
398*16467b97STreehugger Robot
399*16467b97STreehugger Robot teof->setStartIndex (teof, ts->istream->index(ts->istream));
400*16467b97STreehugger Robot teof->setStopIndex (teof, ts->istream->index(ts->istream));
401*16467b97STreehugger Robot return teof;
402*16467b97STreehugger Robot }
403*16467b97STreehugger Robot
404*16467b97STreehugger Robot // Here the token must be in the input vector. Rather then incur
405*16467b97STreehugger Robot // function call penalty, we just return the pointer directly
406*16467b97STreehugger Robot // from the vector
407*16467b97STreehugger Robot //
408*16467b97STreehugger Robot return (pANTLR3_COMMON_TOKEN)cts->tokens->elements[i].element;
409*16467b97STreehugger Robot //return (pANTLR3_COMMON_TOKEN)cts->tokens->get(cts->tokens, i);
410*16467b97STreehugger Robot }
411*16467b97STreehugger Robot
412*16467b97STreehugger Robot /// Debug only method to flag consumption of initial off-channel
413*16467b97STreehugger Robot /// tokens in the input stream
414*16467b97STreehugger Robot ///
415*16467b97STreehugger Robot static void
consumeInitialHiddenTokens(pANTLR3_INT_STREAM is)416*16467b97STreehugger Robot consumeInitialHiddenTokens(pANTLR3_INT_STREAM is)
417*16467b97STreehugger Robot {
418*16467b97STreehugger Robot ANTLR3_MARKER first;
419*16467b97STreehugger Robot ANTLR3_INT32 i;
420*16467b97STreehugger Robot pANTLR3_TOKEN_STREAM ts;
421*16467b97STreehugger Robot
422*16467b97STreehugger Robot ts = (pANTLR3_TOKEN_STREAM) is->super;
423*16467b97STreehugger Robot first = is->index(is);
424*16467b97STreehugger Robot
425*16467b97STreehugger Robot for (i=0; i<first; i++)
426*16467b97STreehugger Robot {
427*16467b97STreehugger Robot ts->debugger->consumeHiddenToken(ts->debugger, ts->get(ts, i));
428*16467b97STreehugger Robot }
429*16467b97STreehugger Robot
430*16467b97STreehugger Robot ts->initialStreamState = ANTLR3_FALSE;
431*16467b97STreehugger Robot
432*16467b97STreehugger Robot }
433*16467b97STreehugger Robot
434*16467b97STreehugger Robot /// As per the normal tokLT but sends information to the debugger
435*16467b97STreehugger Robot ///
436*16467b97STreehugger Robot static pANTLR3_COMMON_TOKEN
dbgTokLT(pANTLR3_TOKEN_STREAM ts,ANTLR3_INT32 k)437*16467b97STreehugger Robot dbgTokLT (pANTLR3_TOKEN_STREAM ts, ANTLR3_INT32 k)
438*16467b97STreehugger Robot {
439*16467b97STreehugger Robot if (ts->initialStreamState == ANTLR3_TRUE)
440*16467b97STreehugger Robot {
441*16467b97STreehugger Robot consumeInitialHiddenTokens(ts->istream);
442*16467b97STreehugger Robot }
443*16467b97STreehugger Robot return tokLT(ts, k);
444*16467b97STreehugger Robot }
445*16467b97STreehugger Robot
446*16467b97STreehugger Robot #ifdef ANTLR3_WINDOWS
447*16467b97STreehugger Robot /* When fully optimized VC7 complains about non reachable code.
448*16467b97STreehugger Robot * Not yet sure if this is an optimizer bug, or a bug in the flow analysis
449*16467b97STreehugger Robot */
450*16467b97STreehugger Robot #pragma warning( disable : 4702 )
451*16467b97STreehugger Robot #endif
452*16467b97STreehugger Robot
453*16467b97STreehugger Robot static pANTLR3_COMMON_TOKEN
LB(pANTLR3_COMMON_TOKEN_STREAM cts,ANTLR3_INT32 k)454*16467b97STreehugger Robot LB(pANTLR3_COMMON_TOKEN_STREAM cts, ANTLR3_INT32 k)
455*16467b97STreehugger Robot {
456*16467b97STreehugger Robot ANTLR3_INT32 i;
457*16467b97STreehugger Robot ANTLR3_INT32 n;
458*16467b97STreehugger Robot
459*16467b97STreehugger Robot if (cts->p == -1)
460*16467b97STreehugger Robot {
461*16467b97STreehugger Robot fillBuffer(cts);
462*16467b97STreehugger Robot }
463*16467b97STreehugger Robot if (k == 0)
464*16467b97STreehugger Robot {
465*16467b97STreehugger Robot return NULL;
466*16467b97STreehugger Robot }
467*16467b97STreehugger Robot if ((cts->p - k) < 0)
468*16467b97STreehugger Robot {
469*16467b97STreehugger Robot return NULL;
470*16467b97STreehugger Robot }
471*16467b97STreehugger Robot
472*16467b97STreehugger Robot i = cts->p;
473*16467b97STreehugger Robot n = 1;
474*16467b97STreehugger Robot
475*16467b97STreehugger Robot /* Need to find k good tokens, going backwards, skipping ones that are off channel
476*16467b97STreehugger Robot */
477*16467b97STreehugger Robot while (n <= (ANTLR3_INT32) k)
478*16467b97STreehugger Robot {
479*16467b97STreehugger Robot /* Skip off-channel tokens
480*16467b97STreehugger Robot */
481*16467b97STreehugger Robot
482*16467b97STreehugger Robot i = skipOffTokenChannelsReverse(cts, i - 1); /* leave p on valid token */
483*16467b97STreehugger Robot n++;
484*16467b97STreehugger Robot }
485*16467b97STreehugger Robot if (i < 0)
486*16467b97STreehugger Robot {
487*16467b97STreehugger Robot return NULL;
488*16467b97STreehugger Robot }
489*16467b97STreehugger Robot // Here the token must be in the input vector. Rather then incut
490*16467b97STreehugger Robot // function call penalty, we jsut return the pointer directly
491*16467b97STreehugger Robot // from the vector
492*16467b97STreehugger Robot //
493*16467b97STreehugger Robot return (pANTLR3_COMMON_TOKEN)cts->tokens->elements[i].element;
494*16467b97STreehugger Robot }
495*16467b97STreehugger Robot
496*16467b97STreehugger Robot static pANTLR3_COMMON_TOKEN
get(pANTLR3_TOKEN_STREAM ts,ANTLR3_UINT32 i)497*16467b97STreehugger Robot get (pANTLR3_TOKEN_STREAM ts, ANTLR3_UINT32 i)
498*16467b97STreehugger Robot {
499*16467b97STreehugger Robot pANTLR3_COMMON_TOKEN_STREAM cts;
500*16467b97STreehugger Robot
501*16467b97STreehugger Robot cts = (pANTLR3_COMMON_TOKEN_STREAM)ts->super;
502*16467b97STreehugger Robot
503*16467b97STreehugger Robot return (pANTLR3_COMMON_TOKEN)(cts->tokens->get(cts->tokens, i)); /* Token index is zero based but vectors are 1 based */
504*16467b97STreehugger Robot }
505*16467b97STreehugger Robot
506*16467b97STreehugger Robot static pANTLR3_TOKEN_SOURCE
getTokenSource(pANTLR3_TOKEN_STREAM ts)507*16467b97STreehugger Robot getTokenSource (pANTLR3_TOKEN_STREAM ts)
508*16467b97STreehugger Robot {
509*16467b97STreehugger Robot return ts->tokenSource;
510*16467b97STreehugger Robot }
511*16467b97STreehugger Robot
512*16467b97STreehugger Robot static void
setTokenSource(pANTLR3_TOKEN_STREAM ts,pANTLR3_TOKEN_SOURCE tokenSource)513*16467b97STreehugger Robot setTokenSource ( pANTLR3_TOKEN_STREAM ts,
514*16467b97STreehugger Robot pANTLR3_TOKEN_SOURCE tokenSource)
515*16467b97STreehugger Robot {
516*16467b97STreehugger Robot ts->tokenSource = tokenSource;
517*16467b97STreehugger Robot }
518*16467b97STreehugger Robot
519*16467b97STreehugger Robot static pANTLR3_STRING
toString(pANTLR3_TOKEN_STREAM ts)520*16467b97STreehugger Robot toString (pANTLR3_TOKEN_STREAM ts)
521*16467b97STreehugger Robot {
522*16467b97STreehugger Robot pANTLR3_COMMON_TOKEN_STREAM cts;
523*16467b97STreehugger Robot
524*16467b97STreehugger Robot cts = (pANTLR3_COMMON_TOKEN_STREAM)ts->super;
525*16467b97STreehugger Robot
526*16467b97STreehugger Robot if (cts->p == -1)
527*16467b97STreehugger Robot {
528*16467b97STreehugger Robot fillBuffer(cts);
529*16467b97STreehugger Robot }
530*16467b97STreehugger Robot
531*16467b97STreehugger Robot return ts->toStringSS(ts, 0, ts->istream->size(ts->istream));
532*16467b97STreehugger Robot }
533*16467b97STreehugger Robot
534*16467b97STreehugger Robot static pANTLR3_STRING
toStringSS(pANTLR3_TOKEN_STREAM ts,ANTLR3_UINT32 start,ANTLR3_UINT32 stop)535*16467b97STreehugger Robot toStringSS(pANTLR3_TOKEN_STREAM ts, ANTLR3_UINT32 start, ANTLR3_UINT32 stop)
536*16467b97STreehugger Robot {
537*16467b97STreehugger Robot pANTLR3_STRING string;
538*16467b97STreehugger Robot pANTLR3_TOKEN_SOURCE tsource;
539*16467b97STreehugger Robot pANTLR3_COMMON_TOKEN tok;
540*16467b97STreehugger Robot ANTLR3_UINT32 i;
541*16467b97STreehugger Robot pANTLR3_COMMON_TOKEN_STREAM cts;
542*16467b97STreehugger Robot
543*16467b97STreehugger Robot cts = (pANTLR3_COMMON_TOKEN_STREAM) ts->super;
544*16467b97STreehugger Robot
545*16467b97STreehugger Robot if (cts->p == -1)
546*16467b97STreehugger Robot {
547*16467b97STreehugger Robot fillBuffer(cts);
548*16467b97STreehugger Robot }
549*16467b97STreehugger Robot if (stop >= ts->istream->size(ts->istream))
550*16467b97STreehugger Robot {
551*16467b97STreehugger Robot stop = ts->istream->size(ts->istream) - 1;
552*16467b97STreehugger Robot }
553*16467b97STreehugger Robot
554*16467b97STreehugger Robot /* Who is giving us these tokens?
555*16467b97STreehugger Robot */
556*16467b97STreehugger Robot tsource = ts->getTokenSource(ts);
557*16467b97STreehugger Robot
558*16467b97STreehugger Robot if (tsource != NULL && cts->tokens != NULL)
559*16467b97STreehugger Robot {
560*16467b97STreehugger Robot /* Finally, let's get a string
561*16467b97STreehugger Robot */
562*16467b97STreehugger Robot string = tsource->strFactory->newRaw(tsource->strFactory);
563*16467b97STreehugger Robot
564*16467b97STreehugger Robot for (i = start; i <= stop; i++)
565*16467b97STreehugger Robot {
566*16467b97STreehugger Robot tok = ts->get(ts, i);
567*16467b97STreehugger Robot if (tok != NULL)
568*16467b97STreehugger Robot {
569*16467b97STreehugger Robot string->appendS(string, tok->getText(tok));
570*16467b97STreehugger Robot }
571*16467b97STreehugger Robot }
572*16467b97STreehugger Robot
573*16467b97STreehugger Robot return string;
574*16467b97STreehugger Robot }
575*16467b97STreehugger Robot return NULL;
576*16467b97STreehugger Robot
577*16467b97STreehugger Robot }
578*16467b97STreehugger Robot
579*16467b97STreehugger Robot static pANTLR3_STRING
toStringTT(pANTLR3_TOKEN_STREAM ts,pANTLR3_COMMON_TOKEN start,pANTLR3_COMMON_TOKEN stop)580*16467b97STreehugger Robot toStringTT (pANTLR3_TOKEN_STREAM ts, pANTLR3_COMMON_TOKEN start, pANTLR3_COMMON_TOKEN stop)
581*16467b97STreehugger Robot {
582*16467b97STreehugger Robot if (start != NULL && stop != NULL)
583*16467b97STreehugger Robot {
584*16467b97STreehugger Robot return ts->toStringSS(ts, (ANTLR3_UINT32)start->getTokenIndex(start), (ANTLR3_UINT32)stop->getTokenIndex(stop));
585*16467b97STreehugger Robot }
586*16467b97STreehugger Robot else
587*16467b97STreehugger Robot {
588*16467b97STreehugger Robot return NULL;
589*16467b97STreehugger Robot }
590*16467b97STreehugger Robot }
591*16467b97STreehugger Robot
592*16467b97STreehugger Robot /** Move the input pointer to the next incoming token. The stream
593*16467b97STreehugger Robot * must become active with LT(1) available. consume() simply
594*16467b97STreehugger Robot * moves the input pointer so that LT(1) points at the next
595*16467b97STreehugger Robot * input symbol. Consume at least one token.
596*16467b97STreehugger Robot *
597*16467b97STreehugger Robot * Walk past any token not on the channel the parser is listening to.
598*16467b97STreehugger Robot */
599*16467b97STreehugger Robot static void
consume(pANTLR3_INT_STREAM is)600*16467b97STreehugger Robot consume (pANTLR3_INT_STREAM is)
601*16467b97STreehugger Robot {
602*16467b97STreehugger Robot pANTLR3_COMMON_TOKEN_STREAM cts;
603*16467b97STreehugger Robot pANTLR3_TOKEN_STREAM ts;
604*16467b97STreehugger Robot
605*16467b97STreehugger Robot ts = (pANTLR3_TOKEN_STREAM) is->super;
606*16467b97STreehugger Robot cts = (pANTLR3_COMMON_TOKEN_STREAM) ts->super;
607*16467b97STreehugger Robot
608*16467b97STreehugger Robot if ((ANTLR3_UINT32)cts->p < cts->tokens->count)
609*16467b97STreehugger Robot {
610*16467b97STreehugger Robot cts->p++;
611*16467b97STreehugger Robot cts->p = skipOffTokenChannels(cts, cts->p);
612*16467b97STreehugger Robot }
613*16467b97STreehugger Robot }
614*16467b97STreehugger Robot
615*16467b97STreehugger Robot
616*16467b97STreehugger Robot /// As per ordinary consume but notifies the debugger about hidden
617*16467b97STreehugger Robot /// tokens and so on.
618*16467b97STreehugger Robot ///
619*16467b97STreehugger Robot static void
dbgConsume(pANTLR3_INT_STREAM is)620*16467b97STreehugger Robot dbgConsume (pANTLR3_INT_STREAM is)
621*16467b97STreehugger Robot {
622*16467b97STreehugger Robot pANTLR3_TOKEN_STREAM ts;
623*16467b97STreehugger Robot ANTLR3_MARKER a;
624*16467b97STreehugger Robot ANTLR3_MARKER b;
625*16467b97STreehugger Robot pANTLR3_COMMON_TOKEN t;
626*16467b97STreehugger Robot
627*16467b97STreehugger Robot ts = (pANTLR3_TOKEN_STREAM) is->super;
628*16467b97STreehugger Robot
629*16467b97STreehugger Robot if (ts->initialStreamState == ANTLR3_TRUE)
630*16467b97STreehugger Robot {
631*16467b97STreehugger Robot consumeInitialHiddenTokens(is);
632*16467b97STreehugger Robot }
633*16467b97STreehugger Robot
634*16467b97STreehugger Robot a = is->index(is); // Where are we right now?
635*16467b97STreehugger Robot t = ts->_LT(ts, 1); // Current token from stream
636*16467b97STreehugger Robot
637*16467b97STreehugger Robot consume(is); // Standard consumer
638*16467b97STreehugger Robot
639*16467b97STreehugger Robot b = is->index(is); // Where are we after consuming 1 on channel token?
640*16467b97STreehugger Robot
641*16467b97STreehugger Robot ts->debugger->consumeToken(ts->debugger, t); // Tell the debugger that we consumed the first token
642*16467b97STreehugger Robot
643*16467b97STreehugger Robot if (b>a+1)
644*16467b97STreehugger Robot {
645*16467b97STreehugger Robot // The standard consume caused the index to advance by more than 1,
646*16467b97STreehugger Robot // which can only happen if it skipped some off-channel tokens.
647*16467b97STreehugger Robot // we need to tell the debugger about those tokens.
648*16467b97STreehugger Robot //
649*16467b97STreehugger Robot ANTLR3_MARKER i;
650*16467b97STreehugger Robot
651*16467b97STreehugger Robot for (i = a+1; i<b; i++)
652*16467b97STreehugger Robot {
653*16467b97STreehugger Robot ts->debugger->consumeHiddenToken(ts->debugger, ts->get(ts, (ANTLR3_UINT32)i));
654*16467b97STreehugger Robot }
655*16467b97STreehugger Robot
656*16467b97STreehugger Robot }
657*16467b97STreehugger Robot }
658*16467b97STreehugger Robot
659*16467b97STreehugger Robot /** A simple filter mechanism whereby you can tell this token stream
660*16467b97STreehugger Robot * to force all tokens of type ttype to be on channel. For example,
661*16467b97STreehugger Robot * when interpreting, we cannot execute actions so we need to tell
662*16467b97STreehugger Robot * the stream to force all WS and NEWLINE to be a different, ignored,
663*16467b97STreehugger Robot * channel.
664*16467b97STreehugger Robot */
665*16467b97STreehugger Robot static void
setTokenTypeChannel(pANTLR3_COMMON_TOKEN_STREAM tokenStream,ANTLR3_UINT32 ttype,ANTLR3_UINT32 channel)666*16467b97STreehugger Robot setTokenTypeChannel (pANTLR3_COMMON_TOKEN_STREAM tokenStream, ANTLR3_UINT32 ttype, ANTLR3_UINT32 channel)
667*16467b97STreehugger Robot {
668*16467b97STreehugger Robot if (tokenStream->channelOverrides == NULL)
669*16467b97STreehugger Robot {
670*16467b97STreehugger Robot tokenStream->channelOverrides = antlr3ListNew(10);
671*16467b97STreehugger Robot }
672*16467b97STreehugger Robot
673*16467b97STreehugger Robot /* We add one to the channel so we can distinguish NULL as being no entry in the
674*16467b97STreehugger Robot * table for a particular token type.
675*16467b97STreehugger Robot */
676*16467b97STreehugger Robot tokenStream->channelOverrides->put(tokenStream->channelOverrides, ttype, ANTLR3_FUNC_PTR((ANTLR3_UINT32)channel + 1), NULL);
677*16467b97STreehugger Robot }
678*16467b97STreehugger Robot
679*16467b97STreehugger Robot static void
discardTokenType(pANTLR3_COMMON_TOKEN_STREAM tokenStream,ANTLR3_INT32 ttype)680*16467b97STreehugger Robot discardTokenType (pANTLR3_COMMON_TOKEN_STREAM tokenStream, ANTLR3_INT32 ttype)
681*16467b97STreehugger Robot {
682*16467b97STreehugger Robot if (tokenStream->discardSet == NULL)
683*16467b97STreehugger Robot {
684*16467b97STreehugger Robot tokenStream->discardSet = antlr3ListNew(31);
685*16467b97STreehugger Robot }
686*16467b97STreehugger Robot
687*16467b97STreehugger Robot /* We add one to the channel so we can distinguish NULL as being no entry in the
688*16467b97STreehugger Robot * table for a particular token type. We could use bitsets for this I suppose too.
689*16467b97STreehugger Robot */
690*16467b97STreehugger Robot tokenStream->discardSet->put(tokenStream->discardSet, ttype, ANTLR3_FUNC_PTR((ANTLR3_UINT32)ttype + 1), NULL);
691*16467b97STreehugger Robot }
692*16467b97STreehugger Robot
693*16467b97STreehugger Robot static void
discardOffChannel(pANTLR3_COMMON_TOKEN_STREAM tokenStream,ANTLR3_BOOLEAN discard)694*16467b97STreehugger Robot discardOffChannel (pANTLR3_COMMON_TOKEN_STREAM tokenStream, ANTLR3_BOOLEAN discard)
695*16467b97STreehugger Robot {
696*16467b97STreehugger Robot tokenStream->discardOffChannel = discard;
697*16467b97STreehugger Robot }
698*16467b97STreehugger Robot
699*16467b97STreehugger Robot static pANTLR3_VECTOR
getTokens(pANTLR3_COMMON_TOKEN_STREAM tokenStream)700*16467b97STreehugger Robot getTokens (pANTLR3_COMMON_TOKEN_STREAM tokenStream)
701*16467b97STreehugger Robot {
702*16467b97STreehugger Robot if (tokenStream->p == -1)
703*16467b97STreehugger Robot {
704*16467b97STreehugger Robot fillBuffer(tokenStream);
705*16467b97STreehugger Robot }
706*16467b97STreehugger Robot
707*16467b97STreehugger Robot return tokenStream->tokens;
708*16467b97STreehugger Robot }
709*16467b97STreehugger Robot
710*16467b97STreehugger Robot static pANTLR3_LIST
getTokenRange(pANTLR3_COMMON_TOKEN_STREAM tokenStream,ANTLR3_UINT32 start,ANTLR3_UINT32 stop)711*16467b97STreehugger Robot getTokenRange (pANTLR3_COMMON_TOKEN_STREAM tokenStream, ANTLR3_UINT32 start, ANTLR3_UINT32 stop)
712*16467b97STreehugger Robot {
713*16467b97STreehugger Robot return tokenStream->getTokensSet(tokenStream, start, stop, NULL);
714*16467b97STreehugger Robot }
715*16467b97STreehugger Robot /** Given a start and stop index, return a List of all tokens in
716*16467b97STreehugger Robot * the token type BitSet. Return null if no tokens were found. This
717*16467b97STreehugger Robot * method looks at both on and off channel tokens.
718*16467b97STreehugger Robot */
719*16467b97STreehugger Robot static pANTLR3_LIST
getTokensSet(pANTLR3_COMMON_TOKEN_STREAM tokenStream,ANTLR3_UINT32 start,ANTLR3_UINT32 stop,pANTLR3_BITSET types)720*16467b97STreehugger Robot getTokensSet (pANTLR3_COMMON_TOKEN_STREAM tokenStream, ANTLR3_UINT32 start, ANTLR3_UINT32 stop, pANTLR3_BITSET types)
721*16467b97STreehugger Robot {
722*16467b97STreehugger Robot pANTLR3_LIST filteredList;
723*16467b97STreehugger Robot ANTLR3_UINT32 i;
724*16467b97STreehugger Robot ANTLR3_UINT32 n;
725*16467b97STreehugger Robot pANTLR3_COMMON_TOKEN tok;
726*16467b97STreehugger Robot
727*16467b97STreehugger Robot if (tokenStream->p == -1)
728*16467b97STreehugger Robot {
729*16467b97STreehugger Robot fillBuffer(tokenStream);
730*16467b97STreehugger Robot }
731*16467b97STreehugger Robot if (stop > tokenStream->tstream->istream->size(tokenStream->tstream->istream))
732*16467b97STreehugger Robot {
733*16467b97STreehugger Robot stop = tokenStream->tstream->istream->size(tokenStream->tstream->istream);
734*16467b97STreehugger Robot }
735*16467b97STreehugger Robot if (start > stop)
736*16467b97STreehugger Robot {
737*16467b97STreehugger Robot return NULL;
738*16467b97STreehugger Robot }
739*16467b97STreehugger Robot
740*16467b97STreehugger Robot /* We have the range set, now we need to iterate through the
741*16467b97STreehugger Robot * installed tokens and create a new list with just the ones we want
742*16467b97STreehugger Robot * in it. We are just moving pointers about really.
743*16467b97STreehugger Robot */
744*16467b97STreehugger Robot filteredList = antlr3ListNew((ANTLR3_UINT32)tokenStream->tstream->istream->size(tokenStream->tstream->istream));
745*16467b97STreehugger Robot
746*16467b97STreehugger Robot for (i = start, n = 0; i<= stop; i++)
747*16467b97STreehugger Robot {
748*16467b97STreehugger Robot tok = tokenStream->tstream->get(tokenStream->tstream, i);
749*16467b97STreehugger Robot
750*16467b97STreehugger Robot if ( types == NULL
751*16467b97STreehugger Robot || types->isMember(types, tok->getType(tok) == ANTLR3_TRUE)
752*16467b97STreehugger Robot )
753*16467b97STreehugger Robot {
754*16467b97STreehugger Robot filteredList->put(filteredList, n++, (void *)tok, NULL);
755*16467b97STreehugger Robot }
756*16467b97STreehugger Robot }
757*16467b97STreehugger Robot
758*16467b97STreehugger Robot /* Did we get any then?
759*16467b97STreehugger Robot */
760*16467b97STreehugger Robot if (filteredList->size(filteredList) == 0)
761*16467b97STreehugger Robot {
762*16467b97STreehugger Robot filteredList->free(filteredList);
763*16467b97STreehugger Robot filteredList = NULL;
764*16467b97STreehugger Robot }
765*16467b97STreehugger Robot
766*16467b97STreehugger Robot return filteredList;
767*16467b97STreehugger Robot }
768*16467b97STreehugger Robot
769*16467b97STreehugger Robot static pANTLR3_LIST
getTokensList(pANTLR3_COMMON_TOKEN_STREAM tokenStream,ANTLR3_UINT32 start,ANTLR3_UINT32 stop,pANTLR3_LIST list)770*16467b97STreehugger Robot getTokensList (pANTLR3_COMMON_TOKEN_STREAM tokenStream, ANTLR3_UINT32 start, ANTLR3_UINT32 stop, pANTLR3_LIST list)
771*16467b97STreehugger Robot {
772*16467b97STreehugger Robot pANTLR3_BITSET bitSet;
773*16467b97STreehugger Robot pANTLR3_LIST newlist;
774*16467b97STreehugger Robot
775*16467b97STreehugger Robot bitSet = antlr3BitsetList(list->table);
776*16467b97STreehugger Robot
777*16467b97STreehugger Robot newlist = tokenStream->getTokensSet(tokenStream, start, stop, bitSet);
778*16467b97STreehugger Robot
779*16467b97STreehugger Robot bitSet->free(bitSet);
780*16467b97STreehugger Robot
781*16467b97STreehugger Robot return newlist;
782*16467b97STreehugger Robot
783*16467b97STreehugger Robot }
784*16467b97STreehugger Robot
785*16467b97STreehugger Robot static pANTLR3_LIST
getTokensType(pANTLR3_COMMON_TOKEN_STREAM tokenStream,ANTLR3_UINT32 start,ANTLR3_UINT32 stop,ANTLR3_UINT32 type)786*16467b97STreehugger Robot getTokensType (pANTLR3_COMMON_TOKEN_STREAM tokenStream, ANTLR3_UINT32 start, ANTLR3_UINT32 stop, ANTLR3_UINT32 type)
787*16467b97STreehugger Robot {
788*16467b97STreehugger Robot pANTLR3_BITSET bitSet;
789*16467b97STreehugger Robot pANTLR3_LIST newlist;
790*16467b97STreehugger Robot
791*16467b97STreehugger Robot bitSet = antlr3BitsetOf(type, -1);
792*16467b97STreehugger Robot newlist = tokenStream->getTokensSet(tokenStream, start, stop, bitSet);
793*16467b97STreehugger Robot
794*16467b97STreehugger Robot bitSet->free(bitSet);
795*16467b97STreehugger Robot
796*16467b97STreehugger Robot return newlist;
797*16467b97STreehugger Robot }
798*16467b97STreehugger Robot
799*16467b97STreehugger Robot static ANTLR3_UINT32
_LA(pANTLR3_INT_STREAM is,ANTLR3_INT32 i)800*16467b97STreehugger Robot _LA (pANTLR3_INT_STREAM is, ANTLR3_INT32 i)
801*16467b97STreehugger Robot {
802*16467b97STreehugger Robot pANTLR3_TOKEN_STREAM ts;
803*16467b97STreehugger Robot pANTLR3_COMMON_TOKEN tok;
804*16467b97STreehugger Robot
805*16467b97STreehugger Robot ts = (pANTLR3_TOKEN_STREAM) is->super;
806*16467b97STreehugger Robot
807*16467b97STreehugger Robot tok = ts->_LT(ts, i);
808*16467b97STreehugger Robot
809*16467b97STreehugger Robot if (tok != NULL)
810*16467b97STreehugger Robot {
811*16467b97STreehugger Robot return tok->getType(tok);
812*16467b97STreehugger Robot }
813*16467b97STreehugger Robot else
814*16467b97STreehugger Robot {
815*16467b97STreehugger Robot return ANTLR3_TOKEN_INVALID;
816*16467b97STreehugger Robot }
817*16467b97STreehugger Robot }
818*16467b97STreehugger Robot
819*16467b97STreehugger Robot /// As per _LA() but for debug mode.
820*16467b97STreehugger Robot ///
821*16467b97STreehugger Robot static ANTLR3_UINT32
dbgLA(pANTLR3_INT_STREAM is,ANTLR3_INT32 i)822*16467b97STreehugger Robot dbgLA (pANTLR3_INT_STREAM is, ANTLR3_INT32 i)
823*16467b97STreehugger Robot {
824*16467b97STreehugger Robot pANTLR3_TOKEN_STREAM ts;
825*16467b97STreehugger Robot
826*16467b97STreehugger Robot ts = (pANTLR3_TOKEN_STREAM) is->super;
827*16467b97STreehugger Robot
828*16467b97STreehugger Robot if (ts->initialStreamState == ANTLR3_TRUE)
829*16467b97STreehugger Robot {
830*16467b97STreehugger Robot consumeInitialHiddenTokens(is);
831*16467b97STreehugger Robot }
832*16467b97STreehugger Robot ts->debugger->LT(ts->debugger, i, tokLT(ts, i));
833*16467b97STreehugger Robot return _LA(is, i);
834*16467b97STreehugger Robot }
835*16467b97STreehugger Robot
836*16467b97STreehugger Robot static ANTLR3_MARKER
mark(pANTLR3_INT_STREAM is)837*16467b97STreehugger Robot mark (pANTLR3_INT_STREAM is)
838*16467b97STreehugger Robot {
839*16467b97STreehugger Robot is->lastMarker = is->index(is);
840*16467b97STreehugger Robot return is->lastMarker;
841*16467b97STreehugger Robot }
842*16467b97STreehugger Robot
843*16467b97STreehugger Robot /// As per mark() but with a call to tell the debugger we are doing this
844*16467b97STreehugger Robot ///
845*16467b97STreehugger Robot static ANTLR3_MARKER
dbgMark(pANTLR3_INT_STREAM is)846*16467b97STreehugger Robot dbgMark (pANTLR3_INT_STREAM is)
847*16467b97STreehugger Robot {
848*16467b97STreehugger Robot pANTLR3_TOKEN_STREAM ts;
849*16467b97STreehugger Robot
850*16467b97STreehugger Robot ts = (pANTLR3_TOKEN_STREAM) is->super;
851*16467b97STreehugger Robot
852*16467b97STreehugger Robot is->lastMarker = is->index(is);
853*16467b97STreehugger Robot ts->debugger->mark(ts->debugger, is->lastMarker);
854*16467b97STreehugger Robot
855*16467b97STreehugger Robot return is->lastMarker;
856*16467b97STreehugger Robot }
857*16467b97STreehugger Robot
858*16467b97STreehugger Robot static void
release(pANTLR3_INT_STREAM is,ANTLR3_MARKER mark)859*16467b97STreehugger Robot release (pANTLR3_INT_STREAM is, ANTLR3_MARKER mark)
860*16467b97STreehugger Robot {
861*16467b97STreehugger Robot return;
862*16467b97STreehugger Robot }
863*16467b97STreehugger Robot
864*16467b97STreehugger Robot static ANTLR3_UINT32
size(pANTLR3_INT_STREAM is)865*16467b97STreehugger Robot size (pANTLR3_INT_STREAM is)
866*16467b97STreehugger Robot {
867*16467b97STreehugger Robot pANTLR3_COMMON_TOKEN_STREAM cts;
868*16467b97STreehugger Robot pANTLR3_TOKEN_STREAM ts;
869*16467b97STreehugger Robot
870*16467b97STreehugger Robot if (is->cachedSize > 0)
871*16467b97STreehugger Robot {
872*16467b97STreehugger Robot return is->cachedSize;
873*16467b97STreehugger Robot }
874*16467b97STreehugger Robot ts = (pANTLR3_TOKEN_STREAM) is->super;
875*16467b97STreehugger Robot cts = (pANTLR3_COMMON_TOKEN_STREAM) ts->super;
876*16467b97STreehugger Robot
877*16467b97STreehugger Robot is->cachedSize = cts->tokens->count;
878*16467b97STreehugger Robot return is->cachedSize;
879*16467b97STreehugger Robot }
880*16467b97STreehugger Robot
881*16467b97STreehugger Robot static ANTLR3_MARKER
tindex(pANTLR3_INT_STREAM is)882*16467b97STreehugger Robot tindex (pANTLR3_INT_STREAM is)
883*16467b97STreehugger Robot {
884*16467b97STreehugger Robot pANTLR3_COMMON_TOKEN_STREAM cts;
885*16467b97STreehugger Robot pANTLR3_TOKEN_STREAM ts;
886*16467b97STreehugger Robot
887*16467b97STreehugger Robot ts = (pANTLR3_TOKEN_STREAM) is->super;
888*16467b97STreehugger Robot cts = (pANTLR3_COMMON_TOKEN_STREAM) ts->super;
889*16467b97STreehugger Robot
890*16467b97STreehugger Robot return cts->p;
891*16467b97STreehugger Robot }
892*16467b97STreehugger Robot
893*16467b97STreehugger Robot static void
dbgRewindLast(pANTLR3_INT_STREAM is)894*16467b97STreehugger Robot dbgRewindLast (pANTLR3_INT_STREAM is)
895*16467b97STreehugger Robot {
896*16467b97STreehugger Robot pANTLR3_TOKEN_STREAM ts;
897*16467b97STreehugger Robot
898*16467b97STreehugger Robot ts = (pANTLR3_TOKEN_STREAM) is->super;
899*16467b97STreehugger Robot
900*16467b97STreehugger Robot ts->debugger->rewindLast(ts->debugger);
901*16467b97STreehugger Robot
902*16467b97STreehugger Robot is->rewind(is, is->lastMarker);
903*16467b97STreehugger Robot }
904*16467b97STreehugger Robot static void
rewindLast(pANTLR3_INT_STREAM is)905*16467b97STreehugger Robot rewindLast (pANTLR3_INT_STREAM is)
906*16467b97STreehugger Robot {
907*16467b97STreehugger Robot is->rewind(is, is->lastMarker);
908*16467b97STreehugger Robot }
909*16467b97STreehugger Robot static void
rewindStream(pANTLR3_INT_STREAM is,ANTLR3_MARKER marker)910*16467b97STreehugger Robot rewindStream (pANTLR3_INT_STREAM is, ANTLR3_MARKER marker)
911*16467b97STreehugger Robot {
912*16467b97STreehugger Robot is->seek(is, (ANTLR3_UINT32)(marker));
913*16467b97STreehugger Robot }
914*16467b97STreehugger Robot static void
dbgRewindStream(pANTLR3_INT_STREAM is,ANTLR3_MARKER marker)915*16467b97STreehugger Robot dbgRewindStream (pANTLR3_INT_STREAM is, ANTLR3_MARKER marker)
916*16467b97STreehugger Robot {
917*16467b97STreehugger Robot pANTLR3_TOKEN_STREAM ts;
918*16467b97STreehugger Robot
919*16467b97STreehugger Robot ts = (pANTLR3_TOKEN_STREAM) is->super;
920*16467b97STreehugger Robot
921*16467b97STreehugger Robot ts->debugger->rewind(ts->debugger, marker);
922*16467b97STreehugger Robot
923*16467b97STreehugger Robot is->seek(is, (ANTLR3_UINT32)(marker));
924*16467b97STreehugger Robot }
925*16467b97STreehugger Robot
926*16467b97STreehugger Robot static void
seek(pANTLR3_INT_STREAM is,ANTLR3_MARKER index)927*16467b97STreehugger Robot seek (pANTLR3_INT_STREAM is, ANTLR3_MARKER index)
928*16467b97STreehugger Robot {
929*16467b97STreehugger Robot pANTLR3_COMMON_TOKEN_STREAM cts;
930*16467b97STreehugger Robot pANTLR3_TOKEN_STREAM ts;
931*16467b97STreehugger Robot
932*16467b97STreehugger Robot ts = (pANTLR3_TOKEN_STREAM) is->super;
933*16467b97STreehugger Robot cts = (pANTLR3_COMMON_TOKEN_STREAM) ts->super;
934*16467b97STreehugger Robot
935*16467b97STreehugger Robot cts->p = (ANTLR3_UINT32)index;
936*16467b97STreehugger Robot }
937*16467b97STreehugger Robot static void
dbgSeek(pANTLR3_INT_STREAM is,ANTLR3_MARKER index)938*16467b97STreehugger Robot dbgSeek (pANTLR3_INT_STREAM is, ANTLR3_MARKER index)
939*16467b97STreehugger Robot {
940*16467b97STreehugger Robot // TODO: Implement seek in debugger when Ter adds it to Java
941*16467b97STreehugger Robot //
942*16467b97STreehugger Robot seek(is, index);
943*16467b97STreehugger Robot }
944*16467b97STreehugger Robot ANTLR3_API void
fillBufferExt(pANTLR3_COMMON_TOKEN_STREAM tokenStream)945*16467b97STreehugger Robot fillBufferExt(pANTLR3_COMMON_TOKEN_STREAM tokenStream)
946*16467b97STreehugger Robot {
947*16467b97STreehugger Robot fillBuffer(tokenStream);
948*16467b97STreehugger Robot }
949*16467b97STreehugger Robot static void
fillBuffer(pANTLR3_COMMON_TOKEN_STREAM tokenStream)950*16467b97STreehugger Robot fillBuffer(pANTLR3_COMMON_TOKEN_STREAM tokenStream) {
951*16467b97STreehugger Robot ANTLR3_UINT32 index;
952*16467b97STreehugger Robot pANTLR3_COMMON_TOKEN tok;
953*16467b97STreehugger Robot ANTLR3_BOOLEAN discard;
954*16467b97STreehugger Robot void * channelI;
955*16467b97STreehugger Robot
956*16467b97STreehugger Robot /* Start at index 0 of course
957*16467b97STreehugger Robot */
958*16467b97STreehugger Robot index = 0;
959*16467b97STreehugger Robot
960*16467b97STreehugger Robot /* Pick out the next token from the token source
961*16467b97STreehugger Robot * Remember we just get a pointer (reference if you like) here
962*16467b97STreehugger Robot * and so if we store it anywhere, we don't set any pointers to auto free it.
963*16467b97STreehugger Robot */
964*16467b97STreehugger Robot tok = tokenStream->tstream->tokenSource->nextToken(tokenStream->tstream->tokenSource);
965*16467b97STreehugger Robot
966*16467b97STreehugger Robot while (tok != NULL && tok->type != ANTLR3_TOKEN_EOF)
967*16467b97STreehugger Robot {
968*16467b97STreehugger Robot discard = ANTLR3_FALSE; /* Assume we are not discarding */
969*16467b97STreehugger Robot
970*16467b97STreehugger Robot /* I employ a bit of a trick, or perhaps hack here. Rather than
971*16467b97STreehugger Robot * store a pointer to a structure in the override map and discard set
972*16467b97STreehugger Robot * we store the value + 1 cast to a void *. Hence on systems where NULL = (void *)0
973*16467b97STreehugger Robot * we can distinguish "not being there" from "being channel or type 0"
974*16467b97STreehugger Robot */
975*16467b97STreehugger Robot
976*16467b97STreehugger Robot if (tokenStream->discardSet != NULL
977*16467b97STreehugger Robot && tokenStream->discardSet->get(tokenStream->discardSet, tok->getType(tok)) != NULL)
978*16467b97STreehugger Robot {
979*16467b97STreehugger Robot discard = ANTLR3_TRUE;
980*16467b97STreehugger Robot }
981*16467b97STreehugger Robot else if ( tokenStream->discardOffChannel == ANTLR3_TRUE
982*16467b97STreehugger Robot && tok->getChannel(tok) != tokenStream->channel
983*16467b97STreehugger Robot )
984*16467b97STreehugger Robot {
985*16467b97STreehugger Robot discard = ANTLR3_TRUE;
986*16467b97STreehugger Robot }
987*16467b97STreehugger Robot else if (tokenStream->channelOverrides != NULL)
988*16467b97STreehugger Robot {
989*16467b97STreehugger Robot /* See if this type is in the override map
990*16467b97STreehugger Robot */
991*16467b97STreehugger Robot channelI = tokenStream->channelOverrides->get(tokenStream->channelOverrides, tok->getType(tok) + 1);
992*16467b97STreehugger Robot
993*16467b97STreehugger Robot if (channelI != NULL)
994*16467b97STreehugger Robot {
995*16467b97STreehugger Robot /* Override found
996*16467b97STreehugger Robot */
997*16467b97STreehugger Robot tok->setChannel(tok, ANTLR3_UINT32_CAST(channelI) - 1);
998*16467b97STreehugger Robot }
999*16467b97STreehugger Robot }
1000*16467b97STreehugger Robot
1001*16467b97STreehugger Robot /* If not discarding it, add it to the list at the current index
1002*16467b97STreehugger Robot */
1003*16467b97STreehugger Robot if (discard == ANTLR3_FALSE)
1004*16467b97STreehugger Robot {
1005*16467b97STreehugger Robot /* Add it, indicating that we will delete it and the table should not
1006*16467b97STreehugger Robot */
1007*16467b97STreehugger Robot tok->setTokenIndex(tok, index);
1008*16467b97STreehugger Robot tokenStream->p++;
1009*16467b97STreehugger Robot tokenStream->tokens->add(tokenStream->tokens, (void *) tok, NULL);
1010*16467b97STreehugger Robot index++;
1011*16467b97STreehugger Robot }
1012*16467b97STreehugger Robot
1013*16467b97STreehugger Robot tok = tokenStream->tstream->tokenSource->nextToken(tokenStream->tstream->tokenSource);
1014*16467b97STreehugger Robot }
1015*16467b97STreehugger Robot
1016*16467b97STreehugger Robot /* Cache the size so we don't keep doing indirect method calls. We do this as
1017*16467b97STreehugger Robot * early as possible so that anything after this may utilize the cached value.
1018*16467b97STreehugger Robot */
1019*16467b97STreehugger Robot tokenStream->tstream->istream->cachedSize = tokenStream->tokens->count;
1020*16467b97STreehugger Robot
1021*16467b97STreehugger Robot /* Set the consume pointer to the first token that is on our channel
1022*16467b97STreehugger Robot */
1023*16467b97STreehugger Robot tokenStream->p = 0;
1024*16467b97STreehugger Robot tokenStream->p = skipOffTokenChannels(tokenStream, tokenStream->p);
1025*16467b97STreehugger Robot
1026*16467b97STreehugger Robot }
1027*16467b97STreehugger Robot
1028*16467b97STreehugger Robot /// Given a starting index, return the index of the first on-channel
1029*16467b97STreehugger Robot /// token.
1030*16467b97STreehugger Robot ///
1031*16467b97STreehugger Robot static ANTLR3_UINT32
skipOffTokenChannels(pANTLR3_COMMON_TOKEN_STREAM tokenStream,ANTLR3_INT32 i)1032*16467b97STreehugger Robot skipOffTokenChannels(pANTLR3_COMMON_TOKEN_STREAM tokenStream, ANTLR3_INT32 i) {
1033*16467b97STreehugger Robot ANTLR3_INT32 n;
1034*16467b97STreehugger Robot pANTLR3_COMMON_TOKEN tok;
1035*16467b97STreehugger Robot
1036*16467b97STreehugger Robot n = tokenStream->tstream->istream->cachedSize;
1037*16467b97STreehugger Robot
1038*16467b97STreehugger Robot while (i < n)
1039*16467b97STreehugger Robot {
1040*16467b97STreehugger Robot tok = (pANTLR3_COMMON_TOKEN)tokenStream->tokens->elements[i].element;
1041*16467b97STreehugger Robot
1042*16467b97STreehugger Robot if (tok->channel!= tokenStream->channel)
1043*16467b97STreehugger Robot {
1044*16467b97STreehugger Robot i++;
1045*16467b97STreehugger Robot }
1046*16467b97STreehugger Robot else
1047*16467b97STreehugger Robot {
1048*16467b97STreehugger Robot return i;
1049*16467b97STreehugger Robot }
1050*16467b97STreehugger Robot }
1051*16467b97STreehugger Robot return i;
1052*16467b97STreehugger Robot }
1053*16467b97STreehugger Robot
1054*16467b97STreehugger Robot static ANTLR3_UINT32
skipOffTokenChannelsReverse(pANTLR3_COMMON_TOKEN_STREAM tokenStream,ANTLR3_INT32 x)1055*16467b97STreehugger Robot skipOffTokenChannelsReverse(pANTLR3_COMMON_TOKEN_STREAM tokenStream, ANTLR3_INT32 x)
1056*16467b97STreehugger Robot {
1057*16467b97STreehugger Robot pANTLR3_COMMON_TOKEN tok;
1058*16467b97STreehugger Robot
1059*16467b97STreehugger Robot while (x >= 0)
1060*16467b97STreehugger Robot {
1061*16467b97STreehugger Robot tok = (pANTLR3_COMMON_TOKEN)tokenStream->tokens->elements[x].element;
1062*16467b97STreehugger Robot
1063*16467b97STreehugger Robot if ((tok->channel != tokenStream->channel))
1064*16467b97STreehugger Robot {
1065*16467b97STreehugger Robot x--;
1066*16467b97STreehugger Robot }
1067*16467b97STreehugger Robot else
1068*16467b97STreehugger Robot {
1069*16467b97STreehugger Robot return x;
1070*16467b97STreehugger Robot }
1071*16467b97STreehugger Robot }
1072*16467b97STreehugger Robot return x;
1073*16467b97STreehugger Robot }
1074*16467b97STreehugger Robot
1075*16467b97STreehugger Robot /// Return a string that represents the name assoicated with the input source
1076*16467b97STreehugger Robot ///
1077*16467b97STreehugger Robot /// /param[in] is The ANTLR3_INT_STREAM interface that is representing this token stream.
1078*16467b97STreehugger Robot ///
1079*16467b97STreehugger Robot /// /returns
1080*16467b97STreehugger Robot /// /implements ANTLR3_INT_STREAM_struct::getSourceName()
1081*16467b97STreehugger Robot ///
1082*16467b97STreehugger Robot static pANTLR3_STRING
getSourceName(pANTLR3_INT_STREAM is)1083*16467b97STreehugger Robot getSourceName (pANTLR3_INT_STREAM is)
1084*16467b97STreehugger Robot {
1085*16467b97STreehugger Robot // Slightly convoluted as we must trace back to the lexer's input source
1086*16467b97STreehugger Robot // via the token source. The streamName that is here is not initialized
1087*16467b97STreehugger Robot // because this is a token stream, not a file or string stream, which are the
1088*16467b97STreehugger Robot // only things that have a context for a source name.
1089*16467b97STreehugger Robot //
1090*16467b97STreehugger Robot return ((pANTLR3_TOKEN_STREAM)(is->super))->tokenSource->fileName;
1091*16467b97STreehugger Robot }
1092