/** * {@inheritdoc} */ public function getLastEntry() : EntryInterface { if (0 === $this->stack->count()) { throw new \RuntimeException('Trace empty'); } return $this->stack->top(); }
public function parse($data) { $tokens = $this->tokenizer($data); $this->stack = new \SplStack(); $this->stack->push(0); while (true) { $token = $tokens[0]; $state = $this->stack->top(); $terminal = $token[0]; if (!isset($this->action[$state][$terminal])) { throw new \Exception('Token not allowed here (' . $token[1] . ')'); } $action = $this->action[$state][$terminal]; if ($action[0] === 0) { $this->stack->push($token[1]); $this->stack->push($action[1]); array_shift($tokens); } elseif ($action[0] === 1) { $value = $this->reduce($action[2], $action[1]); array_unshift($tokens, array($action[3], $value)); } elseif ($action[0] === 2) { $this->stack->pop(); return $this->stack->pop(); } else { throw new \RuntimeException('Cannot compile'); } } throw new \RuntimeException('Cannot compile. EOF'); }
/** * {@inheritdoc} */ protected function onElementData($parser, $data) { if (!empty($data)) { switch ($this->stack->top()) { case 'DATE': $this->date = \DateTime::createFromFormat('d.m.Y', $data); break; case 'TYPE': $data = trim($data); if ($data === 'FOREIGN EXCHANGE') { $this->rateType = 'foreign_exchange'; } elseif ($data === 'FOREIGN CASH') { $this->rateType = 'foreign_cash'; } break; case 'CURRENCY': $this->currentRate['currencyCode'] = trim($data); break; case 'UNIT': $this->currentRate['unit'] = (int) trim($data); break; case 'BUYING_RATE': $this->currentRate['buyingRate'] = (double) trim($data); break; case 'SELLING_RATE': $this->currentRate['sellingRate'] = (double) trim($data); break; case 'MIDDLE_RATE': $this->currentRate['middleRate'] = (double) trim($data); break; } } }
public function startOrGroup() { $predicate = new OrPredicate(new NullPredicate()); $this->predicateStack->top()->pushPredicate($predicate); $this->predicateStack->push($predicate); return $this; }
/** * {@inheritdoc} */ public function enterNode(Node $node) { $isCurrentNodeFunctionLike = $node instanceof Node\FunctionLike; if ($isCurrentNodeFunctionLike || $this->argumentModificationStack->isEmpty() || !$this->argumentModificationStack->top() || !$this->functionAnalyzer->isFunctionCallByStaticName($node, array_flip(array('func_get_arg', 'func_get_args')))) { $isCurrentNodeFunctionLike && $this->argumentModificationStack->push(false); return; } /** @var Node\Expr\FuncCall $node */ $functionName = $node->name->toString(); $this->addContextMessage(sprintf('Function argument(s) returned by "%s" might have been modified', $functionName), $node); }
/** * Conversão de Formato Infixo para Posfixo * @return array Fila de Tokens para Cálculo Posfixo */ public function toPostfix() { /* Analisador Léxico */ $lexer = $this->getLexer(); /* Pilha para Conversão */ $stack = new \SplStack(); /* Notação Polonesa Reversa */ $postfix = array(); /* Execução */ while (($token = $lexer->getToken()) != null) { /* Analisador Sintático */ if ($token->isA('T_NUMBER') || $token->isA('T_FLOAT') || $token->isA('T_VAR') || $token->isA('T_DEF') || $token->isA('T_BLOCKDEF')) { $postfix[] = $token; } elseif ($token->isA('T_OPERATOR') || $token->isA('T_ASSIGN')) { /* @todo Melhorar Pesquisa */ $found = false; while (!$found) { if ($stack->isEmpty()) { $stack->push($token); $found = true; } else { if ($stack->top()->isA('T_OB')) { $stack->push($token); $found = true; } elseif ($this->precedence($token, $stack->top()) > 0) { $stack->push($token); $found = true; } else { $postfix[] = $stack->pop(); } } } } elseif ($token->isA('T_OB')) { $stack->push($token); } elseif ($token->isA('T_CB')) { while (!$stack->isEmpty() && !$stack->top()->isA('T_OB')) { $postfix[] = $stack->pop(); } $stack->pop(); } else { $format = "Invalid Token '%s' @column %d"; $message = sprintf($format, $token->getType(), $token->getPosition()); throw new Exception($message); } } /* Tokens Restantes na Pilha */ while (!$stack->isEmpty()) { $postfix[] = $stack->pop(); } return $postfix; }
/** * To get the class name of the caller according to scope visibility. * * @return string */ private function getCallerStatedClassName() : string { if (true !== $this->callerStatedClassesStack->isEmpty()) { return $this->callerStatedClassesStack->top(); } return ''; }
/** * Get the current suite * * @static * @return \DrSlump\Spec\TestSuite */ public static function suite() { if (self::$suites->isEmpty()) { return null; } return self::$suites->top(); }
/** * A hook to the $system special variable. Returns the * compiled PHP code for the call. * * @internal * @param array $namespace The namespace to parse * @return string */ public function processSystemVar($opt) { if ($this->_stack->count() == 0) { throw new Opt_SysVariableInvalidUse_Exception('$' . implode('.', $opt), 'components'); } return $this->_stack->top() . '->get(\'' . $opt[2] . '\')'; }
/** * 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); }
/** * Convenient access to the last handler return value. * * If the collection is empty, returns null. Otherwise, returns value * returned by last handler. * * @return mixed The last handler return value */ public function last() { if (count($this) === 0) { return null; } return parent::top(); }
/** * When we reach a closing element do something. * * This is mostly used to add stuff to the end of a statement, like putting new lines where div tags close * * @see xml_set_element_handler() * * @param resource $parser * @param string $name */ public function endElement($parser, $name) { switch ($name) { case 'P': $this->appendBlockText("\n\n"); break; case 'UL': $this->appendBlockText("\n\n"); break; case 'LI': $this->appendBlockText("\n"); break; case 'DIV': $this->appendBlockText("\n\n\n"); break; case 'A': $attrs = $this->blockAttributesStack->top(); if (isset($attrs['HREF'])) { $this->appendBlockText(" ({$attrs['HREF']})"); } } $blockContent = $this->blockFinished(); if (count($this->transformedTextStack)) { $this->appendBlockText($blockContent); } else { $this->text .= $blockContent; } }
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(); }
/** * Returns the form stack head element. If the stack is empty, * the method returns NULL. * * @internal * @static * @return Opf_Form */ public static function topOfStack() { if (self::$_stack === null) { self::$_stack = new SplStack(); } if (self::$_stack->count() == 0) { return null; } return self::$_stack->top(); }
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); }
/** * Run current callback in the pipeline. * * @param $initial * @param $carry * @return mixed */ private function run($initial, $carry) { /** @var callable $callback */ $callback = $this->pipeline->current(); /** @var array $args */ $args = $this->pipeline->getInfo(); array_unshift($args, $this->DTOs->top()); array_unshift($args, $initial); array_unshift($args, $carry); return $this->maybeCast(call_user_func_array($callback, $args)); }
/** * Determine if there is operator token in operato stack * * @return boolean */ private function hasOperatorInStack() { $hasOperatorInStack = false; if (!$this->operatorStack->isEmpty()) { $top = $this->operatorStack->top(); if (Token::T_OPERATOR == $top->getType()) { $hasOperatorInStack = true; } } return $hasOperatorInStack; }
/** * Determine if there is operator token in operator stack * * @return boolean */ private function hasOperatorInStack() { $hasOperatorInStack = false; if (!$this->operatorStack->isEmpty()) { $top = $this->operatorStack->top(); if ($top instanceof Operator) { $hasOperatorInStack = true; } } return $hasOperatorInStack; }
/** * get the total executed time * * @return float */ public function getTotal() { $ret_total = $this->total; // if there is still stuff on the stack, the first item is the oldest, so use that // to calculate the total time... if (!$this->stack_started->isEmpty()) { $profile_map = $this->stack_started->top(); $ret_total += $this->getTime($profile_map['start'], microtime(true)); } //if return $ret_total; }
/** * Call middleware stack * * @param ServerRequestInterface $req A request object * @param ResponseInterface $res A response object * * @return ResponseInterface */ public function callMiddlewareStack(ServerRequestInterface $req, ResponseInterface $res) { if (is_null($this->stack)) { $this->seedMiddlewareStack(); } /** @var callable $start */ $start = $this->stack->top(); $this->middlewareLock = true; $resp = $start($req, $res); $this->middlewareLock = false; return $resp; }
/** * @param bool $pop * @return Item|null */ public function top($pop = false) { if ($this->items->isEmpty()) { return null; } if ($pop) { return $this->items->pop(); } while ($top = $this->items->top()) { /** @var Item $top */ // WARNING Non-parallel code for the stack may be modified by other code if ($top->getState() instanceof StateStopped) { $this->handle($this->items->pop()); if ($this->items->isEmpty()) { return null; } } else { return $top; } } return null; }
/** * Set an exception in the group. * * @param mixed $index Index. * @param Exception $exception Exception. * @return void */ public function offsetSet($index, $exception) { if (!$exception instanceof \Exception) { return null; } $group = $this->_group->top(); if (null === $index || true === is_int($index)) { $group[] = $exception; } else { $group[$index] = $exception; } return; }
/** * 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(); }
private function match($type, $callbacks = null, $ws = false) { if ($this->isEof()) { return false; } $type = (array) $type; $token = $this->tokens->top(); if (!empty($type) && !in_array($token[0], $type)) { return false; } foreach ($this->backtracks as &$backtrack) { array_push($backtrack, $token); } $this->tokens->pop(); foreach ((array) $callbacks as $callback) { $callback($token); } !$ws ?: $this->match(self::TOKEN_WS); return true; }
public function wordsToNumber($data) { // Replace all number words with an equivalent numeric value $data = strtr($data, array('zero' => '0', 'a' => '1', 'one' => '1', 'two' => '2', 'three' => '3', 'four' => '4', 'five' => '5', 'six' => '6', 'seven' => '7', 'eight' => '8', 'nine' => '9', 'ten' => '10', 'eleven' => '11', 'twelve' => '12', 'thirteen' => '13', 'fourteen' => '14', 'fifteen' => '15', 'sixteen' => '16', 'seventeen' => '17', 'eighteen' => '18', 'nineteen' => '19', 'twenty' => '20', 'thirty' => '30', 'forty' => '40', 'fourty' => '40', 'fifty' => '50', 'sixty' => '60', 'seventy' => '70', 'eighty' => '80', 'ninety' => '90', 'hundred' => '100', 'thousand' => '1000', 'million' => '1000000', 'billion' => '1000000000', 'and' => '')); // Coerce all tokens to numbers $parts = array_map(function ($val) { return floatval($val); }, preg_split('/[\\s-]+/', $data)); $stack = new SplStack(); // Current work stack $sum = 0; // Running total $last = null; foreach ($parts as $part) { if (!$stack->isEmpty()) { // We're part way through a phrase if ($stack->top() > $part) { // Decreasing step, e.g. from hundreds to ones if ($last >= 1000) { // If we drop from more than 1000 then we've finished the phrase $sum += $stack->pop(); // This is the first element of a new phrase $stack->push($part); } else { // Drop down from less than 1000, just addition // e.g. "seventy one" -> "70 1" -> "70 + 1" $stack->push($stack->pop() + $part); } } else { // Increasing step, e.g ones to hundreds $stack->push($stack->pop() * $part); } } else { // This is the first element of a new phrase $stack->push($part); } // Store the last processed part $last = $part; } return $sum + $stack->pop(); }
private function compareToStackTop(Operator $operator) { $top = $this->operatorStack->top(); if ($top === null) { return false; } if ($this->binaryOperators->exists($operator) && $operator === $top) { if ($operator->isAssociativity(Operator::LEFT)) { return true; } if ($operator->isAssociativity(Operator::RIGHT)) { return false; } //e.g. (5 is divisible by 2 is divisible by 3) is not considered valid $symbols = $operator->operators(); if (is_array($symbols)) { $symbols = implode(', ', $symbols); } throw new ParseException("Binary operator '{$symbols}' is not associative", $this->stream->current()->getLine()); } return $top->getPrecedence() >= $operator->getPrecedence(); }
/** * Validates the section record, determines the section parent and * the data format. * * @internal * @param Array &$section The section record. */ private function _validateSection(array &$section) { // Verify the value of the "order" attribute. if ($section['order'] != 'asc' && $section['order'] != 'desc') { throw new Opt_InvalidAttributeType_Exception('order', $node->getXmlName(), '"asc" or "desc"'); } // Determine the parent of the specified section. // if the attribute is not set, the default behaviour is to find the nearest // top-level and active section and link to it. Otherwise we must check if // the chosen section exists and is active. // Note that "parent" is ignored when we set "datasource" if (is_null($section['parent'])) { if (self::$_stack->count() > 0) { $section['parent'] = self::$_stack->top(); } } elseif ($section['parent'] != '') { if (is_null(self::getSection($section['parent']))) { $exception = new Opt_SectionNotFound_Exception('parent', $section['parent']); $sections = array(); self::$_stack->setIteratorMode(SplDoublyLinkedList::IT_MODE_LIFO | SplDoublyLinkedList::IT_MODE_KEEP); foreach (self::$_stack as $up) { $sections[] = $up; } $exception->setData($sections); throw $exception; } } else { // For the situation, if we had 'parent=""' in the template. $section['parent'] = null; } $section['nesting'] = self::countSections() + 1; // Now we need to obtain the information about the data format. $section['format'] = $this->_compiler->getFormat($section['name']); if (!$section['format']->supports('section')) { throw new Opt_FormatNotSupported_Exception($section['format']->getName(), 'section'); } }
public function getCurrent() { return $this->stack->isEmpty() ? null : $this->stack->top(); }
/** * @return ResourceInterface */ public function top() { return $this->transform(parent::top()); }
/** * Handles a repetition token * * @param Token $token Token * * @return void */ protected function _handleRepetition(Token $token) { //If there is no current item, throw exception if ($this->_currentItem === null) { throw new Exception\InvalidRepetition("Nothing to repeat"); } //Repetitions are allowed only after certain tokens, so check the last //emitted token $lastToken = $this->_tokensStack->top(); switch ($lastToken->getType()) { //Handle lazy repetition case Token::TYPE_REPETITION: $prevLastToken = $this->_tokensStack->offsetGet(1); //if this token is "?" and follows a repetition token that //does not come after another repetition token set the lazy flag if ($token->getIdentifier() === "?" && $prevLastToken->getType() !== Token::TYPE_REPETITION) { //Check if last repetition supports the lazy flag $lastRepetition = $this->_currentItem->getRepetition(); if ($lastRepetition->supportsLazy()) { $lastRepetition->setLazy(true); } return; } else { throw new Exception\InvalidRepetition("Nothing to repeat"); } break; //Tokens that can handle the repetition //Tokens that can handle the repetition case Token::TYPE_NON_PRINTING_CHAR: case Token::TYPE_GENERIC_CHAR_TYPE: case Token::TYPE_CONTROL_CHAR: case Token::TYPE_EXT_UNICODE_SEQUENCE: case Token::TYPE_UNICODE_CHAR_CLASS: case Token::TYPE_HEX_CHAR: case Token::TYPE_DOT: case Token::TYPE_BYTE: case Token::TYPE_SUBPATTERN_END: case Token::TYPE_COMMENT: case Token::TYPE_OCTAL_CHAR: case Token::TYPE_BACK_REFERENCE: case Token::TYPE_CHAR_CLASS_END: case Token::TYPE_RECURSIVE_PATTERN: break; //When simple characters are grouped, repetition is valid only //for the last one, so it needs to be splitted so that the last //character belongs to a different object //When simple characters are grouped, repetition is valid only //for the last one, so it needs to be splitted so that the last //character belongs to a different object case Token::TYPE_CHAR: $chars = $this->_currentItem->getChar(); if (strlen($chars) > 1) { $this->_currentItem->setChar(substr($chars, 0, -1)); $this->_currentItem = new Pattern\Char($chars[strlen($chars) - 1]); $this->_containersStack->top()->addChild($this->_currentItem); } break; default: throw new Exception\InvalidRepetition("Repetition cannot be inserted at this point"); break; } //Get the right repetition class switch ($token->getIdentifier()) { case "*": $repetition = new Pattern\Repetition\ZeroOrMore(); break; case "+": $repetition = new Pattern\Repetition\OneOrMore(); break; case "?": $repetition = new Pattern\Repetition\Optional(); break; case "{": //Check if {} if (strpos($token->getSubject(), ",") === false) { $repetition = new Pattern\Repetition\Number($token->getSubject()); } else { $limits = explode(",", $token->getSubject()); $repetition = new Pattern\Repetition\Range($limits[0], $limits[1] === "" ? null : $limits[1]); } break; } //Set the repetition on the current item $this->_currentItem->setRepetition($repetition); }