Example #1
0
 /**
  * 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());
 }