/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. * Use of this file is governed by the BSD 3-clause license that * can be found in the LICENSE.txt file in the project root. */ #include "ConsoleErrorListener.h" #include "RecognitionException.h" #include "support/CPPUtils.h" #include "Token.h" #include "atn/ATN.h" #include "atn/ATNSimulator.h" #include "support/CPPUtils.h" #include "support/StringUtils.h" #include "Vocabulary.h" #include "Recognizer.h" using namespace antlr4; using namespace antlr4::atn; using namespace antlr4::internal; std::map> Recognizer::_tokenTypeMapCache; std::map, std::map> Recognizer::_ruleIndexMapCache; Recognizer::Recognizer() { InitializeInstanceFields(); _proxListener.addErrorListener(&ConsoleErrorListener::INSTANCE); } Recognizer::~Recognizer() { } std::map Recognizer::getTokenTypeMap() { const dfa::Vocabulary& vocabulary = getVocabulary(); UniqueLock lck(_mutex); std::map result; auto iterator = _tokenTypeMapCache.find(&vocabulary); if (iterator != _tokenTypeMapCache.end()) { result = iterator->second; } else { for (size_t i = 0; i <= getATN().maxTokenType; ++i) { std::string_view literalName = vocabulary.getLiteralName(i); if (!literalName.empty()) { result[literalName] = i; } std::string_view symbolicName = vocabulary.getSymbolicName(i); if (!symbolicName.empty()) { result[symbolicName] = i; } } result["EOF"] = EOF; _tokenTypeMapCache[&vocabulary] = result; } return result; } std::map Recognizer::getRuleIndexMap() { const std::vector& ruleNames = getRuleNames(); if (ruleNames.empty()) { throw "The current recognizer does not provide a list of rule names."; } UniqueLock lck(_mutex); std::map result; auto iterator = _ruleIndexMapCache.find(ruleNames); if (iterator != _ruleIndexMapCache.end()) { result = iterator->second; } else { result = antlrcpp::toMap(ruleNames); _ruleIndexMapCache[ruleNames] = result; } return result; } size_t Recognizer::getTokenType(std::string_view tokenName) { const std::map &map = getTokenTypeMap(); auto iterator = map.find(tokenName); if (iterator == map.end()) return Token::INVALID_TYPE; return iterator->second; } void Recognizer::setInterpreter(atn::ATNSimulator *interpreter) { // Usually the interpreter is set by the descendant (lexer or parser (simulator), but can also be exchanged // by the profiling ATN simulator. delete _interpreter; _interpreter = interpreter; } std::string Recognizer::getErrorHeader(RecognitionException *e) { // We're having issues with cross header dependencies, these two classes will need to be // rewritten to remove that. size_t line = e->getOffendingToken()->getLine(); size_t charPositionInLine = e->getOffendingToken()->getCharPositionInLine(); return std::string("line ") + std::to_string(line) + ":" + std::to_string(charPositionInLine); } std::string Recognizer::getTokenErrorDisplay(Token *t) { if (t == nullptr) { return ""; } std::string s = t->getText(); if (s == "") { if (t->getType() == EOF) { s = ""; } else { s = std::string("<") + std::to_string(t->getType()) + std::string(">"); } } std::string result; result.reserve(s.size() + 2); result.push_back('\''); antlrcpp::escapeWhitespace(result, s); result.push_back('\''); result.shrink_to_fit(); return result; } void Recognizer::addErrorListener(ANTLRErrorListener *listener) { _proxListener.addErrorListener(listener); } void Recognizer::removeErrorListener(ANTLRErrorListener *listener) { _proxListener.removeErrorListener(listener); } void Recognizer::removeErrorListeners() { _proxListener.removeErrorListeners(); } ProxyErrorListener& Recognizer::getErrorListenerDispatch() { return _proxListener; } bool Recognizer::sempred(RuleContext * /*localctx*/, size_t /*ruleIndex*/, size_t /*actionIndex*/) { return true; } bool Recognizer::precpred(RuleContext * /*localctx*/, int /*precedence*/) { return true; } void Recognizer::action(RuleContext * /*localctx*/, size_t /*ruleIndex*/, size_t /*actionIndex*/) { } void Recognizer::InitializeInstanceFields() { _stateNumber = ATNState::INVALID_STATE_NUMBER; _interpreter = nullptr; }