| /* 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<ErrorNode *>(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<tree::TerminalNode *>(o)) { |
| tree::TerminalNode *tnode = dynamic_cast<tree::TerminalNode *>(o); |
| Token *symbol = tnode->getSymbol(); |
| if (symbol->getType() == ttype) { |
| if (j++ == i) { |
| return tnode; |
| } |
| } |
| } |
| } |
| |
| return nullptr; |
| } |
| |
| 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); |
| 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<std::string> 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()) + '}'; |
| } |
| |