/* * [The "BSD licence"] * Copyright (c) 2005-2008 Terence Parr * All rights reserved. * * Conversion to C#: * Copyright (c) 2008-2009 Sam Harwell, Pixel Mine, Inc. * 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. */ namespace Antlr.Runtime { using System.Collections.Generic; using InvalidOperationException = System.InvalidOperationException; using StringBuilder = System.Text.StringBuilder; /** * The most common stream of tokens is one where every token is buffered up * and tokens are prefiltered for a certain channel (the parser will only * see these tokens and cannot change the filter channel number during the * parse). * * * TODO: how to access the full token stream? How to track all tokens matched per rule? */ [System.Serializable] public class CommonTokenStream : BufferedTokenStream { /** Skip tokens on any channel but this one; this is how we skip whitespace... */ private int _channel; public CommonTokenStream() { } public CommonTokenStream(ITokenSource tokenSource) : this(tokenSource, TokenChannels.Default) { } public CommonTokenStream(ITokenSource tokenSource, int channel) : base(tokenSource) { this._channel = channel; } public int Channel { get { return _channel; } } /** Reset this token stream by setting its token source. */ public override ITokenSource TokenSource { get { return base.TokenSource; } set { base.TokenSource = value; _channel = TokenChannels.Default; } } /** Always leave p on an on-channel token. */ public override void Consume() { if (_p == -1) Setup(); _p++; Sync(_p); while (_tokens[_p].Channel != _channel) { _p++; Sync(_p); } } protected override IToken LB(int k) { if (k == 0 || (_p - k) < 0) return null; int i = _p; int n = 1; // find k good tokens looking backwards while (n <= k) { // skip off-channel tokens i = SkipOffTokenChannelsReverse(i - 1); n++; } if (i < 0) return null; return _tokens[i]; } public override IToken LT(int k) { if (_p == -1) Setup(); if (k == 0) return null; if (k < 0) return LB(-k); int i = _p; int n = 1; // we know tokens[p] is a good one // find k good tokens while (n < k) { // skip off-channel tokens i = SkipOffTokenChannels(i + 1); n++; } if (i > Range) Range = i; return _tokens[i]; } /** Given a starting index, return the index of the first on-channel * token. */ protected virtual int SkipOffTokenChannels(int i) { Sync(i); while (_tokens[i].Channel != _channel) { // also stops at EOF (it's on channel) i++; Sync(i); } return i; } protected virtual int SkipOffTokenChannelsReverse(int i) { while (i >= 0 && ((IToken)_tokens[i]).Channel != _channel) { i--; } return i; } protected override void Setup() { _p = 0; Sync(0); int i = 0; while (_tokens[i].Channel != _channel) { i++; Sync(i); } _p = i; } } }