Example #1
0
 /**
  * When the given token is the next token then move
  * to it, otherwise throw a syntax error exception.
  *
  * @param int $token The token code to check.
  * @return AnnotationToken The next token.
  */
 private function next($token)
 {
     /* @var \com\mohiva\common\lang\AnnotationToken $lookahead */
     $lookahead = $this->stream->getLookahead();
     if ($lookahead && $lookahead->getCode() !== $token || !$lookahead) {
         $this->syntaxError(array($token), $lookahead);
     }
     $this->stream->next();
     return $this->stream->current();
 }
Example #2
0
 /**
  * Create an array from the token stream which contains only the tokens and the operators/values.
  *
  * @param TokenStream $stream The stream containing the lexer tokens.
  * @return array The actual list with tokens and operators/values.
  */
 private function buildActualTokens(TokenStream $stream)
 {
     $actual = array();
     while ($stream->valid()) {
         /* @var \com\mohiva\pyramid\Token $current */
         $current = $stream->current();
         $stream->next();
         $actual[] = array($current->getCode() => $current->getValue());
     }
     return $actual;
 }
Example #3
0
 /**
  * Parse the operand.
  *
  * This example shows how you should parse sub expressions. You must only create a
  * new parser with the passed grammar and token stream.
  *
  * @param Grammar $grammar The grammar of the parser.
  * @param TokenStream $stream The token stream to parse.
  * @return Node The node between the parentheses.
  * @throws SyntaxErrorException if an unexpected token was found.
  */
 public function parse(Grammar $grammar, TokenStream $stream)
 {
     $stream->next();
     $parser = new Parser($grammar);
     $node = $parser->parse($stream);
     $stream->expect(array(Lexer::T_CLOSE_PARENTHESIS), function (Token $current = null) {
         if ($current) {
             $message = "Expected `)`; got `{$current->getValue()}`";
         } else {
             $message = "Expected `)` but end of stream reached";
         }
         throw new SyntaxErrorException($message);
     });
     return $node;
 }
Example #4
0
 /**
  * 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;
 }
Example #5
0
 /**
  * Test if a specified token is the next token.
  *
  * @param \com\mohiva\common\parser\TokenStream $stream The token stream to use for this test.
  * @dataProvider tokenStreamProvider
  */
 public function testIsNext(TokenStream $stream)
 {
     // user.name.split(" ").join("-")
     $this->assertTrue($stream->isNext(self::T_POINT));
     $stream->next();
     $this->assertTrue($stream->isNext(self::T_NAME));
     $stream->next();
     $this->assertTrue($stream->isNext(self::T_POINT));
     $stream->next();
     $this->assertTrue($stream->isNext(self::T_NAME));
     $stream->next();
     $this->assertTrue($stream->isNext(self::T_OPEN_PARENTHESIS));
     $stream->next();
     $this->assertTrue($stream->isNext(self::T_VALUE));
     $this->assertTrue($stream->isNext(self::T_CLOSE_PARENTHESIS, 2));
     $this->assertTrue($stream->isNext(self::T_POINT, 3));
     $this->assertTrue($stream->isNext(self::T_NAME, 4));
     $this->assertTrue($stream->isNext(self::T_OPEN_PARENTHESIS, 5));
     $this->assertTrue($stream->isNext(self::T_VALUE, 6));
     $this->assertTrue($stream->isNext(self::T_CLOSE_PARENTHESIS, 7));
     $this->assertFalse($stream->isNext(self::T_NAME, 8));
 }