Coverage Report

Created: 2025-11-29 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/proc/self/cwd/external/antlr4-cpp-runtime~/runtime/src/Parser.cpp
Line
Count
Source
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 "atn/ATNDeserializationOptions.h"
7
#include "tree/pattern/ParseTreePatternMatcher.h"
8
#include "dfa/DFA.h"
9
#include "ParserRuleContext.h"
10
#include "tree/TerminalNode.h"
11
#include "tree/ErrorNodeImpl.h"
12
#include "Lexer.h"
13
#include "atn/ParserATNSimulator.h"
14
#include "misc/IntervalSet.h"
15
#include "atn/RuleStartState.h"
16
#include "DefaultErrorStrategy.h"
17
#include "atn/ATNDeserializer.h"
18
#include "atn/RuleTransition.h"
19
#include "atn/ATN.h"
20
#include "Exceptions.h"
21
#include "ANTLRErrorListener.h"
22
#include "tree/pattern/ParseTreePattern.h"
23
#include "internal/Synchronization.h"
24
25
#include "atn/ProfilingATNSimulator.h"
26
#include "atn/ParseInfo.h"
27
28
#include "Parser.h"
29
30
using namespace antlr4;
31
using namespace antlr4::atn;
32
using namespace antlr4::internal;
33
using namespace antlrcpp;
34
35
namespace {
36
37
struct BypassAltsAtnCache final {
38
  std::shared_mutex mutex;
39
  /// This field maps from the serialized ATN string to the deserialized <seealso cref="ATN"/> with
40
  /// bypass alternatives.
41
  ///
42
  /// <seealso cref= ATNDeserializationOptions#isGenerateRuleBypassTransitions() </seealso>
43
  std::map<std::vector<int32_t>, std::unique_ptr<const atn::ATN>, std::less<>> map;
44
};
45
46
0
BypassAltsAtnCache* getBypassAltsAtnCache() {
47
0
  static BypassAltsAtnCache* const instance = new BypassAltsAtnCache();
48
0
  return instance;
49
0
}
50
51
}
52
53
0
Parser::TraceListener::TraceListener(Parser *outerInstance_) : outerInstance(outerInstance_) {
54
0
}
55
56
0
Parser::TraceListener::~TraceListener() {
57
0
}
58
59
0
void Parser::TraceListener::enterEveryRule(ParserRuleContext *ctx) {
60
0
  std::cout << "enter   " << outerInstance->getRuleNames()[ctx->getRuleIndex()]
61
0
    << ", LT(1)=" << outerInstance->_input->LT(1)->getText() << std::endl;
62
0
}
63
64
0
void Parser::TraceListener::visitTerminal(tree::TerminalNode *node) {
65
0
  std::cout << "consume " << node->getSymbol() << " rule "
66
0
    << outerInstance->getRuleNames()[outerInstance->getContext()->getRuleIndex()] << std::endl;
67
0
}
68
69
0
void Parser::TraceListener::visitErrorNode(tree::ErrorNode * /*node*/) {
70
0
}
71
72
0
void Parser::TraceListener::exitEveryRule(ParserRuleContext *ctx) {
73
0
  std::cout << "exit    " << outerInstance->getRuleNames()[ctx->getRuleIndex()]
74
0
    << ", LT(1)=" << outerInstance->_input->LT(1)->getText() << std::endl;
75
0
}
76
77
Parser::TrimToSizeListener Parser::TrimToSizeListener::INSTANCE;
78
79
0
Parser::TrimToSizeListener::~TrimToSizeListener() {
80
0
}
81
82
0
void Parser::TrimToSizeListener::enterEveryRule(ParserRuleContext * /*ctx*/) {
83
0
}
84
85
0
void Parser::TrimToSizeListener::visitTerminal(tree::TerminalNode * /*node*/) {
86
0
}
87
88
0
void Parser::TrimToSizeListener::visitErrorNode(tree::ErrorNode * /*node*/) {
89
0
}
90
91
0
void Parser::TrimToSizeListener::exitEveryRule(ParserRuleContext * ctx) {
92
0
  ctx->children.shrink_to_fit();
93
0
}
94
95
4.20k
Parser::Parser(TokenStream *input) {
96
4.20k
  InitializeInstanceFields();
97
4.20k
  setInputStream(input);
98
4.20k
}
99
100
4.20k
Parser::~Parser() {
101
4.20k
  _tracker.reset();
102
4.20k
  delete _tracer;
103
4.20k
}
104
105
4.20k
void Parser::reset() {
106
4.20k
  if (getInputStream() != nullptr) {
107
0
    getInputStream()->seek(0);
108
0
  }
109
4.20k
  _errHandler->reset(this); // Watch out, this is not shared_ptr.reset().
110
111
4.20k
  _matchedEOF = false;
112
4.20k
  _syntaxErrors = 0;
113
4.20k
  setTrace(false);
114
4.20k
  _precedenceStack.clear();
115
4.20k
  _precedenceStack.push_back(0);
116
4.20k
  _ctx = nullptr;
117
4.20k
  _tracker.reset();
118
119
4.20k
  atn::ATNSimulator *interpreter = getInterpreter<atn::ParserATNSimulator>();
120
4.20k
  if (interpreter != nullptr) {
121
0
    interpreter->reset();
122
0
  }
123
4.20k
}
124
125
5.13M
Token* Parser::match(size_t ttype) {
126
5.13M
  Token *t = getCurrentToken();
127
5.13M
  if (t->getType() == ttype) {
128
5.12M
    if (ttype == EOF) {
129
3.35k
      _matchedEOF = true;
130
3.35k
    }
131
5.12M
    _errHandler->reportMatch(this);
132
5.12M
    consume();
133
5.12M
  } else {
134
6.24k
    t = _errHandler->recoverInline(this);
135
6.24k
    if (_buildParseTrees && t->getTokenIndex() == INVALID_INDEX) {
136
      // we must have conjured up a new token during single token insertion
137
      // if it's not the current symbol
138
2.16k
      _ctx->addChild(createErrorNode(t));
139
2.16k
    }
140
6.24k
  }
141
5.13M
  return t;
142
5.13M
}
143
144
0
Token* Parser::matchWildcard() {
145
0
  Token *t = getCurrentToken();
146
0
  if (t->getType() > 0) {
147
0
    _errHandler->reportMatch(this);
148
0
    consume();
149
0
  } else {
150
0
    t = _errHandler->recoverInline(this);
151
0
    if (_buildParseTrees && t->getTokenIndex() == INVALID_INDEX) {
152
      // we must have conjured up a new token during single token insertion
153
      // if it's not the current symbol
154
0
      _ctx->addChild(createErrorNode(t));
155
0
    }
156
0
  }
157
158
0
  return t;
159
0
}
160
161
0
void Parser::setBuildParseTree(bool buildParseTrees) {
162
0
  this->_buildParseTrees = buildParseTrees;
163
0
}
164
165
0
bool Parser::getBuildParseTree() {
166
0
  return _buildParseTrees;
167
0
}
168
169
0
void Parser::setTrimParseTree(bool trimParseTrees) {
170
0
  if (trimParseTrees) {
171
0
    if (getTrimParseTree()) {
172
0
      return;
173
0
    }
174
0
    addParseListener(&TrimToSizeListener::INSTANCE);
175
0
  } else {
176
0
    removeParseListener(&TrimToSizeListener::INSTANCE);
177
0
  }
178
0
}
179
180
0
bool Parser::getTrimParseTree() {
181
0
  return std::find(getParseListeners().begin(), getParseListeners().end(), &TrimToSizeListener::INSTANCE) != getParseListeners().end();
182
0
}
183
184
0
std::vector<tree::ParseTreeListener *> Parser::getParseListeners() {
185
0
  return _parseListeners;
186
0
}
187
188
4.20k
void Parser::addParseListener(tree::ParseTreeListener *listener) {
189
4.20k
  if (!listener) {
190
0
    throw NullPointerException("listener");
191
0
  }
192
193
4.20k
  this->_parseListeners.push_back(listener);
194
4.20k
}
195
196
0
void Parser::removeParseListener(tree::ParseTreeListener *listener) {
197
0
  if (!_parseListeners.empty()) {
198
0
    auto it = std::find(_parseListeners.begin(), _parseListeners.end(), listener);
199
0
    if (it != _parseListeners.end()) {
200
0
      _parseListeners.erase(it);
201
0
    }
202
0
  }
203
0
}
204
205
0
void Parser::removeParseListeners() {
206
0
  _parseListeners.clear();
207
0
}
208
209
18.9M
void Parser::triggerEnterRuleEvent() {
210
18.9M
  for (auto *listener : _parseListeners) {
211
18.9M
    listener->enterEveryRule(_ctx);
212
18.9M
    _ctx->enterRule(listener);
213
18.9M
  }
214
18.9M
}
215
216
18.9M
void Parser::triggerExitRuleEvent() {
217
  // reverse order walk of listeners
218
37.9M
  for (auto it = _parseListeners.rbegin(); it != _parseListeners.rend(); ++it) {
219
18.9M
    _ctx->exitRule(*it);
220
18.9M
    (*it)->exitEveryRule(_ctx);
221
18.9M
  }
222
18.9M
}
223
224
0
size_t Parser::getNumberOfSyntaxErrors() {
225
0
  return _syntaxErrors;
226
0
}
227
228
2.16k
TokenFactory<CommonToken>* Parser::getTokenFactory() {
229
2.16k
  return _input->getTokenSource()->getTokenFactory();
230
2.16k
}
231
232
0
const atn::ATN& Parser::getATNWithBypassAlts() {
233
0
  auto serializedAtn = getSerializedATN();
234
0
  if (serializedAtn.empty()) {
235
0
    throw UnsupportedOperationException("The current parser does not support an ATN with bypass alternatives.");
236
0
  }
237
  // XXX: using the entire serialized ATN as key into the map is a big resource waste.
238
  //      How large can that thing become?
239
0
  auto *cache = getBypassAltsAtnCache();
240
0
  {
241
0
    std::shared_lock<std::shared_mutex> lock(cache->mutex);
242
0
    auto existing = cache->map.find(serializedAtn);
243
0
    if (existing != cache->map.end()) {
244
0
      return *existing->second;
245
0
    }
246
0
  }
247
248
0
  std::unique_lock<std::shared_mutex> lock(cache->mutex);
249
0
  auto existing = cache->map.find(serializedAtn);
250
0
  if (existing != cache->map.end()) {
251
0
    return *existing->second;
252
0
  }
253
0
  atn::ATNDeserializationOptions deserializationOptions;
254
0
  deserializationOptions.setGenerateRuleBypassTransitions(true);
255
0
  atn::ATNDeserializer deserializer(deserializationOptions);
256
0
  auto atn = deserializer.deserialize(serializedAtn);
257
0
  return *cache->map.insert(std::make_pair(std::vector<int32_t>(serializedAtn.begin(), serializedAtn.end()), std::move(atn))).first->second;
258
0
}
259
260
0
tree::pattern::ParseTreePattern Parser::compileParseTreePattern(const std::string &pattern, int patternRuleIndex) {
261
0
  if (getTokenStream() != nullptr) {
262
0
    TokenSource *tokenSource = getTokenStream()->getTokenSource();
263
0
    if (is<Lexer*>(tokenSource)) {
264
0
      Lexer *lexer = dynamic_cast<Lexer *>(tokenSource);
265
0
      return compileParseTreePattern(pattern, patternRuleIndex, lexer);
266
0
    }
267
0
  }
268
0
  throw UnsupportedOperationException("Parser can't discover a lexer to use");
269
0
}
270
271
tree::pattern::ParseTreePattern Parser::compileParseTreePattern(const std::string &pattern, int patternRuleIndex,
272
0
  Lexer *lexer) {
273
0
  tree::pattern::ParseTreePatternMatcher m(lexer, this);
274
0
  return m.compile(pattern, patternRuleIndex);
275
0
}
276
277
0
Ref<ANTLRErrorStrategy> Parser::getErrorHandler() {
278
0
  return _errHandler;
279
0
}
280
281
4.20k
void Parser::setErrorHandler(Ref<ANTLRErrorStrategy> const& handler) {
282
4.20k
  _errHandler = handler;
283
4.20k
}
284
285
6.63M
IntStream* Parser::getInputStream() {
286
6.63M
  return getTokenStream();
287
6.63M
}
288
289
4.20k
void Parser::setInputStream(IntStream *input) {
290
4.20k
  setTokenStream(static_cast<TokenStream*>(input));
291
4.20k
}
292
293
30.9M
TokenStream* Parser::getTokenStream() {
294
30.9M
  return _input;
295
30.9M
}
296
297
4.20k
void Parser::setTokenStream(TokenStream *input) {
298
4.20k
  _input = nullptr; // Just a reference we don't own.
299
4.20k
  reset();
300
4.20k
  _input = input;
301
4.20k
}
302
303
11.6M
Token* Parser::getCurrentToken() {
304
11.6M
  return _input->LT(1);
305
11.6M
}
306
307
483
void Parser::notifyErrorListeners(const std::string &msg) {
308
483
  notifyErrorListeners(getCurrentToken(), msg, nullptr);
309
483
}
310
311
14.0k
void Parser::notifyErrorListeners(Token *offendingToken, const std::string &msg, std::exception_ptr e) {
312
14.0k
  _syntaxErrors++;
313
14.0k
  size_t line = offendingToken->getLine();
314
14.0k
  size_t charPositionInLine = offendingToken->getCharPositionInLine();
315
316
14.0k
  ProxyErrorListener &listener = getErrorListenerDispatch();
317
14.0k
  listener.syntaxError(this, offendingToken, line, charPositionInLine, msg, e);
318
14.0k
}
319
320
6.52M
Token* Parser::consume() {
321
6.52M
  Token *o = getCurrentToken();
322
6.52M
  if (o->getType() != EOF) {
323
6.52M
    getInputStream()->consume();
324
6.52M
  }
325
326
6.52M
  bool hasListener = _parseListeners.size() > 0 && !_parseListeners.empty();
327
6.52M
  if (_buildParseTrees || hasListener) {
328
6.52M
    if (_errHandler->inErrorRecoveryMode(this)) {
329
57.6k
      tree::ErrorNode *node = createErrorNode(o);
330
57.6k
      _ctx->addChild(node);
331
57.6k
      if (_parseListeners.size() > 0) {
332
57.6k
        for (auto *listener : _parseListeners) {
333
57.6k
          listener->visitErrorNode(node);
334
57.6k
        }
335
57.6k
      }
336
6.47M
    } else {
337
6.47M
      tree::TerminalNode *node = _ctx->addChild(createTerminalNode(o));
338
6.47M
      if (_parseListeners.size() > 0) {
339
6.47M
        for (auto *listener : _parseListeners) {
340
6.47M
          listener->visitTerminal(node);
341
6.47M
        }
342
6.47M
      }
343
6.47M
    }
344
6.52M
  }
345
6.52M
  return o;
346
6.52M
}
347
348
11.1M
void Parser::addContextToParseTree() {
349
  // Add current context to parent if we have a parent.
350
11.1M
  if (_ctx->parent == nullptr)
351
4.20k
    return;
352
353
11.1M
  downCast<ParserRuleContext*>(_ctx->parent)->addChild(_ctx);
354
11.1M
}
355
356
11.1M
void Parser::enterRule(ParserRuleContext *localctx, size_t state, size_t /*ruleIndex*/) {
357
11.1M
  setState(state);
358
11.1M
  _ctx = localctx;
359
11.1M
  _ctx->start = _input->LT(1);
360
11.1M
  if (_buildParseTrees) {
361
11.1M
    addContextToParseTree();
362
11.1M
  }
363
11.1M
  if (_parseListeners.size() > 0) {
364
11.1M
    triggerEnterRuleEvent();
365
11.1M
  }
366
11.1M
}
367
368
11.1M
void Parser::exitRule() {
369
11.1M
  if (_matchedEOF) {
370
    // if we have matched EOF, it cannot consume past EOF so we use LT(1) here
371
3.35k
    _ctx->stop = _input->LT(1); // LT(1) will be end of file
372
11.1M
  } else {
373
11.1M
    _ctx->stop = _input->LT(-1); // stop node is what we just matched
374
11.1M
  }
375
376
  // trigger event on ctx, before it reverts to parent
377
11.1M
  if (_parseListeners.size() > 0) {
378
11.1M
    triggerExitRuleEvent();
379
11.1M
  }
380
11.1M
  setState(_ctx->invokingState);
381
11.1M
  _ctx = downCast<ParserRuleContext*>(_ctx->parent);
382
11.1M
}
383
384
17.5M
void Parser::enterOuterAlt(ParserRuleContext *localctx, size_t altNum) {
385
17.5M
  localctx->setAltNumber(altNum);
386
387
  // if we have new localctx, make sure we replace existing ctx
388
  // that is previous child of parse tree
389
17.5M
  if (_buildParseTrees && _ctx != localctx) {
390
6.87M
    if (_ctx->parent != nullptr) {
391
6.87M
      ParserRuleContext *parent = downCast<ParserRuleContext*>(_ctx->parent);
392
6.87M
      parent->removeLastChild();
393
6.87M
      parent->addChild(localctx);
394
6.87M
    }
395
6.87M
  }
396
17.5M
  _ctx = localctx;
397
17.5M
}
398
399
7.79M
int Parser::getPrecedence() const {
400
7.79M
  if (_precedenceStack.empty()) {
401
0
    return -1;
402
0
  }
403
404
7.79M
  return _precedenceStack.back();
405
7.79M
}
406
407
0
void Parser::enterRecursionRule(ParserRuleContext *localctx, size_t ruleIndex) {
408
0
  enterRecursionRule(localctx, getATN().ruleToStartState[ruleIndex]->stateNumber, ruleIndex, 0);
409
0
}
410
411
6.41M
void Parser::enterRecursionRule(ParserRuleContext *localctx, size_t state, size_t /*ruleIndex*/, int precedence) {
412
6.41M
  setState(state);
413
6.41M
  _precedenceStack.push_back(precedence);
414
6.41M
  _ctx = localctx;
415
6.41M
  _ctx->start = _input->LT(1);
416
6.41M
  if (!_parseListeners.empty()) {
417
6.41M
    triggerEnterRuleEvent(); // simulates rule entry for left-recursive rules
418
6.41M
  }
419
6.41M
}
420
421
1.40M
void Parser::pushNewRecursionContext(ParserRuleContext *localctx, size_t state, size_t /*ruleIndex*/) {
422
1.40M
  ParserRuleContext *previous = _ctx;
423
1.40M
  previous->parent = localctx;
424
1.40M
  previous->invokingState = state;
425
1.40M
  previous->stop = _input->LT(-1);
426
427
1.40M
  _ctx = localctx;
428
1.40M
  _ctx->start = previous->start;
429
1.40M
  if (_buildParseTrees) {
430
1.40M
    _ctx->addChild(previous);
431
1.40M
  }
432
433
1.40M
  if (_parseListeners.size() > 0) {
434
1.40M
    triggerEnterRuleEvent(); // simulates rule entry for left-recursive rules
435
1.40M
  }
436
1.40M
}
437
438
6.41M
void Parser::unrollRecursionContexts(ParserRuleContext *parentctx) {
439
6.41M
  _precedenceStack.pop_back();
440
6.41M
  _ctx->stop = _input->LT(-1);
441
6.41M
  ParserRuleContext *retctx = _ctx; // save current ctx (return value)
442
443
  // unroll so ctx is as it was before call to recursive method
444
6.41M
  if (_parseListeners.size() > 0) {
445
12.8M
    while (_ctx != parentctx) {
446
6.41M
      triggerExitRuleEvent();
447
6.41M
      _ctx = downCast<ParserRuleContext*>(_ctx->parent);
448
6.41M
    }
449
6.41M
  } else {
450
0
    _ctx = parentctx;
451
0
  }
452
453
  // hook into tree
454
6.41M
  retctx->parent = parentctx;
455
456
6.41M
  if (_buildParseTrees && parentctx != nullptr) {
457
    // add return ctx into invoking rule's tree
458
6.41M
    parentctx->addChild(retctx);
459
6.41M
  }
460
6.41M
}
461
462
0
ParserRuleContext* Parser::getInvokingContext(size_t ruleIndex) {
463
0
  ParserRuleContext *p = _ctx;
464
0
  while (p) {
465
0
    if (p->getRuleIndex() == ruleIndex) {
466
0
      return p;
467
0
    }
468
0
    if (p->parent == nullptr)
469
0
      break;
470
0
    p = downCast<ParserRuleContext*>(p->parent);
471
0
  }
472
0
  return nullptr;
473
0
}
474
475
46.9k
ParserRuleContext* Parser::getContext() {
476
46.9k
  return _ctx;
477
46.9k
}
478
479
0
void Parser::setContext(ParserRuleContext *ctx) {
480
0
  _ctx = ctx;
481
0
}
482
483
2.81M
bool Parser::precpred(RuleContext * /*localctx*/, int precedence) {
484
2.81M
  return precedence >= _precedenceStack.back();
485
2.81M
}
486
487
0
bool Parser::inContext(const std::string &/*context*/) {
488
  // TODO: useful in parser?
489
0
  return false;
490
0
}
491
492
0
bool Parser::isExpectedToken(size_t symbol) {
493
0
  const atn::ATN &atn = getInterpreter<atn::ParserATNSimulator>()->atn;
494
0
  ParserRuleContext *ctx = _ctx;
495
0
  atn::ATNState *s = atn.states[getState()];
496
0
  misc::IntervalSet following = atn.nextTokens(s);
497
498
0
  if (following.contains(symbol)) {
499
0
    return true;
500
0
  }
501
502
0
  if (!following.contains(Token::EPSILON)) {
503
0
    return false;
504
0
  }
505
506
0
  while (ctx && ctx->invokingState != ATNState::INVALID_STATE_NUMBER && following.contains(Token::EPSILON)) {
507
0
    atn::ATNState *invokingState = atn.states[ctx->invokingState];
508
0
    const atn::RuleTransition *rt = static_cast<const atn::RuleTransition*>(invokingState->transitions[0].get());
509
0
    following = atn.nextTokens(rt->followState);
510
0
    if (following.contains(symbol)) {
511
0
      return true;
512
0
    }
513
514
0
    ctx = downCast<ParserRuleContext*>(ctx->parent);
515
0
  }
516
517
0
  if (following.contains(Token::EPSILON) && symbol == EOF) {
518
0
    return true;
519
0
  }
520
521
0
  return false;
522
0
}
523
524
0
bool Parser::isMatchedEOF() const {
525
0
  return _matchedEOF;
526
0
}
527
528
24.4k
misc::IntervalSet Parser::getExpectedTokens() {
529
24.4k
  return getATN().getExpectedTokens(getState(), getContext());
530
24.4k
}
531
532
0
misc::IntervalSet Parser::getExpectedTokensWithinCurrentRule() {
533
0
  const atn::ATN &atn = getInterpreter<atn::ParserATNSimulator>()->atn;
534
0
  atn::ATNState *s = atn.states[getState()];
535
0
  return atn.nextTokens(s);
536
0
}
537
538
0
size_t Parser::getRuleIndex(const std::string &ruleName) {
539
0
  const std::map<std::string, size_t> &m = getRuleIndexMap();
540
0
  auto iterator = m.find(ruleName);
541
0
  if (iterator == m.end()) {
542
0
    return INVALID_INDEX;
543
0
  }
544
0
  return iterator->second;
545
0
}
546
547
0
ParserRuleContext* Parser::getRuleContext() {
548
0
  return _ctx;
549
0
}
550
551
0
std::vector<std::string> Parser::getRuleInvocationStack() {
552
0
  return getRuleInvocationStack(_ctx);
553
0
}
554
555
0
std::vector<std::string> Parser::getRuleInvocationStack(RuleContext *p) {
556
0
  std::vector<std::string> const& ruleNames = getRuleNames();
557
0
  std::vector<std::string> stack;
558
0
  RuleContext *run = p;
559
0
  while (run != nullptr) {
560
    // compute what follows who invoked us
561
0
    size_t ruleIndex = run->getRuleIndex();
562
0
    if (ruleIndex == INVALID_INDEX ) {
563
0
      stack.push_back("n/a");
564
0
    } else {
565
0
      stack.push_back(ruleNames[ruleIndex]);
566
0
    }
567
0
    if (!RuleContext::is(run->parent)) {
568
0
      break;
569
0
    }
570
0
    run = downCast<RuleContext*>(run->parent);
571
0
  }
572
0
  return stack;
573
0
}
574
575
0
std::vector<std::string> Parser::getDFAStrings() {
576
0
  atn::ParserATNSimulator *simulator = getInterpreter<atn::ParserATNSimulator>();
577
0
  if (!simulator->decisionToDFA.empty()) {
578
0
    UniqueLock<Mutex> lck(_mutex);
579
580
0
    std::vector<std::string> s;
581
0
    for (size_t d = 0; d < simulator->decisionToDFA.size(); d++) {
582
0
      dfa::DFA &dfa = simulator->decisionToDFA[d];
583
0
      s.push_back(dfa.toString(getVocabulary()));
584
0
    }
585
0
    return s;
586
0
  }
587
0
  return std::vector<std::string>();
588
0
}
589
590
0
void Parser::dumpDFA() {
591
0
  atn::ParserATNSimulator *simulator = getInterpreter<atn::ParserATNSimulator>();
592
0
  if (!simulator->decisionToDFA.empty()) {
593
0
    UniqueLock<Mutex> lck(_mutex);
594
0
    bool seenOne = false;
595
0
    for (size_t d = 0; d < simulator->decisionToDFA.size(); d++) {
596
0
      dfa::DFA &dfa = simulator->decisionToDFA[d];
597
0
      if (!dfa.states.empty()) {
598
0
        if (seenOne) {
599
0
          std::cout << std::endl;
600
0
        }
601
0
        std::cout << "Decision " << dfa.decision << ":" << std::endl;
602
0
        std::cout << dfa.toString(getVocabulary());
603
0
        seenOne = true;
604
0
      }
605
0
    }
606
0
  }
607
0
}
608
609
0
std::string Parser::getSourceName() {
610
0
  return _input->getSourceName();
611
0
}
612
613
0
atn::ParseInfo Parser::getParseInfo() const {
614
0
  atn::ParserATNSimulator *simulator = getInterpreter<atn::ParserATNSimulator>();
615
0
  return atn::ParseInfo(dynamic_cast<atn::ProfilingATNSimulator*>(simulator));
616
0
}
617
618
0
void Parser::setProfile(bool profile) {
619
0
  atn::ParserATNSimulator *interp = getInterpreter<atn::ParserATNSimulator>();
620
0
  atn::PredictionMode saveMode = interp != nullptr ? interp->getPredictionMode() : atn::PredictionMode::LL;
621
0
  if (profile) {
622
0
    if (!is<atn::ProfilingATNSimulator *>(interp)) {
623
0
      setInterpreter(new atn::ProfilingATNSimulator(this)); /* mem-check: replacing existing interpreter which gets deleted. */
624
0
    }
625
0
  } else if (is<atn::ProfilingATNSimulator *>(interp)) {
626
    /* mem-check: replacing existing interpreter which gets deleted. */
627
0
    atn::ParserATNSimulator *sim = new atn::ParserATNSimulator(this, getATN(), interp->decisionToDFA, interp->getSharedContextCache());
628
0
    setInterpreter(sim);
629
0
  }
630
0
  getInterpreter<atn::ParserATNSimulator>()->setPredictionMode(saveMode);
631
0
}
632
633
4.20k
void Parser::setTrace(bool trace) {
634
4.20k
  if (!trace) {
635
4.20k
    if (_tracer)
636
0
      removeParseListener(_tracer);
637
4.20k
    delete _tracer;
638
4.20k
    _tracer = nullptr;
639
4.20k
  } else {
640
0
    if (_tracer)
641
0
      removeParseListener(_tracer); // Just in case this is triggered multiple times.
642
0
    _tracer = new TraceListener(this);
643
0
    addParseListener(_tracer);
644
0
  }
645
4.20k
}
646
647
0
bool Parser::isTrace() const {
648
0
  return _tracer != nullptr;
649
0
}
650
651
6.47M
tree::TerminalNode *Parser::createTerminalNode(Token *t) {
652
6.47M
  return _tracker.createInstance<tree::TerminalNodeImpl>(t);
653
6.47M
}
654
655
59.7k
tree::ErrorNode *Parser::createErrorNode(Token *t) {
656
59.7k
  return _tracker.createInstance<tree::ErrorNodeImpl>(t);
657
59.7k
}
658
659
4.20k
void Parser::InitializeInstanceFields() {
660
4.20k
  _errHandler = std::make_shared<DefaultErrorStrategy>();
661
4.20k
  _precedenceStack.clear();
662
4.20k
  _precedenceStack.push_back(0);
663
4.20k
  _buildParseTrees = true;
664
4.20k
  _syntaxErrors = 0;
665
4.20k
  _matchedEOF = false;
666
4.20k
  _input = nullptr;
667
4.20k
  _tracer = nullptr;
668
4.20k
  _ctx = nullptr;
669
4.20k
}
670