/** * Translate array sequence of tokens from infix to * Reverse Polish notation (RPN) which representing mathematical expression. * * @param array $tokens Collection of Token intances * @return array Collection of Token intances * @throws InvalidArgumentException */ public function translate(array $tokens) { $this->operatorStack = new SplStack(); $this->outputQueue = new SplQueue(); for ($i = 0; $i < count($tokens); $i++) { $token = $tokens[$i]; switch ($token->getType()) { case Token::T_OPERAND: $this->outputQueue->enqueue($token); break; case Token::T_OPERATOR: case Token::T_FUNCTION: $o1 = $token; $isUnary = $this->isPreviousTokenOperator($tokens, $i) || $this->isPreviousTokenLeftParenthesis($tokens, $i) || $this->hasPreviousToken($i) === false; if ($isUnary) { if ($o1->getValue() === '-' || $o1->getValue() === '+') { $o1 = new Operator($o1->getValue() . 'u', 3, Operator::O_NONE_ASSOCIATIVE); } else { if (!$o1 instanceof FunctionToken) { throw new \InvalidArgumentException("Syntax error: operator '" . $o1->getValue() . "' cannot be used as a unary operator or with an operator as an operand."); } } } else { while ($this->hasOperatorInStack() && ($o2 = $this->operatorStack->top()) && $o1->hasLowerPriority($o2)) { $this->outputQueue->enqueue($this->operatorStack->pop()); } } $this->operatorStack->push($o1); break; case Token::T_LEFT_BRACKET: $this->operatorStack->push($token); break; case Token::T_RIGHT_BRACKET: if ($this->isPreviousTokenOperator($tokens, $i)) { throw new \InvalidArgumentException('Syntax error: an operator cannot be followed by a right parenthesis.'); } elseif ($this->isPreviousTokenLeftParenthesis($tokens, $i)) { throw new \InvalidArgumentException('Syntax error: empty parenthesis.'); } while (!$this->operatorStack->isEmpty() && Token::T_LEFT_BRACKET != $this->operatorStack->top()->getType()) { $this->outputQueue->enqueue($this->operatorStack->pop()); } if ($this->operatorStack->isEmpty()) { throw new \InvalidArgumentException('Syntax error: mismatched parentheses.'); } $this->operatorStack->pop(); break; default: throw new \InvalidArgumentException(sprintf('Invalid token detected: %s.', $token)); break; } } while ($this->hasOperatorInStack()) { $this->outputQueue->enqueue($this->operatorStack->pop()); } if (!$this->operatorStack->isEmpty()) { throw new InvalidArgumentException('Syntax error: mismatched parentheses or misplaced number.'); } return iterator_to_array($this->outputQueue); }
/** * Evaluate array sequence of tokens in Reverse Polish notation (RPN) * representing mathematical expression. * * @param array $expressionTokens * @return float * @throws \InvalidArgumentException */ private function evaluateRPN(array $expressionTokens) { $stack = new \SplStack(); foreach ($expressionTokens as $token) { $tokenValue = $token->getValue(); if (is_numeric($tokenValue)) { $stack->push((double) $tokenValue); continue; } switch ($tokenValue) { case '+': $stack->push($stack->pop() + $stack->pop()); break; case '-': $n = $stack->pop(); $stack->push($stack->pop() - $n); break; case '*': $stack->push($stack->pop() * $stack->pop()); break; case '/': $n = $stack->pop(); $stack->push($stack->pop() / $n); break; case '%': $n = $stack->pop(); $stack->push($stack->pop() % $n); break; default: throw new \InvalidArgumentException(sprintf('Invalid operator detected: %s', $tokenValue)); break; } } return $stack->top(); }
/** * That nested case will be corrected and fully supported * {% softdeleteable %} * <span> * {% softdeleteable 'Acme\Bundle\CoreBundle\Entity\Foo' %} * {% softdeleteable %} * {% softdeleteable 'Acme\Bundle\CoreBundle\Entity\Bar' %} * {{ object.owner.fullName }} * {% endsoftdeleteable %} * {% endsoftdeleteable %} * {% endsoftdeleteable %} * </span> * {% endsoftdeleteable %} * @param null $class * @return bool */ public function enable($class = null) { if (!$this->entityManager->getFilters()->isEnabled('softdeleteable')) { if ($class !== null) { // Nested tags case. // {% softdeleteable 'FQCN' %} inside {% softdeleteable %} // So, just pop classes stack $this->classStack->pop(); } else { // When we enable globally we need to restore disabled entities $this->entityManager->getFilters()->enable('softdeleteable'); // Populate from stack of disabled entities /** @var SoftDeleteableFilter $filter */ $filter = $this->entityManager->getFilters()->getFilter('softdeleteable'); foreach ($this->classStack as $class) { $filter->disableForEntity($class); } } } else { if ($class !== null) { /** @var SoftDeleteableFilter $filter */ $filter = $this->entityManager->getFilters()->getFilter('softdeleteable'); $filter->enableForEntity($class); $this->classStack->pop(); } } }
public function calculate(array $variables) { $stack = new \SplStack(); foreach ($this->reversePolandNotation as $token) { if ($token->getExpressionType() == ExpressionElementInterface::CONSTANT) { /** @var $token Constant */ $stack->push($token->getValue()); } if ($token->getExpressionType() == ExpressionElementInterface::VARIABLE) { /** @var $token Variable*/ $variableName = $token->getValue(); if (isset($variables[$variableName])) { $stack->push($variables[$variableName]); } else { throw new ExpressionParserException("Undefined variable: " . $variableName); } } if ($token->getExpressionType() == ExpressionElementInterface::OPERATOR) { /** @var $token OperatorInterface */ $arg1 = $stack->pop(); $arg2 = $stack->pop(); $stack->push($token->calculate($arg1, $arg2)); } } return $stack->top(); }
/** * {@inheritdoc} */ public function leaveNode(Node $node) { if ($node instanceof Node\FunctionLike) { $this->loopStacks->pop(); } elseif ($this->isTargetLoopNode($node)) { $this->getCurrentLoopStack()->pop(); } }
public function stopVisiting($object) { $this->visitingSet->detach($object); $poppedObject = $this->visitingStack->pop(); if ($object !== $poppedObject) { throw new RuntimeException('Context visitingStack not working well'); } }
public function endGroup() { if ($this->predicateStack->count() <= 1) { throw new \BadMethodCallException('Invalid operation: Not in a condition group.'); } $this->predicateStack->pop(); return $this; }
function postorder($tree) { $lst = array(); if (!$tree) { return $lst; } $stack = new SplStack(); $stack->push($tree); $stack->rewind(); $prev = null; while ($stack->valid()) { $curr = $stack->current(); // go down the tree. //check if current node is leaf, if so, process it and pop stack, //otherwise, keep going down if (!$prev || @$prev->left->key == @$curr->key || @$prev->right->key == @$curr->key) { //prev == null is the situation for the root node if ($curr->left) { $stack->push($curr->left); $stack->rewind(); } else { if ($curr->right) { $stack->push($curr->right); $stack->rewind(); } else { $stack->pop(); $stack->rewind(); $lst[] = $curr->key; } } //go up the tree from left node //need to check if there is a right child //if yes, push it to stack //otherwise, process parent and pop stack } else { if (@$curr->left->key == @$prev->key) { if (@$curr->right->key) { $stack->push($curr->right); $stack->rewind(); } else { $stack->pop(); $stack->rewind(); $lst[] = $curr->key; } } else { if (@$curr->right->key == @$prev->key) { $stack->pop(); $stack->rewind(); $lst[] = $curr->key; } } } $prev = $curr; } return $lst; }
/** * stop a profiling session * * profiling sessions are saved in a stack (LIFO) so this will pop the newest session * off the top and stop it * * @return array the information about the profiling session */ public function stop() { // canary... if ($this->stack_started->isEmpty()) { return array(); } //if $profile_map = $this->stack_started->pop(); $profile_map['stop'] = microtime(true); $profile_map['time'] = $this->getTime($profile_map['start'], $profile_map['stop']); $profile_map['summary'] = sprintf('%s = %s ms', $profile_map['title'], $profile_map['time']); if ($this->stack_started->isEmpty()) { // the stack is empty, so this was a top level call, so it should be merged into an already // existing key with the same name (because we've maybe stopped children), or a new key if no // children were ever started and stopped. if (isset($this->stopped_map[$profile_map['title']])) { $this->stopped_map[$profile_map['title']] = array_merge($this->stopped_map[$profile_map['title']], $profile_map); } else { $this->stopped_map[$profile_map['title']] = $profile_map; } //if/else // we add to total here because otherwise it will get counted twice $this->total += $profile_map['time']; } else { // this is a child, so if there were 3 nested calls: Foo -> Bar -> che, and we // are stopping che, we should build a map that has a Foo key, with a Bar child, and // that Bar child will have a Che child, that's where this profile map will go // go through and build a path, by the time this is done, we'll know where $profile_map goes $current_map =& $this->stopped_map; // stack iteration is fixes as LIFO now, so we need to go through it backward $stack_key = count($this->stack_started) - 1; while (isset($this->stack_started[$stack_key])) { $map = $this->stack_started[$stack_key--]; if (!isset($current_map[$map['title']])) { $current_map[$map['title']] = array('time' => 0, 'children' => array()); } else { if (!isset($current_map[$map['title']]['children'])) { $current_map[$map['title']]['children'] = array(); } //if } //if/else $current_map =& $current_map[$map['title']]['children']; } //while if (isset($current_map[$profile_map['title']])) { $current_map[$profile_map['title']] = array_merge($current_map[$profile_map['title']], $profile_map); } else { $current_map[$profile_map['title']] = $profile_map; } //if/else } //if/else return $profile_map; }
/** * Walks through the pageIdStack, collects all pageIds * as array and passes them on to clearPageCache. * * @return void */ public function clearCachesOfRegisteredPageIds() { if (!$this->pageIdStack->isEmpty()) { $pageIds = array(); while (!$this->pageIdStack->isEmpty()) { $pageIds[] = (int) $this->pageIdStack->pop(); } $pageIds = array_values(array_unique($pageIds)); $this->clearPageCache($pageIds); } }
/** * @param \PHP\Manipulator\Token $token */ protected function _checkLevel(Token $token) { if ($this->isOpeningCurlyBrace($token)) { $this->_level++; $this->_maxLevel = max(array($this->_level, $this->_maxLevel)); } if ($this->isClosingCurlyBrace($token)) { $this->_level--; if (!$this->_classStack->isEmpty() && $this->_level === $this->_classStack[count($this->_classStack) - 1]) { $this->_classStack->pop(); } } }
/** * Converts the current expression into a single matcher, applying * coordination operators to operands according to their binding rules * * @throws \RuntimeException * @return \Hamcrest_Matcher */ public function build() { // Apply Shunting Yard algorithm to convert the infix expression // into Reverse Polish Notation. Since we have a very limited // set of operators and binding rules, the implementation becomes // really simple $ops = new \SplStack(); $rpn = array(); foreach ($this->parts as $token) { if ($token instanceof Operator) { while (!$ops->isEmpty() && $token->compare($ops->top()) <= 0) { $rpn[] = $ops->pop(); } $ops->push($token); } else { $rpn[] = $token; } } // Append the remaining operators while (!$ops->isEmpty()) { $rpn[] = $ops->pop(); } // Walk the RPN expression to create AnyOf and AllOf matchers $stack = new \splStack(); foreach ($rpn as $token) { if ($token instanceof Operator) { // Our operators always need two operands if ($stack->count() < 2) { throw new \RuntimeException('Unable to build a valid expression. Not enough operands available.'); } $operands = array($stack->pop(), $stack->pop()); // Check what kind of matcher we need to create if ($token->getKeyword() === 'OR') { $matcher = new \Hamcrest_Core_AnyOf($operands); } else { // AND, BUT $matcher = new \Hamcrest_Core_AllOf($operands); } $stack->push($matcher); } else { $stack[] = $token; } } if ($stack->count() !== 1) { throw new \RuntimeException('Unable to build a valid expression. The RPN stack should have just one item.'); } return $stack->pop(); }
/** * Apply modifiers to the modifiers stack * * @param string $modifiers Modifiers to apply * * @return void */ protected function _applyModifiers($modifiers) { $currentModifiers = $this->_modifiersStack->top(); //If $modifiers is an empty string just take current modifiers and //add them to the modifiers stack //Othwerwise if ($modifiers !== "") { //Explode modifiers with the dash, the first group of modifiers //represents the modifiers to add, every following group represents //the modifiers to subtract $groups = explode("-", $modifiers); foreach ($groups as $k => $group) { if (!$group) { continue; } $len = strlen($group); for ($i = 0; $i < $len; $i++) { $contains = strpos($currentModifiers, $group[$i]) !== false; if (!$k && !$contains) { $currentModifiers .= $group[$i]; } elseif ($k && $contains) { $currentModifiers = str_replace($group[$i], "", $currentModifiers); } } } //Remove the last entry in modifiers stack $this->_modifiersStack->pop(); } //Add calculated modifiers to the top of the modifiers stack $this->_modifiersStack->push($currentModifiers); }
/** * Resolves yield calls tree * and gives a return value if outcome of yield is CoroutineReturnValue instance * * @param \Generator $coroutine nested coroutine tree * @return \Generator */ private static function stackedCoroutine(\Generator $coroutine) { $stack = new \SplStack(); while (true) { $value = $coroutine->current(); // nested generator/coroutine if ($value instanceof \Generator) { $stack->push($coroutine); $coroutine = $value; continue; } // coroutine end or value is a value object instance if (!$coroutine->valid() || $value instanceof CoroutineReturnValue) { // if till this point, there are no coroutines in a stack thatn stop here if ($stack->isEmpty()) { return; } $coroutine = $stack->pop(); $value = $value instanceof CoroutineReturnValue ? $value->getValue() : null; $coroutine->send($value); continue; } $coroutine->send((yield $coroutine->key() => $value)); } }
public function group() { $args = func_get_args(); $argc = count($args); $uri = ''; $closure; $options = []; if ($argc >= 3) { $uri = array_shift($args); $closure = array_pop($args); $options = array_shift($args); } elseif ($argc == 2) { $uri = array_shift($args); $closure = array_pop($args); $options = []; } elseif ($argc == 1) { $uri = ''; $closure = array_pop($args); $options = []; } elseif ($argc == 0) { throw new ClearException("Calling Whitout Argument", 1); } $this->groups->push(['uri' => $uri, 'options' => $options]); if (is_callable($closure)) { call_user_func($closure); } $this->groups->pop(); return $this; }
/** * 加载指定目录下的配置并生成[绝对路径=>配置] * (备用) * * @param $filePath * @param string $ext */ private function LoadV2($filePath, $ext = '.php') { $resConfig = []; $split = '.'; if (file_exists($filePath)) { $key = basename($filePath, $ext); $configs = (include $filePath); $keyStack = new \SplStack(); $keyStack->push([$key, $configs]); $whileCount = 0; //防止意外进入死循环,限制最多循环1024层 while (!$keyStack->isEmpty() && $whileCount < 1024) { $whileCount++; $pair = $keyStack->pop(); foreach ($pair[1] as $pairKey => $pairVal) { if (is_array($pairVal)) { $keyStack->push([$pair[0] . $split . $pairKey, $pairVal]); } else { $resConfig[$pair[0] . $split . $pairKey] = $pairVal; } } } } return $resConfig; }
public function restoreWorldSnapshot() { $freezer = new \DrSlump\Object\Freezer(); $freezed = $this->snapshots->pop(); $world = $freezer->thaw($freezed); $this->world = $world; }
public function parse($code) { $ary = new BrainDog_OpArray(); $pst = new SplStack(); foreach (str_split($code) as $op) { $idx = count($ary); switch ($op) { case self::OP_GT: case self::OP_LT: case self::OP_ADD: case self::OP_SUB: case self::OP_DOT: case self::OP_COM: $ary[$idx] = new BrainDog_OpCode($op); break; case self::OP_LBR: $pst->push($idx); $ary[$idx] = new BrainDog_OpCode($op); break; case self::OP_RBR: $pos = $pst->pop(); $ary[$pos]->jmp = $idx; $ary[$idx] = new BrainDog_OpCode($op, $pos - 1); break; } } return $ary; }
/** * To pop the current caller in the stated class name stack. * * @return ProxyInterface */ private function popCallerStatedClassName() : ProxyInterface { if (false === $this->callerStatedClassesStack->isEmpty()) { $this->callerStatedClassesStack->pop(); } return $this; }
/** * Get the transformed text off the stack, and clear down the other stacks. * * @return string */ private function blockFinished() { $transformedText = $this->transformedTextStack->pop(); $this->blockTypeStack->pop(); $this->blockAttributesStack->pop(); return $transformedText; }
public function popClassMetadata() { $metadata = $this->metadataStack->pop(); if (!$metadata instanceof ClassMetadata) { throw new RuntimeException('Context metadataStack not working well'); } }
/** * {@inheritdoc} */ public function leaveNode(Node $node) { if ($this->argumentModificationStack->isEmpty()) { return; } if ($node instanceof Node\FunctionLike) { $this->argumentModificationStack->pop(); return; } foreach ($this->possiblyArgumentModifyingClasses as $class) { if ($node instanceof $class) { $this->argumentModificationStack->pop(); $this->argumentModificationStack->push(true); return; } } }
/** * Finishes the public processing of the component. * * @param Opt_Xml_Node $node The recognized node. */ public function postprocessComponent(Opt_Xml_Node $node) { if (!is_null($attribute = $node->get('_componentTemplate'))) { $this->_compiler->processor('snippet')->postprocessAttribute($node, $attribute); $node->set('_componentTemplate', NULL); } $this->_stack->pop(); }
function stackedCoroutine(Generator $gen) { $stack = new SplStack(); $exception = null; for (;;) { try { if ($exception) { $gen->throw($exception); $exception = null; continue; } $value = $gen->current(); if ($value instanceof Generator) { $stack->push($gen); $gen = $value; continue; } $isReturnValue = $value instanceof CoroutineReturnValue; if (!$gen->valid() || $isReturnValue) { if ($stack->isEmpty()) { return; } $gen = $stack->pop(); $gen->send($isReturnValue ? $value->getValue() : NULL); continue; } if ($value instanceof CoroutinePlainValue) { $value = $value->getValue(); } try { $sendValue = (yield $gen->key() => $value); } catch (Exception $e) { $gen->throw($e); continue; } $gen->send($sendValue); } catch (Exception $e) { if ($stack->isEmpty()) { throw $e; } $gen = $stack->pop(); $exception = $e; } } }
protected function reduce($count, $index) { $args = array(); for ($i = 0; $i < $count; $i++) { $this->stack->pop(); $args[] = $this->stack->pop(); } return call_user_func_array([$this, 'reduce' . $index], array_reverse($args)); }
/** * Accepts an array of ComparatorVersions & logical operators in reverse polish notation & returns a single * instance of a class implementing VersionRangeInterface. * * @param array $resultList * * @return VersionRangeInterface */ private function buildRanges(array $resultList) { $stack = new \SplStack(); foreach ($resultList as $result) { if ($result instanceof VersionRangeInterface) { $stack->push($result); } else { $operator1 = $stack->pop(); $operator2 = $stack->pop(); /** @var Token $result */ if (Token::LOGICAL_AND === $result->getType()) { $stack->push(new LogicalAnd($operator2, $operator1)); } else { $stack->push(new LogicalOr($operator2, $operator1)); } } } return $stack->pop(); }
/** * Ends a section. If a name is provided checks that the name provided is the right one. * * @param string|void Section to close * @return \Foil\Contracts\SectionInterface * @throws InvalidArgumentException If provided name is not the section to be closed. */ private function end($name) { $this->last = $this->names->pop(); if (!is_null($name) && $this->last !== $name) { $n = is_string($name) ? $name : 'a bad'; $msg = 'You tried to close %s section where you should have closed %s.'; throw new InvalidArgumentException(sprintf($msg, $n, $this->last)); } return $this->stack->pop(); }
function infix_to_rpn($tokens) { $out_q = new SplQueue(); $stack = new SplStack(); $index = 0; while (count($tokens) > $index) { $t = $tokens[$index]; switch ($t) { case !in_array($t, self::operators_dictionary): $out_q->enqueue($t); break; case $t == "not": case $t == "and": case $t == "or": $stack->push($t); break; case $t == "(": $stack->push($t); break; case $t == ")": while ($stack->top() != "(") { $out_q->enqueue($stack->pop()); } $stack->pop(); if ($stack->count() > 0 && $stack->top() == "not") { $out_q->enqueue($stack->pop()); } break; default: break; } ++$index; } while ($stack->count() > 0) { $out_q->enqueue($stack->pop()); } $reversed_q = array(); foreach ($out_q as $value) { $reversed_q[] = $value; } return array_reverse($reversed_q); }
/** * Pops the form from a stack. If the stack is empty, the method * throws an exception. * * @internal * @static * @param Opf_Form $form The form to be popped. * @return Opf_Form */ public static function popFromStack(Opf_Form $form) { if (self::$_stack === null) { self::$_stack = new SplStack(); } $element = self::$_stack->pop(); if ($element !== $form) { throw new Opf_Exception('Invalid form ' . $form->getName() . ' on stack ' . $element->getName()); } return $element; }
/** * Commit a transaction. * * @return \Hoa\Exception\Group */ public function commitTransaction() { if (false === $this->hasUncommittedExceptions()) { $this->_group->pop(); return $this; } foreach ($this->_group->pop() as $index => $exception) { $this[$index] = $exception; } return $this; }