1 /*
2  * [The "BSD license"]
3  *  Copyright (c) 2012 Terence Parr
4  *  Copyright (c) 2012 Sam Harwell
5  *  All rights reserved.
6  *
7  *  Redistribution and use in source and binary forms, with or without
8  *  modification, are permitted provided that the following conditions
9  *  are met:
10  *
11  *  1. Redistributions of source code must retain the above copyright
12  *     notice, this list of conditions and the following disclaimer.
13  *  2. Redistributions in binary form must reproduce the above copyright
14  *     notice, this list of conditions and the following disclaimer in the
15  *     documentation and/or other materials provided with the distribution.
16  *  3. The name of the author may not be used to endorse or promote products
17  *     derived from this software without specific prior written permission.
18  *
19  *  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20  *  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21  *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22  *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24  *  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 module antlr.v4.runtime.tree.AbstractParseTreeVisitor;
32 
33 import antlr.v4.runtime.tree.ParseTreeVisitor;
34 
35 // Class Template AbstractParseTreeVisitor
36 /**
37  * TODO add class description
38  */
39 abstract class AbstractParseTreeVisitor(T) : ParseTreeVisitor!T
40 {
41 
42     /**
43      * @uml
44      * {@inheritDoc}
45      *
46      *  <p>The default implementation calls {@link ParseTree#accept} on the
47      *  specified tree.</p>
48      */
49     public T visit(ParseTree tree)
50     {
51         return tree.accept(this);
52     }
53 
54     /**
55      * @uml
56      * {@inheritDoc}
57      *
58      * <p>The default implementation initializes the aggregate result to
59      * {@link #defaultResult defaultResult()}. Before visiting each child, it
60      * calls {@link #shouldVisitNextChild shouldVisitNextChild}; if the result
61      * is {@code false} no more children are visited and the current aggregate
62      * result is returned. After visiting a child, the aggregate result is
63      * updated by calling {@link #aggregateResult aggregateResult} with the
64      * previous aggregate result and the result of visiting the child.</p>
65      *
66      * <p>The default implementation is not safe for use in visitors that modify
67      * the tree structure. Visitors that modify the tree should override this
68      * method to behave properly in respect to the specific algorithm in use.</p>
69      * @override
70      */
71     public override T visitChildren(RuleNode node)
72     {
73         T result = defaultResult();
74         int n = node.getChildCount();
75         for (int i=0; i<n; i++) {
76             if (!shouldVisitNextChild(node, result)) {
77                 break;
78             }
79 
80             ParseTree c = node.getChild(i);
81             T childResult = c.accept(this);
82             result = aggregateResult(result, childResult);
83         }
84 
85         return result;
86     }
87 
88     /**
89      * @uml
90      * {@inheritDoc}
91      *
92      * <p>The default implementation returns the result of
93      * {@link #defaultResult defaultResult}.</p>
94      * @override
95      */
96     public override T visitTerminal(TerminalNode node)
97     {
98         return defaultResult();
99     }
100 
101     /**
102      * @uml
103      * {@inheritDoc}
104      *
105      * <p>The default implementation returns the result of
106      * {@link #defaultResult defaultResult}.</p>
107      * @override
108      */
109     public override T visitErrorNode(ErrorNode node)
110     {
111         return defaultResult();
112     }
113 
114     /**
115      * @uml
116      * Gets the default value returned by visitor methods. This value is
117      * returned by the default implementations of
118      * {@link #visitTerminal visitTerminal}, {@link #visitErrorNode visitErrorNode}.
119      * The default implementation of {@link #visitChildren visitChildren}
120      * initializes its aggregate result to this value.
121      *
122      * <p>The base implementation returns {@code null}.</p>
123      *
124      *  @return The default value returned by visitor methods.
125      */
126     private T defaultResult()
127     {
128         return null;
129     }
130 
131     /**
132      * @uml
133      * Aggregates the results of visiting multiple children of a node. After
134      * either all children are visited or {@link #shouldVisitNextChild} returns
135      * {@code false}, the aggregate value is returned as the result of
136      * {@link #visitChildren}.
137      *
138      * <p>The default implementation returns {@code nextResult}, meaning
139      * {@link #visitChildren} will return the result of the last child visited
140      * (or return the initial value if the node has no children).</p>
141      *
142      *  @param aggregate The previous aggregate value. In the default
143      * implementation, the aggregate value is initialized to
144      *  {@link #defaultResult}, which is passed as the {@code aggregate} argument
145      * to this method after the first child node is visited.
146      *  @param nextResult The result of the immediately preceeding call to visit
147      * a child node.
148      *
149      *  @return The updated aggregate result.
150      */
151     private T aggregateResult(T aggregate, T nextResult)
152     {
153     }
154 
155     /**
156      * @uml
157      * This method is called after visiting each child in
158      * {@link #visitChildren}. This method is first called before the first
159      * child is visited; at that point {@code currentResult} will be the initial
160      * value (in the default implementation, the initial value is returned by a
161      * call to {@link #defaultResult}. This method is not called after the last
162      * child is visited.
163      *
164      * <p>The default implementation always returns {@code true}, indicating that
165      * {@code visitChildren} should only return after all children are visited.
166      * One reason to override this method is to provide a "short circuit"
167      * evaluation option for situations where the result of visiting a single
168      * child has the potential to determine the result of the visit operation as
169      * a whole.</p>
170      *
171      *  @param node The {@link RuleNode} whose children are currently being
172      * visited.
173      *  @param currentResult The current aggregate result of the children visited
174      * to the current point.
175      *
176      *  @return {@code true} to continue visiting children. Otherwise return
177      *  {@code false} to stop visiting children and immediately return the
178      *  current aggregate result from {@link #visitChildren}.
179      */
180     private bool shouldVisitNextChild(RuleNode node, T currentResult)
181     {
182     }
183 
184 }