/** * Test the `setSource` and `getSource` accessors. */ public function testSourceAccessors() { $source = 'a string'; $stream = new TokenStream(); $stream->setSource($source); $this->assertSame($source, $stream->getSource()); }
/** * Throw a syntax error exception. * * @param array $tokens A list with expected tokens. * @param AnnotationToken $lookahead The lookahead token. * @throws SyntaxErrorException if a syntax error occurs. */ private function syntaxError(array $tokens, AnnotationToken $lookahead = null) { $refObject = new ReflectionClass(__NAMESPACE__ . '\\AnnotationLexer'); $tokens = array_map(array($refObject, 'getConstantByValue'), $tokens); $tokens = implode('`,`', $tokens); if (!$lookahead) { $message = "Syntax error in DocBlock for: {$this->context->getLocation()}, "; $message .= "expected tokens: `{$tokens}` but end of string reached"; } else { $snippet = preg_replace('/[\\r\\n\\t]*/', '', substr($this->stream->getSource(), $lookahead->getOffset(), 50)); $message = "Syntax error in DocBlock for: {$this->context->getLocation()}, "; $message .= "expected tokens: `{$tokens}` but found `{$lookahead->getValue()}` "; $message .= "at offset `{$lookahead->getOffset()}` near: `{$snippet}`"; } throw new SyntaxErrorException($message); }
/** * Parse the ternary operator. * * @param Node $node The expression node. * @param int $precedence The precedence level. * @return Node The ternary operator node or the given expression node. * @throws SyntaxErrorException if no ternary else can be found after a ternary if. */ private function parseTernary(Node $node, $precedence) { /* @var Token $token */ while (($token = $this->stream->current()) && $this->operatorTable->isTernary($token)) { $operator = $this->operatorTable->getTernaryOperator($token); if ($operator->getIfCode() != $token->getCode() || $operator->getPrecedence() < $precedence) { break; } $operatorNode = $operator->getNode(); $subPrecedence = $operator->isRightAssociative() ? $operator->getPrecedence() : $operator->getPrecedence() + 1; // Parse the if expression if ($operator->isShorthandAllowed() && $this->stream->getLookaheadCode() == $operator->getElseCode()) { $this->stream->next(); $if = null; } else { $this->stream->next(); $if = $this->parseExpression($subPrecedence); } // Parse the else expression $this->stream->expect([$operator->getElseCode()], function (Token $current = null) { if ($current) { $near = substr($this->stream->getSource(), 0, $current->getOffset()); $message = "Ternary else expected; got `{$current->getValue()}`; near: " . $near; } else { $near = substr($this->stream->getSource(), 0, strlen($this->stream->getSource())); $message = "Ternary else expected but end of stream reached; near: " . $near; } throw new SyntaxErrorException($message); }); $this->stream->next(); $else = $this->parseExpression($subPrecedence); // Create the ternary operator node $node = $operatorNode($node, $if, $else); } return $node; }