Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[C++] Cleanup ATNDeserializer interface #3326

Merged
merged 2 commits into from
Nov 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ public String execModule(String fileName) {
}

try {
List<String> command2 = new ArrayList<String>(Arrays.asList("clang++", "-std=c++11", "-I", includePath, "-L.", "-lantlr4-runtime", "-o", "a.out"));
List<String> command2 = new ArrayList<String>(Arrays.asList("clang++", "-std=c++11", "-I", includePath, "-L.", "-lantlr4-runtime", "-pthread", "-o", "a.out"));
command2.addAll(allCppFiles(getTempDirPath()));
if (runCommand(command2.toArray(new String[0]), getTempDirPath(), "building test binary", true) == null) {
return null;
Expand Down
4 changes: 2 additions & 2 deletions runtime/Cpp/runtime/src/atn/ATNConfigSet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@ std::vector<ATNState*> ATNConfigSet::getStates() {

BitSet ATNConfigSet::getAlts() {
BitSet alts;
for (const ATNConfig &config : configs) {
alts.set(config.alt);
for (const auto &config : configs) {
alts.set(config->alt);
}
return alts;
}
Expand Down
54 changes: 22 additions & 32 deletions runtime/Cpp/runtime/src/atn/ATNDeserializationOptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,61 +4,51 @@
*/

#include "atn/ATNDeserializationOptions.h"
#include "Exceptions.h"

#include <memory>
#include <mutex>

using namespace antlr4;
using namespace antlr4::atn;

const ATNDeserializationOptions ATNDeserializationOptions::defaultOptions;
namespace {
jcking marked this conversation as resolved.
Show resolved Hide resolved

ATNDeserializationOptions::ATNDeserializationOptions() {
InitializeInstanceFields();
}
std::once_flag defaultATNDeserializationOptionsOnceFlag;
std::unique_ptr<ATNDeserializationOptions> defaultATNDeserializationOptions;

ATNDeserializationOptions::ATNDeserializationOptions(ATNDeserializationOptions *options) : ATNDeserializationOptions() {
this->verifyATN = options->verifyATN;
this->generateRuleBypassTransitions = options->generateRuleBypassTransitions;
void initializeDefaultATNDeserializationOptions() {
defaultATNDeserializationOptions.reset(new ATNDeserializationOptions());
}

ATNDeserializationOptions::~ATNDeserializationOptions() {
}

const ATNDeserializationOptions& ATNDeserializationOptions::getDefaultOptions() {
return defaultOptions;
}
ATNDeserializationOptions::ATNDeserializationOptions(ATNDeserializationOptions *options)
: _readOnly(false), _verifyATN(options->_verifyATN),
_generateRuleBypassTransitions(options->_generateRuleBypassTransitions) {}

bool ATNDeserializationOptions::isReadOnly() {
return readOnly;
const ATNDeserializationOptions& ATNDeserializationOptions::getDefaultOptions() {
std::call_once(defaultATNDeserializationOptionsOnceFlag,
initializeDefaultATNDeserializationOptions);
return *defaultATNDeserializationOptions;
}

void ATNDeserializationOptions::makeReadOnly() {
readOnly = true;
}

bool ATNDeserializationOptions::isVerifyATN() {
return verifyATN;
_readOnly = true;
}

void ATNDeserializationOptions::setVerifyATN(bool verify) {
throwIfReadOnly();
verifyATN = verify;
}

bool ATNDeserializationOptions::isGenerateRuleBypassTransitions() {
return generateRuleBypassTransitions;
_verifyATN = verify;
}

void ATNDeserializationOptions::setGenerateRuleBypassTransitions(bool generate) {
throwIfReadOnly();
generateRuleBypassTransitions = generate;
_generateRuleBypassTransitions = generate;
}

void ATNDeserializationOptions::throwIfReadOnly() {
void ATNDeserializationOptions::throwIfReadOnly() const {
if (isReadOnly()) {
throw "The object is read only.";
throw IllegalStateException("ATNDeserializationOptions is read only.");
}
}

void ATNDeserializationOptions::InitializeInstanceFields() {
readOnly = false;
verifyATN = true;
generateRuleBypassTransitions = false;
}
46 changes: 22 additions & 24 deletions runtime/Cpp/runtime/src/atn/ATNDeserializationOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,41 +10,39 @@
namespace antlr4 {
namespace atn {

class ANTLR4CPP_PUBLIC ATNDeserializationOptions {
private:
static const ATNDeserializationOptions defaultOptions;
class ANTLR4CPP_PUBLIC ATNDeserializationOptions final {
public:
ATNDeserializationOptions()
: _readOnly(false), _verifyATN(true), _generateRuleBypassTransitions(false) {}

bool readOnly;
bool verifyATN;
bool generateRuleBypassTransitions;
// TODO: Is this useful? If so we should mark it as explicit, otherwise remove it.
ATNDeserializationOptions(ATNDeserializationOptions *options);

public:
ATNDeserializationOptions();
ATNDeserializationOptions(ATNDeserializationOptions *options);
ATNDeserializationOptions(ATNDeserializationOptions const&) = default;
virtual ~ATNDeserializationOptions();
ATNDeserializationOptions& operator=(ATNDeserializationOptions const&) = default;
ATNDeserializationOptions(const ATNDeserializationOptions&) = default;

static const ATNDeserializationOptions& getDefaultOptions();
ATNDeserializationOptions& operator=(const ATNDeserializationOptions&) = default;

bool isReadOnly();
static const ATNDeserializationOptions& getDefaultOptions();

void makeReadOnly();
bool isReadOnly() const { return _readOnly; }

bool isVerifyATN();
void makeReadOnly();

void setVerifyATN(bool verify);
bool isVerifyATN() const { return _verifyATN; }

bool isGenerateRuleBypassTransitions();
void setVerifyATN(bool verify);

void setGenerateRuleBypassTransitions(bool generate);
bool isGenerateRuleBypassTransitions() const { return _generateRuleBypassTransitions; }

protected:
virtual void throwIfReadOnly();
void setGenerateRuleBypassTransitions(bool generate);

private:
void InitializeInstanceFields();
};
private:
void throwIfReadOnly() const;

bool _readOnly;
bool _verifyATN;
bool _generateRuleBypassTransitions;
};

} // namespace atn
} // namespace antlr4
63 changes: 49 additions & 14 deletions runtime/Cpp/runtime/src/atn/ATNDeserializer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,47 @@

#include "atn/ATNDeserializer.h"

#include <mutex>
#include <string>
#include <vector>

using namespace antlr4;
using namespace antlr4::atn;
using namespace antlrcpp;

namespace {

struct WellKnownUuids final {
WellKnownUuids() = default;

WellKnownUuids(const WellKnownUuids&) = delete;

WellKnownUuids(WellKnownUuids&&) = delete;

antlrcpp::Guid addedPrecedenceTransitions;
antlrcpp::Guid addedLexerActions;
antlrcpp::Guid addedUnicodeSmp;
antlrcpp::Guid baseSerialized;
std::vector<antlrcpp::Guid> supported;
};

std::once_flag wellKnownUuidsOnceFlag;
std::unique_ptr<WellKnownUuids> wellKnownUuids;

void initializeWellKnownUuids() {
wellKnownUuids.reset(new WellKnownUuids());
wellKnownUuids->addedPrecedenceTransitions = antlrcpp::Guid("1DA0C57D-6C06-438A-9B27-10BCB3CE0F61");
wellKnownUuids->addedLexerActions = antlrcpp::Guid("AADB8D7E-AEEF-4415-AD2B-8204D6CF042E");
wellKnownUuids->addedUnicodeSmp = antlrcpp::Guid("59627784-3BE5-417A-B9EB-8131A7286089");
wellKnownUuids->baseSerialized = antlrcpp::Guid("33761B2D-78BB-4A43-8B0B-4F5BEE8AACF3");
wellKnownUuids->supported.assign({
wellKnownUuids->baseSerialized, wellKnownUuids->addedPrecedenceTransitions,
wellKnownUuids->addedLexerActions, wellKnownUuids->addedUnicodeSmp});
wellKnownUuids->supported.shrink_to_fit();
}

uint32_t deserializeInt32(const std::vector<uint16_t>& data, size_t offset) {
return (uint32_t)data[offset] | ((uint32_t)data[offset + 1] << 16);
return static_cast<uint32_t>(data[offset]) | (static_cast<uint32_t>(data[offset + 1]) << 16);
}

ssize_t readUnicodeInt(const std::vector<uint16_t>& data, int& p) {
Expand Down Expand Up @@ -105,7 +136,7 @@ void deserializeSets(
ATNDeserializer::ATNDeserializer(): ATNDeserializer(ATNDeserializationOptions::getDefaultOptions()) {
}

ATNDeserializer::ATNDeserializer(const ATNDeserializationOptions& dso): deserializationOptions(dso) {
ATNDeserializer::ATNDeserializer(const ATNDeserializationOptions& dso): _deserializationOptions(dso) {
}

ATNDeserializer::~ATNDeserializer() {
Expand All @@ -116,28 +147,32 @@ ATNDeserializer::~ATNDeserializer() {
* reflected as change in the unique ID SERIALIZED_UUID.
*/
antlrcpp::Guid ATNDeserializer::ADDED_PRECEDENCE_TRANSITIONS() {
return antlrcpp::Guid("1DA0C57D-6C06-438A-9B27-10BCB3CE0F61");
std::call_once(wellKnownUuidsOnceFlag, initializeWellKnownUuids);
return wellKnownUuids->addedPrecedenceTransitions;
}

antlrcpp::Guid ATNDeserializer::ADDED_LEXER_ACTIONS() {
return antlrcpp::Guid("AADB8D7E-AEEF-4415-AD2B-8204D6CF042E");
std::call_once(wellKnownUuidsOnceFlag, initializeWellKnownUuids);
return wellKnownUuids->addedLexerActions;
}

antlrcpp::Guid ATNDeserializer::ADDED_UNICODE_SMP() {
return antlrcpp::Guid("59627784-3BE5-417A-B9EB-8131A7286089");
std::call_once(wellKnownUuidsOnceFlag, initializeWellKnownUuids);
return wellKnownUuids->addedUnicodeSmp;
}

antlrcpp::Guid ATNDeserializer::SERIALIZED_UUID() {
return ADDED_UNICODE_SMP();
}

antlrcpp::Guid ATNDeserializer::BASE_SERIALIZED_UUID() {
return antlrcpp::Guid("33761B2D-78BB-4A43-8B0B-4F5BEE8AACF3");
std::call_once(wellKnownUuidsOnceFlag, initializeWellKnownUuids);
return wellKnownUuids->baseSerialized;
}

std::vector<antlrcpp::Guid>& ATNDeserializer::SUPPORTED_UUIDS() {
static std::vector<antlrcpp::Guid> singleton = { BASE_SERIALIZED_UUID(), ADDED_PRECEDENCE_TRANSITIONS(), ADDED_LEXER_ACTIONS(), ADDED_UNICODE_SMP() };
return singleton;
const std::vector<antlrcpp::Guid>& ATNDeserializer::SUPPORTED_UUIDS() {
std::call_once(wellKnownUuidsOnceFlag, initializeWellKnownUuids);
return wellKnownUuids->supported;
}

bool ATNDeserializer::isFeatureSupported(const antlrcpp::Guid &feature, const antlrcpp::Guid &actualUuid) {
Expand Down Expand Up @@ -433,11 +468,11 @@ ATN ATNDeserializer::deserialize(const std::vector<uint16_t>& input) {

markPrecedenceDecisions(atn);

if (deserializationOptions.isVerifyATN()) {
if (_deserializationOptions.isVerifyATN()) {
verifyATN(atn);
}

if (deserializationOptions.isGenerateRuleBypassTransitions() && atn.grammarType == ATNType::PARSER) {
if (_deserializationOptions.isGenerateRuleBypassTransitions() && atn.grammarType == ATNType::PARSER) {
atn.ruleToTokenType.resize(atn.ruleToStartState.size());
for (size_t i = 0; i < atn.ruleToStartState.size(); i++) {
atn.ruleToTokenType[i] = int(atn.maxTokenType + i + 1);
Expand Down Expand Up @@ -521,7 +556,7 @@ ATN ATNDeserializer::deserialize(const std::vector<uint16_t>& input) {
bypassStart->addTransition(new EpsilonTransition(matchState)); /* mem check: freed in ATNState d-tor */
}

if (deserializationOptions.isVerifyATN()) {
if (_deserializationOptions.isVerifyATN()) {
// reverify after modification
verifyATN(atn);
}
Expand All @@ -537,7 +572,7 @@ ATN ATNDeserializer::deserialize(const std::vector<uint16_t>& input) {
*
* @param atn The ATN.
*/
void ATNDeserializer::markPrecedenceDecisions(const ATN &atn) {
void ATNDeserializer::markPrecedenceDecisions(const ATN &atn) const {
for (ATNState *state : atn.states) {
if (!is<StarLoopEntryState *>(state)) {
continue;
Expand Down Expand Up @@ -723,7 +758,7 @@ ATNState* ATNDeserializer::stateFactory(size_t type, size_t ruleIndex) {
return s;
}

Ref<LexerAction> ATNDeserializer::lexerActionFactory(LexerActionType type, int data1, int data2) {
Ref<LexerAction> ATNDeserializer::lexerActionFactory(LexerActionType type, int data1, int data2) const {
switch (type) {
case LexerActionType::CHANNEL:
return std::make_shared<LexerChannelAction>(data1);
Expand Down
Loading