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 "support/Any.h" 9 : 10 : namespace antlr4 { 11 : namespace tree { 12 : 13 : /// An interface to access the tree of <seealso cref="RuleContext"/> objects created 14 : /// during a parse that makes the data structure look like a simple parse tree. 15 : /// This node represents both internal nodes, rule invocations, 16 : /// and leaf nodes, token matches. 17 : /// 18 : /// The payload is either a <seealso cref="Token"/> or a <seealso cref="RuleContext"/> object. 19 : // ml: This class unites 4 Java classes: RuleNode, ParseTree, SyntaxTree and Tree. 20 : class ANTLR4CPP_PUBLIC ParseTree { 21 : public: 22 : ParseTree(); 23 : ParseTree(ParseTree const&) = delete; 24 0 : virtual ~ParseTree() {} 25 : 26 : ParseTree& operator=(ParseTree const&) = delete; 27 : 28 : /// The parent of this node. If the return value is null, then this 29 : /// node is the root of the tree. 30 : ParseTree *parent; 31 : 32 : /// If we are debugging or building a parse tree for a visitor, 33 : /// we need to track all of the tokens and rule invocations associated 34 : /// with this rule's context. This is empty for parsing w/o tree constr. 35 : /// operation because we don't the need to track the details about 36 : /// how we parse this rule. 37 : // ml: memory is not managed here, but by the owning class. This is just for the structure. 38 : std::vector<ParseTree *> children; 39 : 40 : /// Print out a whole tree, not just a node, in LISP format 41 : /// {@code (root child1 .. childN)}. Print just a node if this is a leaf. 42 : virtual std::string toStringTree(bool pretty = false) = 0; 43 : virtual std::string toString() = 0; 44 : 45 : /// Specialize toStringTree so that it can print out more information 46 : /// based upon the parser. 47 : virtual std::string toStringTree(Parser *parser, bool pretty = false) = 0; 48 : 49 : virtual bool operator == (const ParseTree &other) const; 50 : 51 : /// The <seealso cref="ParseTreeVisitor"/> needs a double dispatch method. 52 : // ml: This has been changed to use Any instead of a template parameter, to avoid the need of a virtual template function. 53 : virtual antlrcpp::Any accept(ParseTreeVisitor *visitor) = 0; 54 : 55 : /// Return the combined text of all leaf nodes. Does not get any 56 : /// off-channel tokens (if any) so won't return whitespace and 57 : /// comments if they are sent to parser on hidden channel. 58 : virtual std::string getText() = 0; 59 : 60 : /** 61 : * Return an {@link Interval} indicating the index in the 62 : * {@link TokenStream} of the first and last token associated with this 63 : * subtree. If this node is a leaf, then the interval represents a single 64 : * token and has interval i..i for token index i. 65 : * 66 : * <p>An interval of i..i-1 indicates an empty interval at position 67 : * i in the input stream, where 0 <= i <= the size of the input 68 : * token stream. Currently, the code base can only have i=0..n-1 but 69 : * in concept one could have an empty interval after EOF. </p> 70 : * 71 : * <p>If source interval is unknown, this returns {@link Interval#INVALID}.</p> 72 : * 73 : * <p>As a weird special case, the source interval for rules matched after 74 : * EOF is unspecified.</p> 75 : */ 76 : virtual misc::Interval getSourceInterval() = 0; 77 : }; 78 : 79 : // A class to help managing ParseTree instances without the need of a shared_ptr. 80 : class ANTLR4CPP_PUBLIC ParseTreeTracker { 81 : public: 82 : template<typename T, typename ... Args> 83 0 : T* createInstance(Args&& ... args) { 84 : static_assert(std::is_base_of<ParseTree, T>::value, "Argument must be a parse tree type"); 85 0 : T* result = new T(args...); 86 0 : _allocated.push_back(result); 87 0 : return result; 88 : } 89 : 90 : void reset() { 91 : for (auto entry : _allocated) 92 : delete entry; 93 : _allocated.clear(); 94 : } 95 : 96 : private: 97 : std::vector<ParseTree *> _allocated; 98 : }; 99 : 100 : 101 : } // namespace tree 102 : } // namespace antlr4