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++] Fix const correctness in ATN and DFA #3530

Merged
merged 1 commit into from
Feb 12, 2022
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
2 changes: 1 addition & 1 deletion runtime/Cpp/runtime/src/DefaultErrorStrategy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ misc::IntervalSet DefaultErrorStrategy::getErrorRecoverySet(Parser *recognizer)
while (ctx->invokingState != ATNState::INVALID_STATE_NUMBER) {
// compute what follows who invoked us
atn::ATNState *invokingState = atn.states[ctx->invokingState];
atn::RuleTransition *rt = dynamic_cast<atn::RuleTransition*>(invokingState->transitions[0]);
const atn::RuleTransition *rt = dynamic_cast<const atn::RuleTransition*>(invokingState->transitions[0].get());
misc::IntervalSet follow = atn.nextTokens(rt->followState);
recoverSet.addAll(follow);

Expand Down
8 changes: 4 additions & 4 deletions runtime/Cpp/runtime/src/FailedPredicateException.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ FailedPredicateException::FailedPredicateException(Parser *recognizer, const std
recognizer->getInputStream(), recognizer->getContext(), recognizer->getCurrentToken()) {

atn::ATNState *s = recognizer->getInterpreter<atn::ATNSimulator>()->atn.states[recognizer->getState()];
atn::Transition *transition = s->transitions[0];
if (is<atn::PredicateTransition*>(transition)) {
_ruleIndex = static_cast<atn::PredicateTransition *>(transition)->ruleIndex;
_predicateIndex = static_cast<atn::PredicateTransition *>(transition)->predIndex;
const atn::Transition *transition = s->transitions[0].get();
if (is<const atn::PredicateTransition*>(transition)) {
_ruleIndex = static_cast<const atn::PredicateTransition *>(transition)->ruleIndex;
_predicateIndex = static_cast<const atn::PredicateTransition *>(transition)->predIndex;
} else {
_ruleIndex = 0;
_predicateIndex = 0;
Expand Down
2 changes: 1 addition & 1 deletion runtime/Cpp/runtime/src/FailedPredicateException.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace antlr4 {
/// prediction.
class ANTLR4CPP_PUBLIC FailedPredicateException : public RecognitionException {
public:
FailedPredicateException(Parser *recognizer);
explicit FailedPredicateException(Parser *recognizer);
FailedPredicateException(Parser *recognizer, const std::string &predicate);
FailedPredicateException(Parser *recognizer, const std::string &predicate, const std::string &message);

Expand Down
2 changes: 1 addition & 1 deletion runtime/Cpp/runtime/src/Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,7 @@ bool Parser::isExpectedToken(size_t symbol) {

while (ctx && ctx->invokingState != ATNState::INVALID_STATE_NUMBER && following.contains(Token::EPSILON)) {
atn::ATNState *invokingState = atn.states[ctx->invokingState];
atn::RuleTransition *rt = static_cast<atn::RuleTransition*>(invokingState->transitions[0]);
const atn::RuleTransition *rt = static_cast<const atn::RuleTransition*>(invokingState->transitions[0].get());
following = atn.nextTokens(rt->followState);
if (following.contains(symbol)) {
return true;
Expand Down
16 changes: 8 additions & 8 deletions runtime/Cpp/runtime/src/ParserInterpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ void ParserInterpreter::visitState(atn::ATNState *p) {
predictedAlt = visitDecisionState(dynamic_cast<DecisionState *>(p));
}

atn::Transition *transition = p->transitions[predictedAlt - 1];
const atn::Transition *transition = p->transitions[predictedAlt - 1].get();
switch (transition->getSerializationType()) {
case atn::Transition::EPSILON:
if (p->getStateType() == ATNState::STAR_LOOP_ENTRY &&
Expand All @@ -167,7 +167,7 @@ void ParserInterpreter::visitState(atn::ATNState *p) {
break;

case atn::Transition::ATOM:
match(static_cast<int>(static_cast<atn::AtomTransition*>(transition)->_label));
match(static_cast<int>(static_cast<const atn::AtomTransition*>(transition)->_label));
break;

case atn::Transition::RANGE:
Expand All @@ -189,7 +189,7 @@ void ParserInterpreter::visitState(atn::ATNState *p) {
size_t ruleIndex = ruleStartState->ruleIndex;
InterpreterRuleContext *newctx = createInterpreterRuleContext(_ctx, p->stateNumber, ruleIndex);
if (ruleStartState->isLeftRecursiveRule) {
enterRecursionRule(newctx, ruleStartState->stateNumber, ruleIndex, static_cast<atn::RuleTransition*>(transition)->precedence);
enterRecursionRule(newctx, ruleStartState->stateNumber, ruleIndex, static_cast<const atn::RuleTransition*>(transition)->precedence);
} else {
enterRule(newctx, transition->target->stateNumber, ruleIndex);
}
Expand All @@ -198,7 +198,7 @@ void ParserInterpreter::visitState(atn::ATNState *p) {

case atn::Transition::PREDICATE:
{
atn::PredicateTransition *predicateTransition = static_cast<atn::PredicateTransition*>(transition);
const atn::PredicateTransition *predicateTransition = static_cast<const atn::PredicateTransition*>(transition);
if (!sempred(_ctx, predicateTransition->ruleIndex, predicateTransition->predIndex)) {
throw FailedPredicateException(this);
}
Expand All @@ -207,15 +207,15 @@ void ParserInterpreter::visitState(atn::ATNState *p) {

case atn::Transition::ACTION:
{
atn::ActionTransition *actionTransition = static_cast<atn::ActionTransition*>(transition);
const atn::ActionTransition *actionTransition = static_cast<const atn::ActionTransition*>(transition);
action(_ctx, actionTransition->ruleIndex, actionTransition->actionIndex);
}
break;

case atn::Transition::PRECEDENCE:
{
if (!precpred(_ctx, static_cast<atn::PrecedencePredicateTransition*>(transition)->precedence)) {
throw FailedPredicateException(this, "precpred(_ctx, " + std::to_string(static_cast<atn::PrecedencePredicateTransition*>(transition)->precedence) + ")");
if (!precpred(_ctx, static_cast<const atn::PrecedencePredicateTransition*>(transition)->precedence)) {
throw FailedPredicateException(this, "precpred(_ctx, " + std::to_string(static_cast<const atn::PrecedencePredicateTransition*>(transition)->precedence) + ")");
}
}
break;
Expand Down Expand Up @@ -259,7 +259,7 @@ void ParserInterpreter::visitRuleStopState(atn::ATNState *p) {
exitRule();
}

atn::RuleTransition *ruleTransition = static_cast<atn::RuleTransition*>(_atn.states[getState()]->transitions[0]);
const atn::RuleTransition *ruleTransition = static_cast<const atn::RuleTransition*>(_atn.states[getState()]->transitions[0].get());
setState(ruleTransition->followState->stateNumber);
}

Expand Down
2 changes: 1 addition & 1 deletion runtime/Cpp/runtime/src/atn/ATN.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ misc::IntervalSet ATN::getExpectedTokens(size_t stateNumber, RuleContext *contex
expected.remove(Token::EPSILON);
while (ctx && ctx->invokingState != ATNState::INVALID_STATE_NUMBER && following.contains(Token::EPSILON)) {
ATNState *invokingState = states.at(ctx->invokingState);
RuleTransition *rt = static_cast<RuleTransition*>(invokingState->transitions[0]);
const RuleTransition *rt = static_cast<const RuleTransition*>(invokingState->transitions[0].get());
following = nextTokens(rt->followState);
expected.addAll(following);
expected.remove(Token::EPSILON);
Expand Down
58 changes: 28 additions & 30 deletions runtime/Cpp/runtime/src/atn/ATNConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,38 +11,40 @@

using namespace antlr4::atn;

ATNConfig::ATNConfig(ATNState *state_, size_t alt, Ref<PredictionContext> context)
: ATNConfig(state_, alt, std::move(context), SemanticContext::NONE) {
}
namespace {

ATNConfig::ATNConfig(ATNState *state, size_t alt, Ref<PredictionContext> context, Ref<SemanticContext> semanticContext)
: state(state), alt(alt), context(std::move(context)), semanticContext(std::move(semanticContext)) {
reachesIntoOuterContext = 0;
}
/**
* This field stores the bit mask for implementing the
* {@link #isPrecedenceFilterSuppressed} property as a bit within the
* existing {@link #reachesIntoOuterContext} field.
*/
inline constexpr size_t SUPPRESS_PRECEDENCE_FILTER = 0x40000000;

ATNConfig::ATNConfig(Ref<ATNConfig> const& c) : ATNConfig(c, c->state, c->context, c->semanticContext) {
}

ATNConfig::ATNConfig(Ref<ATNConfig> const& c, ATNState *state_) : ATNConfig(c, state_, c->context, c->semanticContext) {
}
ATNConfig::ATNConfig(ATNState *state, size_t alt, Ref<const PredictionContext> context)
: ATNConfig(state, alt, std::move(context), 0, SemanticContext::NONE) {}

ATNConfig::ATNConfig(Ref<ATNConfig> const& c, ATNState *state, Ref<SemanticContext> semanticContext)
: ATNConfig(c, state, c->context, std::move(semanticContext)) {
}
ATNConfig::ATNConfig(ATNState *state, size_t alt, Ref<const PredictionContext> context, Ref<const SemanticContext> semanticContext)
: ATNConfig(state, alt, std::move(context), 0, std::move(semanticContext)) {}

ATNConfig::ATNConfig(Ref<ATNConfig> const& c, Ref<SemanticContext> semanticContext)
: ATNConfig(c, c->state, c->context, std::move(semanticContext)) {
}
ATNConfig::ATNConfig(ATNConfig const& other, Ref<const SemanticContext> semanticContext)
: ATNConfig(other.state, other.alt, other.context, other.reachesIntoOuterContext, std::move(semanticContext)) {}

ATNConfig::ATNConfig(Ref<ATNConfig> const& c, ATNState *state, Ref<PredictionContext> context)
: ATNConfig(c, state, std::move(context), c->semanticContext) {
}
ATNConfig::ATNConfig(ATNConfig const& other, ATNState *state)
: ATNConfig(state, other.alt, other.context, other.reachesIntoOuterContext, other.semanticContext) {}

ATNConfig::ATNConfig(Ref<ATNConfig> const& c, ATNState *state, Ref<PredictionContext> context,
Ref<SemanticContext> semanticContext)
: state(state), alt(c->alt), context(std::move(context)), reachesIntoOuterContext(c->reachesIntoOuterContext),
semanticContext(std::move(semanticContext)) {
}
ATNConfig::ATNConfig(ATNConfig const& other, ATNState *state, Ref<const SemanticContext> semanticContext)
: ATNConfig(state, other.alt, other.context, other.reachesIntoOuterContext, std::move(semanticContext)) {}

ATNConfig::ATNConfig(ATNConfig const& other, ATNState *state, Ref<const PredictionContext> context)
: ATNConfig(state, other.alt, std::move(context), other.reachesIntoOuterContext, other.semanticContext) {}

ATNConfig::ATNConfig(ATNConfig const& other, ATNState *state, Ref<const PredictionContext> context, Ref<const SemanticContext> semanticContext)
: ATNConfig(state, other.alt, std::move(context), other.reachesIntoOuterContext, std::move(semanticContext)) {}

ATNConfig::ATNConfig(ATNState *state, size_t alt, Ref<const PredictionContext> context, size_t reachesIntoOuterContext, Ref<const SemanticContext> semanticContext)
: state(state), alt(alt), context(std::move(context)), reachesIntoOuterContext(reachesIntoOuterContext), semanticContext(std::move(semanticContext)) {}

size_t ATNConfig::hashCode() const {
size_t hashCode = misc::MurmurHash::initialize(7);
Expand Down Expand Up @@ -77,10 +79,6 @@ bool ATNConfig::operator==(const ATNConfig &other) const {
isPrecedenceFilterSuppressed() == other.isPrecedenceFilterSuppressed();
}

bool ATNConfig::operator!=(const ATNConfig &other) const {
return !operator==(other);
}

std::string ATNConfig::toString() const {
return toString(true);
}
Expand All @@ -97,12 +95,12 @@ std::string ATNConfig::toString(bool showAlt) const {
ss << ",[" << context->toString() << "]";
}
if (semanticContext != nullptr && semanticContext != SemanticContext::NONE) {
ss << "," << semanticContext.get();
ss << ",[" << semanticContext->toString() << "]";
}
if (getOuterContextDepth() > 0) {
ss << ",up=" << getOuterContextDepth();
}
ss << ')';
ss << ")";

return ss.str();
}
44 changes: 24 additions & 20 deletions runtime/Cpp/runtime/src/atn/ATNConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@

#pragma once

#include <cassert>

#include "antlr4-common.h"
#include "atn/SemanticContext.h"

namespace antlr4 {
namespace atn {
Expand All @@ -22,32 +25,39 @@ namespace atn {
public:
struct Hasher
{
size_t operator()(Ref<ATNConfig> const& k) const {
return k->hashCode();
}

size_t operator()(ATNConfig const& k) const {
return k.hashCode();
}
};

struct Comparer {
bool operator()(Ref<ATNConfig> const& lhs, Ref<ATNConfig> const& rhs) const {
return (lhs == rhs) || (*lhs == *rhs);
}

bool operator()(ATNConfig const& lhs, ATNConfig const& rhs) const {
return (&lhs == &rhs) || (lhs == rhs);
}
};


using Set = std::unordered_set<Ref<ATNConfig>, Hasher, Comparer>;

/// The ATN state associated with this configuration.
ATNState * state;
ATNState *state = nullptr;

/// What alt (or lexer rule) is predicted by this configuration.
const size_t alt;
const size_t alt = 0;

/// The stack of invoking states leading to the rule/states associated
/// with this config. We track only those contexts pushed during
/// execution of the ATN simulator.
///
/// Can be shared between multiple ANTConfig instances.
Ref<PredictionContext> context;
Ref<const PredictionContext> context;

/**
* We cannot execute predicates dependent upon local context unless
Expand All @@ -72,20 +82,19 @@ namespace atn {
* {@link ATNConfigSet#add(ATNConfig, DoubleKeyMap)} method are
* <em>completely</em> unaffected by the change.</p>
*/
size_t reachesIntoOuterContext;
size_t reachesIntoOuterContext = 0;

/// Can be shared between multiple ATNConfig instances.
Ref<SemanticContext> semanticContext;
Ref<const SemanticContext> semanticContext;

ATNConfig(ATNState *state, size_t alt, Ref<PredictionContext> context);
ATNConfig(ATNState *state, size_t alt, Ref<PredictionContext> context, Ref<SemanticContext> semanticContext);
ATNConfig(ATNState *state, size_t alt, Ref<const PredictionContext> context);
ATNConfig(ATNState *state, size_t alt, Ref<const PredictionContext> context, Ref<const SemanticContext> semanticContext);

ATNConfig(Ref<ATNConfig> const& c); // dup
ATNConfig(Ref<ATNConfig> const& c, ATNState *state);
ATNConfig(Ref<ATNConfig> const& c, ATNState *state, Ref<SemanticContext> semanticContext);
ATNConfig(Ref<ATNConfig> const& c, Ref<SemanticContext> semanticContext);
ATNConfig(Ref<ATNConfig> const& c, ATNState *state, Ref<PredictionContext> context);
ATNConfig(Ref<ATNConfig> const& c, ATNState *state, Ref<PredictionContext> context, Ref<SemanticContext> semanticContext);
ATNConfig(ATNConfig const& other, Ref<const SemanticContext> semanticContext);
ATNConfig(ATNConfig const& other, ATNState *state);
ATNConfig(ATNConfig const& other, ATNState *state, Ref<const SemanticContext> semanticContext);
ATNConfig(ATNConfig const& other, ATNState *state, Ref<const PredictionContext> context);
ATNConfig(ATNConfig const& other, ATNState *state, Ref<const PredictionContext> context, Ref<const SemanticContext> semanticContext);

ATNConfig(ATNConfig const&) = default;

Expand Down Expand Up @@ -114,12 +123,7 @@ namespace atn {
std::string toString(bool showAlt) const;

private:
/**
* This field stores the bit mask for implementing the
* {@link #isPrecedenceFilterSuppressed} property as a bit within the
* existing {@link #reachesIntoOuterContext} field.
*/
static constexpr size_t SUPPRESS_PRECEDENCE_FILTER = 0x40000000;
ATNConfig(ATNState *state, size_t alt, Ref<const PredictionContext> context, size_t reachesIntoOuterContext, Ref<const SemanticContext> semanticContext);
};

} // namespace atn
Expand Down
Loading