Parse the expression nodes into a tree.
@param Node[] $nodes
Array of operands and operators
@param string $filename
Filename being parsed.
@return Node
@throws ParserException
504204
public function parse($nodes, $filename = NULL) {
    $this->nodes = $nodes;
    $this->filename = $filename;
    $this->position = 0;
    $this->length = count($nodes);
    $this->operators = [$this->sentinel];
    $this->operands = [];
    $this->E();
    if ($this->next()) {
      $next = $this->next();
      throw new ParserException(
        $this->filename,
        $next->getLineNumber(),
        $next->getColumnNumber(),
        "invalid expression");
    }
    return self::arrayLast($this->operands);
  }
1009119
public function parseFile($filename)
    {
        // Run the fileEval the string, if it throws an exception, rethrow it
        try {
            $data = require $filename;
        } catch (Exception $exception) {
            throw new ParseException(
                [
                    'message'   => 'PHP file threw an exception',
                    'exception' => $exception,
                ]
            );
        }

        // Complete parsing
        return (array)$this->parse($data, $filename);
    }
272025
public function parseFile($filename)
    {
        $data = json_decode(file_get_contents($filename), true);

        return (array)$this->parse($data, $filename);
    }
741137
public function parseExpressionNode(Node\Expr $node)
    {
        switch (true) {
            case $mappedNode = $this->parseOperatorNode($node):
                return $mappedNode;

            case $node instanceof Node\Scalar
                    && $mappedNode = $this->parseScalarNode($node):
                return $mappedNode;

            case $node instanceof Node\Expr\Variable:
                return Expression::variable($this->parseNameNode($node->name));

            case $node instanceof Node\Expr\Array_:
                return $this->parseArrayNode($node);

            case $node instanceof Node\Expr\FuncCall:
                return $this->parseFunctionCallNode($node);

            case $node instanceof Node\Expr\New_:
                return Expression::newExpression(
                        $this->parseNameNode($node->class),
                        $this->parseNodes($node->args)
                );

            case $node instanceof Node\Expr\MethodCall:
                return Expression::methodCall(
                        $this->parseNode($node->var),
                        $this->parseNameNode($node->name),
                        $this->parseNodes($node->args)
                );

            case $node instanceof Node\Expr\PropertyFetch:
                return Expression::field(
                        $this->parseNode($node->var),
                        $this->parseNameNode($node->name)
                );

            case $node instanceof Node\Expr\ArrayDimFetch:
                return Expression::index(
                        $this->parseNode($node->var),
                        $node->dim === null ? null : $this->parseNode($node->dim)
                );

            case $node instanceof Node\Expr\ConstFetch:
                return Expression::constant($this->parseAbsoluteName($node->name));

            case $node instanceof Node\Expr\ClassConstFetch:
                return Expression::classConstant(
                        $this->parseNameNode($node->class),
                        $node->name
                );

            case $node instanceof Node\Expr\StaticCall:
                return Expression::staticMethodCall(
                        $this->parseNameNode($node->class),
                        $this->parseNameNode($node->name),
                        $this->parseNodes($node->args)
                );

            case $node instanceof Node\Expr\StaticPropertyFetch:
                return Expression::staticField(
                        $this->parseNameNode($node->class),
                        $this->parseNameNode($node->name)
                );

            case $node instanceof Node\Expr\Ternary:
                return $this->parseTernaryNode($node);

            case $node instanceof Node\Expr\Closure:
                return $this->parseClosureNode($node);

            case $node instanceof Node\Expr\Empty_:
                return Expression::emptyExpression($this->parseNode($node->expr));

            case $node instanceof Node\Expr\Isset_:
                return Expression::issetExpression($this->parseNodes($node->vars));

            default:
                throw new ASTException(
                        'Cannot parse AST with unknown expression node: %s',
                        get_class($node));
        }
    }
1295199
private function parseXml(\DOMNode $node, array $context = [])
    {
        $data = $this->parseXmlAttributes($node, $context);

        $value = $this->parseXmlValue($node, $context);

        if (!\count($data)) {
            return $value;
        }

        if (!\is_array($value)) {
            $data['#'] = $value;

            return $data;
        }

        if (1 === \count($value) && key($value)) {
            $data[key($value)] = current($value);

            return $data;
        }

        foreach ($value as $key => $val) {
            $data[$key] = $val;
        }

        return $data;
    }
374579
public function compile(Node\File $node): array {
        if (is_null($node->class)) {
            throw new UnexpectedValueException('File without class cannot be saved');
        }

        $result = $node->uses;

        if (is_a($node->class, Node\Class_::class)) {
            $result[] = $this->compileClass($node->class);
        } else if (is_a($node->class, Node\Enum::class)) {
            $result[] = $this->compileEnum($node->class);
        }

        if (!is_null($node->namespace)) {
            $result = [new PHPNode\Stmt\Namespace_($node->namespace, $result)];
        }

        return $result;
    }
713047
public function parse($node, $command)
    {
        if ($node->command() === '!') {
            $type = strtok($node->value(), ' ');

            if ($type === 'sub') {
                $value             = str_replace('sub', '', $node->value());
                list($key, $value) = explode('=', $value);

                $key   = trim($key);
                $key   = '/\b'.preg_quote($key, '/').'\b/'; // Convert the "key" to a regular expression ready format
                $value = trim($value);

                synapse()->memory->substitute()->put($key, $value);
            }
        }
    }
1298484
public function enterNode(Node $node)
    {
        // @todo support MethodCall and StaticCall as well.
        if ($node instanceof FuncCall) {
            // if function name is an expression or a variable, give it a pass for now.
            if ($node->name instanceof Expr || $node->name instanceof Variable) {
                return;
            }

            $name = (string) $node->name;

            if ($name === 'array_multisort') {
                return $this->validateArrayMultisort($node);
            }

            try {
                $refl = new \ReflectionFunction($name);
            } catch (\ReflectionException $e) {
                // Well, we gave it a shot!
                return;
            }

            foreach ($refl->getParameters() as $key => $param) {
                if (\array_key_exists($key, $node->args)) {
                    $arg = $node->args[$key];
                    if ($param->isPassedByReference() && !$this->isPassableByReference($arg)) {
                        throw new FatalErrorException(self::EXCEPTION_MESSAGE, 0, E_ERROR, null, $node->getLine());
                    }
                }
            }
        }
    }
618171
public function refactor(Node $node): ?Node
    {
        if (! $this->isName($node, 'parse')) {
            return null;
        }

        if (! $this->isType($node->class, 'Symfony\Component\Yaml\Yaml')) {
            return null;
        }

        if (! $this->isArgumentYamlFile($node)) {
            return null;
        }

        $fileGetContentsFunCallNode = $this->createFunction('file_get_contents', [$node->args[0]]);
        $node->args[0] = new Arg($fileGetContentsFunCallNode);

        return $node;
    }
936352
static public function fromFile(string $filename)
    {
        $yaml = filter_var($filename, FILTER_VALIDATE_URL)
            ? yaml_parse_url($filename)
            : yaml_parse_file($filename);

        YamlException::importFromFile($yaml);
        return $yaml;
    }
1019131
public static function fromFile($filename)
    {
        if (!is_file($filename) || !is_readable($filename)) {
            throw new \LogicException(sprintf('The file "%s" does not exist or is not readable.', $filename));
        }

        $html = file_get_contents($filename);

        return new static($html);
    }
1335705
public function parse($source, $filename = '', $env = null)
    {
        if (!$env) {
            $env = $this->options;
        }

        if (!class_exists('H2o_Parser', false)) {
            require H2O_ROOT.'h2o/parser.php';
        }

        $parser = new H2o_Parser($source, $filename, $this, $env);
        $nodelist = $parser->parse();

        return $nodelist;
    }
626299
private function parseOperatorNode(Node\Expr $node)
    {
        $nodeType = str_replace('Expr_', '', $node->getType());
        switch (true) {

            case isset(self::$assignOperatorsMap[$nodeType]):
                return Expression::assign(
                        $this->parseNode($node->var),
                        self::$assignOperatorsMap[$nodeType],
                        $this->parseNode($node->expr)
                );

            case $node instanceof Node\Expr\Instanceof_:
                return Expression::binaryOperation(
                        $this->parseNode($node->expr),
                        Operators\Binary::IS_INSTANCE_OF,
                        $this->parseNameNode($node->class)
                );

            case isset(self::$binaryOperatorsMap[$nodeType]):
                return Expression::binaryOperation(
                        $this->parseNode($node->left),
                        self::$binaryOperatorsMap[$nodeType],
                        $this->parseNode($node->right)
                );

            case isset(self::$unaryOperatorsMap[$nodeType]):
                return Expression::unaryOperation(
                        self::$unaryOperatorsMap[$nodeType],
                        $this->parseNode(isset($node->expr) ? $node->expr : $node->var)
                );

            case isset(self::$castOperatorMap[$nodeType]):
                return Expression::cast(
                        self::$castOperatorMap[$nodeType],
                        $this->parseNode($node->expr)
                );

            default:
                return null;
        }
    }
946330
public function loadConfigurationByFilename($filename)
    {

        // initialize the DOMDocument with the configuration file to be validated
        $configurationFile = new \DOMDocument();
        $configurationFile->load($filename);

        // substitute xincludes
        $configurationFile->xinclude(LIBXML_SCHEMA_CREATE);

        // create a DOMElement with the base.dir configuration
        $paramElement = $configurationFile->createElement('param', APPSERVER_BP);
        $paramElement->setAttribute('name', DirectoryKeys::BASE);
        $paramElement->setAttribute('type', ParamNode::TYPE_STRING);

        // create an XPath instance
        $xpath = new \DOMXpath($configurationFile);
        $xpath->registerNamespace('a', 'http://www.appserver.io/appserver');

        // for node data in a selected id
        $baseDirParam = $xpath->query(sprintf('/a:appserver/a:params/a:param[@name="%s"]', DirectoryKeys::BASE));
        if ($baseDirParam->length === 0) {
            // load the <params> node
            $paramNodes = $xpath->query('/a:appserver/a:params');

            // load the first item => the node itself
            if ($paramsNode = $paramNodes->item(0)) {
                // append the base.dir DOMElement
                $paramsNode->appendChild($paramElement);
            } else {
                // throw an exception, because we can't find a mandatory node
                throw new \Exception('Can\'t find /appserver/params node');
            }
        }

        // create a new DOMDocument with the merge content => necessary because else, schema validation fails!!
        $doc = new \DOMDocument();
        $doc->loadXML($configurationFile->saveXML());

        // return the XML document
        return $doc;
    }
833289
public function addNode(Node $node)
    {
        if (array_key_exists($node->basename(), $this->children)) {
            throw new FileExistsException(sprintf('%s already exists', $node->basename()));
        }

        $this->children[$node->basename()] = $node;
        $node->setParent($this);
    }
682205
protected function parseValues(\SimpleXMLElement $node)
    {
        $values = [];

        foreach ($node->value as $item) {
            if ($item->count() > 0) {
                $value = $this->parseValues($item);
            } else {
                $value = trim($item);
            }

            if (isset($item['key'])) {
                $values[(string) $item['key']] = $value;
            } else {
                $values[] = $value;
            }
        }

        return $values;
    }
1271682
public function enterNode(PhpParser\Node $node)
    {
        $attrs = $node->getAttributes();

        if ($cs = $node->getComments()) {
            $new_comments = [];

            foreach ($cs as $c) {
                if ($c instanceof PhpParser\Comment\Doc) {
                    $new_comments[] = new PhpParser\Comment\Doc(
                        $c->getText(),
                        $c->getLine() + $this->line_offset,
                        $c->getFilePos() + $this->file_offset
                    );
                } else {
                    $new_comments[] = new PhpParser\Comment(
                        $c->getText(),
                        $c->getLine() + $this->line_offset,
                        $c->getFilePos() + $this->file_offset
                    );
                }
            }

            $node->setAttribute('comments', $new_comments);
        }

        /** @psalm-suppress MixedOperand */
        $node->setAttribute('startFilePos', $attrs['startFilePos'] + $this->file_offset);
        /** @psalm-suppress MixedOperand */
        $node->setAttribute('endFilePos', $attrs['endFilePos'] + $this->file_offset);
        /** @psalm-suppress MixedOperand */
        $node->setAttribute('startLine', $attrs['startLine'] + $this->line_offset);
    }