1 /*
2 * Copyright (c) 2012-2019 The ANTLR Project. All rights reserved.
3 * Use of this file is governed by the BSD 3-clause license that
4 * can be found in the LICENSE.txt file in the project root.
5 */6 7 moduleantlr.v4.runtime.tree.AbstractParseTreeVisitor;
8 9 importantlr.v4.runtime.tree.ParseTreeVisitor;
10 importantlr.v4.runtime.tree.ParseTree;
11 importantlr.v4.runtime.tree.RuleNode;
12 importantlr.v4.runtime.tree.TerminalNode;
13 importantlr.v4.runtime.tree.ErrorNode;
14 importstd.variant : Variant;
15 16 /**
17 * TODO add class description
18 */19 abstractclassAbstractParseTreeVisitor : ParseTreeVisitor20 {
21 22 /**
23 * @uml
24 * {@inheritDoc}
25 *
26 * <p>The default implementation calls {@link ParseTree#accept} on the
27 * specified tree.</p>
28 */29 publicVariantvisit(ParseTreetree)
30 {
31 returntree.accept(this);
32 }
33 34 /**
35 * @uml
36 * {@inheritDoc}
37 *
38 * <p>The default implementation initializes the aggregate result to
39 * {@link #defaultResult defaultResult()}. Before visiting each child, it
40 * calls {@link #shouldVisitNextChild shouldVisitNextChild}; if the result
41 * is {@code false} no more children are visited and the current aggregate
42 * result is returned. After visiting a child, the aggregate result is
43 * updated by calling {@link #aggregateResult aggregateResult} with the
44 * previous aggregate result and the result of visiting the child.</p>
45 *
46 * <p>The default implementation is not safe for use in visitors that modify
47 * the tree structure. Visitors that modify the tree should override this
48 * method to behave properly in respect to the specific algorithm in use.</p>
49 * @override
50 */51 publicoverrideVariantvisitChildren(RuleNodenode)
52 {
53 Variantresult = defaultResult();
54 intn = node.getChildCount();
55 for (inti=0; i<n; i++) {
56 if (!shouldVisitNextChild(node, result)) {
57 break;
58 }
59 60 ParseTreec = node.getChild(i);
61 VariantchildResult = c.accept(this);
62 result = aggregateResult(result, childResult);
63 }
64 65 returnresult;
66 }
67 68 /**
69 * @uml
70 * {@inheritDoc}
71 *
72 * <p>The default implementation returns the result of
73 * {@link #defaultResult defaultResult}.</p>
74 * @override
75 */76 publicoverrideVariantvisitTerminal(TerminalNodenode)
77 {
78 returndefaultResult();
79 }
80 81 /**
82 * @uml
83 * {@inheritDoc}
84 *
85 * <p>The default implementation returns the result of
86 * {@link #defaultResult defaultResult}.</p>
87 * @override
88 */89 publicoverrideVariantvisitErrorNode(ErrorNodenode)
90 {
91 returndefaultResult();
92 }
93 94 /**
95 * @uml
96 * Gets the default value returned by visitor methods. This value is
97 * returned by the default implementations of
98 * {@link #visitTerminal visitTerminal}, {@link #visitErrorNode visitErrorNode}.
99 * The default implementation of {@link #visitChildren visitChildren}
100 * initializes its aggregate result to this value.
101 *
102 * <p>The base implementation returns {@code null}.</p>
103 *
104 * @return The default value returned by visitor methods.
105 */106 privateVariantdefaultResult()
107 {
108 returnVariant(null);
109 }
110 111 /**
112 * @uml
113 * Aggregates the results of visiting multiple children of a node. After
114 * either all children are visited or {@link #shouldVisitNextChild} returns
115 * {@code false}, the aggregate value is returned as the result of
116 * {@link #visitChildren}.
117 *
118 * <p>The default implementation returns {@code nextResult}, meaning
119 * {@link #visitChildren} will return the result of the last child visited
120 * (or return the initial value if the node has no children).</p>
121 *
122 * @param aggregate The previous aggregate value. In the default
123 * implementation, the aggregate value is initialized to
124 * {@link #defaultResult}, which is passed as the {@code aggregate} argument
125 * to this method after the first child node is visited.
126 * @param nextResult The result of the immediately preceeding call to visit
127 * a child node.
128 *
129 * @return The updated aggregate result.
130 */131 privateVariantaggregateResult(Variantaggregate, VariantnextResult)
132 {
133 returnnextResult;
134 }
135 136 /**
137 * @uml
138 * This method is called after visiting each child in
139 * {@link #visitChildren}. This method is first called before the first
140 * child is visited; at that point {@code currentResult} will be the initial
141 * value (in the default implementation, the initial value is returned by a
142 * call to {@link #defaultResult}. This method is not called after the last
143 * child is visited.
144 *
145 * <p>The default implementation always returns {@code true}, indicating that
146 * {@code visitChildren} should only return after all children are visited.
147 * One reason to override this method is to provide a "short circuit"
148 * evaluation option for situations where the result of visiting a single
149 * child has the potential to determine the result of the visit operation as
150 * a whole.</p>
151 *
152 * @param node The {@link RuleNode} whose children are currently being
153 * visited.
154 * @param currentResult The current aggregate result of the children visited
155 * to the current point.
156 *
157 * @return {@code true} to continue visiting children. Otherwise return
158 * {@code false} to stop visiting children and immediately return the
159 * current aggregate result from {@link #visitChildren}.
160 */161 privateboolshouldVisitNextChild(RuleNodenode, VariantcurrentResult)
162 {
163 returntrue;
164 }
165 166 }