]> gitweb.ps.run Git - toc/blob - antlr4-cpp-runtime-4.9.2-source/runtime/src/atn/LexerActionExecutor.cpp
add antlr source code and ReadMe
[toc] / antlr4-cpp-runtime-4.9.2-source / runtime / src / atn / LexerActionExecutor.cpp
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 "misc/MurmurHash.h"
7 #include "atn/LexerIndexedCustomAction.h"
8 #include "support/CPPUtils.h"
9 #include "support/Arrays.h"
10
11 #include "atn/LexerActionExecutor.h"
12
13 using namespace antlr4;
14 using namespace antlr4::atn;
15 using namespace antlr4::misc;
16 using namespace antlrcpp;
17
18 LexerActionExecutor::LexerActionExecutor(const std::vector<Ref<LexerAction>> &lexerActions)
19   : _lexerActions(lexerActions), _hashCode(generateHashCode()) {
20 }
21
22 LexerActionExecutor::~LexerActionExecutor() {
23 }
24
25 Ref<LexerActionExecutor> LexerActionExecutor::append(Ref<LexerActionExecutor> const& lexerActionExecutor,
26                                                      Ref<LexerAction> const& lexerAction) {
27   if (lexerActionExecutor == nullptr) {
28     return std::make_shared<LexerActionExecutor>(std::vector<Ref<LexerAction>> { lexerAction });
29   }
30
31   std::vector<Ref<LexerAction>> lexerActions = lexerActionExecutor->_lexerActions; // Make a copy.
32   lexerActions.push_back(lexerAction);
33   return std::make_shared<LexerActionExecutor>(lexerActions);
34 }
35
36 Ref<LexerActionExecutor> LexerActionExecutor::fixOffsetBeforeMatch(int offset) {
37   std::vector<Ref<LexerAction>> updatedLexerActions;
38   for (size_t i = 0; i < _lexerActions.size(); i++) {
39     if (_lexerActions[i]->isPositionDependent() && !is<LexerIndexedCustomAction>(_lexerActions[i])) {
40       if (updatedLexerActions.empty()) {
41         updatedLexerActions = _lexerActions; // Make a copy.
42       }
43
44       updatedLexerActions[i] = std::make_shared<LexerIndexedCustomAction>(offset, _lexerActions[i]);
45     }
46   }
47
48   if (updatedLexerActions.empty()) {
49     return shared_from_this();
50   }
51
52   return std::make_shared<LexerActionExecutor>(updatedLexerActions);
53 }
54
55 std::vector<Ref<LexerAction>> LexerActionExecutor::getLexerActions() const {
56   return _lexerActions;
57 }
58
59 void LexerActionExecutor::execute(Lexer *lexer, CharStream *input, size_t startIndex) {
60   bool requiresSeek = false;
61   size_t stopIndex = input->index();
62
63   auto onExit = finally([requiresSeek, input, stopIndex]() {
64     if (requiresSeek) {
65       input->seek(stopIndex);
66     }
67   });
68   for (auto lexerAction : _lexerActions) {
69     if (is<LexerIndexedCustomAction>(lexerAction)) {
70       int offset = (std::static_pointer_cast<LexerIndexedCustomAction>(lexerAction))->getOffset();
71       input->seek(startIndex + offset);
72       lexerAction = std::static_pointer_cast<LexerIndexedCustomAction>(lexerAction)->getAction();
73       requiresSeek = (startIndex + offset) != stopIndex;
74     } else if (lexerAction->isPositionDependent()) {
75       input->seek(stopIndex);
76       requiresSeek = false;
77     }
78
79     lexerAction->execute(lexer);
80   }
81 }
82
83 size_t LexerActionExecutor::hashCode() const {
84   return _hashCode;
85 }
86
87 bool LexerActionExecutor::operator == (const LexerActionExecutor &obj) const {
88   if (&obj == this) {
89     return true;
90   }
91
92   return _hashCode == obj._hashCode && Arrays::equals(_lexerActions, obj._lexerActions);
93 }
94
95 bool LexerActionExecutor::operator != (const LexerActionExecutor &obj) const {
96   return !operator==(obj);
97 }
98
99 size_t LexerActionExecutor::generateHashCode() const {
100   size_t hash = MurmurHash::initialize();
101   for (auto lexerAction : _lexerActions) {
102     hash = MurmurHash::update(hash, lexerAction);
103   }
104   hash = MurmurHash::finish(hash, _lexerActions.size());
105
106   return hash;
107 }