/** * Parse an expression operand. * @return Node * @throws ParserException */ private function exprOperand() { switch ($this->currentType) { case T_STRING_VARNAME: case T_CLASS_C: case T_LNUMBER: case T_DNUMBER: case T_LINE: case T_FILE: case T_DIR: case T_TRAIT_C: case T_METHOD_C: case T_FUNC_C: case T_NS_C: case T_YIELD: return $this->mustMatchToken($this->currentType); case T_CONSTANT_ENCAPSED_STRING: return $this->arrayDeference($this->mustMatchToken(T_CONSTANT_ENCAPSED_STRING)); case T_ARRAY: $node = new ArrayNode(); $this->mustMatch(T_ARRAY, $node); $this->mustMatch('(', $node, 'openParen'); $this->arrayPairList($node, ')'); $this->mustMatch(')', $node, 'closeParen', TRUE); return $this->arrayDeference($node); case '[': $node = new ArrayNode(); $this->mustMatch('[', $node); $this->arrayPairList($node, ']'); $this->mustMatch(']', $node, NULL, TRUE); return $this->arrayDeference($node); case '(': $node = new ParenthesisNode(); $this->mustMatch('(', $node, 'openParen'); if ($this->currentType === T_NEW) { $node->addChild($this->newExpr(), 'expression'); $this->mustMatch(')', $node, 'closeParen', TRUE); $node = $this->objectDereference($this->arrayDeference($node)); } elseif ($this->currentType === T_YIELD) { $node->addChild($this->_yield()); $this->mustMatch(')', $node, 'closeParen', TRUE); } else { $node->addChild($this->expr()); $this->mustMatch(')', $node, 'closeParen', TRUE); } return $node; case T_START_HEREDOC: $node = new HeredocNode(); $this->mustMatch(T_START_HEREDOC, $node); if ($this->tryMatch(T_END_HEREDOC, $node, NULL, TRUE)) { return $node; } else { $this->encapsList($node, T_END_HEREDOC, TRUE); $this->mustMatch(T_END_HEREDOC, $node, NULL, TRUE); return $node; } case '"': $node = new InterpolatedStringNode(); $this->mustMatch('"', $node); $this->encapsList($node, '"'); $this->mustMatch('"', $node); return $node; case T_STRING: case T_NS_SEPARATOR: case T_NAMESPACE: $namespace_path = $this->name(); if ($this->currentType === T_DOUBLE_COLON) { return $this->exprClass($namespace_path); } elseif ($this->currentType === '(') { return $this->functionCall($namespace_path); } else { $constant_name = strtolower($namespace_path->getText()); if ($constant_name === 'true') { $node = new TrueNode(); } elseif ($constant_name === 'false') { $node = new FalseNode(); } elseif ($constant_name === 'null') { $node = new NullNode(); } else { $node = new ConstantNode(); } $node->addChild($namespace_path, 'constantName'); return $node; } case T_STATIC: $static = $this->mustMatchToken(T_STATIC); if ($this->currentType === T_FUNCTION) { return $this->anonymousFunction($static); } else { return $this->exprClass($static); } case '$': case T_VARIABLE: $operand = $this->indirectReference(); if (!$operand instanceof VariableVariableNode && $this->currentType === T_DOUBLE_COLON) { return $this->exprClass($operand); } elseif ($this->currentType === '(') { return $this->functionCall($operand, TRUE); } else { return $this->objectDereference($operand); } case T_ISSET: $node = new IssetNode(); $this->mustMatch(T_ISSET, $node, 'name'); $arguments = new CommaListNode(); $this->mustMatch('(', $node, 'openParen'); $node->addChild($arguments, 'arguments'); do { $arguments->addChild($this->variable()); } while ($this->tryMatch(',', $arguments)); $this->mustMatch(')', $node, 'closeParen', TRUE); return $node; case T_EMPTY: case T_EVAL: if ($this->currentType === T_EMPTY) { $node = new EmptyNode(); } else { $node = new EvalNode(); } $this->mustMatch($this->currentType, $node, 'name'); $arguments = new CommaListNode(); $this->mustMatch('(', $node, 'openParen'); $node->addChild($arguments, 'arguments'); $arguments->addChild($this->expr()); $this->mustMatch(')', $node, 'closeParen', TRUE); return $node; case T_INCLUDE: case T_REQUIRE: case T_INCLUDE_ONCE: case T_REQUIRE_ONCE: if ($this->currentType === T_INCLUDE) { $node = new IncludeNode(); } elseif ($this->currentType === T_INCLUDE_ONCE) { $node = new IncludeOnceNode(); } elseif ($this->currentType === T_REQUIRE) { $node = new RequireNode(); } else { $node = new RequireOnceNode(); } $this->mustMatch($this->currentType, $node); $node->addChild($this->expr(), 'expression'); return $node; case T_NEW: return $this->newExpr(); case T_LIST: return $this->_list(); case T_EXIT: $node = new ExitNode(); $this->mustMatch(T_EXIT, $node, NULL, TRUE); if ($this->currentType !== '(') { return $node; } $this->mustMatch('(', $node, 'openParen'); if ($this->tryMatch(')', $node, 'closeParen', TRUE)) { return $node; } if ($this->currentType === T_YIELD) { $node->addChild($this->_yield(), 'expression'); } else { $node->addChild($this->expr(), 'expression'); } $this->mustMatch(')', $node, 'closeParen', TRUE); return $node; case T_FUNCTION: return $this->anonymousFunction(); case '`': return $this->backtick(); } throw new ParserException($this->filename, $this->iterator->getLineNumber(), $this->iterator->getColumnNumber(), "excepted expression operand but got " . $this->current->getTypeName()); }