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 "tree/ParseTreeVisitor.h" 9 : 10 : namespace antlr4 { 11 : namespace tree { 12 : 13 : class ANTLR4CPP_PUBLIC AbstractParseTreeVisitor : public ParseTreeVisitor { 14 : public: 15 : /// The default implementation calls <seealso cref="ParseTree#accept"/> on the 16 : /// specified tree. 17 : virtual antlrcpp::Any visit(ParseTree *tree) override { 18 : return tree->accept(this); 19 : } 20 : 21 : /** 22 : * <p>The default implementation initializes the aggregate result to 23 : * {@link #defaultResult defaultResult()}. Before visiting each child, it 24 : * calls {@link #shouldVisitNextChild shouldVisitNextChild}; if the result 25 : * is {@code false} no more children are visited and the current aggregate 26 : * result is returned. After visiting a child, the aggregate result is 27 : * updated by calling {@link #aggregateResult aggregateResult} with the 28 : * previous aggregate result and the result of visiting the child.</p> 29 : * 30 : * <p>The default implementation is not safe for use in visitors that modify 31 : * the tree structure. Visitors that modify the tree should override this 32 : * method to behave properly in respect to the specific algorithm in use.</p> 33 : */ 34 0 : virtual antlrcpp::Any visitChildren(ParseTree *node) override { 35 0 : antlrcpp::Any result = defaultResult(); 36 0 : size_t n = node->children.size(); 37 0 : for (size_t i = 0; i < n; i++) { 38 0 : if (!shouldVisitNextChild(node, result)) { 39 : break; 40 : } 41 : 42 0 : antlrcpp::Any childResult = node->children[i]->accept(this); 43 0 : result = aggregateResult(result, childResult); 44 : } 45 : 46 0 : return result; 47 : } 48 : 49 : /// The default implementation returns the result of 50 : /// <seealso cref="#defaultResult defaultResult"/>. 51 : virtual antlrcpp::Any visitTerminal(TerminalNode * /*node*/) override { 52 : return defaultResult(); 53 : } 54 : 55 : /// The default implementation returns the result of 56 : /// <seealso cref="#defaultResult defaultResult"/>. 57 : virtual antlrcpp::Any visitErrorNode(ErrorNode * /*node*/) override { 58 : return defaultResult(); 59 : } 60 : 61 : protected: 62 : /// <summary> 63 : /// Gets the default value returned by visitor methods. This value is 64 : /// returned by the default implementations of 65 : /// <seealso cref="#visitTerminal visitTerminal"/>, <seealso cref="#visitErrorNode visitErrorNode"/>. 66 : /// The default implementation of <seealso cref="#visitChildren visitChildren"/> 67 : /// initializes its aggregate result to this value. 68 : /// <p/> 69 : /// The base implementation returns {@code null}. 70 : /// </summary> 71 : /// <returns> The default value returned by visitor methods. </returns> 72 0 : virtual antlrcpp::Any defaultResult() { 73 0 : return nullptr; // support isNotNull 74 : } 75 : 76 : /// <summary> 77 : /// Aggregates the results of visiting multiple children of a node. After 78 : /// either all children are visited or <seealso cref="#shouldVisitNextChild"/> returns 79 : /// {@code false}, the aggregate value is returned as the result of 80 : /// <seealso cref="#visitChildren"/>. 81 : /// <p/> 82 : /// The default implementation returns {@code nextResult}, meaning 83 : /// <seealso cref="#visitChildren"/> will return the result of the last child visited 84 : /// (or return the initial value if the node has no children). 85 : /// </summary> 86 : /// <param name="aggregate"> The previous aggregate value. In the default 87 : /// implementation, the aggregate value is initialized to 88 : /// <seealso cref="#defaultResult"/>, which is passed as the {@code aggregate} argument 89 : /// to this method after the first child node is visited. </param> 90 : /// <param name="nextResult"> The result of the immediately preceeding call to visit 91 : /// a child node. 92 : /// </param> 93 : /// <returns> The updated aggregate result. </returns> 94 0 : virtual antlrcpp::Any aggregateResult(antlrcpp::Any /*aggregate*/, const antlrcpp::Any &nextResult) { 95 0 : return nextResult; 96 : } 97 : 98 : /// <summary> 99 : /// This method is called after visiting each child in 100 : /// <seealso cref="#visitChildren"/>. This method is first called before the first 101 : /// child is visited; at that point {@code currentResult} will be the initial 102 : /// value (in the default implementation, the initial value is returned by a 103 : /// call to <seealso cref="#defaultResult"/>. This method is not called after the last 104 : /// child is visited. 105 : /// <p/> 106 : /// The default implementation always returns {@code true}, indicating that 107 : /// {@code visitChildren} should only return after all children are visited. 108 : /// One reason to override this method is to provide a "short circuit" 109 : /// evaluation option for situations where the result of visiting a single 110 : /// child has the potential to determine the result of the visit operation as 111 : /// a whole. 112 : /// </summary> 113 : /// <param name="node"> The <seealso cref="ParseTree"/> whose children are currently being 114 : /// visited. </param> 115 : /// <param name="currentResult"> The current aggregate result of the children visited 116 : /// to the current point. 117 : /// </param> 118 : /// <returns> {@code true} to continue visiting children. Otherwise return 119 : /// {@code false} to stop visiting children and immediately return the 120 : /// current aggregate result from <seealso cref="#visitChildren"/>. </returns> 121 0 : virtual bool shouldVisitNextChild(ParseTree * /*node*/, const antlrcpp::Any &/*currentResult*/) { 122 0 : return true; 123 : } 124 : 125 : }; 126 : 127 : } // namespace tree 128 : } // namespace antlr4