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.
8 #include "atn/ATNSimulator.h"
9 #include "atn/LexerATNConfig.h"
10 #include "atn/ATNConfigSet.h"
15 /// "dup" of ParserInterpreter
16 class ANTLR4CPP_PUBLIC LexerATNSimulator : public ATNSimulator {
26 dfa::DFAState *dfaState;
28 friend class LexerATNSimulator;
31 void InitializeInstanceFields();
35 InitializeInstanceFields();
41 #if __cplusplus >= 201703L
42 static constexpr size_t MIN_DFA_EDGE = 0;
43 static constexpr size_t MAX_DFA_EDGE = 127; // forces unicode to stay in ATN
47 MAX_DFA_EDGE = 127, // forces unicode to stay in ATN
53 /// When we hit an accept state in either the DFA or the ATN, we
54 /// have to notify the character stream to start buffering characters
55 /// via <seealso cref="IntStream#mark"/> and record the current state. The current sim state
56 /// includes the current index into the input, the current line,
57 /// and current character position in that line. Note that the Lexer is
58 /// tracking the starting line and characterization of the token. These
59 /// variables track the "state" of the simulator when it hits an accept state.
61 /// We track these variables separately for the DFA and ATN simulation
62 /// because the DFA simulation often has to fail over to the ATN
63 /// simulation. If the ATN simulation fails, we need the DFA to fall
64 /// back to its previously accepted state, if any. If the ATN succeeds,
65 /// then the ATN does the accept and the DFA simulator that invoked it
66 /// can simply return the predicted token type.
70 /// The current token's starting index into the character stream.
71 /// Shared across DFA to ATN simulation in case the ATN fails and the
72 /// DFA did not have a previous accept state. In this case, we use the
73 /// ATN-generated exception object.
76 /// line number 1..n within the input.
79 /// The index of the character relative to the beginning of the line 0..n-1.
80 size_t _charPositionInLine;
83 std::vector<dfa::DFA> &_decisionToDFA;
88 /// Used during DFA/ATN exec to record the most recent accept configuration info.
92 static int match_calls;
94 LexerATNSimulator(const ATN &atn, std::vector<dfa::DFA> &decisionToDFA, PredictionContextCache &sharedContextCache);
95 LexerATNSimulator(Lexer *recog, const ATN &atn, std::vector<dfa::DFA> &decisionToDFA, PredictionContextCache &sharedContextCache);
96 virtual ~LexerATNSimulator () {}
98 virtual void copyState(LexerATNSimulator *simulator);
99 virtual size_t match(CharStream *input, size_t mode);
100 virtual void reset() override;
102 virtual void clearDFA() override;
105 virtual size_t matchATN(CharStream *input);
106 virtual size_t execATN(CharStream *input, dfa::DFAState *ds0);
109 /// Get an existing target state for an edge in the DFA. If the target state
110 /// for the edge has not yet been computed or is otherwise not available,
111 /// this method returns {@code null}.
113 /// <param name="s"> The current DFA state </param>
114 /// <param name="t"> The next input symbol </param>
115 /// <returns> The existing target DFA state for the given input symbol
116 /// {@code t}, or {@code null} if the target state for this edge is not
117 /// already cached </returns>
118 virtual dfa::DFAState *getExistingTargetState(dfa::DFAState *s, size_t t);
121 /// Compute a target state for an edge in the DFA, and attempt to add the
122 /// computed state and corresponding edge to the DFA.
124 /// <param name="input"> The input stream </param>
125 /// <param name="s"> The current DFA state </param>
126 /// <param name="t"> The next input symbol
128 /// <returns> The computed target DFA state for the given input symbol
129 /// {@code t}. If {@code t} does not lead to a valid DFA state, this method
130 /// returns <seealso cref="#ERROR"/>. </returns>
131 virtual dfa::DFAState *computeTargetState(CharStream *input, dfa::DFAState *s, size_t t);
133 virtual size_t failOrAccept(CharStream *input, ATNConfigSet *reach, size_t t);
136 /// Given a starting configuration set, figure out all ATN configurations
137 /// we can reach upon input {@code t}. Parameter {@code reach} is a return
140 void getReachableConfigSet(CharStream *input, ATNConfigSet *closure_, // closure_ as we have a closure() already
141 ATNConfigSet *reach, size_t t);
143 virtual void accept(CharStream *input, const Ref<LexerActionExecutor> &lexerActionExecutor, size_t startIndex, size_t index,
144 size_t line, size_t charPos);
146 virtual ATNState *getReachableTarget(Transition *trans, size_t t);
148 virtual std::unique_ptr<ATNConfigSet> computeStartState(CharStream *input, ATNState *p);
151 /// Since the alternatives within any lexer decision are ordered by
152 /// preference, this method stops pursuing the closure as soon as an accept
153 /// state is reached. After the first accept state is reached by depth-first
154 /// search from {@code config}, all other (potentially reachable) states for
155 /// this rule would have a lower priority.
157 /// <returns> {@code true} if an accept state is reached, otherwise
158 /// {@code false}. </returns>
159 virtual bool closure(CharStream *input, const Ref<LexerATNConfig> &config, ATNConfigSet *configs,
160 bool currentAltReachedAcceptState, bool speculative, bool treatEofAsEpsilon);
162 // side-effect: can alter configs.hasSemanticContext
163 virtual Ref<LexerATNConfig> getEpsilonTarget(CharStream *input, const Ref<LexerATNConfig> &config, Transition *t,
164 ATNConfigSet *configs, bool speculative, bool treatEofAsEpsilon);
167 /// Evaluate a predicate specified in the lexer.
169 /// If {@code speculative} is {@code true}, this method was called before
170 /// <seealso cref="#consume"/> for the matched character. This method should call
171 /// <seealso cref="#consume"/> before evaluating the predicate to ensure position
172 /// sensitive values, including <seealso cref="Lexer#getText"/>, <seealso cref="Lexer#getLine"/>,
173 /// and <seealso cref="Lexer#getCharPositionInLine"/>, properly reflect the current
174 /// lexer state. This method should restore {@code input} and the simulator
175 /// to the original state before returning (i.e. undo the actions made by the
176 /// call to <seealso cref="#consume"/>.
178 /// <param name="input"> The input stream. </param>
179 /// <param name="ruleIndex"> The rule containing the predicate. </param>
180 /// <param name="predIndex"> The index of the predicate within the rule. </param>
181 /// <param name="speculative"> {@code true} if the current index in {@code input} is
182 /// one character before the predicate's location.
184 /// <returns> {@code true} if the specified predicate evaluates to
185 /// {@code true}. </returns>
186 virtual bool evaluatePredicate(CharStream *input, size_t ruleIndex, size_t predIndex, bool speculative);
188 virtual void captureSimState(CharStream *input, dfa::DFAState *dfaState);
189 virtual dfa::DFAState* addDFAEdge(dfa::DFAState *from, size_t t, ATNConfigSet *q);
190 virtual void addDFAEdge(dfa::DFAState *p, size_t t, dfa::DFAState *q);
193 /// Add a new DFA state if there isn't one with this set of
194 /// configurations already. This method also detects the first
195 /// configuration containing an ATN rule stop state. Later, when
196 /// traversing the DFA, we will know which rule to accept.
198 virtual dfa::DFAState *addDFAState(ATNConfigSet *configs);
201 dfa::DFA& getDFA(size_t mode);
203 /// Get the text matched so far for the current token.
204 virtual std::string getText(CharStream *input);
205 virtual size_t getLine() const;
206 virtual void setLine(size_t line);
207 virtual size_t getCharPositionInLine();
208 virtual void setCharPositionInLine(size_t charPositionInLine);
209 virtual void consume(CharStream *input);
210 virtual std::string getTokenName(size_t t);
213 void InitializeInstanceFields();
217 } // namespace antlr4