/** * @return Expression */ public function parseVariableOrMethodCallExpression() { list($token, $name) = $this->tokenStream->current(); if ($token !== Tokens::T_LITERAL) { throw ParseException::createInvalidTokenException([Tokens::T_LITERAL], $this->tokenStream); } $this->tokenStream->next(); list($token, ) = $this->tokenStream->current(); // check for method call if ($token === Tokens::T_OPEN_PAREN) { // eat open paren $this->tokenStream->next(); $arguments = []; do { list($token, ) = $this->tokenStream->current(); if ($token !== Tokens::T_CLOSE_PAREN) { $arguments[] = $this->parseExpression(); list($token, ) = $this->tokenStream->current(); if ($token !== Tokens::T_COMMA && $token !== Tokens::T_CLOSE_PAREN) { throw ParseException::createInvalidTokenException([Tokens::T_COMMA, Tokens::T_CLOSE_PAREN], $this->tokenStream); } } // eat T_COMMA or T_CLOSE_PAREN $this->tokenStream->next(); } while ($token !== Tokens::T_CLOSE_PAREN); $expression = new Expressions\MethodCall($name, $arguments); list($token, ) = $this->tokenStream->current(); } else { // strip preceding '$' string, if present if (strpos($name, '$') === 0) { $name = substr($name, 1); } $expression = new Expressions\Variable($name); while ($token === Tokens::T_ATTR_SEP) { $this->tokenStream->next(); list($token, $attributeName) = $this->tokenStream->current(); if ($token !== Tokens::T_LITERAL) { throw ParseException::createInvalidTokenException([Tokens::T_LITERAL], $this->tokenStream); } $this->tokenStream->next(); $expression = new Expressions\GetAttribute($expression, $attributeName); list($token, ) = $this->tokenStream->current(); } } if ($token === Tokens::T_PIPE) { // eat pipe token $this->tokenStream->next(); list($token, $filterName) = $this->tokenStream->current(); if ($token !== Tokens::T_LITERAL) { throw ParseException::createInvalidTokenException([Tokens::T_LITERAL], $this->tokenStream); } $this->tokenStream->next(); $expression = new Expressions\MethodCall($filterName, [$expression]); } return $expression; }
private function parseIfBlock() { list($token, ) = $this->tokenStream->current(); if ($token !== Tokens::T_BLOCK_IF && $token !== Tokens::T_BLOCK_UNLESS) { throw ParseException::createInvalidTokenException([Tokens::T_BLOCK_IF, Tokens::T_BLOCK_UNLESS], $this->tokenStream); } $invertedCondition = $token === Tokens::T_BLOCK_UNLESS; $this->tokenStream->next(); $condition = $this->expressionParser->parseExpression(); if ($invertedCondition) { $condition = new Expressions\Unary($condition, Expressions\Unary::OPERATION_NOT); } $this->visitor->ifBlock($condition); // keep parsing statements until we see a block end list($token, ) = $this->tokenStream->current(); while ($token !== Tokens::T_BLOCK_END) { // check if we have an "else" or "else if" block if ($token === Tokens::T_BLOCK_ELSE) { $this->visitor->elseBlock(); $this->tokenStream->next(); } else { if ($token === Tokens::T_BLOCK_ELSE_IF) { $this->tokenStream->next(); $condition = $this->expressionParser->parseExpression(); $this->visitor->elseIfBlock($condition); } } $this->parseStatement(); list($token, ) = $this->tokenStream->current(); } // consume T_BLOCK_END $this->tokenStream->next(); // skip optional trailing literal if ($this->tokenStream->current()[0] === Tokens::T_LITERAL) { $this->tokenStream->next(); } $this->visitor->endIfBlock(); }