Skip to content

Commit

Permalink
[C++] Avoid using dynamic_cast where possible by using hand rolled RTTI
Browse files Browse the repository at this point in the history
  • Loading branch information
jcking committed Mar 14, 2022
1 parent d1e8dbe commit 31e81f6
Show file tree
Hide file tree
Showing 67 changed files with 475 additions and 299 deletions.
12 changes: 6 additions & 6 deletions runtime/Cpp/runtime/src/DefaultErrorStrategy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,19 +106,19 @@ void DefaultErrorStrategy::sync(Parser *recognizer) {
}

switch (s->getStateType()) {
case atn::ATNState::BLOCK_START:
case atn::ATNState::STAR_BLOCK_START:
case atn::ATNState::PLUS_BLOCK_START:
case atn::ATNState::STAR_LOOP_ENTRY:
case atn::ATNStateType::BLOCK_START:
case atn::ATNStateType::STAR_BLOCK_START:
case atn::ATNStateType::PLUS_BLOCK_START:
case atn::ATNStateType::STAR_LOOP_ENTRY:
// report error and recover if possible
if (singleTokenDeletion(recognizer) != nullptr) {
return;
}

throw InputMismatchException(recognizer);

case atn::ATNState::PLUS_LOOP_BACK:
case atn::ATNState::STAR_LOOP_BACK: {
case atn::ATNStateType::PLUS_LOOP_BACK:
case atn::ATNStateType::STAR_LOOP_BACK: {
reportUnwantedToken(recognizer);
misc::IntervalSet expecting = recognizer->getExpectedTokens();
misc::IntervalSet whatFollowsLoopIterationOrRule = expecting.Or(getErrorRecoverySet(recognizer));
Expand Down
26 changes: 13 additions & 13 deletions runtime/Cpp/runtime/src/ParserInterpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ ParserRuleContext* ParserInterpreter::parse(size_t startRuleIndex) {
while (true) {
atn::ATNState *p = getATNState();
switch (p->getStateType()) {
case atn::ATNState::RULE_STOP :
case atn::ATNStateType::RULE_STOP :
// pop; return from rule
if (_ctx->isEmpty()) {
if (startRuleStartState->isLeftRecursiveRule) {
Expand Down Expand Up @@ -153,9 +153,9 @@ void ParserInterpreter::visitState(atn::ATNState *p) {
}

const atn::Transition *transition = p->transitions[predictedAlt - 1].get();
switch (transition->getSerializationType()) {
case atn::Transition::EPSILON:
if (p->getStateType() == ATNState::STAR_LOOP_ENTRY &&
switch (transition->getTransitionType()) {
case atn::TransitionType::EPSILON:
if (p->getStateType() == ATNStateType::STAR_LOOP_ENTRY &&
(dynamic_cast<StarLoopEntryState *>(p))->isPrecedenceDecision &&
!is<LoopEndState *>(transition->target)) {
// We are at the start of a left recursive rule's (...)* loop
Expand All @@ -166,24 +166,24 @@ void ParserInterpreter::visitState(atn::ATNState *p) {
}
break;

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

case atn::Transition::RANGE:
case atn::Transition::SET:
case atn::Transition::NOT_SET:
case atn::TransitionType::RANGE:
case atn::TransitionType::SET:
case atn::TransitionType::NOT_SET:
if (!transition->matches(static_cast<int>(_input->LA(1)), Token::MIN_USER_TOKEN_TYPE, Lexer::MAX_CHAR_VALUE)) {
recoverInline();
}
matchWildcard();
break;

case atn::Transition::WILDCARD:
case atn::TransitionType::WILDCARD:
matchWildcard();
break;

case atn::Transition::RULE:
case atn::TransitionType::RULE:
{
atn::RuleStartState *ruleStartState = static_cast<atn::RuleStartState*>(transition->target);
size_t ruleIndex = ruleStartState->ruleIndex;
Expand All @@ -196,7 +196,7 @@ void ParserInterpreter::visitState(atn::ATNState *p) {
}
break;

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

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

case atn::Transition::PRECEDENCE:
case atn::TransitionType::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) + ")");
Expand Down
9 changes: 5 additions & 4 deletions runtime/Cpp/runtime/src/ParserRuleContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "Parser.h"
#include "Token.h"

#include "support/Casts.h"
#include "support/CPPUtils.h"

#include "ParserRuleContext.h"
Expand Down Expand Up @@ -83,8 +84,8 @@ tree::TerminalNode* ParserRuleContext::getToken(size_t ttype, size_t i) {

size_t j = 0; // what token with ttype have we found?
for (auto *o : children) {
if (is<tree::TerminalNode *>(o)) {
tree::TerminalNode *tnode = dynamic_cast<tree::TerminalNode *>(o);
if (o->getTreeType() == ParseTreeType::TERMINAL || o->getTreeType() == ParseTreeType::ERROR) {
tree::TerminalNode *tnode = downCast<tree::TerminalNode *>(o);
Token *symbol = tnode->getSymbol();
if (symbol->getType() == ttype) {
if (j++ == i) {
Expand All @@ -100,8 +101,8 @@ tree::TerminalNode* ParserRuleContext::getToken(size_t ttype, size_t i) {
std::vector<tree::TerminalNode *> ParserRuleContext::getTokens(size_t ttype) {
std::vector<tree::TerminalNode *> tokens;
for (auto &o : children) {
if (is<tree::TerminalNode *>(o)) {
tree::TerminalNode *tnode = dynamic_cast<tree::TerminalNode *>(o);
if (o->getTreeType() == ParseTreeType::TERMINAL || o->getTreeType() == ParseTreeType::ERROR) {
tree::TerminalNode *tnode = downCast<tree::TerminalNode *>(o);
Token *symbol = tnode->getSymbol();
if (symbol->getType() == ttype) {
tokens.push_back(tnode);
Expand Down
5 changes: 5 additions & 0 deletions runtime/Cpp/runtime/src/RuleContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

using namespace antlr4;
using namespace antlr4::atn;
using namespace antlr4::tree;

RuleContext::RuleContext() {
InitializeInstanceFields();
Expand Down Expand Up @@ -137,6 +138,10 @@ std::string RuleContext::toString(Recognizer *recog, RuleContext *stop) {
return toString(recog->getRuleNames(), stop);
}

ParseTreeType RuleContext::getTreeType() const {
return ParseTreeType::RULE;
}

void RuleContext::InitializeInstanceFields() {
invokingState = INVALID_INDEX;
}
Expand Down
2 changes: 2 additions & 0 deletions runtime/Cpp/runtime/src/RuleContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ namespace antlr4 {

virtual std::string toString(const std::vector<std::string> &ruleNames, RuleContext *stop);

tree::ParseTreeType getTreeType() const final;

bool operator == (const RuleContext &other) { return this == &other; } // Simple address comparison.

private:
Expand Down
Loading

0 comments on commit 31e81f6

Please sign in to comment.