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/ParserInterpreter.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 "dfa/DFA.h"
7
#include "atn/RuleStartState.h"
8
#include "InterpreterRuleContext.h"
9
#include "atn/ParserATNSimulator.h"
10
#include "ANTLRErrorStrategy.h"
11
#include "atn/LoopEndState.h"
12
#include "FailedPredicateException.h"
13
#include "atn/StarLoopEntryState.h"
14
#include "atn/AtomTransition.h"
15
#include "atn/RuleTransition.h"
16
#include "atn/PredicateTransition.h"
17
#include "atn/PrecedencePredicateTransition.h"
18
#include "atn/ActionTransition.h"
19
#include "atn/ATN.h"
20
#include "atn/RuleStopState.h"
21
#include "Lexer.h"
22
#include "Token.h"
23
#include "Vocabulary.h"
24
#include "InputMismatchException.h"
25
#include "CommonToken.h"
26
#include "tree/ErrorNode.h"
27
28
#include "support/CPPUtils.h"
29
#include "support/Casts.h"
30
31
#include "ParserInterpreter.h"
32
33
using namespace antlr4;
34
using namespace antlr4::atn;
35
using namespace antlr4::misc;
36
37
using namespace antlrcpp;
38
39
ParserInterpreter::ParserInterpreter(const std::string &grammarFileName, const dfa::Vocabulary &vocabulary,
40
  const std::vector<std::string> &ruleNames, const atn::ATN &atn, TokenStream *input)
41
0
  : Parser(input), _grammarFileName(grammarFileName), _atn(atn), _ruleNames(ruleNames), _vocabulary(vocabulary) {
42
43
  // init decision DFA
44
0
  for (size_t i = 0; i < atn.getNumberOfDecisions(); ++i) {
45
0
    atn::DecisionState *decisionState = atn.getDecisionState(i);
46
0
    _decisionToDFA.push_back(dfa::DFA(decisionState, i));
47
0
  }
48
49
  // get atn simulator that knows how to do predictions
50
0
  _interpreter = new atn::ParserATNSimulator(this, atn, _decisionToDFA, _sharedContextCache); /* mem-check: deleted in d-tor */
51
0
}
52
53
0
ParserInterpreter::~ParserInterpreter() {
54
0
  delete _interpreter;
55
0
}
56
57
0
void ParserInterpreter::reset() {
58
0
  Parser::reset();
59
0
  _overrideDecisionReached = false;
60
0
  _overrideDecisionRoot = nullptr;
61
0
}
62
63
0
const atn::ATN& ParserInterpreter::getATN() const {
64
0
  return _atn;
65
0
}
66
67
0
const dfa::Vocabulary& ParserInterpreter::getVocabulary() const {
68
0
  return _vocabulary;
69
0
}
70
71
0
const std::vector<std::string>& ParserInterpreter::getRuleNames() const {
72
0
  return _ruleNames;
73
0
}
74
75
0
std::string ParserInterpreter::getGrammarFileName() const {
76
0
  return _grammarFileName;
77
0
}
78
79
0
ParserRuleContext* ParserInterpreter::parse(size_t startRuleIndex) {
80
0
  atn::RuleStartState *startRuleStartState = _atn.ruleToStartState[startRuleIndex];
81
82
0
  _rootContext = createInterpreterRuleContext(nullptr, atn::ATNState::INVALID_STATE_NUMBER, startRuleIndex);
83
84
0
  if (startRuleStartState->isLeftRecursiveRule) {
85
0
    enterRecursionRule(_rootContext, startRuleStartState->stateNumber, startRuleIndex, 0);
86
0
  } else {
87
0
    enterRule(_rootContext, startRuleStartState->stateNumber, startRuleIndex);
88
0
  }
89
90
0
  while (true) {
91
0
    atn::ATNState *p = getATNState();
92
0
    switch (p->getStateType()) {
93
0
      case atn::ATNStateType::RULE_STOP :
94
        // pop; return from rule
95
0
        if (_ctx->isEmpty()) {
96
0
          if (startRuleStartState->isLeftRecursiveRule) {
97
0
            ParserRuleContext *result = _ctx;
98
0
            auto parentContext = _parentContextStack.top();
99
0
            _parentContextStack.pop();
100
0
            unrollRecursionContexts(parentContext.first);
101
0
            return result;
102
0
          } else {
103
0
            exitRule();
104
0
            return _rootContext;
105
0
          }
106
0
        }
107
108
0
        visitRuleStopState(p);
109
0
        break;
110
111
0
      default :
112
0
        try {
113
0
          visitState(p);
114
0
        }
115
0
        catch (RecognitionException &e) {
116
0
          setState(_atn.ruleToStopState[p->ruleIndex]->stateNumber);
117
0
          getErrorHandler()->reportError(this, e);
118
0
          getContext()->exception = std::current_exception();
119
0
          recover(e);
120
0
        }
121
122
0
        break;
123
0
    }
124
0
  }
125
0
}
126
127
0
void ParserInterpreter::enterRecursionRule(ParserRuleContext *localctx, size_t state, size_t ruleIndex, int precedence) {
128
0
  _parentContextStack.push({ _ctx, localctx->invokingState });
129
0
  Parser::enterRecursionRule(localctx, state, ruleIndex, precedence);
130
0
}
131
132
0
void ParserInterpreter::addDecisionOverride(int decision, int tokenIndex, int forcedAlt) {
133
0
  _overrideDecision = decision;
134
0
  _overrideDecisionInputIndex = tokenIndex;
135
0
  _overrideDecisionAlt = forcedAlt;
136
0
}
137
138
0
Ref<InterpreterRuleContext> ParserInterpreter::getOverrideDecisionRoot() const {
139
0
  return _overrideDecisionRoot;
140
0
}
141
142
0
InterpreterRuleContext* ParserInterpreter::getRootContext() {
143
0
  return _rootContext;
144
0
}
145
146
0
atn::ATNState* ParserInterpreter::getATNState() {
147
0
  return _atn.states[getState()];
148
0
}
149
150
0
void ParserInterpreter::visitState(atn::ATNState *p) {
151
0
  size_t predictedAlt = 1;
152
0
  if (DecisionState::is(p)) {
153
0
    predictedAlt = visitDecisionState(downCast<DecisionState*>(p));
154
0
  }
155
156
0
  const atn::Transition *transition = p->transitions[predictedAlt - 1].get();
157
0
  switch (transition->getTransitionType()) {
158
0
    case atn::TransitionType::EPSILON:
159
0
      if (p->getStateType() == ATNStateType::STAR_LOOP_ENTRY &&
160
0
        (downCast<StarLoopEntryState *>(p))->isPrecedenceDecision &&
161
0
        !LoopEndState::is(transition->target)) {
162
        // We are at the start of a left recursive rule's (...)* loop
163
        // and we're not taking the exit branch of loop.
164
0
        InterpreterRuleContext *localctx = createInterpreterRuleContext(_parentContextStack.top().first,
165
0
          _parentContextStack.top().second, static_cast<int>(_ctx->getRuleIndex()));
166
0
        pushNewRecursionContext(localctx, _atn.ruleToStartState[p->ruleIndex]->stateNumber, static_cast<int>(_ctx->getRuleIndex()));
167
0
      }
168
0
      break;
169
170
0
    case atn::TransitionType::ATOM:
171
0
      match(static_cast<int>(static_cast<const atn::AtomTransition*>(transition)->_label));
172
0
      break;
173
174
0
    case atn::TransitionType::RANGE:
175
0
    case atn::TransitionType::SET:
176
0
    case atn::TransitionType::NOT_SET:
177
0
      if (!transition->matches(static_cast<int>(_input->LA(1)), Token::MIN_USER_TOKEN_TYPE, Lexer::MAX_CHAR_VALUE)) {
178
0
        recoverInline();
179
0
      }
180
0
      matchWildcard();
181
0
      break;
182
183
0
    case atn::TransitionType::WILDCARD:
184
0
      matchWildcard();
185
0
      break;
186
187
0
    case atn::TransitionType::RULE:
188
0
    {
189
0
      atn::RuleStartState *ruleStartState = static_cast<atn::RuleStartState*>(transition->target);
190
0
      size_t ruleIndex = ruleStartState->ruleIndex;
191
0
      InterpreterRuleContext *newctx = createInterpreterRuleContext(_ctx, p->stateNumber, ruleIndex);
192
0
      if (ruleStartState->isLeftRecursiveRule) {
193
0
        enterRecursionRule(newctx, ruleStartState->stateNumber, ruleIndex, static_cast<const atn::RuleTransition*>(transition)->precedence);
194
0
      } else {
195
0
        enterRule(newctx, transition->target->stateNumber, ruleIndex);
196
0
      }
197
0
    }
198
0
      break;
199
200
0
    case atn::TransitionType::PREDICATE:
201
0
    {
202
0
      const atn::PredicateTransition *predicateTransition = static_cast<const atn::PredicateTransition*>(transition);
203
0
      if (!sempred(_ctx, predicateTransition->getRuleIndex(), predicateTransition->getPredIndex())) {
204
0
        throw FailedPredicateException(this);
205
0
      }
206
0
    }
207
0
      break;
208
209
0
    case atn::TransitionType::ACTION:
210
0
    {
211
0
      const atn::ActionTransition *actionTransition = static_cast<const atn::ActionTransition*>(transition);
212
0
      action(_ctx, actionTransition->ruleIndex, actionTransition->actionIndex);
213
0
    }
214
0
      break;
215
216
0
    case atn::TransitionType::PRECEDENCE:
217
0
    {
218
0
      if (!precpred(_ctx, static_cast<const atn::PrecedencePredicateTransition*>(transition)->getPrecedence())) {
219
0
        throw FailedPredicateException(this, "precpred(_ctx, " + std::to_string(static_cast<const atn::PrecedencePredicateTransition*>(transition)->getPrecedence()) +  ")");
220
0
      }
221
0
    }
222
0
      break;
223
224
0
    default:
225
0
      throw UnsupportedOperationException("Unrecognized ATN transition type.");
226
0
  }
227
228
0
  setState(transition->target->stateNumber);
229
0
}
230
231
0
size_t ParserInterpreter::visitDecisionState(DecisionState *p) {
232
0
  size_t predictedAlt = 1;
233
0
  if (p->transitions.size() > 1) {
234
0
    getErrorHandler()->sync(this);
235
0
    int decision = p->decision;
236
0
    if (decision == _overrideDecision && _input->index() == _overrideDecisionInputIndex && !_overrideDecisionReached) {
237
0
      predictedAlt = _overrideDecisionAlt;
238
0
      _overrideDecisionReached = true;
239
0
    } else {
240
0
      predictedAlt = getInterpreter<ParserATNSimulator>()->adaptivePredict(_input, decision, _ctx);
241
0
    }
242
0
  }
243
0
  return predictedAlt;
244
0
}
245
246
InterpreterRuleContext* ParserInterpreter::createInterpreterRuleContext(ParserRuleContext *parent,
247
0
  size_t invokingStateNumber, size_t ruleIndex) {
248
0
  return _tracker.createInstance<InterpreterRuleContext>(parent, invokingStateNumber, ruleIndex);
249
0
}
250
251
0
void ParserInterpreter::visitRuleStopState(atn::ATNState *p) {
252
0
  atn::RuleStartState *ruleStartState = _atn.ruleToStartState[p->ruleIndex];
253
0
  if (ruleStartState->isLeftRecursiveRule) {
254
0
    std::pair<ParserRuleContext *, size_t> parentContext = _parentContextStack.top();
255
0
    _parentContextStack.pop();
256
257
0
    unrollRecursionContexts(parentContext.first);
258
0
    setState(parentContext.second);
259
0
  } else {
260
0
    exitRule();
261
0
  }
262
263
0
  const atn::RuleTransition *ruleTransition = static_cast<const atn::RuleTransition*>(_atn.states[getState()]->transitions[0].get());
264
0
  setState(ruleTransition->followState->stateNumber);
265
0
}
266
267
0
void ParserInterpreter::recover(RecognitionException &e) {
268
0
  size_t i = _input->index();
269
0
  getErrorHandler()->recover(this, std::make_exception_ptr(e));
270
271
0
  if (_input->index() == i) {
272
    // no input consumed, better add an error node
273
0
    if (is<InputMismatchException *>(&e)) {
274
0
      InputMismatchException &ime = static_cast<InputMismatchException&>(e);
275
0
      Token *tok = e.getOffendingToken();
276
0
      size_t expectedTokenType = ime.getExpectedTokens().getMinElement(); // get any element
277
0
      _errorToken = getTokenFactory()->create({ tok->getTokenSource(), tok->getTokenSource()->getInputStream() },
278
0
        expectedTokenType, tok->getText(), Token::DEFAULT_CHANNEL, INVALID_INDEX, INVALID_INDEX, // invalid start/stop
279
0
        tok->getLine(), tok->getCharPositionInLine());
280
0
      _ctx->addChild(createErrorNode(_errorToken.get()));
281
0
    }
282
0
    else { // NoViableAlt
283
0
      Token *tok = e.getOffendingToken();
284
0
      _errorToken = getTokenFactory()->create({ tok->getTokenSource(), tok->getTokenSource()->getInputStream() },
285
0
        Token::INVALID_TYPE, tok->getText(), Token::DEFAULT_CHANNEL, INVALID_INDEX, INVALID_INDEX, // invalid start/stop
286
0
        tok->getLine(), tok->getCharPositionInLine());
287
0
      _ctx->addChild(createErrorNode(_errorToken.get()));
288
0
    }
289
0
  }
290
0
}
291
292
0
Token* ParserInterpreter::recoverInline() {
293
0
  return _errHandler->recoverInline(this);
294
0
}