1 /* 2 * [The "BSD licence"] 3 * Copyright (c) 2005-2008 Terence Parr 4 * All rights reserved. 5 * 6 * Conversion to C#: 7 * Copyright (c) 2008-2009 Sam Harwell, Pixel Mine, Inc. 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 namespace Antlr.Runtime 34 { 35 using System.Collections.Generic; 36 37 using InvalidOperationException = System.InvalidOperationException; 38 using StringBuilder = System.Text.StringBuilder; 39 40 /** <summary> 41 * The most common stream of tokens is one where every token is buffered up 42 * and tokens are prefiltered for a certain channel (the parser will only 43 * see these tokens and cannot change the filter channel number during the 44 * parse). 45 * </summary> 46 * 47 * <remarks>TODO: how to access the full token stream? How to track all tokens matched per rule?</remarks> 48 */ 49 [System.Serializable] 50 public class CommonTokenStream : BufferedTokenStream 51 { 52 /** Skip tokens on any channel but this one; this is how we skip whitespace... */ 53 private int _channel; 54 CommonTokenStream()55 public CommonTokenStream() 56 { 57 } 58 CommonTokenStream(ITokenSource tokenSource)59 public CommonTokenStream(ITokenSource tokenSource) 60 : this(tokenSource, TokenChannels.Default) 61 { 62 } 63 CommonTokenStream(ITokenSource tokenSource, int channel)64 public CommonTokenStream(ITokenSource tokenSource, int channel) 65 : base(tokenSource) 66 { 67 this._channel = channel; 68 } 69 70 public int Channel 71 { 72 get 73 { 74 return _channel; 75 } 76 } 77 78 /** Reset this token stream by setting its token source. */ 79 public override ITokenSource TokenSource 80 { 81 get 82 { 83 return base.TokenSource; 84 } 85 set 86 { 87 base.TokenSource = value; 88 _channel = TokenChannels.Default; 89 } 90 } 91 92 /** Always leave p on an on-channel token. */ Consume()93 public override void Consume() 94 { 95 if (_p == -1) 96 Setup(); 97 _p++; 98 _p = SkipOffTokenChannels(_p); 99 } 100 LB(int k)101 protected override IToken LB(int k) 102 { 103 if (k == 0 || (_p - k) < 0) 104 return null; 105 106 int i = _p; 107 int n = 1; 108 // find k good tokens looking backwards 109 while (n <= k) 110 { 111 // skip off-channel tokens 112 i = SkipOffTokenChannelsReverse(i - 1); 113 n++; 114 } 115 if (i < 0) 116 return null; 117 return _tokens[i]; 118 } 119 LT(int k)120 public override IToken LT(int k) 121 { 122 if (_p == -1) 123 Setup(); 124 if (k == 0) 125 return null; 126 if (k < 0) 127 return LB(-k); 128 int i = _p; 129 int n = 1; // we know tokens[p] is a good one 130 // find k good tokens 131 while (n < k) 132 { 133 // skip off-channel tokens 134 i = SkipOffTokenChannels(i + 1); 135 n++; 136 } 137 138 if (i > Range) 139 Range = i; 140 141 return _tokens[i]; 142 } 143 144 /** Given a starting index, return the index of the first on-channel 145 * token. 146 */ SkipOffTokenChannels(int i)147 protected virtual int SkipOffTokenChannels(int i) 148 { 149 Sync(i); 150 while (_tokens[i].Channel != _channel) 151 { 152 // also stops at EOF (it's on channel) 153 i++; 154 Sync(i); 155 } 156 return i; 157 } 158 SkipOffTokenChannelsReverse(int i)159 protected virtual int SkipOffTokenChannelsReverse(int i) 160 { 161 while (i >= 0 && ((IToken)_tokens[i]).Channel != _channel) 162 { 163 i--; 164 } 165 166 return i; 167 } 168 Setup()169 protected override void Setup() 170 { 171 _p = 0; 172 _p = SkipOffTokenChannels(_p); 173 } 174 } 175 } 176