summaryrefslogtreecommitdiff
path: root/antlr/libantlr3c-3.4/src/antlr3tokenstream.c
diff options
context:
space:
mode:
Diffstat (limited to 'antlr/libantlr3c-3.4/src/antlr3tokenstream.c')
-rw-r--r--antlr/libantlr3c-3.4/src/antlr3tokenstream.c1091
1 files changed, 1091 insertions, 0 deletions
diff --git a/antlr/libantlr3c-3.4/src/antlr3tokenstream.c b/antlr/libantlr3c-3.4/src/antlr3tokenstream.c
new file mode 100644
index 0000000..ec06f15
--- /dev/null
+++ b/antlr/libantlr3c-3.4/src/antlr3tokenstream.c
@@ -0,0 +1,1091 @@
+/// \file
+/// Default implementation of CommonTokenStream
+///
+
+// [The "BSD licence"]
+// Copyright (c) 2005-2009 Jim Idle, Temporal Wave LLC
+// http://www.temporal-wave.com
+// http://www.linkedin.com/in/jimidle
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. The name of the author may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <antlr3tokenstream.h>
+
+#ifdef ANTLR3_WINDOWS
+#pragma warning( disable : 4100 )
+#endif
+
+// COMMON_TOKEN_STREAM API
+//
+static void setTokenTypeChannel (pANTLR3_COMMON_TOKEN_STREAM cts, ANTLR3_UINT32 ttype, ANTLR3_UINT32 channel);
+static void discardTokenType (pANTLR3_COMMON_TOKEN_STREAM cts, ANTLR3_INT32 ttype);
+static void discardOffChannel (pANTLR3_COMMON_TOKEN_STREAM cts, ANTLR3_BOOLEAN discard);
+static pANTLR3_VECTOR getTokens (pANTLR3_COMMON_TOKEN_STREAM cts);
+static pANTLR3_LIST getTokenRange (pANTLR3_COMMON_TOKEN_STREAM cts, ANTLR3_UINT32 start, ANTLR3_UINT32 stop);
+static pANTLR3_LIST getTokensSet (pANTLR3_COMMON_TOKEN_STREAM cts, ANTLR3_UINT32 start, ANTLR3_UINT32 stop, pANTLR3_BITSET types);
+static pANTLR3_LIST getTokensList (pANTLR3_COMMON_TOKEN_STREAM cts, ANTLR3_UINT32 start, ANTLR3_UINT32 stop, pANTLR3_LIST list);
+static pANTLR3_LIST getTokensType (pANTLR3_COMMON_TOKEN_STREAM cts, ANTLR3_UINT32 start, ANTLR3_UINT32 stop, ANTLR3_UINT32 type);
+static void reset (pANTLR3_COMMON_TOKEN_STREAM cts);
+
+// TOKEN_STREAM API
+//
+static pANTLR3_COMMON_TOKEN tokLT (pANTLR3_TOKEN_STREAM ts, ANTLR3_INT32 k);
+static pANTLR3_COMMON_TOKEN dbgTokLT (pANTLR3_TOKEN_STREAM ts, ANTLR3_INT32 k);
+static pANTLR3_COMMON_TOKEN get (pANTLR3_TOKEN_STREAM ts, ANTLR3_UINT32 i);
+static pANTLR3_TOKEN_SOURCE getTokenSource (pANTLR3_TOKEN_STREAM ts);
+static void setTokenSource (pANTLR3_TOKEN_STREAM ts, pANTLR3_TOKEN_SOURCE tokenSource);
+static pANTLR3_STRING toString (pANTLR3_TOKEN_STREAM ts);
+static pANTLR3_STRING toStringSS (pANTLR3_TOKEN_STREAM ts, ANTLR3_UINT32 start, ANTLR3_UINT32 stop);
+static pANTLR3_STRING toStringTT (pANTLR3_TOKEN_STREAM ts, pANTLR3_COMMON_TOKEN start, pANTLR3_COMMON_TOKEN stop);
+static void setDebugListener (pANTLR3_TOKEN_STREAM ts, pANTLR3_DEBUG_EVENT_LISTENER debugger);
+
+// INT STREAM API
+//
+static void consume (pANTLR3_INT_STREAM is);
+static void dbgConsume (pANTLR3_INT_STREAM is);
+static ANTLR3_UINT32 _LA (pANTLR3_INT_STREAM is, ANTLR3_INT32 i);
+static ANTLR3_UINT32 dbgLA (pANTLR3_INT_STREAM is, ANTLR3_INT32 i);
+static ANTLR3_MARKER mark (pANTLR3_INT_STREAM is);
+static ANTLR3_MARKER dbgMark (pANTLR3_INT_STREAM is);
+static void release (pANTLR3_INT_STREAM is, ANTLR3_MARKER mark);
+static ANTLR3_UINT32 size (pANTLR3_INT_STREAM is);
+static ANTLR3_MARKER tindex (pANTLR3_INT_STREAM is);
+static void rewindStream (pANTLR3_INT_STREAM is, ANTLR3_MARKER marker);
+static void dbgRewindStream (pANTLR3_INT_STREAM is, ANTLR3_MARKER marker);
+static void rewindLast (pANTLR3_INT_STREAM is);
+static void dbgRewindLast (pANTLR3_INT_STREAM is);
+static void seek (pANTLR3_INT_STREAM is, ANTLR3_MARKER index);
+static void dbgSeek (pANTLR3_INT_STREAM is, ANTLR3_MARKER index);
+static pANTLR3_STRING getSourceName (pANTLR3_INT_STREAM is);
+static void antlr3TokenStreamFree (pANTLR3_TOKEN_STREAM stream);
+static void antlr3CTSFree (pANTLR3_COMMON_TOKEN_STREAM stream);
+
+// Helpers
+//
+static void fillBuffer (pANTLR3_COMMON_TOKEN_STREAM tokenStream);
+static ANTLR3_UINT32 skipOffTokenChannels (pANTLR3_COMMON_TOKEN_STREAM tokenStream, ANTLR3_INT32 i);
+static ANTLR3_UINT32 skipOffTokenChannelsReverse (pANTLR3_COMMON_TOKEN_STREAM tokenStream, ANTLR3_INT32 i);
+static pANTLR3_COMMON_TOKEN LB (pANTLR3_COMMON_TOKEN_STREAM tokenStream, ANTLR3_INT32 i);
+
+ANTLR3_API pANTLR3_TOKEN_STREAM
+antlr3TokenStreamNew()
+{
+ pANTLR3_TOKEN_STREAM stream;
+
+ // Memory for the interface structure
+ //
+ stream = (pANTLR3_TOKEN_STREAM) ANTLR3_MALLOC(sizeof(ANTLR3_TOKEN_STREAM));
+
+ if (stream == NULL)
+ {
+ return NULL;
+ }
+
+ // Install basic API
+ //
+ stream->free = antlr3TokenStreamFree;
+
+
+ return stream;
+}
+
+static void
+antlr3TokenStreamFree(pANTLR3_TOKEN_STREAM stream)
+{
+ ANTLR3_FREE(stream);
+}
+
+static void
+antlr3CTSFree (pANTLR3_COMMON_TOKEN_STREAM stream)
+{
+ // We only free up our subordinate interfaces if they belong
+ // to us, otherwise we let whoever owns them deal with them.
+ //
+ if (stream->tstream->super == stream)
+ {
+ if (stream->tstream->istream->super == stream->tstream)
+ {
+ stream->tstream->istream->free(stream->tstream->istream);
+ stream->tstream->istream = NULL;
+ }
+ stream->tstream->free(stream->tstream);
+ }
+
+ // Now we free our own resources
+ //
+ if (stream->tokens != NULL)
+ {
+ stream->tokens->free(stream->tokens);
+ stream->tokens = NULL;
+ }
+ if (stream->discardSet != NULL)
+ {
+ stream->discardSet->free(stream->discardSet);
+ stream->discardSet = NULL;
+ }
+ if (stream->channelOverrides != NULL)
+ {
+ stream->channelOverrides->free(stream->channelOverrides);
+ stream->channelOverrides = NULL;
+ }
+
+ // Free our memory now
+ //
+ ANTLR3_FREE(stream);
+}
+
+// Reset a token stream so it can be used again and can reuse it's
+// resources.
+//
+static void
+reset (pANTLR3_COMMON_TOKEN_STREAM cts)
+{
+
+ // Free any resources that ar most like specifc to the
+ // run we just did.
+ //
+ if (cts->discardSet != NULL)
+ {
+ cts->discardSet->free(cts->discardSet);
+ cts->discardSet = NULL;
+ }
+ if (cts->channelOverrides != NULL)
+ {
+ cts->channelOverrides->free(cts->channelOverrides);
+ cts->channelOverrides = NULL;
+ }
+
+ // Now, if there were any existing tokens in the stream,
+ // then we just reset the vector count so that it starts
+ // again. We must traverse the entries unfortunately as
+ // there may be free pointers for custom token types and
+ // so on. However that is just a quick NULL check on the
+ // vector entries.
+ //
+ if (cts->tokens != NULL)
+ {
+ cts->tokens->clear(cts->tokens);
+ }
+ else
+ {
+ /* Install the token tracking tables
+ */
+ cts->tokens = antlr3VectorNew(0);
+ }
+
+ // Reset to defaults
+ //
+ cts->discardOffChannel = ANTLR3_FALSE;
+ cts->channel = ANTLR3_TOKEN_DEFAULT_CHANNEL;
+ cts->p = -1;
+}
+
+ANTLR3_API pANTLR3_COMMON_TOKEN_STREAM
+antlr3CommonTokenDebugStreamSourceNew(ANTLR3_UINT32 hint, pANTLR3_TOKEN_SOURCE source, pANTLR3_DEBUG_EVENT_LISTENER debugger)
+{
+ pANTLR3_COMMON_TOKEN_STREAM stream;
+
+ // Create a standard token stream
+ //
+ stream = antlr3CommonTokenStreamSourceNew(hint, source);
+
+ // Install the debugger object
+ //
+ stream->tstream->debugger = debugger;
+
+ // Override standard token stream methods with debugging versions
+ //
+ stream->tstream->initialStreamState = ANTLR3_FALSE;
+
+ stream->tstream->_LT = dbgTokLT;
+
+ stream->tstream->istream->consume = dbgConsume;
+ stream->tstream->istream->_LA = dbgLA;
+ stream->tstream->istream->mark = dbgMark;
+ stream->tstream->istream->rewind = dbgRewindStream;
+ stream->tstream->istream->rewindLast = dbgRewindLast;
+ stream->tstream->istream->seek = dbgSeek;
+
+ return stream;
+}
+
+ANTLR3_API pANTLR3_COMMON_TOKEN_STREAM
+antlr3CommonTokenStreamSourceNew(ANTLR3_UINT32 hint, pANTLR3_TOKEN_SOURCE source)
+{
+ pANTLR3_COMMON_TOKEN_STREAM stream;
+
+ stream = antlr3CommonTokenStreamNew(hint);
+
+ stream->channel = ANTLR3_TOKEN_DEFAULT_CHANNEL;
+
+ stream->channelOverrides = NULL;
+ stream->discardSet = NULL;
+ stream->discardOffChannel = ANTLR3_FALSE;
+
+ stream->tstream->setTokenSource(stream->tstream, source);
+
+ stream->free = antlr3CTSFree;
+ return stream;
+}
+
+ANTLR3_API pANTLR3_COMMON_TOKEN_STREAM
+antlr3CommonTokenStreamNew(ANTLR3_UINT32 hint)
+{
+ pANTLR3_COMMON_TOKEN_STREAM stream;
+
+ /* Memory for the interface structure
+ */
+ stream = (pANTLR3_COMMON_TOKEN_STREAM) ANTLR3_MALLOC(sizeof(ANTLR3_COMMON_TOKEN_STREAM));
+
+ if (stream == NULL)
+ {
+ return NULL;
+ }
+
+ /* Create space for the token stream interface
+ */
+ stream->tstream = antlr3TokenStreamNew();
+ stream->tstream->super = stream;
+
+ /* Create space for the INT_STREAM interfacce
+ */
+ stream->tstream->istream = antlr3IntStreamNew();
+ stream->tstream->istream->super = (stream->tstream);
+ stream->tstream->istream->type = ANTLR3_TOKENSTREAM;
+
+ /* Install the token tracking tables
+ */
+ stream->tokens = antlr3VectorNew(0);
+
+ /* Defaults
+ */
+ stream->p = -1;
+
+ /* Install the common token stream API
+ */
+ stream->setTokenTypeChannel = setTokenTypeChannel;
+ stream->discardTokenType = discardTokenType;
+ stream->discardOffChannelToks = discardOffChannel;
+ stream->getTokens = getTokens;
+ stream->getTokenRange = getTokenRange;
+ stream->getTokensSet = getTokensSet;
+ stream->getTokensList = getTokensList;
+ stream->getTokensType = getTokensType;
+ stream->reset = reset;
+
+ /* Install the token stream API
+ */
+ stream->tstream->_LT = tokLT;
+ stream->tstream->get = get;
+ stream->tstream->getTokenSource = getTokenSource;
+ stream->tstream->setTokenSource = setTokenSource;
+ stream->tstream->toString = toString;
+ stream->tstream->toStringSS = toStringSS;
+ stream->tstream->toStringTT = toStringTT;
+ stream->tstream->setDebugListener = setDebugListener;
+
+ /* Install INT_STREAM interface
+ */
+ stream->tstream->istream->_LA = _LA;
+ stream->tstream->istream->mark = mark;
+ stream->tstream->istream->release = release;
+ stream->tstream->istream->size = size;
+ stream->tstream->istream->index = tindex;
+ stream->tstream->istream->rewind = rewindStream;
+ stream->tstream->istream->rewindLast= rewindLast;
+ stream->tstream->istream->seek = seek;
+ stream->tstream->istream->consume = consume;
+ stream->tstream->istream->getSourceName = getSourceName;
+
+ return stream;
+}
+
+// Install a debug listener adn switch to debug mode methods
+//
+static void
+setDebugListener (pANTLR3_TOKEN_STREAM ts, pANTLR3_DEBUG_EVENT_LISTENER debugger)
+{
+ // Install the debugger object
+ //
+ ts->debugger = debugger;
+
+ // Override standard token stream methods with debugging versions
+ //
+ ts->initialStreamState = ANTLR3_FALSE;
+
+ ts->_LT = dbgTokLT;
+
+ ts->istream->consume = dbgConsume;
+ ts->istream->_LA = dbgLA;
+ ts->istream->mark = dbgMark;
+ ts->istream->rewind = dbgRewindStream;
+ ts->istream->rewindLast = dbgRewindLast;
+ ts->istream->seek = dbgSeek;
+}
+
+/** Get the ith token from the current position 1..n where k=1 is the
+* first symbol of lookahead.
+*/
+static pANTLR3_COMMON_TOKEN
+tokLT (pANTLR3_TOKEN_STREAM ts, ANTLR3_INT32 k)
+{
+ ANTLR3_INT32 i;
+ ANTLR3_INT32 n;
+ pANTLR3_COMMON_TOKEN_STREAM cts;
+
+ cts = (pANTLR3_COMMON_TOKEN_STREAM)ts->super;
+
+ if (k < 0)
+ {
+ return LB(cts, -k);
+ }
+
+ if (cts->p == -1)
+ {
+ fillBuffer(cts);
+ }
+
+ // Here we used to check for k == 0 and return 0, but this seems
+ // a superfluous check to me. LT(k=0) is therefore just undefined
+ // and we won't waste the clock cycles on the check
+ //
+
+ if ((cts->p + k - 1) >= (ANTLR3_INT32)ts->istream->cachedSize)
+ {
+ pANTLR3_COMMON_TOKEN teof = &(ts->tokenSource->eofToken);
+
+ teof->setStartIndex (teof, ts->istream->index (ts->istream));
+ teof->setStopIndex (teof, ts->istream->index (ts->istream));
+ return teof;
+ }
+
+ i = cts->p;
+ n = 1;
+
+ /* Need to find k good tokens, skipping ones that are off channel
+ */
+ while ( n < k)
+ {
+ /* Skip off-channel tokens */
+ i = skipOffTokenChannels(cts, i+1); /* leave p on valid token */
+ n++;
+ }
+ if ( (ANTLR3_UINT32) i >= ts->istream->cachedSize)
+ {
+ pANTLR3_COMMON_TOKEN teof = &(ts->tokenSource->eofToken);
+
+ teof->setStartIndex (teof, ts->istream->index(ts->istream));
+ teof->setStopIndex (teof, ts->istream->index(ts->istream));
+ return teof;
+ }
+
+ // Here the token must be in the input vector. Rather then incur
+ // function call penalty, we just return the pointer directly
+ // from the vector
+ //
+ return (pANTLR3_COMMON_TOKEN)cts->tokens->elements[i].element;
+ //return (pANTLR3_COMMON_TOKEN)cts->tokens->get(cts->tokens, i);
+}
+
+/// Debug only method to flag consumption of initial off-channel
+/// tokens in the input stream
+///
+static void
+consumeInitialHiddenTokens(pANTLR3_INT_STREAM is)
+{
+ ANTLR3_MARKER first;
+ ANTLR3_INT32 i;
+ pANTLR3_TOKEN_STREAM ts;
+
+ ts = (pANTLR3_TOKEN_STREAM) is->super;
+ first = is->index(is);
+
+ for (i=0; i<first; i++)
+ {
+ ts->debugger->consumeHiddenToken(ts->debugger, ts->get(ts, i));
+ }
+
+ ts->initialStreamState = ANTLR3_FALSE;
+
+}
+
+/// As per the normal tokLT but sends information to the debugger
+///
+static pANTLR3_COMMON_TOKEN
+dbgTokLT (pANTLR3_TOKEN_STREAM ts, ANTLR3_INT32 k)
+{
+ if (ts->initialStreamState == ANTLR3_TRUE)
+ {
+ consumeInitialHiddenTokens(ts->istream);
+ }
+ return tokLT(ts, k);
+}
+
+#ifdef ANTLR3_WINDOWS
+ /* When fully optimized VC7 complains about non reachable code.
+ * Not yet sure if this is an optimizer bug, or a bug in the flow analysis
+ */
+#pragma warning( disable : 4702 )
+#endif
+
+static pANTLR3_COMMON_TOKEN
+LB(pANTLR3_COMMON_TOKEN_STREAM cts, ANTLR3_INT32 k)
+{
+ ANTLR3_INT32 i;
+ ANTLR3_INT32 n;
+
+ if (cts->p == -1)
+ {
+ fillBuffer(cts);
+ }
+ if (k == 0)
+ {
+ return NULL;
+ }
+ if ((cts->p - k) < 0)
+ {
+ return NULL;
+ }
+
+ i = cts->p;
+ n = 1;
+
+ /* Need to find k good tokens, going backwards, skipping ones that are off channel
+ */
+ while (n <= (ANTLR3_INT32) k)
+ {
+ /* Skip off-channel tokens
+ */
+
+ i = skipOffTokenChannelsReverse(cts, i - 1); /* leave p on valid token */
+ n++;
+ }
+ if (i < 0)
+ {
+ return NULL;
+ }
+ // Here the token must be in the input vector. Rather then incut
+ // function call penalty, we jsut return the pointer directly
+ // from the vector
+ //
+ return (pANTLR3_COMMON_TOKEN)cts->tokens->elements[i].element;
+}
+
+static pANTLR3_COMMON_TOKEN
+get (pANTLR3_TOKEN_STREAM ts, ANTLR3_UINT32 i)
+{
+ pANTLR3_COMMON_TOKEN_STREAM cts;
+
+ cts = (pANTLR3_COMMON_TOKEN_STREAM)ts->super;
+
+ return (pANTLR3_COMMON_TOKEN)(cts->tokens->get(cts->tokens, i)); /* Token index is zero based but vectors are 1 based */
+}
+
+static pANTLR3_TOKEN_SOURCE
+getTokenSource (pANTLR3_TOKEN_STREAM ts)
+{
+ return ts->tokenSource;
+}
+
+static void
+setTokenSource ( pANTLR3_TOKEN_STREAM ts,
+ pANTLR3_TOKEN_SOURCE tokenSource)
+{
+ ts->tokenSource = tokenSource;
+}
+
+static pANTLR3_STRING
+toString (pANTLR3_TOKEN_STREAM ts)
+{
+ pANTLR3_COMMON_TOKEN_STREAM cts;
+
+ cts = (pANTLR3_COMMON_TOKEN_STREAM)ts->super;
+
+ if (cts->p == -1)
+ {
+ fillBuffer(cts);
+ }
+
+ return ts->toStringSS(ts, 0, ts->istream->size(ts->istream));
+}
+
+static pANTLR3_STRING
+toStringSS(pANTLR3_TOKEN_STREAM ts, ANTLR3_UINT32 start, ANTLR3_UINT32 stop)
+{
+ pANTLR3_STRING string;
+ pANTLR3_TOKEN_SOURCE tsource;
+ pANTLR3_COMMON_TOKEN tok;
+ ANTLR3_UINT32 i;
+ pANTLR3_COMMON_TOKEN_STREAM cts;
+
+ cts = (pANTLR3_COMMON_TOKEN_STREAM) ts->super;
+
+ if (cts->p == -1)
+ {
+ fillBuffer(cts);
+ }
+ if (stop >= ts->istream->size(ts->istream))
+ {
+ stop = ts->istream->size(ts->istream) - 1;
+ }
+
+ /* Who is giving us these tokens?
+ */
+ tsource = ts->getTokenSource(ts);
+
+ if (tsource != NULL && cts->tokens != NULL)
+ {
+ /* Finally, let's get a string
+ */
+ string = tsource->strFactory->newRaw(tsource->strFactory);
+
+ for (i = start; i <= stop; i++)
+ {
+ tok = ts->get(ts, i);
+ if (tok != NULL)
+ {
+ string->appendS(string, tok->getText(tok));
+ }
+ }
+
+ return string;
+ }
+ return NULL;
+
+}
+
+static pANTLR3_STRING
+toStringTT (pANTLR3_TOKEN_STREAM ts, pANTLR3_COMMON_TOKEN start, pANTLR3_COMMON_TOKEN stop)
+{
+ if (start != NULL && stop != NULL)
+ {
+ return ts->toStringSS(ts, (ANTLR3_UINT32)start->getTokenIndex(start), (ANTLR3_UINT32)stop->getTokenIndex(stop));
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+/** Move the input pointer to the next incoming token. The stream
+ * must become active with LT(1) available. consume() simply
+ * moves the input pointer so that LT(1) points at the next
+ * input symbol. Consume at least one token.
+ *
+ * Walk past any token not on the channel the parser is listening to.
+ */
+static void
+consume (pANTLR3_INT_STREAM is)
+{
+ pANTLR3_COMMON_TOKEN_STREAM cts;
+ pANTLR3_TOKEN_STREAM ts;
+
+ ts = (pANTLR3_TOKEN_STREAM) is->super;
+ cts = (pANTLR3_COMMON_TOKEN_STREAM) ts->super;
+
+ if ((ANTLR3_UINT32)cts->p < cts->tokens->count)
+ {
+ cts->p++;
+ cts->p = skipOffTokenChannels(cts, cts->p);
+ }
+}
+
+
+/// As per ordinary consume but notifies the debugger about hidden
+/// tokens and so on.
+///
+static void
+dbgConsume (pANTLR3_INT_STREAM is)
+{
+ pANTLR3_TOKEN_STREAM ts;
+ ANTLR3_MARKER a;
+ ANTLR3_MARKER b;
+ pANTLR3_COMMON_TOKEN t;
+
+ ts = (pANTLR3_TOKEN_STREAM) is->super;
+
+ if (ts->initialStreamState == ANTLR3_TRUE)
+ {
+ consumeInitialHiddenTokens(is);
+ }
+
+ a = is->index(is); // Where are we right now?
+ t = ts->_LT(ts, 1); // Current token from stream
+
+ consume(is); // Standard consumer
+
+ b = is->index(is); // Where are we after consuming 1 on channel token?
+
+ ts->debugger->consumeToken(ts->debugger, t); // Tell the debugger that we consumed the first token
+
+ if (b>a+1)
+ {
+ // The standard consume caused the index to advance by more than 1,
+ // which can only happen if it skipped some off-channel tokens.
+ // we need to tell the debugger about those tokens.
+ //
+ ANTLR3_MARKER i;
+
+ for (i = a+1; i<b; i++)
+ {
+ ts->debugger->consumeHiddenToken(ts->debugger, ts->get(ts, (ANTLR3_UINT32)i));
+ }
+
+ }
+}
+
+/** A simple filter mechanism whereby you can tell this token stream
+ * to force all tokens of type ttype to be on channel. For example,
+ * when interpreting, we cannot execute actions so we need to tell
+ * the stream to force all WS and NEWLINE to be a different, ignored,
+ * channel.
+ */
+static void
+setTokenTypeChannel (pANTLR3_COMMON_TOKEN_STREAM tokenStream, ANTLR3_UINT32 ttype, ANTLR3_UINT32 channel)
+{
+ if (tokenStream->channelOverrides == NULL)
+ {
+ tokenStream->channelOverrides = antlr3ListNew(10);
+ }
+
+ /* We add one to the channel so we can distinguish NULL as being no entry in the
+ * table for a particular token type.
+ */
+ tokenStream->channelOverrides->put(tokenStream->channelOverrides, ttype, ANTLR3_FUNC_PTR((ANTLR3_UINT32)channel + 1), NULL);
+}
+
+static void
+discardTokenType (pANTLR3_COMMON_TOKEN_STREAM tokenStream, ANTLR3_INT32 ttype)
+{
+ if (tokenStream->discardSet == NULL)
+ {
+ tokenStream->discardSet = antlr3ListNew(31);
+ }
+
+ /* We add one to the channel so we can distinguish NULL as being no entry in the
+ * table for a particular token type. We could use bitsets for this I suppose too.
+ */
+ tokenStream->discardSet->put(tokenStream->discardSet, ttype, ANTLR3_FUNC_PTR((ANTLR3_UINT32)ttype + 1), NULL);
+}
+
+static void
+discardOffChannel (pANTLR3_COMMON_TOKEN_STREAM tokenStream, ANTLR3_BOOLEAN discard)
+{
+ tokenStream->discardOffChannel = discard;
+}
+
+static pANTLR3_VECTOR
+getTokens (pANTLR3_COMMON_TOKEN_STREAM tokenStream)
+{
+ if (tokenStream->p == -1)
+ {
+ fillBuffer(tokenStream);
+ }
+
+ return tokenStream->tokens;
+}
+
+static pANTLR3_LIST
+getTokenRange (pANTLR3_COMMON_TOKEN_STREAM tokenStream, ANTLR3_UINT32 start, ANTLR3_UINT32 stop)
+{
+ return tokenStream->getTokensSet(tokenStream, start, stop, NULL);
+}
+/** Given a start and stop index, return a List of all tokens in
+ * the token type BitSet. Return null if no tokens were found. This
+ * method looks at both on and off channel tokens.
+ */
+static pANTLR3_LIST
+getTokensSet (pANTLR3_COMMON_TOKEN_STREAM tokenStream, ANTLR3_UINT32 start, ANTLR3_UINT32 stop, pANTLR3_BITSET types)
+{
+ pANTLR3_LIST filteredList;
+ ANTLR3_UINT32 i;
+ ANTLR3_UINT32 n;
+ pANTLR3_COMMON_TOKEN tok;
+
+ if (tokenStream->p == -1)
+ {
+ fillBuffer(tokenStream);
+ }
+ if (stop > tokenStream->tstream->istream->size(tokenStream->tstream->istream))
+ {
+ stop = tokenStream->tstream->istream->size(tokenStream->tstream->istream);
+ }
+ if (start > stop)
+ {
+ return NULL;
+ }
+
+ /* We have the range set, now we need to iterate through the
+ * installed tokens and create a new list with just the ones we want
+ * in it. We are just moving pointers about really.
+ */
+ filteredList = antlr3ListNew((ANTLR3_UINT32)tokenStream->tstream->istream->size(tokenStream->tstream->istream));
+
+ for (i = start, n = 0; i<= stop; i++)
+ {
+ tok = tokenStream->tstream->get(tokenStream->tstream, i);
+
+ if ( types == NULL
+ || types->isMember(types, tok->getType(tok) == ANTLR3_TRUE)
+ )
+ {
+ filteredList->put(filteredList, n++, (void *)tok, NULL);
+ }
+ }
+
+ /* Did we get any then?
+ */
+ if (filteredList->size(filteredList) == 0)
+ {
+ filteredList->free(filteredList);
+ filteredList = NULL;
+ }
+
+ return filteredList;
+}
+
+static pANTLR3_LIST
+getTokensList (pANTLR3_COMMON_TOKEN_STREAM tokenStream, ANTLR3_UINT32 start, ANTLR3_UINT32 stop, pANTLR3_LIST list)
+{
+ pANTLR3_BITSET bitSet;
+ pANTLR3_LIST newlist;
+
+ bitSet = antlr3BitsetList(list->table);
+
+ newlist = tokenStream->getTokensSet(tokenStream, start, stop, bitSet);
+
+ bitSet->free(bitSet);
+
+ return newlist;
+
+}
+
+static pANTLR3_LIST
+getTokensType (pANTLR3_COMMON_TOKEN_STREAM tokenStream, ANTLR3_UINT32 start, ANTLR3_UINT32 stop, ANTLR3_UINT32 type)
+{
+ pANTLR3_BITSET bitSet;
+ pANTLR3_LIST newlist;
+
+ bitSet = antlr3BitsetOf(type, -1);
+ newlist = tokenStream->getTokensSet(tokenStream, start, stop, bitSet);
+
+ bitSet->free(bitSet);
+
+ return newlist;
+}
+
+static ANTLR3_UINT32
+_LA (pANTLR3_INT_STREAM is, ANTLR3_INT32 i)
+{
+ pANTLR3_TOKEN_STREAM ts;
+ pANTLR3_COMMON_TOKEN tok;
+
+ ts = (pANTLR3_TOKEN_STREAM) is->super;
+
+ tok = ts->_LT(ts, i);
+
+ if (tok != NULL)
+ {
+ return tok->getType(tok);
+ }
+ else
+ {
+ return ANTLR3_TOKEN_INVALID;
+ }
+}
+
+/// As per _LA() but for debug mode.
+///
+static ANTLR3_UINT32
+dbgLA (pANTLR3_INT_STREAM is, ANTLR3_INT32 i)
+{
+ pANTLR3_TOKEN_STREAM ts;
+
+ ts = (pANTLR3_TOKEN_STREAM) is->super;
+
+ if (ts->initialStreamState == ANTLR3_TRUE)
+ {
+ consumeInitialHiddenTokens(is);
+ }
+ ts->debugger->LT(ts->debugger, i, tokLT(ts, i));
+ return _LA(is, i);
+}
+
+static ANTLR3_MARKER
+mark (pANTLR3_INT_STREAM is)
+{
+ is->lastMarker = is->index(is);
+ return is->lastMarker;
+}
+
+/// As per mark() but with a call to tell the debugger we are doing this
+///
+static ANTLR3_MARKER
+dbgMark (pANTLR3_INT_STREAM is)
+{
+ pANTLR3_TOKEN_STREAM ts;
+
+ ts = (pANTLR3_TOKEN_STREAM) is->super;
+
+ is->lastMarker = is->index(is);
+ ts->debugger->mark(ts->debugger, is->lastMarker);
+
+ return is->lastMarker;
+}
+
+static void
+release (pANTLR3_INT_STREAM is, ANTLR3_MARKER mark)
+{
+ return;
+}
+
+static ANTLR3_UINT32
+size (pANTLR3_INT_STREAM is)
+{
+ pANTLR3_COMMON_TOKEN_STREAM cts;
+ pANTLR3_TOKEN_STREAM ts;
+
+ if (is->cachedSize > 0)
+ {
+ return is->cachedSize;
+ }
+ ts = (pANTLR3_TOKEN_STREAM) is->super;
+ cts = (pANTLR3_COMMON_TOKEN_STREAM) ts->super;
+
+ is->cachedSize = cts->tokens->count;
+ return is->cachedSize;
+}
+
+static ANTLR3_MARKER
+tindex (pANTLR3_INT_STREAM is)
+{
+ pANTLR3_COMMON_TOKEN_STREAM cts;
+ pANTLR3_TOKEN_STREAM ts;
+
+ ts = (pANTLR3_TOKEN_STREAM) is->super;
+ cts = (pANTLR3_COMMON_TOKEN_STREAM) ts->super;
+
+ return cts->p;
+}
+
+static void
+dbgRewindLast (pANTLR3_INT_STREAM is)
+{
+ pANTLR3_TOKEN_STREAM ts;
+
+ ts = (pANTLR3_TOKEN_STREAM) is->super;
+
+ ts->debugger->rewindLast(ts->debugger);
+
+ is->rewind(is, is->lastMarker);
+}
+static void
+rewindLast (pANTLR3_INT_STREAM is)
+{
+ is->rewind(is, is->lastMarker);
+}
+static void
+rewindStream (pANTLR3_INT_STREAM is, ANTLR3_MARKER marker)
+{
+ is->seek(is, (ANTLR3_UINT32)(marker));
+}
+static void
+dbgRewindStream (pANTLR3_INT_STREAM is, ANTLR3_MARKER marker)
+{
+ pANTLR3_TOKEN_STREAM ts;
+
+ ts = (pANTLR3_TOKEN_STREAM) is->super;
+
+ ts->debugger->rewind(ts->debugger, marker);
+
+ is->seek(is, (ANTLR3_UINT32)(marker));
+}
+
+static void
+seek (pANTLR3_INT_STREAM is, ANTLR3_MARKER index)
+{
+ pANTLR3_COMMON_TOKEN_STREAM cts;
+ pANTLR3_TOKEN_STREAM ts;
+
+ ts = (pANTLR3_TOKEN_STREAM) is->super;
+ cts = (pANTLR3_COMMON_TOKEN_STREAM) ts->super;
+
+ cts->p = (ANTLR3_UINT32)index;
+}
+static void
+dbgSeek (pANTLR3_INT_STREAM is, ANTLR3_MARKER index)
+{
+ // TODO: Implement seek in debugger when Ter adds it to Java
+ //
+ seek(is, index);
+}
+ANTLR3_API void
+fillBufferExt(pANTLR3_COMMON_TOKEN_STREAM tokenStream)
+{
+ fillBuffer(tokenStream);
+}
+static void
+fillBuffer(pANTLR3_COMMON_TOKEN_STREAM tokenStream) {
+ ANTLR3_UINT32 index;
+ pANTLR3_COMMON_TOKEN tok;
+ ANTLR3_BOOLEAN discard;
+ void * channelI;
+
+ /* Start at index 0 of course
+ */
+ index = 0;
+
+ /* Pick out the next token from the token source
+ * Remember we just get a pointer (reference if you like) here
+ * and so if we store it anywhere, we don't set any pointers to auto free it.
+ */
+ tok = tokenStream->tstream->tokenSource->nextToken(tokenStream->tstream->tokenSource);
+
+ while (tok != NULL && tok->type != ANTLR3_TOKEN_EOF)
+ {
+ discard = ANTLR3_FALSE; /* Assume we are not discarding */
+
+ /* I employ a bit of a trick, or perhaps hack here. Rather than
+ * store a pointer to a structure in the override map and discard set
+ * we store the value + 1 cast to a void *. Hence on systems where NULL = (void *)0
+ * we can distinguish "not being there" from "being channel or type 0"
+ */
+
+ if (tokenStream->discardSet != NULL
+ && tokenStream->discardSet->get(tokenStream->discardSet, tok->getType(tok)) != NULL)
+ {
+ discard = ANTLR3_TRUE;
+ }
+ else if ( tokenStream->discardOffChannel == ANTLR3_TRUE
+ && tok->getChannel(tok) != tokenStream->channel
+ )
+ {
+ discard = ANTLR3_TRUE;
+ }
+ else if (tokenStream->channelOverrides != NULL)
+ {
+ /* See if this type is in the override map
+ */
+ channelI = tokenStream->channelOverrides->get(tokenStream->channelOverrides, tok->getType(tok) + 1);
+
+ if (channelI != NULL)
+ {
+ /* Override found
+ */
+ tok->setChannel(tok, ANTLR3_UINT32_CAST(channelI) - 1);
+ }
+ }
+
+ /* If not discarding it, add it to the list at the current index
+ */
+ if (discard == ANTLR3_FALSE)
+ {
+ /* Add it, indicating that we will delete it and the table should not
+ */
+ tok->setTokenIndex(tok, index);
+ tokenStream->p++;
+ tokenStream->tokens->add(tokenStream->tokens, (void *) tok, NULL);
+ index++;
+ }
+
+ tok = tokenStream->tstream->tokenSource->nextToken(tokenStream->tstream->tokenSource);
+ }
+
+ /* Cache the size so we don't keep doing indirect method calls. We do this as
+ * early as possible so that anything after this may utilize the cached value.
+ */
+ tokenStream->tstream->istream->cachedSize = tokenStream->tokens->count;
+
+ /* Set the consume pointer to the first token that is on our channel
+ */
+ tokenStream->p = 0;
+ tokenStream->p = skipOffTokenChannels(tokenStream, tokenStream->p);
+
+}
+
+/// Given a starting index, return the index of the first on-channel
+/// token.
+///
+static ANTLR3_UINT32
+skipOffTokenChannels(pANTLR3_COMMON_TOKEN_STREAM tokenStream, ANTLR3_INT32 i) {
+ ANTLR3_INT32 n;
+ pANTLR3_COMMON_TOKEN tok;
+
+ n = tokenStream->tstream->istream->cachedSize;
+
+ while (i < n)
+ {
+ tok = (pANTLR3_COMMON_TOKEN)tokenStream->tokens->elements[i].element;
+
+ if (tok->channel!= tokenStream->channel)
+ {
+ i++;
+ }
+ else
+ {
+ return i;
+ }
+ }
+ return i;
+}
+
+static ANTLR3_UINT32
+skipOffTokenChannelsReverse(pANTLR3_COMMON_TOKEN_STREAM tokenStream, ANTLR3_INT32 x)
+{
+ pANTLR3_COMMON_TOKEN tok;
+
+ while (x >= 0)
+ {
+ tok = (pANTLR3_COMMON_TOKEN)tokenStream->tokens->elements[x].element;
+
+ if ((tok->channel != tokenStream->channel))
+ {
+ x--;
+ }
+ else
+ {
+ return x;
+ }
+ }
+ return x;
+}
+
+/// Return a string that represents the name assoicated with the input source
+///
+/// /param[in] is The ANTLR3_INT_STREAM interface that is representing this token stream.
+///
+/// /returns
+/// /implements ANTLR3_INT_STREAM_struct::getSourceName()
+///
+static pANTLR3_STRING
+getSourceName (pANTLR3_INT_STREAM is)
+{
+ // Slightly convoluted as we must trace back to the lexer's input source
+ // via the token source. The streamName that is here is not initialized
+ // because this is a token stream, not a file or string stream, which are the
+ // only things that have a context for a source name.
+ //
+ return ((pANTLR3_TOKEN_STREAM)(is->super))->tokenSource->fileName;
+}