/**
  * 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));
     }
 }