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.
6 #include "ConsoleErrorListener.h"
7 #include "RecognitionException.h"
8 #include "support/CPPUtils.h"
9 #include "support/StringUtils.h"
12 #include "atn/ATNSimulator.h"
13 #include "support/CPPUtils.h"
15 #include "Vocabulary.h"
17 #include "Recognizer.h"
19 using namespace antlr4;
20 using namespace antlr4::atn;
22 std::map<const dfa::Vocabulary*, std::map<std::string, size_t>> Recognizer::_tokenTypeMapCache;
23 std::map<std::vector<std::string>, std::map<std::string, size_t>> Recognizer::_ruleIndexMapCache;
25 Recognizer::Recognizer() {
26 InitializeInstanceFields();
27 _proxListener.addErrorListener(&ConsoleErrorListener::INSTANCE);
30 Recognizer::~Recognizer() {
33 dfa::Vocabulary const& Recognizer::getVocabulary() const {
34 static dfa::Vocabulary vocabulary = dfa::Vocabulary::fromTokenNames(getTokenNames());
38 std::map<std::string, size_t> Recognizer::getTokenTypeMap() {
39 const dfa::Vocabulary& vocabulary = getVocabulary();
41 std::lock_guard<std::mutex> lck(_mutex);
42 std::map<std::string, size_t> result;
43 auto iterator = _tokenTypeMapCache.find(&vocabulary);
44 if (iterator != _tokenTypeMapCache.end()) {
45 result = iterator->second;
47 for (size_t i = 0; i <= getATN().maxTokenType; ++i) {
48 std::string literalName = vocabulary.getLiteralName(i);
49 if (!literalName.empty()) {
50 result[literalName] = i;
53 std::string symbolicName = vocabulary.getSymbolicName(i);
54 if (!symbolicName.empty()) {
55 result[symbolicName] = i;
59 _tokenTypeMapCache[&vocabulary] = result;
65 std::map<std::string, size_t> Recognizer::getRuleIndexMap() {
66 const std::vector<std::string>& ruleNames = getRuleNames();
67 if (ruleNames.empty()) {
68 throw "The current recognizer does not provide a list of rule names.";
71 std::lock_guard<std::mutex> lck(_mutex);
72 std::map<std::string, size_t> result;
73 auto iterator = _ruleIndexMapCache.find(ruleNames);
74 if (iterator != _ruleIndexMapCache.end()) {
75 result = iterator->second;
77 result = antlrcpp::toMap(ruleNames);
78 _ruleIndexMapCache[ruleNames] = result;
83 size_t Recognizer::getTokenType(const std::string &tokenName) {
84 const std::map<std::string, size_t> &map = getTokenTypeMap();
85 auto iterator = map.find(tokenName);
86 if (iterator == map.end())
87 return Token::INVALID_TYPE;
89 return iterator->second;
92 void Recognizer::setInterpreter(atn::ATNSimulator *interpreter) {
93 // Usually the interpreter is set by the descendant (lexer or parser (simulator), but can also be exchanged
94 // by the profiling ATN simulator.
96 _interpreter = interpreter;
99 std::string Recognizer::getErrorHeader(RecognitionException *e) {
100 // We're having issues with cross header dependencies, these two classes will need to be
101 // rewritten to remove that.
102 size_t line = e->getOffendingToken()->getLine();
103 size_t charPositionInLine = e->getOffendingToken()->getCharPositionInLine();
104 return std::string("line ") + std::to_string(line) + ":" + std::to_string(charPositionInLine);
108 std::string Recognizer::getTokenErrorDisplay(Token *t) {
112 std::string s = t->getText();
114 if (t->getType() == EOF) {
117 s = std::string("<") + std::to_string(t->getType()) + std::string(">");
121 antlrcpp::replaceAll(s, "\n", "\\n");
122 antlrcpp::replaceAll(s, "\r","\\r");
123 antlrcpp::replaceAll(s, "\t", "\\t");
125 return "'" + s + "'";
128 void Recognizer::addErrorListener(ANTLRErrorListener *listener) {
129 _proxListener.addErrorListener(listener);
132 void Recognizer::removeErrorListener(ANTLRErrorListener *listener) {
133 _proxListener.removeErrorListener(listener);
136 void Recognizer::removeErrorListeners() {
137 _proxListener.removeErrorListeners();
140 ProxyErrorListener& Recognizer::getErrorListenerDispatch() {
141 return _proxListener;
144 bool Recognizer::sempred(RuleContext * /*localctx*/, size_t /*ruleIndex*/, size_t /*actionIndex*/) {
148 bool Recognizer::precpred(RuleContext * /*localctx*/, int /*precedence*/) {
152 void Recognizer::action(RuleContext * /*localctx*/, size_t /*ruleIndex*/, size_t /*actionIndex*/) {
155 size_t Recognizer::getState() const {
159 void Recognizer::setState(size_t atnState) {
160 _stateNumber = atnState;
163 void Recognizer::InitializeInstanceFields() {
164 _stateNumber = ATNState::INVALID_STATE_NUMBER;
165 _interpreter = nullptr;