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