xref: /plugin/combo/vendor/antlr/antlr4-php-runtime/src/Tree/AbstractParseTreeVisitor.php (revision 37748cd8654635afbeca80942126742f0f4cc346)
1*37748cd8SNickeau<?php
2*37748cd8SNickeau
3*37748cd8SNickeaudeclare(strict_types=1);
4*37748cd8SNickeau
5*37748cd8SNickeaunamespace Antlr\Antlr4\Runtime\Tree;
6*37748cd8SNickeau
7*37748cd8SNickeauclass AbstractParseTreeVisitor implements ParseTreeVisitor
8*37748cd8SNickeau{
9*37748cd8SNickeau    /**
10*37748cd8SNickeau     * {@inheritdoc}
11*37748cd8SNickeau     *
12*37748cd8SNickeau     * The default implementation calls {@see ParseTree::accept()} on the specified tree.
13*37748cd8SNickeau     *
14*37748cd8SNickeau     * @return mixed
15*37748cd8SNickeau     */
16*37748cd8SNickeau    public function visit(ParseTree $tree)
17*37748cd8SNickeau    {
18*37748cd8SNickeau        return $tree->accept($this);
19*37748cd8SNickeau    }
20*37748cd8SNickeau
21*37748cd8SNickeau    /**
22*37748cd8SNickeau     * {@inheritdoc}
23*37748cd8SNickeau     *
24*37748cd8SNickeau     * The default implementation initializes the aggregate result to
25*37748cd8SNickeau     * {@see AbstractParseTreeVisitor::defaultResult()}. Before visiting each
26*37748cd8SNickeau     * child, it calls {@see AbstractParseTreeVisitor::shouldVisitNextChild()};
27*37748cd8SNickeau     * if the result is `false` no more children are visited and the current
28*37748cd8SNickeau     * aggregate result is returned. After visiting a child, the aggregate
29*37748cd8SNickeau     * result is updated by calling {@see AbstractParseTreeVisitor::aggregateResult()}
30*37748cd8SNickeau     * with the previous aggregate result and the result of visiting the child.
31*37748cd8SNickeau     *
32*37748cd8SNickeau     * The default implementation is not safe for use in visitors that modify
33*37748cd8SNickeau     * the tree structure. Visitors that modify the tree should override this
34*37748cd8SNickeau     * method to behave properly in respect to the specific algorithm in use.
35*37748cd8SNickeau     *
36*37748cd8SNickeau     * @return mixed
37*37748cd8SNickeau     */
38*37748cd8SNickeau    public function visitChildren(RuleNode $node)
39*37748cd8SNickeau    {
40*37748cd8SNickeau        $result = $this->defaultResult();
41*37748cd8SNickeau
42*37748cd8SNickeau        $n = $node->getChildCount();
43*37748cd8SNickeau
44*37748cd8SNickeau        for ($i=0; $i < $n; $i++) {
45*37748cd8SNickeau            if (!$this->shouldVisitNextChild($node, $result)) {
46*37748cd8SNickeau                break;
47*37748cd8SNickeau            }
48*37748cd8SNickeau
49*37748cd8SNickeau            /** @var ParseTree $child */
50*37748cd8SNickeau            $child = $node->getChild($i);
51*37748cd8SNickeau
52*37748cd8SNickeau            $childResult = $child->accept($this);
53*37748cd8SNickeau
54*37748cd8SNickeau            $result = $this->aggregateResult($result, $childResult);
55*37748cd8SNickeau        }
56*37748cd8SNickeau
57*37748cd8SNickeau        return $result;
58*37748cd8SNickeau    }
59*37748cd8SNickeau
60*37748cd8SNickeau    /**
61*37748cd8SNickeau     * {@inheritdoc}
62*37748cd8SNickeau     *
63*37748cd8SNickeau     * The default implementation returns the result of
64*37748cd8SNickeau     * {@see AbstractParseTreeVisitor::defaultResult()}.
65*37748cd8SNickeau     *
66*37748cd8SNickeau     * @return mixed
67*37748cd8SNickeau     */
68*37748cd8SNickeau    public function visitTerminal(TerminalNode $node)
69*37748cd8SNickeau    {
70*37748cd8SNickeau        return $this->defaultResult();
71*37748cd8SNickeau    }
72*37748cd8SNickeau
73*37748cd8SNickeau    /**
74*37748cd8SNickeau     * {@inheritdoc}
75*37748cd8SNickeau     *
76*37748cd8SNickeau     * The default implementation returns the result of
77*37748cd8SNickeau     * {@see AbstractParseTreeVisitor::defaultResult()}.
78*37748cd8SNickeau     *
79*37748cd8SNickeau     * @return mixed
80*37748cd8SNickeau     */
81*37748cd8SNickeau    public function visitErrorNode(ErrorNode $tree)
82*37748cd8SNickeau    {
83*37748cd8SNickeau        return $this->defaultResult();
84*37748cd8SNickeau    }
85*37748cd8SNickeau
86*37748cd8SNickeau    /**
87*37748cd8SNickeau     * Gets the default value returned by visitor methods. This value is
88*37748cd8SNickeau     * returned by the default implementations of
89*37748cd8SNickeau     * {@see AbstractParseTreeVisitor::visitTerminal()},
90*37748cd8SNickeau     * {@see AbstractParseTreeVisitor::visitErrorNode()}.
91*37748cd8SNickeau     * The default implementation of {@see AbstractParseTreeVisitor::visitChildren()}
92*37748cd8SNickeau     * initializes its aggregate result to this value.
93*37748cd8SNickeau     *
94*37748cd8SNickeau     * The base implementation returns `null`.
95*37748cd8SNickeau     *
96*37748cd8SNickeau     * @return mixed
97*37748cd8SNickeau     */
98*37748cd8SNickeau    protected function defaultResult()
99*37748cd8SNickeau    {
100*37748cd8SNickeau        return null;
101*37748cd8SNickeau    }
102*37748cd8SNickeau
103*37748cd8SNickeau    /**
104*37748cd8SNickeau     * Aggregates the results of visiting multiple children of a node. After
105*37748cd8SNickeau     * either all children are visited or
106*37748cd8SNickeau     * {@see AbstractParseTreeVisitor::shouldVisitNextChild()} returns `false`,
107*37748cd8SNickeau     * the aggregate value is returned as the result of
108*37748cd8SNickeau     * {@see AbstractParseTreeVisitor::visitChildren()}.
109*37748cd8SNickeau     *
110*37748cd8SNickeau     * The default implementation returns `nextResult`, meaning
111*37748cd8SNickeau     * {@see AbstractParseTreeVisitor::visitChildren()} will return the result
112*37748cd8SNickeau     * of the last child visited (or return the initial value if the node has
113*37748cd8SNickeau     * no children).
114*37748cd8SNickeau     *
115*37748cd8SNickeau     * @param mixed $aggregate  The previous aggregate value. In the default
116*37748cd8SNickeau     *                          implementation, the aggregate value is initialized
117*37748cd8SNickeau     *                          to {@see AbstractParseTreeVisitor::defaultResult()},
118*37748cd8SNickeau     *                          which is passed as the `aggregate` argument to
119*37748cd8SNickeau     *                          this method after the first child node is visited.
120*37748cd8SNickeau     * @param mixed $nextResult The result of the immediately preceeding call to
121*37748cd8SNickeau     *                          visit a child node.
122*37748cd8SNickeau     *
123*37748cd8SNickeau     * @return mixed
124*37748cd8SNickeau     */
125*37748cd8SNickeau    protected function aggregateResult($aggregate, $nextResult)
126*37748cd8SNickeau    {
127*37748cd8SNickeau        return $nextResult;
128*37748cd8SNickeau    }
129*37748cd8SNickeau
130*37748cd8SNickeau    /**
131*37748cd8SNickeau     * This method is called after visiting each child in
132*37748cd8SNickeau     * {@see AbstractParseTreeVisitor::visitChildren()}. This method is first
133*37748cd8SNickeau     * called before the first child is visited; at that point `currentResult`
134*37748cd8SNickeau     * will be the initial value (in the default implementation, the initial
135*37748cd8SNickeau     * value is returned by a call to {@see AbstractParseTreeVisitor::defaultResult()}.
136*37748cd8SNickeau     * This method is not called after the last child is visited.
137*37748cd8SNickeau     *
138*37748cd8SNickeau     * The default implementation always returns `true`, indicating that
139*37748cd8SNickeau     * `visitChildren` should only return after all children are visited.
140*37748cd8SNickeau     * One reason to override this method is to provide a "short circuit"
141*37748cd8SNickeau     * evaluation option for situations where the result of visiting a single
142*37748cd8SNickeau     * child has the potential to determine the result of the visit operation as
143*37748cd8SNickeau     * a whole.
144*37748cd8SNickeau     *
145*37748cd8SNickeau     * @param RuleNode $node          The {@see RuleNode} whose children are
146*37748cd8SNickeau     *                                currently being visited.
147*37748cd8SNickeau     * @param mixed    $currentResult The current aggregate result of the children
148*37748cd8SNickeau     *                                visited to the current point.
149*37748cd8SNickeau     *
150*37748cd8SNickeau     * @return bool `true` to continue visiting children. Otherwise return `false`
151*37748cd8SNickeau     *              to stop visiting children and immediately return the current
152*37748cd8SNickeau     *              aggregate result from {@see AbstractParseTreeVisitor::visitChildren()}.
153*37748cd8SNickeau     */
154*37748cd8SNickeau    protected function shouldVisitNextChild(RuleNode $node, $currentResult) : bool
155*37748cd8SNickeau    {
156*37748cd8SNickeau        return true;
157*37748cd8SNickeau    }
158*37748cd8SNickeau}
159