/** * Walks the tree to restore left-associativity of some operators * * @param TreeNode $root AST root node */ private function fixOperatorAssociativity(TreeNode &$root) { switch ($root->getChildrenNumber()) { case 0: // Leaf nodes can't be rotated, and have no childs return; case 2: // We only want to rotate tree contained in the left associative // subset of operators $rootType = $root->getId(); if (!in_array($rootType, self::$leftAssociativeOperators)) { break; } // Do not break operator precedence $pivot = $root->getChild(1); if ($pivot->getId() !== $rootType) { break; } $this->leftRotateTree($root); break; } // Recursively fix tree branches $children = $root->getChildren(); foreach ($children as $index => $_) { $this->fixOperatorAssociativity($children[$index]); } $root->setChildren($children); }
private function assertChildrenCount(TreeNode $node, $count) { if ($node->getChildrenNumber() !== $count) { throw new Exception(sprintf('Node was expected to have only %s children.', $count)); } }