ATNState::transactions improvements

The transaction field was access with trivial getters and setters which server no real purpose, so I made the vector public and remove all the obsolete accessor functions. This simplifies the API (e.g. use .size() instead of getNumberOfTransitions()).
This change required a few other changes in runtime.

Additionally, I radically cut down the ATN::toString method to return only what the Java runtime is doing instead of a full dump of the state and it's transitions.
This commit is contained in:
Mike Lischke 2016-10-14 17:10:00 +02:00
parent aabf4baf60
commit 9e77edcb34
17 changed files with 77 additions and 126 deletions

View File

@ -117,8 +117,7 @@ namespace antlr4 {
virtual std::string getText(RuleContext *ctx) override; virtual std::string getText(RuleContext *ctx) override;
virtual std::string getText(Token *start, Token *stop) override; virtual std::string getText(Token *start, Token *stop) override;
/// <summary> /// Get all tokens from lexer until EOF.
/// Get all tokens from lexer until EOF </summary>
virtual void fill(); virtual void fill();
protected: protected:

View File

@ -246,7 +246,7 @@ bool DefaultErrorStrategy::singleTokenInsertion(Parser *recognizer) {
// ATN state, then we know we're missing a token; error recovery // ATN state, then we know we're missing a token; error recovery
// is free to conjure up and insert the missing token // is free to conjure up and insert the missing token
atn::ATNState *currentState = recognizer->getInterpreter<atn::ATNSimulator>()->atn.states[recognizer->getState()]; atn::ATNState *currentState = recognizer->getInterpreter<atn::ATNSimulator>()->atn.states[recognizer->getState()];
atn::ATNState *next = currentState->transition(0)->target; atn::ATNState *next = currentState->transitions[0]->target;
const atn::ATN &atn = recognizer->getInterpreter<atn::ATNSimulator>()->atn; const atn::ATN &atn = recognizer->getInterpreter<atn::ATNSimulator>()->atn;
misc::IntervalSet expectingAtLL2 = atn.nextTokens(next, recognizer->getContext()); misc::IntervalSet expectingAtLL2 = atn.nextTokens(next, recognizer->getContext());
if (expectingAtLL2.contains(currentSymbolType)) { if (expectingAtLL2.contains(currentSymbolType)) {
@ -336,7 +336,7 @@ misc::IntervalSet DefaultErrorStrategy::getErrorRecoverySet(Parser *recognizer)
while (ctx->invokingState != ATNState::INVALID_STATE_NUMBER) { while (ctx->invokingState != ATNState::INVALID_STATE_NUMBER) {
// compute what follows who invoked us // compute what follows who invoked us
atn::ATNState *invokingState = atn.states[ctx->invokingState]; atn::ATNState *invokingState = atn.states[ctx->invokingState];
atn::RuleTransition *rt = dynamic_cast<atn::RuleTransition*>(invokingState->transition(0)); atn::RuleTransition *rt = dynamic_cast<atn::RuleTransition*>(invokingState->transitions[0]);
misc::IntervalSet follow = atn.nextTokens(rt->followState); misc::IntervalSet follow = atn.nextTokens(rt->followState);
recoverSet.addAll(follow); recoverSet.addAll(follow);

View File

@ -52,12 +52,11 @@ FailedPredicateException::FailedPredicateException(Parser *recognizer, const std
recognizer->getInputStream(), recognizer->getContext(), recognizer->getCurrentToken()) { recognizer->getInputStream(), recognizer->getContext(), recognizer->getCurrentToken()) {
atn::ATNState *s = recognizer->getInterpreter<atn::ATNSimulator>()->atn.states[recognizer->getState()]; atn::ATNState *s = recognizer->getInterpreter<atn::ATNSimulator>()->atn.states[recognizer->getState()];
atn::Transition *transition = s->transition(0); atn::Transition *transition = s->transitions[0];
if (is<atn::PredicateTransition*>(transition)) { if (is<atn::PredicateTransition*>(transition)) {
_ruleIndex = ((atn::PredicateTransition *)transition)->ruleIndex; _ruleIndex = ((atn::PredicateTransition *)transition)->ruleIndex;
_predicateIndex = ((atn::PredicateTransition *)transition)->predIndex; _predicateIndex = ((atn::PredicateTransition *)transition)->predIndex;
} } else {
else {
_ruleIndex = 0; _ruleIndex = 0;
_predicateIndex = 0; _predicateIndex = 0;
} }

View File

@ -501,7 +501,7 @@ bool Parser::isExpectedToken(size_t symbol) {
while (ctx && ctx->invokingState != ATNState::INVALID_STATE_NUMBER && following.contains(Token::EPSILON)) { while (ctx && ctx->invokingState != ATNState::INVALID_STATE_NUMBER && following.contains(Token::EPSILON)) {
atn::ATNState *invokingState = atn.states[ctx->invokingState]; atn::ATNState *invokingState = atn.states[ctx->invokingState];
atn::RuleTransition *rt = static_cast<atn::RuleTransition*>(invokingState->transition(0)); atn::RuleTransition *rt = static_cast<atn::RuleTransition*>(invokingState->transitions[0]);
following = atn.nextTokens(rt->followState); following = atn.nextTokens(rt->followState);
if (following.contains(symbol)) { if (following.contains(symbol)) {
return true; return true;

View File

@ -189,7 +189,7 @@ void ParserInterpreter::visitState(atn::ATNState *p) {
predictedAlt = visitDecisionState(dynamic_cast<DecisionState *>(p)); predictedAlt = visitDecisionState(dynamic_cast<DecisionState *>(p));
} }
atn::Transition *transition = p->transition(predictedAlt - 1); atn::Transition *transition = p->transitions[predictedAlt - 1];
switch (transition->getSerializationType()) { switch (transition->getSerializationType()) {
case atn::Transition::EPSILON: case atn::Transition::EPSILON:
if (p->getStateType() == ATNState::STAR_LOOP_ENTRY && if (p->getStateType() == ATNState::STAR_LOOP_ENTRY &&
@ -266,7 +266,7 @@ void ParserInterpreter::visitState(atn::ATNState *p) {
size_t ParserInterpreter::visitDecisionState(DecisionState *p) { size_t ParserInterpreter::visitDecisionState(DecisionState *p) {
size_t predictedAlt = 1; size_t predictedAlt = 1;
if (p->getNumberOfTransitions() > 1) { if (p->transitions.size() > 1) {
getErrorHandler()->sync(this); getErrorHandler()->sync(this);
int decision = p->decision; int decision = p->decision;
if (decision == _overrideDecision && _input->index() == _overrideDecisionInputIndex && !_overrideDecisionReached) { if (decision == _overrideDecision && _input->index() == _overrideDecisionInputIndex && !_overrideDecisionReached) {
@ -296,7 +296,7 @@ void ParserInterpreter::visitRuleStopState(atn::ATNState *p) {
exitRule(); exitRule();
} }
atn::RuleTransition *ruleTransition = static_cast<atn::RuleTransition*>(_atn.states[getState()]->transition(0)); atn::RuleTransition *ruleTransition = static_cast<atn::RuleTransition*>(_atn.states[getState()]->transitions[0]);
setState(ruleTransition->followState->stateNumber); setState(ruleTransition->followState->stateNumber);
} }

View File

@ -63,12 +63,12 @@ void RecognitionException::setOffendingState(size_t offendingState) {
misc::IntervalSet RecognitionException::getExpectedTokens() const { misc::IntervalSet RecognitionException::getExpectedTokens() const {
if (_recognizer) { if (_recognizer) {
return _recognizer->getATN().getExpectedTokens(_offendingState, _ctx.get()); return _recognizer->getATN().getExpectedTokens(_offendingState, _ctx);
} }
return misc::IntervalSet::EMPTY_SET; return misc::IntervalSet::EMPTY_SET;
} }
Ref<RuleContext> RecognitionException::getCtx() const { RuleContext* RecognitionException::getCtx() const {
return _ctx; return _ctx;
} }

View File

@ -167,7 +167,7 @@ misc::IntervalSet ATN::getExpectedTokens(size_t stateNumber, RuleContext *contex
expected.remove(Token::EPSILON); expected.remove(Token::EPSILON);
while (ctx && ctx->invokingState != ATNState::INVALID_STATE_NUMBER && following.contains(Token::EPSILON)) { while (ctx && ctx->invokingState != ATNState::INVALID_STATE_NUMBER && following.contains(Token::EPSILON)) {
ATNState *invokingState = states.at(ctx->invokingState); ATNState *invokingState = states.at(ctx->invokingState);
RuleTransition *rt = static_cast<RuleTransition*>(invokingState->transition(0)); RuleTransition *rt = static_cast<RuleTransition*>(invokingState->transitions[0]);
following = nextTokens(rt->followState); following = nextTokens(rt->followState);
expected.addAll(following); expected.addAll(following);
expected.remove(Token::EPSILON); expected.remove(Token::EPSILON);

View File

@ -175,7 +175,7 @@ ATN ATNDeserializer::deserialize(const std::vector<uint16_t>& input) {
} }
size_t ruleIndex = data[p++]; size_t ruleIndex = data[p++];
if (ruleIndex == 0xFFFF) { // Max Unicode char limit imposed by ANTLR. if (ruleIndex == 0xFFFF) {
ruleIndex = INVALID_INDEX; ruleIndex = INVALID_INDEX;
} }
@ -301,8 +301,8 @@ ATN ATNDeserializer::deserialize(const std::vector<uint16_t>& input) {
// edges for rule stop states can be derived, so they aren't serialized // edges for rule stop states can be derived, so they aren't serialized
for (ATNState *state : atn.states) { for (ATNState *state : atn.states) {
for (size_t i = 0; i < state->getNumberOfTransitions(); i++) { for (size_t i = 0; i < state->transitions.size(); i++) {
Transition *t = state->transition(i); Transition *t = state->transitions[i];
if (!is<RuleTransition*>(t)) { if (!is<RuleTransition*>(t)) {
continue; continue;
} }
@ -339,16 +339,16 @@ ATN ATNDeserializer::deserialize(const std::vector<uint16_t>& input) {
if (is<PlusLoopbackState*>(state)) { if (is<PlusLoopbackState*>(state)) {
PlusLoopbackState *loopbackState = static_cast<PlusLoopbackState *>(state); PlusLoopbackState *loopbackState = static_cast<PlusLoopbackState *>(state);
for (size_t i = 0; i < loopbackState->getNumberOfTransitions(); i++) { for (size_t i = 0; i < loopbackState->transitions.size(); i++) {
ATNState *target = loopbackState->transition(i)->target; ATNState *target = loopbackState->transitions[i]->target;
if (is<PlusBlockStartState *>(target)) { if (is<PlusBlockStartState *>(target)) {
(static_cast<PlusBlockStartState *>(target))->loopBackState = loopbackState; (static_cast<PlusBlockStartState *>(target))->loopBackState = loopbackState;
} }
} }
} else if (is<StarLoopbackState *>(state)) { } else if (is<StarLoopbackState *>(state)) {
StarLoopbackState *loopbackState = static_cast<StarLoopbackState *>(state); StarLoopbackState *loopbackState = static_cast<StarLoopbackState *>(state);
for (size_t i = 0; i < loopbackState->getNumberOfTransitions(); i++) { for (size_t i = 0; i < loopbackState->transitions.size(); i++) {
ATNState *target = loopbackState->transition(i)->target; ATNState *target = loopbackState->transitions[i]->target;
if (is<StarLoopEntryState *>(target)) { if (is<StarLoopEntryState *>(target)) {
(static_cast<StarLoopEntryState*>(target))->loopBackState = loopbackState; (static_cast<StarLoopEntryState*>(target))->loopBackState = loopbackState;
} }
@ -395,8 +395,8 @@ ATN ATNDeserializer::deserialize(const std::vector<uint16_t>& input) {
// serialized action index for action transitions to the new // serialized action index for action transitions to the new
// form, which is the index of a LexerCustomAction // form, which is the index of a LexerCustomAction
for (ATNState *state : atn.states) { for (ATNState *state : atn.states) {
for (size_t i = 0; i < state->getNumberOfTransitions(); i++) { for (size_t i = 0; i < state->transitions.size(); i++) {
Transition *transition = state->transition(i); Transition *transition = state->transitions[i];
if (!is<ActionTransition *>(transition)) { if (!is<ActionTransition *>(transition)) {
continue; continue;
} }
@ -404,7 +404,8 @@ ATN ATNDeserializer::deserialize(const std::vector<uint16_t>& input) {
size_t ruleIndex = static_cast<ActionTransition *>(transition)->ruleIndex; size_t ruleIndex = static_cast<ActionTransition *>(transition)->ruleIndex;
size_t actionIndex = static_cast<ActionTransition *>(transition)->actionIndex; size_t actionIndex = static_cast<ActionTransition *>(transition)->actionIndex;
Ref<LexerCustomAction> lexerAction = std::make_shared<LexerCustomAction>(ruleIndex, actionIndex); Ref<LexerCustomAction> lexerAction = std::make_shared<LexerCustomAction>(ruleIndex, actionIndex);
state->setTransition(i, new ActionTransition(transition->target, ruleIndex, atn.lexerActions.size(), false)); /* mem-check freed in ATNState d-tor */ state->transitions[i] = new ActionTransition(transition->target, ruleIndex, atn.lexerActions.size(), false); /* mem-check freed in ATNState d-tor */
delete transition; // ml: no longer needed since we just replaced it.
atn.lexerActions.push_back(lexerAction); atn.lexerActions.push_back(lexerAction);
} }
} }
@ -451,12 +452,12 @@ ATN ATNDeserializer::deserialize(const std::vector<uint16_t>& input) {
continue; continue;
} }
ATNState *maybeLoopEndState = state->transition(state->getNumberOfTransitions() - 1)->target; ATNState *maybeLoopEndState = state->transitions[state->transitions.size() - 1]->target;
if (!is<LoopEndState*>(maybeLoopEndState)) { if (!is<LoopEndState*>(maybeLoopEndState)) {
continue; continue;
} }
if (maybeLoopEndState->epsilonOnlyTransitions && is<RuleStopState*>(maybeLoopEndState->transition(0)->target)) { if (maybeLoopEndState->epsilonOnlyTransitions && is<RuleStopState*>(maybeLoopEndState->transitions[0]->target)) {
endState = state; endState = state;
break; break;
} }
@ -467,14 +468,14 @@ ATN ATNDeserializer::deserialize(const std::vector<uint16_t>& input) {
} }
excludeTransition = (static_cast<StarLoopEntryState*>(endState))->loopBackState->transition(0); excludeTransition = (static_cast<StarLoopEntryState*>(endState))->loopBackState->transitions[0];
} else { } else {
endState = atn.ruleToStopState[i]; endState = atn.ruleToStopState[i];
} }
// all non-excluded transitions that currently target end state need to target blockEnd instead // all non-excluded transitions that currently target end state need to target blockEnd instead
for (ATNState *state : atn.states) { for (ATNState *state : atn.states) {
for (Transition *transition : state->getTransitions()) { for (Transition *transition : state->transitions) {
if (transition == excludeTransition) { if (transition == excludeTransition) {
continue; continue;
} }
@ -486,8 +487,8 @@ ATN ATNDeserializer::deserialize(const std::vector<uint16_t>& input) {
} }
// all transitions leaving the rule start state need to leave blockStart instead // all transitions leaving the rule start state need to leave blockStart instead
while (atn.ruleToStartState[i]->getNumberOfTransitions() > 0) { while (atn.ruleToStartState[i]->transitions.size() > 0) {
Transition *transition = atn.ruleToStartState[i]->removeTransition((int)atn.ruleToStartState[i]->getNumberOfTransitions() - 1); Transition *transition = atn.ruleToStartState[i]->removeTransition(atn.ruleToStartState[i]->transitions.size() - 1);
bypassStart->addTransition(transition); bypassStart->addTransition(transition);
} }
@ -528,9 +529,9 @@ void ATNDeserializer::markPrecedenceDecisions(const ATN &atn) {
* precedence rule should continue or complete. * precedence rule should continue or complete.
*/ */
if (atn.ruleToStartState[state->ruleIndex]->isLeftRecursiveRule) { if (atn.ruleToStartState[state->ruleIndex]->isLeftRecursiveRule) {
ATNState *maybeLoopEndState = state->transition(state->getNumberOfTransitions() - 1)->target; ATNState *maybeLoopEndState = state->transitions[state->transitions.size() - 1]->target;
if (is<LoopEndState *>(maybeLoopEndState)) { if (is<LoopEndState *>(maybeLoopEndState)) {
if (maybeLoopEndState->epsilonOnlyTransitions && is<RuleStopState *>(maybeLoopEndState->transition(0)->target)) { if (maybeLoopEndState->epsilonOnlyTransitions && is<RuleStopState *>(maybeLoopEndState->transitions[0]->target)) {
static_cast<StarLoopEntryState *>(state)->isPrecedenceDecision = true; static_cast<StarLoopEntryState *>(state)->isPrecedenceDecision = true;
} }
} }
@ -545,7 +546,7 @@ void ATNDeserializer::verifyATN(const ATN &atn) {
continue; continue;
} }
checkCondition(state->onlyHasEpsilonTransitions() || state->getNumberOfTransitions() <= 1); checkCondition(state->epsilonOnlyTransitions || state->transitions.size() <= 1);
if (is<PlusBlockStartState *>(state)) { if (is<PlusBlockStartState *>(state)) {
checkCondition((static_cast<PlusBlockStartState *>(state))->loopBackState != nullptr); checkCondition((static_cast<PlusBlockStartState *>(state))->loopBackState != nullptr);
@ -554,13 +555,13 @@ void ATNDeserializer::verifyATN(const ATN &atn) {
if (is<StarLoopEntryState *>(state)) { if (is<StarLoopEntryState *>(state)) {
StarLoopEntryState *starLoopEntryState = static_cast<StarLoopEntryState*>(state); StarLoopEntryState *starLoopEntryState = static_cast<StarLoopEntryState*>(state);
checkCondition(starLoopEntryState->loopBackState != nullptr); checkCondition(starLoopEntryState->loopBackState != nullptr);
checkCondition(starLoopEntryState->getNumberOfTransitions() == 2); checkCondition(starLoopEntryState->transitions.size() == 2);
if (is<StarBlockStartState *>(starLoopEntryState->transition(0)->target)) { if (is<StarBlockStartState *>(starLoopEntryState->transitions[0]->target)) {
checkCondition(static_cast<LoopEndState *>(starLoopEntryState->transition(1)->target) != nullptr); checkCondition(static_cast<LoopEndState *>(starLoopEntryState->transitions[1]->target) != nullptr);
checkCondition(!starLoopEntryState->nonGreedy); checkCondition(!starLoopEntryState->nonGreedy);
} else if (is<LoopEndState *>(starLoopEntryState->transition(0)->target)) { } else if (is<LoopEndState *>(starLoopEntryState->transitions[0]->target)) {
checkCondition(is<StarBlockStartState *>(starLoopEntryState->transition(1)->target)); checkCondition(is<StarBlockStartState *>(starLoopEntryState->transitions[1]->target));
checkCondition(starLoopEntryState->nonGreedy); checkCondition(starLoopEntryState->nonGreedy);
} else { } else {
throw IllegalStateException(); throw IllegalStateException();
@ -569,8 +570,8 @@ void ATNDeserializer::verifyATN(const ATN &atn) {
} }
if (is<StarLoopbackState *>(state)) { if (is<StarLoopbackState *>(state)) {
checkCondition(state->getNumberOfTransitions() == 1); checkCondition(state->transitions.size() == 1);
checkCondition(is<StarLoopEntryState *>(state->transition(0)->target)); checkCondition(is<StarLoopEntryState *>(state->transitions[0]->target));
} }
if (is<LoopEndState *>(state)) { if (is<LoopEndState *>(state)) {
@ -591,9 +592,9 @@ void ATNDeserializer::verifyATN(const ATN &atn) {
if (is<DecisionState *>(state)) { if (is<DecisionState *>(state)) {
DecisionState *decisionState = static_cast<DecisionState *>(state); DecisionState *decisionState = static_cast<DecisionState *>(state);
checkCondition(decisionState->getNumberOfTransitions() <= 1 || decisionState->decision >= 0); checkCondition(decisionState->transitions.size() <= 1 || decisionState->decision >= 0);
} else { } else {
checkCondition(state->getNumberOfTransitions() <= 1 || is<RuleStopState *>(state)); checkCondition(state->transitions.size() <= 1 || is<RuleStopState *>(state));
} }
} }
} }

View File

@ -127,11 +127,11 @@ std::vector<size_t> ATNSerializer::serialize() {
if (s->getStateType() != ATNState::RULE_STOP) { if (s->getStateType() != ATNState::RULE_STOP) {
// the deserializer can trivially derive these edges, so there's no need // the deserializer can trivially derive these edges, so there's no need
// to serialize them // to serialize them
nedges += s->getNumberOfTransitions(); nedges += s->transitions.size();
} }
for (size_t i = 0; i < s->getNumberOfTransitions(); i++) { for (size_t i = 0; i < s->transitions.size(); i++) {
Transition *t = s->transition(i); Transition *t = s->transitions[i];
Transition::SerializationType edgeType = t->getSerializationType(); Transition::SerializationType edgeType = t->getSerializationType();
if (edgeType == Transition::SET || edgeType == Transition::NOT_SET) { if (edgeType == Transition::SET || edgeType == Transition::NOT_SET) {
SetTransition *st = static_cast<SetTransition *>(t); SetTransition *st = static_cast<SetTransition *>(t);
@ -217,8 +217,8 @@ std::vector<size_t> ATNSerializer::serialize() {
continue; continue;
} }
for (size_t i = 0; i < s->getNumberOfTransitions(); i++) { for (size_t i = 0; i < s->transitions.size(); i++) {
Transition *t = s->transition(i); Transition *t = s->transitions[i];
if (atn->states[t->target->stateNumber] == nullptr) { if (atn->states[t->target->stateNumber] == nullptr) {
throw IllegalStateException("Cannot serialize a transition to a removed state."); throw IllegalStateException("Cannot serialize a transition to a removed state.");

View File

@ -67,34 +67,11 @@ bool ATNState::isNonGreedyExitState() {
} }
std::string ATNState::toString() const { std::string ATNState::toString() const {
std::stringstream ss; return std::to_string(stateNumber);
ss << "(ATNState " << std::hex << this << std::dec << ") {" << std::endl;
if (stateNumber == INVALID_STATE_NUMBER || stateNumber >= serializationNames.size())
ss << " state: INVALID ";
else
ss << " state: " << serializationNames[stateNumber];
ss << " (" << stateNumber << ")" << std::endl;
ss << " ruleIndex: " << ruleIndex << std::endl << " epsilonOnlyTransitions: " << epsilonOnlyTransitions << std::endl;
ss << " transistions (" << transitions.size() << "):" << std::endl;
for (auto transition : transitions) {
ss << indent(transition->toString(), " ") << std::endl;
}
ss << "}";
return ss.str();
}
std::vector<Transition*> ATNState::getTransitions() {
return transitions;
}
size_t ATNState::getNumberOfTransitions() {
return transitions.size();
} }
void ATNState::addTransition(Transition *e) { void ATNState::addTransition(Transition *e) {
addTransition((int)transitions.size(), e); addTransition(transitions.size(), e);
} }
void ATNState::addTransition(size_t index, Transition *e) { void ATNState::addTransition(size_t index, Transition *e) {
@ -108,23 +85,7 @@ void ATNState::addTransition(size_t index, Transition *e) {
transitions.insert(transitions.begin() + index, e); transitions.insert(transitions.begin() + index, e);
} }
Transition *ATNState::transition(size_t i) {
return transitions[i];
}
void ATNState::setTransition(size_t i, Transition *e) {
transitions[i] = e;
}
Transition *ATNState::removeTransition(size_t index) { Transition *ATNState::removeTransition(size_t index) {
transitions.erase(transitions.begin() + index); transitions.erase(transitions.begin() + index);
return nullptr; return nullptr;
} }
bool ATNState::onlyHasEpsilonTransitions() {
return epsilonOnlyTransitions;
}
void ATNState::setRuleIndex(size_t index) {
ruleIndex = index;
}

View File

@ -128,10 +128,6 @@ namespace atn {
size_t ruleIndex = 0; // at runtime, we don't have Rule objects size_t ruleIndex = 0; // at runtime, we don't have Rule objects
bool epsilonOnlyTransitions = false; bool epsilonOnlyTransitions = false;
protected:
/// Track the transitions emanating from this ATN state.
std::vector<Transition*> transitions;
public: public:
/// Used to cache lookahead during parsing, not used during construction. /// Used to cache lookahead during parsing, not used during construction.
misc::IntervalSet nextTokenWithinRule; misc::IntervalSet nextTokenWithinRule;
@ -139,19 +135,15 @@ namespace atn {
virtual size_t hashCode(); virtual size_t hashCode();
bool operator == (const ATNState &other); bool operator == (const ATNState &other);
/// Track the transitions emanating from this ATN state.
std::vector<Transition*> transitions;
virtual bool isNonGreedyExitState(); virtual bool isNonGreedyExitState();
virtual std::string toString() const; virtual std::string toString() const;
virtual std::vector<Transition*> getTransitions();
virtual size_t getNumberOfTransitions();
virtual void addTransition(Transition *e); virtual void addTransition(Transition *e);
virtual void addTransition(size_t index, Transition *e); virtual void addTransition(size_t index, Transition *e);
virtual Transition *transition(size_t i);
virtual void setTransition(size_t i, Transition *e);
virtual Transition* removeTransition(size_t index); virtual Transition* removeTransition(size_t index);
virtual int getStateType() = 0; virtual int getStateType() = 0;
bool onlyHasEpsilonTransitions();
virtual void setRuleIndex(size_t index);
}; };
} // namespace atn } // namespace atn

View File

@ -58,13 +58,13 @@ std::vector<misc::IntervalSet> LL1Analyzer::getDecisionLookahead(ATNState *s) co
return look; return look;
} }
look.resize(s->getNumberOfTransitions()); // Fills all interval sets with defaults. look.resize(s->transitions.size()); // Fills all interval sets with defaults.
for (size_t alt = 0; alt < s->getNumberOfTransitions(); alt++) { for (size_t alt = 0; alt < s->transitions.size(); alt++) {
bool seeThruPreds = false; // fail to get lookahead upon pred bool seeThruPreds = false; // fail to get lookahead upon pred
ATNConfig::Set lookBusy; ATNConfig::Set lookBusy;
antlrcpp::BitSet callRuleStack; antlrcpp::BitSet callRuleStack;
_LOOK(s->transition(alt)->target, nullptr, PredictionContext::EMPTY, _LOOK(s->transitions[alt]->target, nullptr, PredictionContext::EMPTY,
look[alt], lookBusy, callRuleStack, seeThruPreds, false); look[alt], lookBusy, callRuleStack, seeThruPreds, false);
// Wipe out lookahead for this alternative if we found nothing // Wipe out lookahead for this alternative if we found nothing
@ -140,9 +140,9 @@ void LL1Analyzer::_LOOK(ATNState *s, ATNState *stopState, Ref<PredictionContext>
} }
} }
size_t n = s->getNumberOfTransitions(); size_t n = s->transitions.size();
for (size_t i = 0; i < n; i++) { for (size_t i = 0; i < n; i++) {
Transition *t = s->transition(i); Transition *t = s->transitions[i];
if (is<RuleTransition *>(t)) { if (is<RuleTransition *>(t)) {
if (calledRuleStack[(static_cast<RuleTransition*>(t))->target->ruleIndex]) { if (calledRuleStack[(static_cast<RuleTransition*>(t))->target->ruleIndex]) {

View File

@ -272,9 +272,9 @@ void LexerATNSimulator::getReachableConfigSet(CharStream *input, ATNConfigSet *c
std::cout << "testing " << getTokenName((int)t) << " at " << c->toString(true) << std::endl; std::cout << "testing " << getTokenName((int)t) << " at " << c->toString(true) << std::endl;
#endif #endif
size_t n = c->state->getNumberOfTransitions(); size_t n = c->state->transitions.size();
for (size_t ti = 0; ti < n; ti++) { // for each transition for (size_t ti = 0; ti < n; ti++) { // for each transition
Transition *trans = c->state->transition(ti); Transition *trans = c->state->transitions[ti];
ATNState *target = getReachableTarget(trans, (int)t); ATNState *target = getReachableTarget(trans, (int)t);
if (target != nullptr) { if (target != nullptr) {
Ref<LexerActionExecutor> lexerActionExecutor = std::static_pointer_cast<LexerATNConfig>(c)->getLexerActionExecutor(); Ref<LexerActionExecutor> lexerActionExecutor = std::static_pointer_cast<LexerATNConfig>(c)->getLexerActionExecutor();
@ -325,8 +325,8 @@ atn::ATNState *LexerATNSimulator::getReachableTarget(Transition *trans, size_t t
std::unique_ptr<ATNConfigSet> LexerATNSimulator::computeStartState(CharStream *input, ATNState *p) { std::unique_ptr<ATNConfigSet> LexerATNSimulator::computeStartState(CharStream *input, ATNState *p) {
Ref<PredictionContext> initialContext = PredictionContext::EMPTY; // ml: the purpose of this assignment is unclear Ref<PredictionContext> initialContext = PredictionContext::EMPTY; // ml: the purpose of this assignment is unclear
std::unique_ptr<ATNConfigSet> configs(new OrderedATNConfigSet()); std::unique_ptr<ATNConfigSet> configs(new OrderedATNConfigSet());
for (size_t i = 0; i < p->getNumberOfTransitions(); i++) { for (size_t i = 0; i < p->transitions.size(); i++) {
ATNState *target = p->transition(i)->target; ATNState *target = p->transitions[i]->target;
Ref<LexerATNConfig> c = std::make_shared<LexerATNConfig>(target, (int)(i + 1), initialContext); Ref<LexerATNConfig> c = std::make_shared<LexerATNConfig>(target, (int)(i + 1), initialContext);
closure(input, c, configs.get(), false, false, false); closure(input, c, configs.get(), false, false, false);
} }
@ -374,15 +374,15 @@ bool LexerATNSimulator::closure(CharStream *input, const Ref<LexerATNConfig> &co
} }
// optimization // optimization
if (!config->state->onlyHasEpsilonTransitions()) { if (!config->state->epsilonOnlyTransitions) {
if (!currentAltReachedAcceptState || !config->hasPassedThroughNonGreedyDecision()) { if (!currentAltReachedAcceptState || !config->hasPassedThroughNonGreedyDecision()) {
configs->add(config); configs->add(config);
} }
} }
ATNState *p = config->state; ATNState *p = config->state;
for (size_t i = 0; i < p->getNumberOfTransitions(); i++) { for (size_t i = 0; i < p->transitions.size(); i++) {
Transition *t = p->transition(i); Transition *t = p->transitions[i];
Ref<LexerATNConfig> c = getEpsilonTarget(input, config, t, configs, speculative, treatEofAsEpsilon); Ref<LexerATNConfig> c = getEpsilonTarget(input, config, t, configs, speculative, treatEofAsEpsilon);
if (c != nullptr) { if (c != nullptr) {
currentAltReachedAcceptState = closure(input, c, configs, currentAltReachedAcceptState, speculative, treatEofAsEpsilon); currentAltReachedAcceptState = closure(input, c, configs, currentAltReachedAcceptState, speculative, treatEofAsEpsilon);

View File

@ -323,7 +323,7 @@ dfa::DFAState *ParserATNSimulator::computeTargetState(dfa::DFA &dfa, dfa::DFASta
void ParserATNSimulator::predicateDFAState(dfa::DFAState *dfaState, DecisionState *decisionState) { void ParserATNSimulator::predicateDFAState(dfa::DFAState *dfaState, DecisionState *decisionState) {
// We need to test all predicates, even in DFA states that // We need to test all predicates, even in DFA states that
// uniquely predict alternative. // uniquely predict alternative.
size_t nalts = decisionState->getNumberOfTransitions(); size_t nalts = decisionState->transitions.size();
// Update DFA so reach becomes accept state with (predicate,alt) // Update DFA so reach becomes accept state with (predicate,alt)
// pairs if preds found for conflicting alts // pairs if preds found for conflicting alts
@ -476,9 +476,9 @@ std::unique_ptr<ATNConfigSet> ParserATNSimulator::computeReachSet(ATNConfigSet *
continue; continue;
} }
size_t n = c->state->getNumberOfTransitions(); size_t n = c->state->transitions.size();
for (size_t ti = 0; ti < n; ti++) { // for each transition for (size_t ti = 0; ti < n; ti++) { // for each transition
Transition *trans = c->state->transition(ti); Transition *trans = c->state->transitions[ti];
ATNState *target = getReachableTarget(trans, (int)t); ATNState *target = getReachableTarget(trans, (int)t);
if (target != nullptr) { if (target != nullptr) {
intermediate->add(std::make_shared<ATNConfig>(c, target), &mergeCache); intermediate->add(std::make_shared<ATNConfig>(c, target), &mergeCache);
@ -584,7 +584,7 @@ ATNConfigSet* ParserATNSimulator::removeAllConfigsNotInRuleStopState(ATNConfigSe
continue; continue;
} }
if (lookToEndOfRule && config->state->onlyHasEpsilonTransitions()) { if (lookToEndOfRule && config->state->epsilonOnlyTransitions) {
misc::IntervalSet nextTokens = atn.nextTokens(config->state); misc::IntervalSet nextTokens = atn.nextTokens(config->state);
if (nextTokens.contains(Token::EPSILON)) { if (nextTokens.contains(Token::EPSILON)) {
ATNState *endOfRuleState = atn.ruleToStopState[config->state->ruleIndex]; ATNState *endOfRuleState = atn.ruleToStopState[config->state->ruleIndex];
@ -601,8 +601,8 @@ std::unique_ptr<ATNConfigSet> ParserATNSimulator::computeStartState(ATNState *p,
Ref<PredictionContext> initialContext = PredictionContext::fromRuleContext(atn, ctx); Ref<PredictionContext> initialContext = PredictionContext::fromRuleContext(atn, ctx);
std::unique_ptr<ATNConfigSet> configs(new ATNConfigSet(fullCtx)); std::unique_ptr<ATNConfigSet> configs(new ATNConfigSet(fullCtx));
for (size_t i = 0; i < p->getNumberOfTransitions(); i++) { for (size_t i = 0; i < p->transitions.size(); i++) {
ATNState *target = p->transition(i)->target; ATNState *target = p->transitions[i]->target;
Ref<ATNConfig> c = std::make_shared<ATNConfig>(target, (int)i + 1, initialContext); Ref<ATNConfig> c = std::make_shared<ATNConfig>(target, (int)i + 1, initialContext);
ATNConfig::Set closureBusy; ATNConfig::Set closureBusy;
closure(c, configs.get(), closureBusy, true, fullCtx, false); closure(c, configs.get(), closureBusy, true, fullCtx, false);
@ -892,14 +892,14 @@ void ParserATNSimulator::closure_(Ref<ATNConfig> const& config, ATNConfigSet *co
bool collectPredicates, bool fullCtx, int depth, bool treatEofAsEpsilon) { bool collectPredicates, bool fullCtx, int depth, bool treatEofAsEpsilon) {
ATNState *p = config->state; ATNState *p = config->state;
// optimization // optimization
if (!p->onlyHasEpsilonTransitions()) { if (!p->epsilonOnlyTransitions) {
// make sure to not return here, because EOF transitions can act as // make sure to not return here, because EOF transitions can act as
// both epsilon transitions and non-epsilon transitions. // both epsilon transitions and non-epsilon transitions.
configs->add(config, &mergeCache); configs->add(config, &mergeCache);
} }
for (size_t i = 0; i < p->getNumberOfTransitions(); i++) { for (size_t i = 0; i < p->transitions.size(); i++) {
Transition *t = p->transition(i); Transition *t = p->transitions[i];
bool continueCollecting = !is<ActionTransition*>(t) && collectPredicates; bool continueCollecting = !is<ActionTransition*>(t) && collectPredicates;
Ref<ATNConfig> c = getEpsilonTarget(config, t, continueCollecting, depth == 0, fullCtx, treatEofAsEpsilon); Ref<ATNConfig> c = getEpsilonTarget(config, t, continueCollecting, depth == 0, fullCtx, treatEofAsEpsilon);
if (c != nullptr) { if (c != nullptr) {
@ -1133,8 +1133,8 @@ void ParserATNSimulator::dumpDeadEndConfigs(NoViableAltException &nvae) {
std::cerr << "dead end configs: "; std::cerr << "dead end configs: ";
for (auto c : nvae.getDeadEndConfigs()->configs) { for (auto c : nvae.getDeadEndConfigs()->configs) {
std::string trans = "no edges"; std::string trans = "no edges";
if (c->state->getNumberOfTransitions() > 0) { if (c->state->transitions.size() > 0) {
Transition *t = c->state->transition(0); Transition *t = c->state->transitions[0];
if (is<AtomTransition*>(t)) { if (is<AtomTransition*>(t)) {
AtomTransition *at = static_cast<AtomTransition*>(t); AtomTransition *at = static_cast<AtomTransition*>(t);
trans = "Atom " + getTokenName(at->_label); trans = "Atom " + getTokenName(at->_label);

View File

@ -70,7 +70,7 @@ Ref<PredictionContext> PredictionContext::fromRuleContext(const ATN &atn, RuleCo
Ref<PredictionContext> parent = PredictionContext::fromRuleContext(atn, dynamic_cast<RuleContext *>(outerContext->parent)); Ref<PredictionContext> parent = PredictionContext::fromRuleContext(atn, dynamic_cast<RuleContext *>(outerContext->parent));
ATNState *state = atn.states.at(outerContext->invokingState); ATNState *state = atn.states.at(outerContext->invokingState);
RuleTransition *transition = (RuleTransition *)state->transition(0); RuleTransition *transition = (RuleTransition *)state->transitions[0];
return SingletonPredictionContext::create(parent, transition->followState->stateNumber); return SingletonPredictionContext::create(parent, transition->followState->stateNumber);
} }

View File

@ -37,7 +37,7 @@
using namespace antlr4::atn; using namespace antlr4::atn;
StarLoopEntryState *StarLoopbackState::getLoopEntryState() { StarLoopEntryState *StarLoopbackState::getLoopEntryState() {
return static_cast<StarLoopEntryState*>(transition(0)->target); return static_cast<StarLoopEntryState*>(transitions[0]->target);
} }
int StarLoopbackState::getStateType() { int StarLoopbackState::getStateType() {

View File

@ -131,8 +131,7 @@ namespace misc {
/// return true if this set has no members /// return true if this set has no members
virtual bool isEmpty() const; virtual bool isEmpty() const;
/// <summary> /// If this set is a single integer, return it otherwise Token.INVALID_TYPE.
/// If this set is a single integer, return it otherwise Token.INVALID_TYPE </summary>
virtual ssize_t getSingleElement() const; virtual ssize_t getSingleElement() const;
/** /**