X-Git-Url: https://gitweb.ps.run/toc/blobdiff_plain/9f94b672a5dc32da5ad01742bd4e976315a30d9c..c6ad2948bb98d42f8e0883ef82cd14cd2d5eda60:/antlr4-cpp-runtime-4.9.2-source/runtime/src/ParserRuleContext.cpp diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/ParserRuleContext.cpp b/antlr4-cpp-runtime-4.9.2-source/runtime/src/ParserRuleContext.cpp new file mode 100644 index 0000000..b67b9a9 --- /dev/null +++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/ParserRuleContext.cpp @@ -0,0 +1,141 @@ +/* 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. + */ + +#include "tree/TerminalNode.h" +#include "tree/ErrorNode.h" +#include "misc/Interval.h" +#include "Parser.h" +#include "Token.h" + +#include "support/CPPUtils.h" + +#include "ParserRuleContext.h" + +using namespace antlr4; +using namespace antlr4::tree; + +using namespace antlrcpp; + +ParserRuleContext ParserRuleContext::EMPTY; + +ParserRuleContext::ParserRuleContext() + : start(nullptr), stop(nullptr) { +} + +ParserRuleContext::ParserRuleContext(ParserRuleContext *parent, size_t invokingStateNumber) +: RuleContext(parent, invokingStateNumber), start(nullptr), stop(nullptr) { +} + +void ParserRuleContext::copyFrom(ParserRuleContext *ctx) { + // from RuleContext + this->parent = ctx->parent; + this->invokingState = ctx->invokingState; + + this->start = ctx->start; + this->stop = ctx->stop; + + // copy any error nodes to alt label node + if (!ctx->children.empty()) { + for (auto *child : ctx->children) { + auto *errorNode = dynamic_cast(child); + if (errorNode != nullptr) { + errorNode->setParent(this); + children.push_back(errorNode); + } + } + + // Remove the just reparented error nodes from the source context. + ctx->children.erase(std::remove_if(ctx->children.begin(), ctx->children.end(), [this](tree::ParseTree *e) -> bool { + return std::find(children.begin(), children.end(), e) != children.end(); + }), ctx->children.end()); + } +} + +void ParserRuleContext::enterRule(tree::ParseTreeListener * /*listener*/) { +} + +void ParserRuleContext::exitRule(tree::ParseTreeListener * /*listener*/) { +} + +tree::TerminalNode* ParserRuleContext::addChild(tree::TerminalNode *t) { + t->setParent(this); + children.push_back(t); + return t; +} + +RuleContext* ParserRuleContext::addChild(RuleContext *ruleInvocation) { + children.push_back(ruleInvocation); + return ruleInvocation; +} + +void ParserRuleContext::removeLastChild() { + if (!children.empty()) { + children.pop_back(); + } +} + +tree::TerminalNode* ParserRuleContext::getToken(size_t ttype, size_t i) { + if (i >= children.size()) { + return nullptr; + } + + size_t j = 0; // what token with ttype have we found? + for (auto *o : children) { + if (is(o)) { + tree::TerminalNode *tnode = dynamic_cast(o); + Token *symbol = tnode->getSymbol(); + if (symbol->getType() == ttype) { + if (j++ == i) { + return tnode; + } + } + } + } + + return nullptr; +} + +std::vector ParserRuleContext::getTokens(size_t ttype) { + std::vector tokens; + for (auto &o : children) { + if (is(o)) { + tree::TerminalNode *tnode = dynamic_cast(o); + Token *symbol = tnode->getSymbol(); + if (symbol->getType() == ttype) { + tokens.push_back(tnode); + } + } + } + + return tokens; +} + +misc::Interval ParserRuleContext::getSourceInterval() { + if (start == nullptr) { + return misc::Interval::INVALID; + } + + if (stop == nullptr || stop->getTokenIndex() < start->getTokenIndex()) { + return misc::Interval(start->getTokenIndex(), start->getTokenIndex() - 1); // empty + } + return misc::Interval(start->getTokenIndex(), stop->getTokenIndex()); +} + +Token* ParserRuleContext::getStart() { + return start; +} + +Token* ParserRuleContext::getStop() { + return stop; +} + +std::string ParserRuleContext::toInfoString(Parser *recognizer) { + std::vector rules = recognizer->getRuleInvocationStack(this); + std::reverse(rules.begin(), rules.end()); + std::string rulesStr = antlrcpp::arrayToString(rules); + return "ParserRuleContext" + rulesStr + "{start=" + std::to_string(start->getTokenIndex()) + ", stop=" + + std::to_string(stop->getTokenIndex()) + '}'; +} +