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 "ConsoleErrorListener.h"
7 #include "RecognitionException.h"
8 #include "support/CPPUtils.h"
9 #include "support/StringUtils.h"
10 #include "Token.h"
11 #include "atn/ATN.h"
12 #include "atn/ATNSimulator.h"
13 #include "support/CPPUtils.h"
14
15 #include "Vocabulary.h"
16
17 #include "Recognizer.h"
18
19 using namespace antlr4;
20 using namespace antlr4::atn;
21
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;
24
Recognizer()25 Recognizer::Recognizer() {
26 InitializeInstanceFields();
27 _proxListener.addErrorListener(&ConsoleErrorListener::INSTANCE);
28 }
29
~Recognizer()30 Recognizer::~Recognizer() {
31 }
32
getVocabulary() const33 dfa::Vocabulary const& Recognizer::getVocabulary() const {
34 static dfa::Vocabulary vocabulary = dfa::Vocabulary::fromTokenNames(getTokenNames());
35 return vocabulary;
36 }
37
getTokenTypeMap()38 std::map<std::string, size_t> Recognizer::getTokenTypeMap() {
39 const dfa::Vocabulary& vocabulary = getVocabulary();
40
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;
46 } else {
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;
51 }
52
53 std::string symbolicName = vocabulary.getSymbolicName(i);
54 if (!symbolicName.empty()) {
55 result[symbolicName] = i;
56 }
57 }
58 result["EOF"] = EOF;
59 _tokenTypeMapCache[&vocabulary] = result;
60 }
61
62 return result;
63 }
64
getRuleIndexMap()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.";
69 }
70
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;
76 } else {
77 result = antlrcpp::toMap(ruleNames);
78 _ruleIndexMapCache[ruleNames] = result;
79 }
80 return result;
81 }
82
getTokenType(const std::string & tokenName)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;
88
89 return iterator->second;
90 }
91
setInterpreter(atn::ATNSimulator * interpreter)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.
95 delete _interpreter;
96 _interpreter = interpreter;
97 }
98
getErrorHeader(RecognitionException * e)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);
105
106 }
107
getTokenErrorDisplay(Token * t)108 std::string Recognizer::getTokenErrorDisplay(Token *t) {
109 if (t == nullptr) {
110 return "<no Token>";
111 }
112 std::string s = t->getText();
113 if (s == "") {
114 if (t->getType() == EOF) {
115 s = "<EOF>";
116 } else {
117 s = std::string("<") + std::to_string(t->getType()) + std::string(">");
118 }
119 }
120
121 antlrcpp::replaceAll(s, "\n", "\\n");
122 antlrcpp::replaceAll(s, "\r","\\r");
123 antlrcpp::replaceAll(s, "\t", "\\t");
124
125 return "'" + s + "'";
126 }
127
addErrorListener(ANTLRErrorListener * listener)128 void Recognizer::addErrorListener(ANTLRErrorListener *listener) {
129 _proxListener.addErrorListener(listener);
130 }
131
removeErrorListener(ANTLRErrorListener * listener)132 void Recognizer::removeErrorListener(ANTLRErrorListener *listener) {
133 _proxListener.removeErrorListener(listener);
134 }
135
removeErrorListeners()136 void Recognizer::removeErrorListeners() {
137 _proxListener.removeErrorListeners();
138 }
139
getErrorListenerDispatch()140 ProxyErrorListener& Recognizer::getErrorListenerDispatch() {
141 return _proxListener;
142 }
143
sempred(RuleContext *,size_t,size_t)144 bool Recognizer::sempred(RuleContext * /*localctx*/, size_t /*ruleIndex*/, size_t /*actionIndex*/) {
145 return true;
146 }
147
precpred(RuleContext *,int)148 bool Recognizer::precpred(RuleContext * /*localctx*/, int /*precedence*/) {
149 return true;
150 }
151
action(RuleContext *,size_t,size_t)152 void Recognizer::action(RuleContext * /*localctx*/, size_t /*ruleIndex*/, size_t /*actionIndex*/) {
153 }
154
getState() const155 size_t Recognizer::getState() const {
156 return _stateNumber;
157 }
158
setState(size_t atnState)159 void Recognizer::setState(size_t atnState) {
160 _stateNumber = atnState;
161 }
162
InitializeInstanceFields()163 void Recognizer::InitializeInstanceFields() {
164 _stateNumber = ATNState::INVALID_STATE_NUMBER;
165 _interpreter = nullptr;
166 }
167
168