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