]> gitweb.ps.run Git - toc/blob - antlr4-cpp-runtime-4.9.2-source/runtime/src/ParserRuleContext.cpp
add antlr source code and ReadMe
[toc] / antlr4-cpp-runtime-4.9.2-source / runtime / src / ParserRuleContext.cpp
1 /* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
2  * Use of this file is governed by the BSD 3-clause license that
3  * can be found in the LICENSE.txt file in the project root.
4  */
5
6 #include "tree/TerminalNode.h"
7 #include "tree/ErrorNode.h"
8 #include "misc/Interval.h"
9 #include "Parser.h"
10 #include "Token.h"
11
12 #include "support/CPPUtils.h"
13
14 #include "ParserRuleContext.h"
15
16 using namespace antlr4;
17 using namespace antlr4::tree;
18
19 using namespace antlrcpp;
20
21 ParserRuleContext ParserRuleContext::EMPTY;
22
23 ParserRuleContext::ParserRuleContext()
24   : start(nullptr), stop(nullptr) {
25 }
26
27 ParserRuleContext::ParserRuleContext(ParserRuleContext *parent, size_t invokingStateNumber)
28 : RuleContext(parent, invokingStateNumber), start(nullptr), stop(nullptr) {
29 }
30
31 void ParserRuleContext::copyFrom(ParserRuleContext *ctx) {
32   // from RuleContext
33   this->parent = ctx->parent;
34   this->invokingState = ctx->invokingState;
35
36   this->start = ctx->start;
37   this->stop = ctx->stop;
38
39   // copy any error nodes to alt label node
40   if (!ctx->children.empty()) {
41     for (auto *child : ctx->children) {
42       auto *errorNode = dynamic_cast<ErrorNode *>(child);
43       if (errorNode != nullptr) {
44         errorNode->setParent(this);
45         children.push_back(errorNode);
46       }
47     }
48
49     // Remove the just reparented error nodes from the source context.
50     ctx->children.erase(std::remove_if(ctx->children.begin(), ctx->children.end(), [this](tree::ParseTree *e) -> bool {
51       return std::find(children.begin(), children.end(), e) != children.end();
52     }), ctx->children.end());
53   }
54 }
55
56 void ParserRuleContext::enterRule(tree::ParseTreeListener * /*listener*/) {
57 }
58
59 void ParserRuleContext::exitRule(tree::ParseTreeListener * /*listener*/) {
60 }
61
62 tree::TerminalNode* ParserRuleContext::addChild(tree::TerminalNode *t) {
63   t->setParent(this);
64   children.push_back(t);
65   return t;
66 }
67
68 RuleContext* ParserRuleContext::addChild(RuleContext *ruleInvocation) {
69   children.push_back(ruleInvocation);
70   return ruleInvocation;
71 }
72
73 void ParserRuleContext::removeLastChild() {
74   if (!children.empty()) {
75     children.pop_back();
76   }
77 }
78
79 tree::TerminalNode* ParserRuleContext::getToken(size_t ttype, size_t i) {
80   if (i >= children.size()) {
81     return nullptr;
82   }
83
84   size_t j = 0; // what token with ttype have we found?
85   for (auto *o : children) {
86     if (is<tree::TerminalNode *>(o)) {
87       tree::TerminalNode *tnode = dynamic_cast<tree::TerminalNode *>(o);
88       Token *symbol = tnode->getSymbol();
89       if (symbol->getType() == ttype) {
90         if (j++ == i) {
91           return tnode;
92         }
93       }
94     }
95   }
96
97   return nullptr;
98 }
99
100 std::vector<tree::TerminalNode *> ParserRuleContext::getTokens(size_t ttype) {
101   std::vector<tree::TerminalNode *> tokens;
102   for (auto &o : children) {
103     if (is<tree::TerminalNode *>(o)) {
104       tree::TerminalNode *tnode = dynamic_cast<tree::TerminalNode *>(o);
105       Token *symbol = tnode->getSymbol();
106       if (symbol->getType() == ttype) {
107         tokens.push_back(tnode);
108       }
109     }
110   }
111
112   return tokens;
113 }
114
115 misc::Interval ParserRuleContext::getSourceInterval() {
116   if (start == nullptr) {
117     return misc::Interval::INVALID;
118   }
119
120   if (stop == nullptr || stop->getTokenIndex() < start->getTokenIndex()) {
121     return misc::Interval(start->getTokenIndex(), start->getTokenIndex() - 1); // empty
122   }
123   return misc::Interval(start->getTokenIndex(), stop->getTokenIndex());
124 }
125
126 Token* ParserRuleContext::getStart() {
127   return start;
128 }
129
130 Token* ParserRuleContext::getStop() {
131   return stop;
132 }
133
134 std::string ParserRuleContext::toInfoString(Parser *recognizer) {
135   std::vector<std::string> rules = recognizer->getRuleInvocationStack(this);
136   std::reverse(rules.begin(), rules.end());
137   std::string rulesStr = antlrcpp::arrayToString(rules);
138   return "ParserRuleContext" + rulesStr + "{start=" + std::to_string(start->getTokenIndex()) + ", stop=" +
139     std::to_string(stop->getTokenIndex()) + '}';
140 }
141