]> gitweb.ps.run Git - toc/blob - antlr4-cpp-runtime-4.9.2-source/runtime/src/BufferedTokenStream.cpp
add antlr source code and ReadMe
[toc] / antlr4-cpp-runtime-4.9.2-source / runtime / src / BufferedTokenStream.cpp
1 /* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
2  * Use of this file is governed by the BSD 3-clause license that
3  * can be found in the LICENSE.txt file in the project root.
4  */
5
6 #include "WritableToken.h"
7 #include "Lexer.h"
8 #include "RuleContext.h"
9 #include "misc/Interval.h"
10 #include "Exceptions.h"
11 #include "support/CPPUtils.h"
12
13 #include "BufferedTokenStream.h"
14
15 using namespace antlr4;
16 using namespace antlrcpp;
17
18 BufferedTokenStream::BufferedTokenStream(TokenSource *tokenSource) : _tokenSource(tokenSource){
19   InitializeInstanceFields();
20 }
21
22 TokenSource* BufferedTokenStream::getTokenSource() const {
23   return _tokenSource;
24 }
25
26 size_t BufferedTokenStream::index() {
27   return _p;
28 }
29
30 ssize_t BufferedTokenStream::mark() {
31   return 0;
32 }
33
34 void BufferedTokenStream::release(ssize_t /*marker*/) {
35   // no resources to release
36 }
37
38 void BufferedTokenStream::reset() {
39   seek(0);
40 }
41
42 void BufferedTokenStream::seek(size_t index) {
43   lazyInit();
44   _p = adjustSeekIndex(index);
45 }
46
47 size_t BufferedTokenStream::size() {
48   return _tokens.size();
49 }
50
51 void BufferedTokenStream::consume() {
52   bool skipEofCheck = false;
53   if (!_needSetup) {
54     if (_fetchedEOF) {
55       // the last token in tokens is EOF. skip check if p indexes any
56       // fetched token except the last.
57       skipEofCheck = _p < _tokens.size() - 1;
58     } else {
59       // no EOF token in tokens. skip check if p indexes a fetched token.
60       skipEofCheck = _p < _tokens.size();
61     }
62   } else {
63     // not yet initialized
64     skipEofCheck = false;
65   }
66
67   if (!skipEofCheck && LA(1) == Token::EOF) {
68     throw IllegalStateException("cannot consume EOF");
69   }
70
71   if (sync(_p + 1)) {
72     _p = adjustSeekIndex(_p + 1);
73   }
74 }
75
76 bool BufferedTokenStream::sync(size_t i) {
77   if (i + 1 < _tokens.size())
78     return true;
79   size_t n = i - _tokens.size() + 1; // how many more elements we need?
80
81   if (n > 0) {
82     size_t fetched = fetch(n);
83     return fetched >= n;
84   }
85
86   return true;
87 }
88
89 size_t BufferedTokenStream::fetch(size_t n) {
90   if (_fetchedEOF) {
91     return 0;
92   }
93
94   size_t i = 0;
95   while (i < n) {
96     std::unique_ptr<Token> t(_tokenSource->nextToken());
97
98     if (is<WritableToken *>(t.get())) {
99       (static_cast<WritableToken *>(t.get()))->setTokenIndex(_tokens.size());
100     }
101
102     _tokens.push_back(std::move(t));
103     ++i;
104
105     if (_tokens.back()->getType() == Token::EOF) {
106       _fetchedEOF = true;
107       break;
108     }
109   }
110
111   return i;
112 }
113
114 Token* BufferedTokenStream::get(size_t i) const {
115   if (i >= _tokens.size()) {
116     throw IndexOutOfBoundsException(std::string("token index ") +
117                                     std::to_string(i) +
118                                     std::string(" out of range 0..") +
119                                     std::to_string(_tokens.size() - 1));
120   }
121   return _tokens[i].get();
122 }
123
124 std::vector<Token *> BufferedTokenStream::get(size_t start, size_t stop) {
125   std::vector<Token *> subset;
126
127   lazyInit();
128
129   if (_tokens.empty()) {
130     return subset;
131   }
132
133   if (stop >= _tokens.size()) {
134     stop = _tokens.size() - 1;
135   }
136   for (size_t i = start; i <= stop; i++) {
137     Token *t = _tokens[i].get();
138     if (t->getType() == Token::EOF) {
139       break;
140     }
141     subset.push_back(t);
142   }
143   return subset;
144 }
145
146 size_t BufferedTokenStream::LA(ssize_t i) {
147   return LT(i)->getType();
148 }
149
150 Token* BufferedTokenStream::LB(size_t k) {
151   if (k > _p) {
152     return nullptr;
153   }
154   return _tokens[_p - k].get();
155 }
156
157 Token* BufferedTokenStream::LT(ssize_t k) {
158   lazyInit();
159   if (k == 0) {
160     return nullptr;
161   }
162   if (k < 0) {
163     return LB(-k);
164   }
165
166   size_t i = _p + k - 1;
167   sync(i);
168   if (i >= _tokens.size()) { // return EOF token
169                              // EOF must be last token
170     return _tokens.back().get();
171   }
172
173   return _tokens[i].get();
174 }
175
176 ssize_t BufferedTokenStream::adjustSeekIndex(size_t i) {
177   return i;
178 }
179
180 void BufferedTokenStream::lazyInit() {
181   if (_needSetup) {
182     setup();
183   }
184 }
185
186 void BufferedTokenStream::setup() {
187   _needSetup = false;
188   sync(0);
189   _p = adjustSeekIndex(0);
190 }
191
192 void BufferedTokenStream::setTokenSource(TokenSource *tokenSource) {
193   _tokenSource = tokenSource;
194   _tokens.clear();
195   _fetchedEOF = false;
196   _needSetup = true;
197 }
198
199 std::vector<Token *> BufferedTokenStream::getTokens() {
200   std::vector<Token *> result;
201   for (auto &t : _tokens)
202     result.push_back(t.get());
203   return result;
204 }
205
206 std::vector<Token *> BufferedTokenStream::getTokens(size_t start, size_t stop) {
207   return getTokens(start, stop, std::vector<size_t>());
208 }
209
210 std::vector<Token *> BufferedTokenStream::getTokens(size_t start, size_t stop, const std::vector<size_t> &types) {
211   lazyInit();
212   if (stop >= _tokens.size() || start >= _tokens.size()) {
213     throw IndexOutOfBoundsException(std::string("start ") +
214                                     std::to_string(start) +
215                                     std::string(" or stop ") +
216                                     std::to_string(stop) +
217                                     std::string(" not in 0..") +
218                                     std::to_string(_tokens.size() - 1));
219   }
220
221   std::vector<Token *> filteredTokens;
222
223   if (start > stop) {
224     return filteredTokens;
225   }
226
227   for (size_t i = start; i <= stop; i++) {
228     Token *tok = _tokens[i].get();
229
230     if (types.empty() || std::find(types.begin(), types.end(), tok->getType()) != types.end()) {
231       filteredTokens.push_back(tok);
232     }
233   }
234   return filteredTokens;
235 }
236
237 std::vector<Token *> BufferedTokenStream::getTokens(size_t start, size_t stop, size_t ttype) {
238   std::vector<size_t> s;
239   s.push_back(ttype);
240   return getTokens(start, stop, s);
241 }
242
243 ssize_t BufferedTokenStream::nextTokenOnChannel(size_t i, size_t channel) {
244   sync(i);
245   if (i >= size()) {
246     return size() - 1;
247   }
248
249   Token *token = _tokens[i].get();
250   while (token->getChannel() != channel) {
251     if (token->getType() == Token::EOF) {
252       return i;
253     }
254     i++;
255     sync(i);
256     token = _tokens[i].get();
257   }
258   return i;
259 }
260
261 ssize_t BufferedTokenStream::previousTokenOnChannel(size_t i, size_t channel) {
262   sync(i);
263   if (i >= size()) {
264     // the EOF token is on every channel
265     return size() - 1;
266   }
267
268   while (true) {
269     Token *token = _tokens[i].get();
270     if (token->getType() == Token::EOF || token->getChannel() == channel) {
271       return i;
272     }
273
274     if (i == 0)
275       return -1;
276     i--;
277   }
278   return i;
279 }
280
281 std::vector<Token *> BufferedTokenStream::getHiddenTokensToRight(size_t tokenIndex, ssize_t channel) {
282   lazyInit();
283   if (tokenIndex >= _tokens.size()) {
284     throw IndexOutOfBoundsException(std::to_string(tokenIndex) + " not in 0.." + std::to_string(_tokens.size() - 1));
285   }
286
287   ssize_t nextOnChannel = nextTokenOnChannel(tokenIndex + 1, Lexer::DEFAULT_TOKEN_CHANNEL);
288   size_t to;
289   size_t from = tokenIndex + 1;
290   // if none onchannel to right, nextOnChannel=-1 so set to = last token
291   if (nextOnChannel == -1) {
292     to = static_cast<ssize_t>(size() - 1);
293   } else {
294     to = nextOnChannel;
295   }
296
297   return filterForChannel(from, to, channel);
298 }
299
300 std::vector<Token *> BufferedTokenStream::getHiddenTokensToRight(size_t tokenIndex) {
301   return getHiddenTokensToRight(tokenIndex, -1);
302 }
303
304 std::vector<Token *> BufferedTokenStream::getHiddenTokensToLeft(size_t tokenIndex, ssize_t channel) {
305   lazyInit();
306   if (tokenIndex >= _tokens.size()) {
307     throw IndexOutOfBoundsException(std::to_string(tokenIndex) + " not in 0.." + std::to_string(_tokens.size() - 1));
308   }
309
310   if (tokenIndex == 0) {
311     // Obviously no tokens can appear before the first token.
312     return { };
313   }
314
315   ssize_t prevOnChannel = previousTokenOnChannel(tokenIndex - 1, Lexer::DEFAULT_TOKEN_CHANNEL);
316   if (prevOnChannel == static_cast<ssize_t>(tokenIndex - 1)) {
317     return { };
318   }
319   // if none onchannel to left, prevOnChannel=-1 then from=0
320   size_t from = static_cast<size_t>(prevOnChannel + 1);
321   size_t to = tokenIndex - 1;
322
323   return filterForChannel(from, to, channel);
324 }
325
326 std::vector<Token *> BufferedTokenStream::getHiddenTokensToLeft(size_t tokenIndex) {
327   return getHiddenTokensToLeft(tokenIndex, -1);
328 }
329
330 std::vector<Token *> BufferedTokenStream::filterForChannel(size_t from, size_t to, ssize_t channel) {
331   std::vector<Token *> hidden;
332   for (size_t i = from; i <= to; i++) {
333     Token *t = _tokens[i].get();
334     if (channel == -1) {
335       if (t->getChannel() != Lexer::DEFAULT_TOKEN_CHANNEL) {
336         hidden.push_back(t);
337       }
338     } else {
339       if (t->getChannel() == static_cast<size_t>(channel)) {
340         hidden.push_back(t);
341       }
342     }
343   }
344
345   return hidden;
346 }
347
348 bool BufferedTokenStream::isInitialized() const {
349   return !_needSetup;
350 }
351
352 /**
353  * Get the text of all tokens in this buffer.
354  */
355 std::string BufferedTokenStream::getSourceName() const
356 {
357   return _tokenSource->getSourceName();
358 }
359
360 std::string BufferedTokenStream::getText() {
361   fill();
362   return getText(misc::Interval(0U, size() - 1));
363 }
364
365 std::string BufferedTokenStream::getText(const misc::Interval &interval) {
366   lazyInit();
367   size_t start = interval.a;
368   size_t stop = interval.b;
369   if (start == INVALID_INDEX || stop == INVALID_INDEX) {
370     return "";
371   }
372   sync(stop);
373   if (stop >= _tokens.size()) {
374     stop = _tokens.size() - 1;
375   }
376
377   std::stringstream ss;
378   for (size_t i = start; i <= stop; i++) {
379     Token *t = _tokens[i].get();
380     if (t->getType() == Token::EOF) {
381       break;
382     }
383     ss << t->getText();
384   }
385   return ss.str();
386 }
387
388 std::string BufferedTokenStream::getText(RuleContext *ctx) {
389   return getText(ctx->getSourceInterval());
390 }
391
392 std::string BufferedTokenStream::getText(Token *start, Token *stop) {
393   if (start != nullptr && stop != nullptr) {
394     return getText(misc::Interval(start->getTokenIndex(), stop->getTokenIndex()));
395   }
396
397   return "";
398 }
399
400 void BufferedTokenStream::fill() {
401   lazyInit();
402   const size_t blockSize = 1000;
403   while (true) {
404     size_t fetched = fetch(blockSize);
405     if (fetched < blockSize) {
406       return;
407     }
408   }
409 }
410
411 void BufferedTokenStream::InitializeInstanceFields() {
412   _needSetup = true;
413   _fetchedEOF = false;
414 }