Line data Source code
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 : #pragma once 7 : 8 : #include "RuleContext.h" 9 : #include "support/CPPUtils.h" 10 : 11 : namespace antlr4 { 12 : 13 : /// <summary> 14 : /// A rule invocation record for parsing. 15 : /// 16 : /// Contains all of the information about the current rule not stored in the 17 : /// RuleContext. It handles parse tree children list, Any ATN state 18 : /// tracing, and the default values available for rule invocatons: 19 : /// start, stop, rule index, current alt number. 20 : /// 21 : /// Subclasses made for each rule and grammar track the parameters, 22 : /// return values, locals, and labels specific to that rule. These 23 : /// are the objects that are returned from rules. 24 : /// 25 : /// Note text is not an actual field of a rule return value; it is computed 26 : /// from start and stop using the input stream's toString() method. I 27 : /// could add a ctor to this so that we can pass in and store the input 28 : /// stream, but I'm not sure we want to do that. It would seem to be undefined 29 : /// to get the .text property anyway if the rule matches tokens from multiple 30 : /// input streams. 31 : /// 32 : /// I do not use getters for fields of objects that are used simply to 33 : /// group values such as this aggregate. The getters/setters are there to 34 : /// satisfy the superclass interface. 35 : /// </summary> 36 : class ANTLR4CPP_PUBLIC ParserRuleContext : public RuleContext { 37 : public: 38 : static ParserRuleContext EMPTY; 39 : 40 : /// <summary> 41 : /// For debugging/tracing purposes, we want to track all of the nodes in 42 : /// the ATN traversed by the parser for a particular rule. 43 : /// This list indicates the sequence of ATN nodes used to match 44 : /// the elements of the children list. This list does not include 45 : /// ATN nodes and other rules used to match rule invocations. It 46 : /// traces the rule invocation node itself but nothing inside that 47 : /// other rule's ATN submachine. 48 : /// 49 : /// There is NOT a one-to-one correspondence between the children and 50 : /// states list. There are typically many nodes in the ATN traversed 51 : /// for each element in the children list. For example, for a rule 52 : /// invocation there is the invoking state and the following state. 53 : /// 54 : /// The parser setState() method updates field s and adds it to this list 55 : /// if we are debugging/tracing. 56 : /// 57 : /// This does not trace states visited during prediction. 58 : /// </summary> 59 : // public List<Integer> states; 60 : 61 : Token *start; 62 : Token *stop; 63 : 64 : /// The exception that forced this rule to return. If the rule successfully 65 : /// completed, this is "null exception pointer". 66 : std::exception_ptr exception; 67 : 68 : ParserRuleContext(); 69 : ParserRuleContext(ParserRuleContext *parent, size_t invokingStateNumber); 70 0 : virtual ~ParserRuleContext() {} 71 : 72 : /** COPY a ctx (I'm deliberately not using copy constructor) to avoid 73 : * confusion with creating node with parent. Does not copy children 74 : * (except error leaves). 75 : */ 76 : virtual void copyFrom(ParserRuleContext *ctx); 77 : 78 : 79 : // Double dispatch methods for listeners 80 : 81 : virtual void enterRule(tree::ParseTreeListener *listener); 82 : virtual void exitRule(tree::ParseTreeListener *listener); 83 : 84 : /** Add a token leaf node child and force its parent to be this node. */ 85 : tree::TerminalNode* addChild(tree::TerminalNode *t); 86 : RuleContext* addChild(RuleContext *ruleInvocation); 87 : 88 : /// Used by enterOuterAlt to toss out a RuleContext previously added as 89 : /// we entered a rule. If we have # label, we will need to remove 90 : /// generic ruleContext object. 91 : virtual void removeLastChild(); 92 : 93 : virtual tree::TerminalNode* getToken(size_t ttype, std::size_t i); 94 : 95 : virtual std::vector<tree::TerminalNode *> getTokens(size_t ttype); 96 : 97 : template<typename T> 98 0 : T* getRuleContext(size_t i) { 99 0 : if (children.empty()) { 100 : return nullptr; 101 : } 102 : 103 : size_t j = 0; // what element have we found with ctxType? 104 0 : for (auto &child : children) { 105 0 : if (antlrcpp::is<T *>(child)) { 106 0 : if (j++ == i) { 107 0 : return dynamic_cast<T *>(child); 108 : } 109 : } 110 : } 111 : return nullptr; 112 : } 113 : 114 : template<typename T> 115 0 : std::vector<T *> getRuleContexts() { 116 0 : std::vector<T *> contexts; 117 0 : for (auto child : children) { 118 0 : if (antlrcpp::is<T *>(child)) { 119 0 : contexts.push_back(dynamic_cast<T *>(child)); 120 : } 121 : } 122 : 123 0 : return contexts; 124 : } 125 : 126 : virtual misc::Interval getSourceInterval() override; 127 : 128 : /** 129 : * Get the initial token in this context. 130 : * Note that the range from start to stop is inclusive, so for rules that do not consume anything 131 : * (for example, zero length or error productions) this token may exceed stop. 132 : */ 133 : virtual Token *getStart(); 134 : 135 : /** 136 : * Get the final token in this context. 137 : * Note that the range from start to stop is inclusive, so for rules that do not consume anything 138 : * (for example, zero length or error productions) this token may precede start. 139 : */ 140 : virtual Token *getStop(); 141 : 142 : /// <summary> 143 : /// Used for rule context info debugging during parse-time, not so much for ATN debugging </summary> 144 : virtual std::string toInfoString(Parser *recognizer); 145 : }; 146 : 147 : } // namespace antlr4