/* 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/Trees.h" #include "misc/Interval.h" #include "Parser.h" #include "atn/ATN.h" #include "atn/ATNState.h" #include "tree/ParseTreeVisitor.h" #include "RuleContext.h" using namespace antlr4; using namespace antlr4::atn; RuleContext::RuleContext() { InitializeInstanceFields(); } RuleContext::RuleContext(RuleContext *parent_, size_t invokingState_) { InitializeInstanceFields(); this->parent = parent_; this->invokingState = invokingState_; } int RuleContext::depth() { int n = 1; RuleContext *p = this; while (true) { if (p->parent == nullptr) break; p = static_cast(p->parent); n++; } return n; } bool RuleContext::isEmpty() { return invokingState == ATNState::INVALID_STATE_NUMBER; } misc::Interval RuleContext::getSourceInterval() { return misc::Interval::INVALID; } std::string RuleContext::getText() { if (children.empty()) { return ""; } std::stringstream ss; for (size_t i = 0; i < children.size(); i++) { ParseTree *tree = children[i]; if (tree != nullptr) ss << tree->getText(); } return ss.str(); } size_t RuleContext::getRuleIndex() const { return INVALID_INDEX; } size_t RuleContext::getAltNumber() const { return atn::ATN::INVALID_ALT_NUMBER; } void RuleContext::setAltNumber(size_t /*altNumber*/) { } antlrcpp::Any RuleContext::accept(tree::ParseTreeVisitor *visitor) { return visitor->visitChildren(this); } std::string RuleContext::toStringTree(Parser *recog, bool pretty) { return tree::Trees::toStringTree(this, recog, pretty); } std::string RuleContext::toStringTree(std::vector &ruleNames, bool pretty) { return tree::Trees::toStringTree(this, ruleNames, pretty); } std::string RuleContext::toStringTree(bool pretty) { return toStringTree(nullptr, pretty); } std::string RuleContext::toString(const std::vector &ruleNames) { return toString(ruleNames, nullptr); } std::string RuleContext::toString(const std::vector &ruleNames, RuleContext *stop) { std::stringstream ss; RuleContext *currentParent = this; ss << "["; while (currentParent != stop) { if (ruleNames.empty()) { if (!currentParent->isEmpty()) { ss << currentParent->invokingState; } } else { size_t ruleIndex = currentParent->getRuleIndex(); std::string ruleName = (ruleIndex < ruleNames.size()) ? ruleNames[ruleIndex] : std::to_string(ruleIndex); ss << ruleName; } if (currentParent->parent == nullptr) // No parent anymore. break; currentParent = static_cast(currentParent->parent); if (!ruleNames.empty() || !currentParent->isEmpty()) { ss << " "; } } ss << "]"; return ss.str(); } std::string RuleContext::toString() { return toString(nullptr); } std::string RuleContext::toString(Recognizer *recog) { return toString(recog, &ParserRuleContext::EMPTY); } std::string RuleContext::toString(Recognizer *recog, RuleContext *stop) { if (recog == nullptr) return toString(std::vector(), stop); // Don't use an initializer {} here or we end up calling ourselve recursivly. return toString(recog->getRuleNames(), stop); } void RuleContext::InitializeInstanceFields() { invokingState = INVALID_INDEX; }