1324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/*
2324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * [The "BSD licence"]
3324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Copyright (c) 2005-2008 Terence Parr
4324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * All rights reserved.
5324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *
6324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Conversion to C#:
7324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Copyright (c) 2008-2009 Sam Harwell, Pixel Mine, Inc.
8324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * All rights reserved.
9324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *
10324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Redistribution and use in source and binary forms, with or without
11324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * modification, are permitted provided that the following conditions
12324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * are met:
13324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 1. Redistributions of source code must retain the above copyright
14324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *    notice, this list of conditions and the following disclaimer.
15324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 2. Redistributions in binary form must reproduce the above copyright
16324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *    notice, this list of conditions and the following disclaimer in the
17324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *    documentation and/or other materials provided with the distribution.
18324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 3. The name of the author may not be used to endorse or promote products
19324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *    derived from this software without specific prior written permission.
20324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *
21324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */
32324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
33324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvernamespace Antlr.Runtime
34324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{
35324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    using System.Collections.Generic;
36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    using InvalidOperationException = System.InvalidOperationException;
38324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    using StringBuilder = System.Text.StringBuilder;
39324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /** <summary>
41324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     *  The most common stream of tokens is one where every token is buffered up
42324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     *  and tokens are prefiltered for a certain channel (the parser will only
43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     *  see these tokens and cannot change the filter channel number during the
44324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     *  parse).
45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     *  </summary>
46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     *
47324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     *  <remarks>TODO: how to access the full token stream?  How to track all tokens matched per rule?</remarks>
48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    [System.Serializable]
50324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public class LegacyCommonTokenStream : ITokenStream
51324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    {
52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        [System.NonSerialized]
53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ITokenSource _tokenSource;
54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /** <summary>
56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  Record every single token pulled from the source so we can reproduce
57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  chunks of it later.
58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  </summary>
59324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         */
60324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        protected List<IToken> tokens;
61324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
62324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /** <summary>Map<tokentype, channel> to override some Tokens' channel numbers</summary> */
63324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        protected IDictionary<int, int> channelOverrideMap;
64324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
65324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /** <summary>Set<tokentype>; discard any tokens with this type</summary> */
66324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        protected List<int> discardSet;
67324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
68324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /** <summary>Skip tokens on any channel but this one; this is how we skip whitespace...</summary> */
69324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        protected int channel = TokenChannels.Default;
70324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
71324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /** <summary>By default, track all incoming tokens</summary> */
72324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        protected bool discardOffChannelTokens = false;
73324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
74324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /** <summary>Track the last mark() call result value for use in rewind().</summary> */
75324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        protected int lastMarker;
76324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
77324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /** <summary>
78324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  The index into the tokens list of the current token (next token
79324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  to consume).  p==-1 indicates that the tokens list is empty
80324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  </summary>
81324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         */
82324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        protected int p = -1;
83324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
84324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public LegacyCommonTokenStream()
85324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
86324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            tokens = new List<IToken>( 500 );
87324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
88324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
89324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public LegacyCommonTokenStream(ITokenSource tokenSource)
90324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            : this()
91324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
92324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            this._tokenSource = tokenSource;
93324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
94324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
95324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public LegacyCommonTokenStream( ITokenSource tokenSource, int channel )
96324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            : this( tokenSource )
97324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
98324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            this.channel = channel;
99324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public virtual int Index
102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            get
104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                return p;
106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /// <summary>
110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /// How deep have we gone?
111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /// </summary>
112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public virtual int Range
113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            get;
115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            protected set;
116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /** <summary>Reset this token stream by setting its token source.</summary> */
119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public virtual void SetTokenSource( ITokenSource tokenSource )
120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            this._tokenSource = tokenSource;
122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            tokens.Clear();
123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            p = -1;
124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            channel = TokenChannels.Default;
125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /** <summary>
128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  Load all tokens from the token source and put in tokens.
129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  This is done upon first LT request because you might want to
130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  set some token type / channel overrides before filling buffer.
131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  </summary>
132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         */
133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public virtual void FillBuffer()
134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            // fast return if the buffer is already full
136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if ( p != -1 )
137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                return;
138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            int index = 0;
140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            IToken t = _tokenSource.NextToken();
141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            while ( t != null && t.Type != CharStreamConstants.EndOfFile )
142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                bool discard = false;
144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                // is there a channel override for token type?
145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                int channelI;
146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                if ( channelOverrideMap != null && channelOverrideMap.TryGetValue( t.Type, out channelI ) )
147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    t.Channel = channelI;
148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                //if ( channelOverrideMap != null && channelOverrideMap.ContainsKey( t.getType() ) )
150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                //{
151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                //    object channelI = channelOverrideMap.get( t.getType() );
152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                //    if ( channelI != null )
153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                //    {
154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                //        t.setChannel( (int)channelI );
155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                //    }
156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                //}
157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                if ( discardSet != null &&
158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                     discardSet.Contains( t.Type ) )
159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                {
160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    discard = true;
161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                }
162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                else if ( discardOffChannelTokens && t.Channel != this.channel )
163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                {
164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    discard = true;
165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                }
166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                if ( !discard )
167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                {
168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    t.TokenIndex = index;
169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    tokens.Add( t );
170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    index++;
171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                }
172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                t = _tokenSource.NextToken();
173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            // leave p pointing at first token on channel
175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            p = 0;
176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            p = SkipOffTokenChannels( p );
177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /** <summary>
180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  Move the input pointer to the next incoming token.  The stream
181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  must become active with LT(1) available.  consume() simply
182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  moves the input pointer so that LT(1) points at the next
183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  input symbol. Consume at least one token.
184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  </summary>
185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *
186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  <remarks>
187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  Walk past any token not on the channel the parser is listening to.
188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  </remarks>
189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         */
190324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public virtual void Consume()
191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if ( p < tokens.Count )
193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                p++;
195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                p = SkipOffTokenChannels( p ); // leave p on valid token
196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
198324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /** <summary>Given a starting index, return the index of the first on-channel token.</summary> */
200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        protected virtual int SkipOffTokenChannels( int i )
201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            int n = tokens.Count;
203324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            while ( i < n && ( (IToken)tokens[i] ).Channel != channel )
204324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                i++;
206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return i;
208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        protected virtual int SkipOffTokenChannelsReverse( int i )
211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            while ( i >= 0 && ( (IToken)tokens[i] ).Channel != channel )
213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                i--;
215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return i;
217324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /** <summary>
220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  A simple filter mechanism whereby you can tell this token stream
221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  to force all tokens of type ttype to be on channel.  For example,
222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  when interpreting, we cannot exec actions so we need to tell
223324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  the stream to force all WS and NEWLINE to be a different, ignored
224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  channel.
225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  </summary>
226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         */
227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public virtual void SetTokenTypeChannel( int ttype, int channel )
228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if ( channelOverrideMap == null )
230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                channelOverrideMap = new Dictionary<int, int>();
232324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
233324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            channelOverrideMap[ttype] = channel;
234324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
235324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
236324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public virtual void DiscardTokenType( int ttype )
237324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
238324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if ( discardSet == null )
239324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
240324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                discardSet = new List<int>();
241324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
242324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            discardSet.Add( ttype );
243324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
244324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
245324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public virtual void SetDiscardOffChannelTokens( bool discardOffChannelTokens )
246324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
247324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            this.discardOffChannelTokens = discardOffChannelTokens;
248324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
249324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
250324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public virtual IList<IToken> GetTokens()
251324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
252324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if ( p == -1 )
253324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
254324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                FillBuffer();
255324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
256324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return tokens;
257324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
258324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
259324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public virtual IList<IToken> GetTokens( int start, int stop )
260324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
261324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return GetTokens( start, stop, (BitSet)null );
262324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
263324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
264324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /** <summary>
265324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  Given a start and stop index, return a List of all tokens in
266324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  the token type BitSet.  Return null if no tokens were found.  This
267324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  method looks at both on and off channel tokens.
268324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  </summary>
269324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         */
270324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public virtual IList<IToken> GetTokens( int start, int stop, BitSet types )
271324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
272324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if ( p == -1 )
273324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
274324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                FillBuffer();
275324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
276324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if ( stop >= tokens.Count )
277324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
278324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                stop = tokens.Count - 1;
279324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
280324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if ( start < 0 )
281324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
282324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                start = 0;
283324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
284324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if ( start > stop )
285324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
286324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                return null;
287324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
288324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
289324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            // list = tokens[start:stop]:{Token t, t.getType() in types}
290324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            IList<IToken> filteredTokens = new List<IToken>();
291324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            for ( int i = start; i <= stop; i++ )
292324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
293324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                IToken t = tokens[i];
294324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                if ( types == null || types.Member( t.Type ) )
295324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                {
296324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    filteredTokens.Add( t );
297324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                }
298324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
299324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if ( filteredTokens.Count == 0 )
300324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
301324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                filteredTokens = null;
302324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
303324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return filteredTokens;
304324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
305324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
306324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public virtual IList<IToken> GetTokens( int start, int stop, IList<int> types )
307324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
308324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return GetTokens( start, stop, new BitSet( types ) );
309324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
310324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
311324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public virtual IList<IToken> GetTokens( int start, int stop, int ttype )
312324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
313324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return GetTokens( start, stop, BitSet.Of( ttype ) );
314324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
315324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
316324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /** <summary>
317324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  Get the ith token from the current position 1..n where k=1 is the
318324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  first symbol of lookahead.
319324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  </summary>
320324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         */
321324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public virtual IToken LT( int k )
322324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
323324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if ( p == -1 )
324324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
325324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                FillBuffer();
326324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
327324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if ( k == 0 )
328324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
329324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                return null;
330324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
331324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if ( k < 0 )
332324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
333324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                return LB( -k );
334324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
335324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //System.out.print("LT(p="+p+","+k+")=");
336324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if ( ( p + k - 1 ) >= tokens.Count )
337324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
338324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                return tokens[tokens.Count - 1];
339324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
340324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //System.out.println(tokens.get(p+k-1));
341324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            int i = p;
342324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            int n = 1;
343324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            // find k good tokens
344324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            while ( n < k )
345324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
346324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                // skip off-channel tokens
347324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                i = SkipOffTokenChannels( i + 1 ); // leave p on valid token
348324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                n++;
349324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
350324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if ( i >= tokens.Count )
351324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
352324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                return tokens[tokens.Count - 1];
353324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
354324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
355324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if (i > Range)
356324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                Range = i;
357324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
358324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return (IToken)tokens[i];
359324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
360324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
361324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /** <summary>Look backwards k tokens on-channel tokens</summary> */
362324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        protected virtual IToken LB( int k )
363324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
364324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //System.out.print("LB(p="+p+","+k+") ");
365324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if ( p == -1 )
366324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
367324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                FillBuffer();
368324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
369324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if ( k == 0 )
370324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
371324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                return null;
372324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
373324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if ( ( p - k ) < 0 )
374324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
375324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                return null;
376324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
377324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
378324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            int i = p;
379324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            int n = 1;
380324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            // find k good tokens looking backwards
381324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            while ( n <= k )
382324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
383324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                // skip off-channel tokens
384324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                i = SkipOffTokenChannelsReverse( i - 1 ); // leave p on valid token
385324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                n++;
386324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
387324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if ( i < 0 )
388324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
389324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                return null;
390324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
391324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return (IToken)tokens[i];
392324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
393324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
394324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /** <summary>
395324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  Return absolute token i; ignore which channel the tokens are on;
396324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  that is, count all tokens not just on-channel tokens.
397324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  </summary>
398324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         */
399324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public virtual IToken Get( int i )
400324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
401324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return (IToken)tokens[i];
402324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
403324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
404324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#if false
405324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /** Get all tokens from start..stop inclusively */
406324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public virtual List<IToken> Get(int start, int count)
407324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
408324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if (start < 0)
409324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                throw new ArgumentOutOfRangeException("start");
410324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if (count < 0)
411324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                throw new ArgumentOutOfRangeException("count");
412324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
413324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if (p == -1)
414324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                FillBuffer();
415324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
416324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return new List<IToken>(tokens.Skip(start).Take(count));
417324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
418324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#endif
419324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
420324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public virtual int LA( int i )
421324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
422324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return LT( i ).Type;
423324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
424324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
425324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public virtual int Mark()
426324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
427324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if ( p == -1 )
428324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
429324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                FillBuffer();
430324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
431324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            lastMarker = Index;
432324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return lastMarker;
433324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
434324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
435324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public virtual void Release( int marker )
436324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
437324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            // no resources to release
438324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
439324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
440324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public virtual int Count
441324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
442324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            get
443324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
444324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                return tokens.Count;
445324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
446324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
447324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
448324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public virtual void Rewind( int marker )
449324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
450324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            Seek( marker );
451324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
452324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
453324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public virtual void Rewind()
454324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
455324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            Seek( lastMarker );
456324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
457324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
458324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public virtual void Reset()
459324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
460324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            p = 0;
461324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            lastMarker = 0;
462324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
463324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
464324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public virtual void Seek( int index )
465324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
466324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            p = index;
467324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
468324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
469324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public virtual ITokenSource TokenSource
470324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
471324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            get
472324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
473324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                return _tokenSource;
474324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
475324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
476324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
477324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public virtual string SourceName
478324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
479324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            get
480324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
481324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                return TokenSource.SourceName;
482324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
483324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
484324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
485324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public override string ToString()
486324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
487324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if ( p == -1 )
488324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
489324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                throw new InvalidOperationException( "Buffer is not yet filled." );
490324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
491324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return ToString( 0, tokens.Count - 1 );
492324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
493324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
494324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public virtual string ToString( int start, int stop )
495324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
496324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if ( start < 0 || stop < 0 )
497324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
498324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                return null;
499324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
500324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if ( p == -1 )
501324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
502324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                throw new InvalidOperationException( "Buffer is not yet filled." );
503324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
504324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if ( stop >= tokens.Count )
505324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
506324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                stop = tokens.Count - 1;
507324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
508324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            StringBuilder buf = new StringBuilder();
509324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            for ( int i = start; i <= stop; i++ )
510324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
511324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                IToken t = tokens[i];
512324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                buf.Append( t.Text );
513324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
514324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return buf.ToString();
515324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
516324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
517324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public virtual string ToString( IToken start, IToken stop )
518324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
519324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if ( start != null && stop != null )
520324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
521324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                return ToString( start.TokenIndex, stop.TokenIndex );
522324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
523324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return null;
524324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
525324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
526324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
527