PageRenderTime 131ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/projects/antlr-3.4/runtime/Java/src/main/java/org/antlr/runtime/BufferedTokenStream.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 272 lines | 156 code | 42 blank | 74 comment | 47 complexity | b1a3756151d9429572e3c98e48893cde MD5 | raw file
  1. /*
  2. [The "BSD license"]
  3. Copyright (c) 2005-2009 Terence Parr
  4. All rights reserved.
  5. Redistribution and use in source and binary forms, with or without
  6. modification, are permitted provided that the following conditions
  7. are met:
  8. 1. Redistributions of source code must retain the above copyright
  9. notice, this list of conditions and the following disclaimer.
  10. 2. Redistributions in binary form must reproduce the above copyright
  11. notice, this list of conditions and the following disclaimer in the
  12. documentation and/or other materials provided with the distribution.
  13. 3. The name of the author may not be used to endorse or promote products
  14. derived from this software without specific prior written permission.
  15. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  16. IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  17. OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  18. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  19. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  20. NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  21. DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  22. THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  23. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  24. THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. */
  26. package org.antlr.runtime;
  27. import java.util.List;
  28. import java.util.ArrayList;
  29. import java.util.NoSuchElementException;
  30. /** Buffer all input tokens but do on-demand fetching of new tokens from
  31. * lexer. Useful when the parser or lexer has to set context/mode info before
  32. * proper lexing of future tokens. The ST template parser needs this,
  33. * for example, because it has to constantly flip back and forth between
  34. * inside/output templates. E.g., <names:{hi, <it>}> has to parse names
  35. * as part of an expression but "hi, <it>" as a nested template.
  36. *
  37. * You can't use this stream if you pass whitespace or other off-channel
  38. * tokens to the parser. The stream can't ignore off-channel tokens.
  39. * (UnbufferedTokenStream is the same way.)
  40. *
  41. * This is not a subclass of UnbufferedTokenStream because I don't want
  42. * to confuse small moving window of tokens it uses for the full buffer.
  43. */
  44. public class BufferedTokenStream implements TokenStream {
  45. protected TokenSource tokenSource;
  46. /** Record every single token pulled from the source so we can reproduce
  47. * chunks of it later. The buffer in LookaheadStream overlaps sometimes
  48. * as its moving window moves through the input. This list captures
  49. * everything so we can access complete input text.
  50. */
  51. protected List<Token> tokens = new ArrayList<Token>(100);
  52. /** Track the last mark() call result value for use in rewind(). */
  53. protected int lastMarker;
  54. /** The index into the tokens list of the current token (next token
  55. * to consume). tokens[p] should be LT(1). p=-1 indicates need
  56. * to initialize with first token. The ctor doesn't get a token.
  57. * First call to LT(1) or whatever gets the first token and sets p=0;
  58. */
  59. protected int p = -1;
  60. protected int range = -1; // how deep have we gone?
  61. public BufferedTokenStream() {;}
  62. public BufferedTokenStream(TokenSource tokenSource) {
  63. this.tokenSource = tokenSource;
  64. }
  65. public TokenSource getTokenSource() { return tokenSource; }
  66. public int index() { return p; }
  67. public int range() { return range; }
  68. public int mark() {
  69. if ( p == -1 ) setup();
  70. lastMarker = index();
  71. return lastMarker;
  72. }
  73. public void release(int marker) {
  74. // no resources to release
  75. }
  76. public void rewind(int marker) {
  77. seek(marker);
  78. }
  79. public void rewind() {
  80. seek(lastMarker);
  81. }
  82. public void reset() {
  83. p = 0;
  84. lastMarker = 0;
  85. }
  86. public void seek(int index) { p = index; }
  87. public int size() { return tokens.size(); }
  88. /** Move the input pointer to the next incoming token. The stream
  89. * must become active with LT(1) available. consume() simply
  90. * moves the input pointer so that LT(1) points at the next
  91. * input symbol. Consume at least one token.
  92. *
  93. * Walk past any token not on the channel the parser is listening to.
  94. */
  95. public void consume() {
  96. if ( p == -1 ) setup();
  97. p++;
  98. sync(p);
  99. }
  100. /** Make sure index i in tokens has a token. */
  101. protected void sync(int i) {
  102. int n = i - tokens.size() + 1; // how many more elements we need?
  103. //System.out.println("sync("+i+") needs "+n);
  104. if ( n > 0 ) fetch(n);
  105. }
  106. /** add n elements to buffer */
  107. protected void fetch(int n) {
  108. for (int i=1; i<=n; i++) {
  109. Token t = tokenSource.nextToken();
  110. t.setTokenIndex(tokens.size());
  111. //System.out.println("adding "+t+" at index "+tokens.size());
  112. tokens.add(t);
  113. if ( t.getType()==Token.EOF ) break;
  114. }
  115. }
  116. public Token get(int i) {
  117. if ( i < 0 || i >= tokens.size() ) {
  118. throw new NoSuchElementException("token index "+i+" out of range 0.."+(tokens.size()-1));
  119. }
  120. return tokens.get(i);
  121. }
  122. /** Get all tokens from start..stop inclusively */
  123. public List get(int start, int stop) {
  124. if ( start<0 || stop<0 ) return null;
  125. if ( p == -1 ) setup();
  126. List subset = new ArrayList();
  127. if ( stop>=tokens.size() ) stop = tokens.size()-1;
  128. for (int i = start; i <= stop; i++) {
  129. Token t = tokens.get(i);
  130. if ( t.getType()==Token.EOF ) break;
  131. subset.add(t);
  132. }
  133. return subset;
  134. }
  135. public int LA(int i) { return LT(i).getType(); }
  136. protected Token LB(int k) {
  137. if ( (p-k)<0 ) return null;
  138. return tokens.get(p-k);
  139. }
  140. public Token LT(int k) {
  141. if ( p == -1 ) setup();
  142. if ( k==0 ) return null;
  143. if ( k < 0 ) return LB(-k);
  144. int i = p + k - 1;
  145. sync(i);
  146. if ( i >= tokens.size() ) { // return EOF token
  147. // EOF must be last token
  148. return tokens.get(tokens.size()-1);
  149. }
  150. if ( i>range ) range = i;
  151. return tokens.get(i);
  152. }
  153. protected void setup() { sync(0); p = 0; }
  154. /** Reset this token stream by setting its token source. */
  155. public void setTokenSource(TokenSource tokenSource) {
  156. this.tokenSource = tokenSource;
  157. tokens.clear();
  158. p = -1;
  159. }
  160. public List getTokens() { return tokens; }
  161. public List getTokens(int start, int stop) {
  162. return getTokens(start, stop, (BitSet)null);
  163. }
  164. /** Given a start and stop index, return a List of all tokens in
  165. * the token type BitSet. Return null if no tokens were found. This
  166. * method looks at both on and off channel tokens.
  167. */
  168. public List getTokens(int start, int stop, BitSet types) {
  169. if ( p == -1 ) setup();
  170. if ( stop>=tokens.size() ) stop=tokens.size()-1;
  171. if ( start<0 ) start=0;
  172. if ( start>stop ) return null;
  173. // list = tokens[start:stop]:{Token t, t.getType() in types}
  174. List<Token> filteredTokens = new ArrayList<Token>();
  175. for (int i=start; i<=stop; i++) {
  176. Token t = tokens.get(i);
  177. if ( types==null || types.member(t.getType()) ) {
  178. filteredTokens.add(t);
  179. }
  180. }
  181. if ( filteredTokens.size()==0 ) {
  182. filteredTokens = null;
  183. }
  184. return filteredTokens;
  185. }
  186. public List getTokens(int start, int stop, List types) {
  187. return getTokens(start,stop,new BitSet(types));
  188. }
  189. public List getTokens(int start, int stop, int ttype) {
  190. return getTokens(start,stop,BitSet.of(ttype));
  191. }
  192. public String getSourceName() { return tokenSource.getSourceName(); }
  193. /** Grab *all* tokens from stream and return string */
  194. public String toString() {
  195. if ( p == -1 ) setup();
  196. fill();
  197. return toString(0, tokens.size()-1);
  198. }
  199. public String toString(int start, int stop) {
  200. if ( start<0 || stop<0 ) return null;
  201. if ( p == -1 ) setup();
  202. if ( stop>=tokens.size() ) stop = tokens.size()-1;
  203. StringBuffer buf = new StringBuffer();
  204. for (int i = start; i <= stop; i++) {
  205. Token t = tokens.get(i);
  206. if ( t.getType()==Token.EOF ) break;
  207. buf.append(t.getText());
  208. }
  209. return buf.toString();
  210. }
  211. public String toString(Token start, Token stop) {
  212. if ( start!=null && stop!=null ) {
  213. return toString(start.getTokenIndex(), stop.getTokenIndex());
  214. }
  215. return null;
  216. }
  217. /** Get all tokens from lexer until EOF */
  218. public void fill() {
  219. if ( p == -1 ) setup();
  220. if ( tokens.get(p).getType()==Token.EOF ) return;
  221. int i = p+1;
  222. sync(i);
  223. while ( tokens.get(i).getType()!=Token.EOF ) {
  224. i++;
  225. sync(i);
  226. }
  227. }
  228. }