/* 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.
*/
#pragma once
#include "CharStream.h"
#include "atn/LexerAction.h"
namespace antlr4 {
namespace atn {
/// Represents an executor for a sequence of lexer actions which traversed during
/// the matching operation of a lexer rule (token).
///
/// The executor tracks position information for position-dependent lexer actions
/// efficiently, ensuring that actions appearing only at the end of the rule do
/// not cause bloating of the created for the lexer.
class ANTLR4CPP_PUBLIC LexerActionExecutor final : public std::enable_shared_from_this {
public:
///
/// Constructs an executor for a sequence of actions.
/// The lexer actions to execute.
explicit LexerActionExecutor(std::vector[> lexerActions);
///
/// Creates a which executes the actions for
/// the input {@code lexerActionExecutor} followed by a specified
/// {@code lexerAction}.
///
/// The executor for actions already traversed by
/// the lexer while matching a token within a particular
/// . If this is {@code null}, the method behaves as
/// though it were an empty executor.
/// The lexer action to execute after the actions
/// specified in {@code lexerActionExecutor}.
///
/// A for executing the combine actions
/// of {@code lexerActionExecutor} and {@code lexerAction}.
static Ref append(const Ref &lexerActionExecutor,
Ref lexerAction);
///
/// Creates a which encodes the current offset
/// for position-dependent lexer actions.
///
/// Normally, when the executor encounters lexer actions where
/// returns {@code true}, it calls
/// on the input to set the input
/// position to the end of the current token. This behavior provides
/// for efficient DFA representation of lexer actions which appear at the end
/// of a lexer rule, even when the lexer rule matches a variable number of
/// characters.
///
/// Prior to traversing a match transition in the ATN, the current offset
/// from the token start index is assigned to all position-dependent lexer
/// actions which have not already been assigned a fixed offset. By storing
/// the offsets relative to the token start index, the DFA representation of
/// lexer actions which appear in the middle of tokens remains efficient due
/// to sharing among tokens of the same length, regardless of their absolute
/// position in the input stream.
///
/// If the current executor already has offsets assigned to all
/// position-dependent lexer actions, the method returns {@code this}.
///
/// The current offset to assign to all position-dependent
/// lexer actions which do not already have offsets assigned.
///
/// A which stores input stream offsets
/// for all position-dependent lexer actions.
Ref fixOffsetBeforeMatch(int offset) const;
///
/// Gets the lexer actions to be executed by this executor.
/// The lexer actions to be executed by this executor.
const std::vector][>& getLexerActions() const;
///
/// Execute the actions encapsulated by this executor within the context of a
/// particular .
///
/// This method calls to set the position of the
/// {@code input} prior to calling
/// on a position-dependent action. Before the
/// method returns, the input position will be restored to the same position
/// it was in when the method was invoked.
///
/// The lexer instance.
/// The input stream which is the source for the current token.
/// When this method is called, the current for
/// {@code input} should be the start of the following token, i.e. 1
/// character past the end of the current token.
/// The token start index. This value may be passed to
/// to set the {@code input} position to the beginning
/// of the token.
void execute(Lexer *lexer, CharStream *input, size_t startIndex) const;
size_t hashCode() const;
bool equals(const LexerActionExecutor &other) const;
private:
const std::vector][> _lexerActions;
mutable std::atomic _hashCode;
};
inline bool operator==(const LexerActionExecutor &lhs, const LexerActionExecutor &rhs) {
return lhs.equals(rhs);
}
inline bool operator!=(const LexerActionExecutor &lhs, const LexerActionExecutor &rhs) {
return !operator==(lhs, rhs);
}
} // namespace atn
} // namespace antlr4
namespace std {
template <>
struct hash<::antlr4::atn::LexerActionExecutor> {
size_t operator()(const ::antlr4::atn::LexerActionExecutor &lexerActionExecutor) const {
return lexerActionExecutor.hashCode();
}
};
} // namespace std
]