/** * This method optionally parses an expression node and returns it. When no * expression was found this method will return <b>null</b>. * * @return \PDepend\Source\AST\ASTNode * @throws \PDepend\Source\Parser\ParserException * @since 0.9.6 */ protected function parseOptionalExpression() { $expressions = array(); while (($tokenType = $this->tokenizer->peek()) != Tokenizer::T_EOF) { $expr = null; switch ($tokenType) { case Tokens::T_COMMA: case Tokens::T_AS: case Tokens::T_BREAK: case Tokens::T_CLOSE_TAG: case Tokens::T_COLON: case Tokens::T_CONTINUE: case Tokens::T_CURLY_BRACE_CLOSE: case Tokens::T_DECLARE: case Tokens::T_DO: case Tokens::T_DOUBLE_ARROW: case Tokens::T_ECHO: case Tokens::T_END_HEREDOC: case Tokens::T_ENDFOREACH: case Tokens::T_FOR: case Tokens::T_FOREACH: case Tokens::T_GLOBAL: case Tokens::T_GOTO: case Tokens::T_IF: case Tokens::T_PARENTHESIS_CLOSE: case Tokens::T_RETURN: case Tokens::T_SEMICOLON: case Tokens::T_SQUARED_BRACKET_CLOSE: case Tokens::T_SWITCH: case Tokens::T_THROW: case Tokens::T_TRY: case Tokens::T_UNSET: case Tokens::T_WHILE: break 2; case Tokens::T_SELF: case Tokens::T_STRING: case Tokens::T_PARENT: case Tokens::T_STATIC: case Tokens::T_DOLLAR: case Tokens::T_VARIABLE: case Tokens::T_BACKSLASH: case Tokens::T_NAMESPACE: $expressions[] = $this->parseVariableOrConstantOrPrimaryPrefix(); break; case $this->isArrayStartDelimiter(): $expressions[] = $this->doParseArray(); break; case Tokens::T_NULL: case Tokens::T_TRUE: case Tokens::T_FALSE: case Tokens::T_LNUMBER: case Tokens::T_DNUMBER: case Tokens::T_BACKTICK: case Tokens::T_DOUBLE_QUOTE: case Tokens::T_CONSTANT_ENCAPSED_STRING: $expressions[] = $this->parseLiteralOrString(); break; case Tokens::T_NEW: $expressions[] = $this->parseAllocationExpression(); break; case Tokens::T_EVAL: $expressions[] = $this->parseEvalExpression(); break; case Tokens::T_CLONE: $expressions[] = $this->parseCloneExpression(); break; case Tokens::T_INSTANCEOF: $expressions[] = $this->parseInstanceOfExpression(); break; case Tokens::T_ISSET: $expressions[] = $this->parseIssetExpression(); break; case Tokens::T_LIST: $expressions[] = $this->parseListExpression(); break; case Tokens::T_QUESTION_MARK: $expressions[] = $this->parseConditionalExpression(); break; case Tokens::T_BOOLEAN_AND: $expressions[] = $this->parseBooleanAndExpression(); break; case Tokens::T_BOOLEAN_OR: $expressions[] = $this->parseBooleanOrExpression(); break; case Tokens::T_LOGICAL_AND: $expressions[] = $this->parseLogicalAndExpression(); break; case Tokens::T_LOGICAL_OR: $expressions[] = $this->parseLogicalOrExpression(); break; case Tokens::T_LOGICAL_XOR: $expressions[] = $this->parseLogicalXorExpression(); break; case Tokens::T_FUNCTION: $expressions[] = $this->parseClosureDeclaration(); break; case Tokens::T_PARENTHESIS_OPEN: $expressions[] = $this->parseParenthesisExpressionOrPrimaryPrefix(); break; case Tokens::T_EXIT: $expressions[] = $this->parseExitExpression(); break; case Tokens::T_START_HEREDOC: $expressions[] = $this->parseHeredoc(); break; case Tokens::T_CURLY_BRACE_OPEN: $expressions[] = $this->parseBraceExpression($this->builder->buildAstExpression(), $this->consumeToken(Tokens::T_CURLY_BRACE_OPEN), Tokens::T_CURLY_BRACE_CLOSE); break; case Tokens::T_INCLUDE: $expressions[] = $this->parseIncludeExpression(); break; case Tokens::T_INCLUDE_ONCE: $expressions[] = $this->parseIncludeOnceExpression(); break; case Tokens::T_REQUIRE: $expressions[] = $this->parseRequireExpression(); break; case Tokens::T_REQUIRE_ONCE: $expressions[] = $this->parseRequireOnceExpression(); break; case Tokens::T_DEC: $expressions[] = $this->parseDecrementExpression($expressions); break; case Tokens::T_INC: $expressions[] = $this->parseIncrementExpression($expressions); break; case Tokens::T_SL: $expressions[] = $this->parseShiftLeftExpression(); break; case Tokens::T_SR: $expressions[] = $this->parseShiftRightExpression(); break; case Tokens::T_DIR: case Tokens::T_FILE: case Tokens::T_LINE: case Tokens::T_NS_C: case Tokens::T_FUNC_C: case Tokens::T_CLASS_C: case Tokens::T_METHOD_C: $expressions[] = $this->parseConstant(); break; case Tokens::T_INT_CAST: case Tokens::T_BOOL_CAST: case Tokens::T_ARRAY_CAST: case Tokens::T_UNSET_CAST: case Tokens::T_OBJECT_CAST: case Tokens::T_DOUBLE_CAST: case Tokens::T_STRING_CAST: $expressions[] = $this->parseCastExpression(); break; case Tokens::T_EQUAL: case Tokens::T_OR_EQUAL: case Tokens::T_SL_EQUAL: case Tokens::T_SR_EQUAL: case Tokens::T_AND_EQUAL: case Tokens::T_DIV_EQUAL: case Tokens::T_MOD_EQUAL: case Tokens::T_MUL_EQUAL: case Tokens::T_XOR_EQUAL: case Tokens::T_PLUS_EQUAL: case Tokens::T_MINUS_EQUAL: case Tokens::T_CONCAT_EQUAL: $expressions[] = $this->parseAssignmentExpression(array_pop($expressions)); break; // TODO: Handle comments here // TODO: Handle comments here case Tokens::T_COMMENT: case Tokens::T_DOC_COMMENT: $this->consumeToken($tokenType); break; case Tokens::T_PRINT: // TODO: Implement print expression $token = $this->consumeToken($tokenType); $expr = $this->builder->buildAstPrintExpression(); $expr->configureLinesAndColumns($token->startLine, $token->endLine, $token->startColumn, $token->endColumn); $expressions[] = $expr; break; case Tokens::T_STRING_VARNAME: // TODO: Implement this // TODO: Implement this case Tokens::T_PLUS: // TODO: Make this a arithmetic expression // TODO: Make this a arithmetic expression case Tokens::T_MINUS: case Tokens::T_MUL: case Tokens::T_DIV: case Tokens::T_MOD: case Tokens::T_IS_EQUAL: // TODO: Implement compare expressions // TODO: Implement compare expressions case Tokens::T_IS_NOT_EQUAL: case Tokens::T_IS_IDENTICAL: case Tokens::T_IS_NOT_IDENTICAL: case Tokens::T_IS_GREATER_OR_EQUAL: case Tokens::T_IS_SMALLER_OR_EQUAL: case Tokens::T_ANGLE_BRACKET_OPEN: case Tokens::T_ANGLE_BRACKET_CLOSE: case Tokens::T_EMPTY: case Tokens::T_CONCAT: case Tokens::T_BITWISE_OR: case Tokens::T_BITWISE_AND: case Tokens::T_BITWISE_NOT: case Tokens::T_BITWISE_XOR: $token = $this->consumeToken($tokenType); $expr = $this->builder->buildAstExpression($token->image); $expr->configureLinesAndColumns($token->startLine, $token->endLine, $token->startColumn, $token->endColumn); $expressions[] = $expr; break; case Tokens::T_AT: case Tokens::T_EXCLAMATION_MARK: $token = $this->consumeToken($tokenType); $expr = $this->builder->buildAstUnaryExpression($token->image); $expr->configureLinesAndColumns($token->startLine, $token->endLine, $token->startColumn, $token->endColumn); $expressions[] = $expr; break; case Tokens::T_YIELD: $expressions[] = $this->parseYield(); break; default: $expressions[] = $this->parseOptionalExpressionForVersion(); break; } } $expressions = $this->reduce($expressions); $count = count($expressions); if ($count == 0) { return null; } elseif ($count == 1) { return $expressions[0]; } $expr = $this->builder->buildAstExpression(); foreach ($expressions as $node) { $expr->addChild($node); } $expr->configureLinesAndColumns($expressions[0]->getStartLine(), $expressions[$count - 1]->getEndLine(), $expressions[0]->getStartColumn(), $expressions[$count - 1]->getEndColumn()); return $expr; }