pax_global_header00006660000000000000000000000064132324462650014521gustar00rootroot0000000000000052 comment=e57b3a09784f846411aa7ed664eedb73e3399078 PHP-Parser-3.1.4/000077500000000000000000000000001323244626500134075ustar00rootroot00000000000000PHP-Parser-3.1.4/.gitignore000066400000000000000000000000721323244626500153760ustar00rootroot00000000000000vendor/ composer.lock grammar/kmyacc.exe grammar/y.output PHP-Parser-3.1.4/.travis.yml000066400000000000000000000012141323244626500155160ustar00rootroot00000000000000language: php dist: trusty sudo: false cache: directories: - $HOME/.composer/cache php: - 5.5 - 5.6 - 7.0 - nightly - hhvm install: - if [ $TRAVIS_PHP_VERSION = '5.6' ]; then composer require satooshi/php-coveralls '~1.0'; fi - composer install --prefer-dist matrix: allow_failures: - php: nightly fast_finish: true script: - if [ $TRAVIS_PHP_VERSION = '5.6' ]; then vendor/bin/phpunit --coverage-clover build/logs/clover.xml; else vendor/bin/phpunit; fi - if [ $TRAVIS_PHP_VERSION = '7.0' ]; then test_old/run-php-src.sh; fi after_success: if [ $TRAVIS_PHP_VERSION = '5.6' ]; then php vendor/bin/coveralls; fi PHP-Parser-3.1.4/CHANGELOG.md000066400000000000000000000415711323244626500152300ustar00rootroot00000000000000Version 3.1.5-dev ----------------- Nothing yet. Version 3.1.4 (2018-01-25) -------------------------- ### Fixed * Fixed pretty printing of `-(-$x)` and `+(+$x)`. (#459) Version 3.1.3 (2017-12-26) -------------------------- ### Fixed * Improve compatibility with php-scoper, by supporting prefixed namespaces in `NodeAbstract::getType()`. Version 3.1.2 (2017-11-04) -------------------------- ### Fixed * Comments on empty blocks are now preserved on a `Stmt\Nop` node. (#382) ### Added * Added `kind` attribute for `Stmt\Namespace_` node, which is one of `KIND_SEMICOLON` or `KIND_BRACED`. (#417) * Added `setDocComment()` method to namespace builder. (#437) Version 3.1.1 (2017-09-02) -------------------------- ### Fixed * Fixed syntax error on comment after brace-style namespace declaration. (#412) * Added support for TraitUse statements in trait builder. (#413) Version 3.1.0 (2017-07-28) -------------------------- ### Added * [PHP 7.2] Added support for trailing comma in group use statements. * [PHP 7.2] Added support for `object` type. This means `object` types will now be represented as a builtin type (a simple `"object"` string), rather than a class `Name`. ### Fixed * Floating-point numbers are now printed correctly if the LC_NUMERIC locale uses a comma as decimal separator. ### Changed * `Name::$parts` is no longer deprecated. Version 3.0.6 (2017-06-28) -------------------------- ### Fixed * Fixed the spelling of `Class_::VISIBILITY_MODIFIER_MASK`. The previous spelling of `Class_::VISIBILITY_MODIFER_MASK` is preserved for backwards compatibility. * The pretty printing will now preserve comments inside array literals and function calls by printing the array items / function arguments on separate lines. Array literals and functions that do not contain comments are not affected. ### Added * Added `Builder\Param::makeVariadic()`. ### Deprecated * The `Node::setLine()` method has been deprecated. Version 3.0.5 (2017-03-05) -------------------------- ### Fixed * Name resolution of `NullableType`s is now performed earlier, so that a fully resolved signature is available when a function is entered. (#360) * `Error` nodes are now considered empty, while previously they extended until the token where the error occurred. This made some nodes larger than expected. (#359) * Fixed notices being thrown during error recovery in some situations. (#362) Version 3.0.4 (2017-02-10) -------------------------- ### Fixed * Fixed some extensibility issues in pretty printer (`pUseType()` is now public and `pPrec()` calls into `p()`, instead of directly dispatching to the type-specific printing method). * Fixed notice in `bin/php-parse` script. ### Added * Error recovery from missing semicolons is now supported in more cases. * Error recovery from trailing commas in positions where PHP does not support them is now supported. Version 3.0.3 (2017-02-03) -------------------------- ### Fixed * In `"$foo[0]"` the `0` is now parsed as an `LNumber` rather than `String`. (#325) * Ensure integers and floats are always pretty printed preserving semantics, even if the particular value can only be manually constructed. * Throw a `LogicException` when trying to pretty-print an `Error` node. Previously this resulted in an undefined method exception or fatal error. ### Added * [PHP 7.1] Added support for negative interpolated offsets: `"$foo[-1]"` * Added `preserveOriginalNames` option to `NameResolver`. If this option is enabled, an `originalName` attribute, containing the unresolved name, will be added to each resolved name. * Added `php-parse --with-positions` option, which dumps nodes with position information. ### Deprecated * The XML serializer has been deprecated. In particular, the classes `Serializer\XML`, `Unserializer\XML`, as well as the interfaces `Serializer` and `Unserializer` are deprecated. Version 3.0.2 (2016-12-06) -------------------------- ### Fixed * Fixed name resolution of nullable types. (#324) * Fixed pretty-printing of nullable types. Version 3.0.1 (2016-12-01) -------------------------- ### Fixed * Fixed handling of nested `list()`s: If the nested list was unkeyed, it was directly included in the list items. If it was keyed, it was wrapped in `ArrayItem`. Now nested `List_` nodes are always wrapped in `ArrayItem`s. (#321) Version 3.0.0 (2016-11-30) -------------------------- ### Added * Added support for dumping node positions in the NodeDumper through the `dumpPositions` option. * Added error recovery support for `$`, `new`, `Foo::`. Version 3.0.0-beta2 (2016-10-29) -------------------------------- This release primarily improves our support for error recovery. ### Added * Added `Node::setDocComment()` method. * Added `Error::getMessageWithColumnInfo()` method. * Added support for recovery from lexer errors. * Added support for recovering from "special" errors (i.e. non-syntax parse errors). * Added precise location information for lexer errors. * Added `ErrorHandler` interface, and `ErrorHandler\Throwing` and `ErrorHandler\Collecting` as specific implementations. These provide a general mechanism for handling error recovery. * Added optional `ErrorHandler` argument to `Parser::parse()`, `Lexer::startLexing()` and `NameResolver::__construct()`. * The `NameResolver` now adds a `namespacedName` attribute on name nodes that cannot be statically resolved (unqualified unaliased function or constant names in namespaces). ### Fixed * Fixed attribute assignment for `GroupUse` prefix and variables in interpolated strings. ### Changed * The constants on `NameTraverserInterface` have been moved into the `NameTraverser` class. * Due to the error handling changes, the `Parser` interface and `Lexer` API have changed. * The emulative lexer now directly postprocesses tokens, instead of using `~__EMU__~` sequences. This changes the protected API of the lexer. * The `Name::slice()` method now returns `null` for empty slices, previously `new Name([])` was used. `Name::concat()` now also supports concatenation with `null`. ### Removed * Removed `Name::append()` and `Name::prepend()`. These mutable methods have been superseded by the immutable `Name::concat()`. * Removed `Error::getRawLine()` and `Error::setRawLine()`. These methods have been superseded by `Error::getStartLine()` and `Error::setStartLine()`. * Removed support for node cloning in the `NodeTraverser`. * Removed `$separator` argument from `Name::toString()`. * Removed `throw_on_error` parser option and `Parser::getErrors()` method. Use the `ErrorHandler` mechanism instead. Version 3.0.0-beta1 (2016-09-16) -------------------------------- ### Added * [7.1] Function/method and parameter builders now support PHP 7.1 type hints (void, iterable and nullable types). * Nodes and Comments now implement `JsonSerializable`. The node kind is stored in a `nodeType` property. * The `InlineHTML` node now has an `hasLeadingNewline` attribute, that specifies whether the preceding closing tag contained a newline. The pretty printer honors this attribute. * Partial parsing of `$obj->` (with missing property name) is now supported in error recovery mode. * The error recovery mode is now exposed in the `php-parse` script through the `--with-recovery` or `-r` flags. The following changes are also part of PHP-Parser 2.1.1: * The PHP 7 parser will now generate a parse error for `$var =& new Obj` assignments. * Comments on free-standing code blocks will now be retained as comments on the first statement in the code block. Version 3.0.0-alpha1 (2016-07-25) --------------------------------- ### Added * [7.1] Added support for `void` and `iterable` types. These will now be represented as strings (instead of `Name` instances) similar to other builtin types. * [7.1] Added support for class constant visibility. The `ClassConst` node now has a `flags` subnode holding the visibility modifier, as well as `isPublic()`, `isProtected()` and `isPrivate()` methods. The constructor changed to accept the additional subnode. * [7.1] Added support for nullable types. These are represented using a new `NullableType` node with a single `type` subnode. * [7.1] Added support for short array destructuring syntax. This means that `Array` nodes may now appear as the left-hand-side of assignments and foreach value targets. Additionally the array items may now contain `null` values if elements are skipped. * [7.1] Added support for keys in list() destructuring. The `List` subnode `vars` has been renamed to `items` and now contains `ArrayItem`s instead of plain variables. * [7.1] Added support for multi-catch. The `Catch` subnode `type` has been renamed to `types` and is now an array of `Name`s. * `Name::slice()` now supports lengths and negative offsets. This brings it in line with `array_slice()` functionality. ### Changed Due to PHP 7.1 support additions described above, the node structure changed as follows: * `void` and `iterable` types are now stored as strings if the PHP 7 parser is used. * The `ClassConst` constructor changed to accept an additional `flags` subnode. * The `Array` subnode `items` may now contain `null` elements (destructuring). * The `List` subnode `vars` has been renamed to `items` and now contains `ArrayItem`s instead of plain variables. * The `Catch` subnode `type` has been renamed to `types` and is now an array of `Name`s. Additionally the following changes were made: * The `type` subnode on `Class`, `ClassMethod` and `Property` has been renamed to `flags`. The `type` subnode has retained for backwards compatibility and is populated to the same value as `flags`. However, writes to `type` will not update `flags`. * The `TryCatch` subnode `finallyStmts` has been replaced with a `finally` subnode that holds an explicit `Finally` node. This allows for more accurate attribute assignment. * The `Trait` constructor now has the same form as the `Class` and `Interface` constructors: It takes an array of subnodes. Unlike classes/interfaces, traits can only have a `stmts` subnode. * The `NodeDumper` now prints class/method/property/constant modifiers, as well as the include and use type in a textual representation, instead of only showing the number. * All methods on `PrettyPrinter\Standard` are now protected. Previoulsy most of them were public. ### Removed * Removed support for running on PHP 5.4. It is however still possible to parse PHP 5.2-5.4 code while running on a newer version. * The deprecated `Comment::setLine()` and `Comment::setText()` methods have been removed. * The deprecated `Name::set()`, `Name::setFirst()` and `Name::setLast()` methods have been removed. Version 2.1.1 (2016-09-16) -------------------------- ### Changed * The pretty printer will now escape all control characters in the range `\x00-\x1F` inside double quoted strings. If no special escape sequence is available, an octal escape will be used. * The quality of the error recovery has been improved. In particular unterminated expressions should be handled more gracefully. * The PHP 7 parser will now generate a parse error for `$var =& new Obj` assignments. * Comments on free-standing code blocks will no be retained as comments on the first statement in the code block. Version 2.1.0 (2016-04-19) -------------------------- ### Fixed * Properly support `B""` strings (with uppercase `B`) in a number of places. * Fixed reformatting of indented parts in a certain non-standard comment style. ### Added * Added `dumpComments` option to node dumper, to enable dumping of comments associated with nodes. * Added `Stmt\Nop` node, that is used to collect comments located at the end of a block or at the end of a file (without a following node with which they could otherwise be associated). * Added `kind` attribute to `Expr\Exit` to distinguish between `exit` and `die`. * Added `kind` attribute to `Scalar\LNumber` to distinguish between decimal, binary, octal and hexadecimal numbers. * Added `kind` attribtue to `Expr\Array` to distinguish between `array()` and `[]`. * Added `kind` attribute to `Scalar\String` and `Scalar\Encapsed` to distinguish between single-quoted, double-quoted, heredoc and nowdoc string. * Added `docLabel` attribute to `Scalar\String` and `Scalar\Encapsed`, if it is a heredoc or nowdoc string. * Added start file offset information to `Comment` nodes. * Added `setReturnType()` method to function and method builders. * Added `-h` and `--help` options to `php-parse` script. ### Changed * Invalid octal literals now throw a parse error in PHP 7 mode. * The pretty printer takes all the new attributes mentioned in the previous section into account. * The protected `AbstractPrettyPrinter::pComments()` method no longer returns a trailing newline. * The bundled autoloader supports library files being stored in a different directory than `PhpParser` for easier downstream distribution. ### Deprecated * The `Comment::setLine()` and `Comment::setText()` methods have been deprecated. Construct new objects instead. ### Removed * The internal (but public) method `Scalar\LNumber::parse()` has been removed. A non-internal `LNumber::fromString()` method has been added instead. Version 2.0.1 (2016-02-28) -------------------------- ### Fixed * `declare() {}` and `declare();` are not semantically equivalent and will now result in different ASTs. The format case will have an empty `stmts` array, while the latter will set `stmts` to `null`. * Magic constants are now supported as semi-reserved keywords. * A shebang line like `#!/usr/bin/env php` is now allowed at the start of a namespaced file. Previously this generated an exception. * The `prettyPrintFile()` method will not strip a trailing `?>` from the raw data that follows a `__halt_compiler()` statement. * The `prettyPrintFile()` method will not strip an opening `slice()` which takes a subslice of a name. ### Changed * `PhpParser\Parser` is now an interface, implemented by `Parser\Php5`, `Parser\Php7` and `Parser\Multiple`. The `Multiple` parser will try multiple parsers, until one succeeds. * Token constants are now defined on `PhpParser\Parser\Tokens` rather than `PhpParser\Parser`. * The `Name->set()`, `Name->append()`, `Name->prepend()` and `Name->setFirst()` methods are deprecated in favor of `Name::concat()` and `Name->slice()`. * The `NodeTraverser` no longer clones nodes by default. The old behavior can be restored by passing `true` to the constructor. * The constructor for `Scalar` nodes no longer has a default value. E.g. `new LNumber()` should now be written as `new LNumber(0)`. --- **This changelog only includes changes from the 2.0 series. For older changes see the [1.x series changelog](https://github.com/nikic/PHP-Parser/blob/1.x/CHANGELOG.md) and the [0.9 series changelog](https://github.com/nikic/PHP-Parser/blob/0.9/CHANGELOG.md).**PHP-Parser-3.1.4/LICENSE000066400000000000000000000027301323244626500144160ustar00rootroot00000000000000Copyright (c) 2011-2018 by Nikita Popov. Some rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * The names of the contributors may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. PHP-Parser-3.1.4/README.md000066400000000000000000000056221323244626500146730ustar00rootroot00000000000000PHP Parser ========== [![Build Status](https://travis-ci.org/nikic/PHP-Parser.svg?branch=master)](https://travis-ci.org/nikic/PHP-Parser) [![Coverage Status](https://coveralls.io/repos/github/nikic/PHP-Parser/badge.svg?branch=master)](https://coveralls.io/github/nikic/PHP-Parser?branch=master) This is a PHP 5.2 to PHP 7.1 parser written in PHP. Its purpose is to simplify static code analysis and manipulation. [**Documentation for version 3.x**][doc_master] (stable; for running on PHP >= 5.5; for parsing PHP 5.2 to PHP 7.1). [Documentation for version 2.x][doc_2_x] (stable; for running on PHP >= 5.4; for parsing PHP 5.2 to PHP 7.0). [Documentation for version 1.x][doc_1_x] (unsupported; for running on PHP >= 5.3; for parsing PHP 5.2 to PHP 5.6). In a Nutshell ------------- The parser turns PHP source code into an abstract syntax tree. For example, if you pass the following code into the parser: ```php Expr_AssignOp_BitwiseAnd Expr_AssignBitwiseOr => Expr_AssignOp_BitwiseOr Expr_AssignBitwiseXor => Expr_AssignOp_BitwiseXor Expr_AssignConcat => Expr_AssignOp_Concat Expr_AssignDiv => Expr_AssignOp_Div Expr_AssignMinus => Expr_AssignOp_Minus Expr_AssignMod => Expr_AssignOp_Mod Expr_AssignMul => Expr_AssignOp_Mul Expr_AssignPlus => Expr_AssignOp_Plus Expr_AssignShiftLeft => Expr_AssignOp_ShiftLeft Expr_AssignShiftRight => Expr_AssignOp_ShiftRight Expr_BitwiseAnd => Expr_BinaryOp_BitwiseAnd Expr_BitwiseOr => Expr_BinaryOp_BitwiseOr Expr_BitwiseXor => Expr_BinaryOp_BitwiseXor Expr_BooleanAnd => Expr_BinaryOp_BooleanAnd Expr_BooleanOr => Expr_BinaryOp_BooleanOr Expr_Concat => Expr_BinaryOp_Concat Expr_Div => Expr_BinaryOp_Div Expr_Equal => Expr_BinaryOp_Equal Expr_Greater => Expr_BinaryOp_Greater Expr_GreaterOrEqual => Expr_BinaryOp_GreaterOrEqual Expr_Identical => Expr_BinaryOp_Identical Expr_LogicalAnd => Expr_BinaryOp_LogicalAnd Expr_LogicalOr => Expr_BinaryOp_LogicalOr Expr_LogicalXor => Expr_BinaryOp_LogicalXor Expr_Minus => Expr_BinaryOp_Minus Expr_Mod => Expr_BinaryOp_Mod Expr_Mul => Expr_BinaryOp_Mul Expr_NotEqual => Expr_BinaryOp_NotEqual Expr_NotIdentical => Expr_BinaryOp_NotIdentical Expr_Plus => Expr_BinaryOp_Plus Expr_ShiftLeft => Expr_BinaryOp_ShiftLeft Expr_ShiftRight => Expr_BinaryOp_ShiftRight Expr_Smaller => Expr_BinaryOp_Smaller Expr_SmallerOrEqual => Expr_BinaryOp_SmallerOrEqual Scalar_ClassConst => Scalar_MagicConst_Class Scalar_DirConst => Scalar_MagicConst_Dir Scalar_FileConst => Scalar_MagicConst_File Scalar_FuncConst => Scalar_MagicConst_Function Scalar_LineConst => Scalar_MagicConst_Line Scalar_MethodConst => Scalar_MagicConst_Method Scalar_NSConst => Scalar_MagicConst_Namespace Scalar_TraitConst => Scalar_MagicConst_Trait ``` These changes may affect custom pretty printers and code comparing the return value of `Node::getType()` to specific strings. ### Miscellaneous * The classes `Template` and `TemplateLoader` have been removed. You should use some other [code generation][code_gen] project built on top of PHP-Parser instead. * The `PrettyPrinterAbstract::pStmts()` method now emits a leading newline if the statement list is not empty. Custom pretty printers should remove the explicit newline before `pStmts()` calls. Old: ```php public function pStmt_Trait(PHPParser_Node_Stmt_Trait $node) { return 'trait ' . $node->name . "\n" . '{' . "\n" . $this->pStmts($node->stmts) . "\n" . '}'; } ``` New: ```php public function pStmt_Trait(Stmt\Trait_ $node) { return 'trait ' . $node->name . "\n" . '{' . $this->pStmts($node->stmts) . "\n" . '}'; } ``` [code_gen]: https://github.com/nikic/PHP-Parser/wiki/Projects-using-the-PHP-Parser#code-generationPHP-Parser-3.1.4/UPGRADE-2.0.md000066400000000000000000000055201323244626500153170ustar00rootroot00000000000000Upgrading from PHP-Parser 1.x to 2.0 ==================================== ### PHP version requirements PHP-Parser now requires PHP 5.4 or newer to run. It is however still possible to *parse* PHP 5.2 and PHP 5.3 source code, while running on a newer version. ### Creating a parser instance Parser instances should now be created through the `ParserFactory`. Old direct instantiation code will not work, because the parser class was renamed. Old: ```php use PhpParser\Parser, PhpParser\Lexer; $parser = new Parser(new Lexer\Emulative); ``` New: ```php use PhpParser\ParserFactory; $parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7); ``` The first argument to `ParserFactory` determines how different PHP versions are handled. The possible values are: * `ParserFactory::PREFER_PHP7`: Try to parse code as PHP 7. If this fails, try to parse it as PHP 5. * `ParserFactory::PREFER_PHP5`: Try to parse code as PHP 5. If this fails, try to parse it as PHP 7. * `ParserFactory::ONLY_PHP7`: Parse code as PHP 7. * `ParserFactory::ONLY_PHP5`: Parse code as PHP 5. For most practical purposes the difference between `PREFER_PHP7` and `PREFER_PHP5` is mainly whether a scalar type hint like `string` will be stored as `'string'` (PHP 7) or as `new Name('string')` (PHP 5). To use a custom lexer, pass it as the second argument to the `create()` method: ```php use PhpParser\ParserFactory; $lexer = new MyLexer; $parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7, $lexer); ``` ### Rename of the `PhpParser\Parser` class `PhpParser\Parser` is now an interface, which is implemented by `Parser\Php5`, `Parser\Php7` and `Parser\Multiple`. Parser tokens are now defined in `Parser\Tokens`. If you use the `ParserFactory` described above to create your parser instance, these changes should have no further impact on you. ### Removal of legacy aliases All legacy aliases for classes have been removed. This includes the old non-namespaced `PHPParser_` classes, as well as the classes that had to be renamed for PHP 7 support. ### Deprecations The `set()`, `setFirst()`, `append()` and `prepend()` methods of the `Node\Name` class have been deprecated. Instead `Name::concat()` and `Name->slice()` should be used. ### Miscellaneous * The `NodeTraverser` no longer clones nodes by default. If you want to restore the old behavior, pass `true` to the constructor. * The legacy node format has been removed. If you use custom nodes, they are now expected to implement a `getSubNodeNames()` method. * The default value for `Scalar` node constructors was removed. This means that something like `new LNumber()` should be replaced by `new LNumber(0)`. * String parts of encapsed strings are now represented using `Scalar\EncapsStringPart` nodes, while previously raw strings were used. This affects the `parts` child of `Scalar\Encaps` and `Expr\ShellExec`.PHP-Parser-3.1.4/UPGRADE-3.0.md000066400000000000000000000161621323244626500153240ustar00rootroot00000000000000Upgrading from PHP-Parser 2.x to 3.0 ==================================== The backwards-incompatible changes in this release may be summarized as follows: * The specific details of the node representation have changed in some cases, primarily to accomodate new PHP 7.1 features. * There have been significant changes to the error recovery implementation. This may affect you, if you used the error recovery mode or have a custom lexer implementation. * A number of deprecated methods were removed. ### PHP version requirements PHP-Parser now requires PHP 5.5 or newer to run. It is however still possible to *parse* PHP 5.2, 5.3 and 5.4 source code, while running on a newer version. ### Changes to the node structure The following changes are likely to require code changes if the respective nodes are used: * The `List` subnode `vars` has been renamed to `items` and now contains `ArrayItem`s instead of plain variables. * The `Catch` subnode `type` has been renamed to `types` and is now an array of `Name`s. * The `TryCatch` subnode `finallyStmts` has been replaced with a `finally` subnode that holds an explicit `Finally` node. * The `type` subnode on `Class`, `ClassMethod` and `Property` has been renamed to `flags`. The `type` subnode has retained for backwards compatibility and is populated to the same value as `flags`. However, writes to `type` will not update `flags` and use of `type` is discouraged. The following changes are unlikely to require code changes: * The `ClassConst` constructor changed to accept an additional `flags` subnode. * The `Trait` constructor now has the same form as the `Class` and `Interface` constructors: It takes an array of subnodes. Unlike classes/interfaces, traits can only have a `stmts` subnode. * The `Array` subnode `items` may now contain `null` elements (due to destructuring). * `void` and `iterable` types are now stored as strings if the PHP 7 parser is used. Previously these would have been represented as `Name` instances. ### Changes to error recovery mode Previously, error recovery mode was enabled by setting the `throwOnError` option to `false` when creating the parser, while collected errors were retrieved using the `getErrors()` method: ```php $lexer = ...; $parser = (new ParserFactory)->create(ParserFactor::ONLY_PHP7, $lexer, [ 'throwOnError' => true, ]); $stmts = $parser->parse($code); $errors = $parser->getErrors(); if ($errors) { handleErrors($errors); } processAst($stmts); ``` Both the `throwOnError` option and the `getErrors()` method have been removed in PHP-Parser 3.0. Instead an instance of `ErrorHandler\Collecting` should be passed to the `parse()` method: ```php $lexer = ...; $parser = (new ParserFactory)->create(ParserFactor::ONLY_PHP7, $lexer); $errorHandler = new ErrorHandler\Collecting; $stmts = $parser->parse($code, $errorHandler); if ($errorHandler->hasErrors()) { handleErrors($errorHandler->getErrors()); } processAst($stmts); ``` #### Multiple parser fallback in error recovery mode As a result of this change, if a `Multiple` parser is used (e.g. through the `ParserFactory` using `PREFER_PHP7` or `PREFER_PHP5`), it will now return the result of the first *non-throwing* parse. As parsing never throws in error recovery mode, the result from the first parser will always be returned. The PHP 7 parser is a superset of the PHP 5 parser, with the exceptions that `=& new` and `global $$foo->bar` are not supported (other differences are in representation only). The PHP 7 parser will be able to recover from the error in both cases. For this reason, this change will likely pass unnoticed if you do not specifically test for this syntax. It is possible to restore the precise previous behavior with the following code: ```php $lexer = ...; $parser7 = new Parser\Php7($lexer); $parser5 = new Parser\Php5($lexer); $errors7 = new ErrorHandler\Collecting(); $stmts7 = $parser7->parse($code, $errors7); if ($errors7->hasErrors()) { $errors5 = new ErrorHandler\Collecting(); $stmts5 = $parser5->parse($code, $errors5); if (!$errors5->hasErrors()) { // If PHP 7 parse has errors but PHP 5 parse has no errors, use PHP 5 result return [$stmts5, $errors5]; } } // If PHP 7 succeeds or both fail use PHP 7 result return [$stmts7, $errors7]; ``` #### Error handling in the lexer In order to support recovery from lexer errors, the signature of the `startLexing()` method changed to optionally accept an `ErrorHandler`: ```php // OLD public function startLexing($code); // NEW public function startLexing($code, ErrorHandler $errorHandler = null); ``` If you use a custom lexer with overriden `startLexing()` method, it needs to be changed to accept the extra parameter. The value should be passed on to the parent method. #### Error checks in node constructors The constructors of certain nodes used to contain additional checks for semantic errors, such as creating a try block without either catch or finally. These checks have been moved from the node constructors into the parser. This allows recovery from such errors, as well as representing the resulting (invalid) AST. This means that certain error conditions are no longer checked for manually constructed nodes. ### Removed methods, arguments, options The following methods, arguments or options have been removed: * `Comment::setLine()`, `Comment::setText()`: Create new `Comment` instances instead. * `Name::set()`, `Name::setFirst()`, `Name::setLast()`, `Name::append()`, `Name::prepend()`: Use `Name::concat()` in combination with `Name::slice()` instead. * `Error::getRawLine()`, `Error::setRawLine()`. Use `Error::getStartLine()` and `Error::setStartLine()` instead. * `Parser::getErrors()`. Use `ErrorHandler\Collecting` instead. * `$separator` argument of `Name::toString()`. Use `strtr()` instead, if you really need it. * `$cloneNodes` argument of `NodeTraverser::__construct()`. Explicitly clone nodes in the visitor instead. * `throwOnError` parser option. Use `ErrorHandler\Collecting` instead. ### Miscellaneous * The `NameResolver` will now resolve unqualified function and constant names in the global namespace into fully qualified names. For example `foo()` in the global namespace resolves to `\foo()`. For names where no static resolution is possible, a `namespacedName` attribute is added now, containing the namespaced variant of the name. * All methods on `PrettyPrinter\Standard` are now protected. Previoulsy most of them were public. The pretty printer should only be invoked using the `prettyPrint()`, `prettyPrintFile()` and `prettyPrintExpr()` methods. * The node dumper now prints numeric values that act as enums/flags in a string representation. If node dumper results are used in tests, updates may be needed to account for this. * The constants on `NameTraverserInterface` have been moved into the `NameTraverser` class. * The emulative lexer now directly postprocesses tokens, instead of using `~__EMU__~` sequences. This changes the protected API of the emulative lexer. * The `Name::slice()` method now returns `null` for empty slices, previously `new Name([])` was used. `Name::concat()` now also supports concatenation with `null`. PHP-Parser-3.1.4/bin/000077500000000000000000000000001323244626500141575ustar00rootroot00000000000000PHP-Parser-3.1.4/bin/php-parse000077500000000000000000000137221323244626500160110ustar00rootroot00000000000000#!/usr/bin/env php array( 'startLine', 'endLine', 'startFilePos', 'endFilePos', 'comments' ))); $parser = (new PhpParser\ParserFactory)->create( PhpParser\ParserFactory::PREFER_PHP7, $lexer ); $dumper = new PhpParser\NodeDumper([ 'dumpComments' => true, 'dumpPositions' => $attributes['with-positions'], ]); $prettyPrinter = new PhpParser\PrettyPrinter\Standard; $serializer = new PhpParser\Serializer\XML; $traverser = new PhpParser\NodeTraverser(); $traverser->addVisitor(new PhpParser\NodeVisitor\NameResolver); foreach ($files as $file) { if (strpos($file, ' Code $code\n"; } else { if (!file_exists($file)) { die("File $file does not exist.\n"); } $code = file_get_contents($file); echo "====> File $file:\n"; } if ($attributes['with-recovery']) { $errorHandler = new PhpParser\ErrorHandler\Collecting; $stmts = $parser->parse($code, $errorHandler); foreach ($errorHandler->getErrors() as $error) { $message = formatErrorMessage($error, $code, $attributes['with-column-info']); echo $message . "\n"; } if (null === $stmts) { continue; } } else { try { $stmts = $parser->parse($code); } catch (PhpParser\Error $error) { $message = formatErrorMessage($error, $code, $attributes['with-column-info']); die($message . "\n"); } } foreach ($operations as $operation) { if ('dump' === $operation) { echo "==> Node dump:\n"; echo $dumper->dump($stmts, $code), "\n"; } elseif ('pretty-print' === $operation) { echo "==> Pretty print:\n"; echo $prettyPrinter->prettyPrintFile($stmts), "\n"; } elseif ('serialize-xml' === $operation) { echo "==> Serialized XML:\n"; echo $serializer->serialize($stmts), "\n"; } elseif ('var-dump' === $operation) { echo "==> var_dump():\n"; var_dump($stmts); } elseif ('resolve-names' === $operation) { echo "==> Resolved names.\n"; $stmts = $traverser->traverse($stmts); } } } function formatErrorMessage(PhpParser\Error $e, $code, $withColumnInfo) { if ($withColumnInfo && $e->hasColumnInfo()) { return $e->getMessageWithColumnInfo($code); } else { return $e->getMessage(); } } function showHelp($error = '') { if ($error) { echo $error . "\n\n"; } die(<< false, 'with-positions' => false, 'with-recovery' => false, ); array_shift($args); $parseOptions = true; foreach ($args as $arg) { if (!$parseOptions) { $files[] = $arg; continue; } switch ($arg) { case '--dump': case '-d': $operations[] = 'dump'; break; case '--pretty-print': case '-p': $operations[] = 'pretty-print'; break; case '--serialize-xml': $operations[] = 'serialize-xml'; break; case '--var-dump': $operations[] = 'var-dump'; break; case '--resolve-names': case '-N'; $operations[] = 'resolve-names'; break; case '--with-column-info': case '-c'; $attributes['with-column-info'] = true; break; case '--with-positions': case '-P': $attributes['with-positions'] = true; break; case '--with-recovery': case '-r': $attributes['with-recovery'] = true; break; case '--help': case '-h'; showHelp(); break; case '--': $parseOptions = false; break; default: if ($arg[0] === '-') { showHelp("Invalid operation $arg."); } else { $files[] = $arg; } } } return array($operations, $files, $attributes); } PHP-Parser-3.1.4/composer.json000066400000000000000000000011521323244626500161300ustar00rootroot00000000000000{ "name": "nikic/php-parser", "description": "A PHP parser written in PHP", "keywords": ["php", "parser"], "type": "library", "license": "BSD-3-Clause", "authors": [ { "name": "Nikita Popov" } ], "require": { "php": ">=5.5", "ext-tokenizer": "*" }, "require-dev": { "phpunit/phpunit": "~4.0|~5.0" }, "autoload": { "psr-4": { "PhpParser\\": "lib/PhpParser" } }, "bin": ["bin/php-parse"], "extra": { "branch-alias": { "dev-master": "3.0-dev" } } } PHP-Parser-3.1.4/doc/000077500000000000000000000000001323244626500141545ustar00rootroot00000000000000PHP-Parser-3.1.4/doc/0_Introduction.markdown000066400000000000000000000066571323244626500206360ustar00rootroot00000000000000Introduction ============ This project is a PHP 5.2 to PHP 7.1 parser **written in PHP itself**. What is this for? ----------------- A parser is useful for [static analysis][0], manipulation of code and basically any other application dealing with code programmatically. A parser constructs an [Abstract Syntax Tree][1] (AST) of the code and thus allows dealing with it in an abstract and robust way. There are other ways of processing source code. One that PHP supports natively is using the token stream generated by [`token_get_all`][2]. The token stream is much more low level than the AST and thus has different applications: It allows to also analyze the exact formatting of a file. On the other hand the token stream is much harder to deal with for more complex analysis. For example an AST abstracts away the fact that in PHP variables can be written as `$foo`, but also as `$$bar`, `${'foobar'}` or even `${!${''}=barfoo()}`. You don't have to worry about recognizing all the different syntaxes from a stream of tokens. Another question is: Why would I want to have a PHP parser *written in PHP*? Well, PHP might not be a language especially suited for fast parsing, but processing the AST is much easier in PHP than it would be in other, faster languages like C. Furthermore the people most probably wanting to do programmatic PHP code analysis are incidentally PHP developers, not C developers. What can it parse? ------------------ The parser supports parsing PHP 5.2-5.6 and PHP 7. As the parser is based on the tokens returned by `token_get_all` (which is only able to lex the PHP version it runs on), additionally a wrapper for emulating tokens from newer versions is provided. This allows to parse PHP 7.1 source code running on PHP 5.5, for example. This emulation is somewhat hacky and not perfect, but it should work well on any sane code. What output does it produce? ---------------------------- The parser produces an [Abstract Syntax Tree][1] (AST) also known as a node tree. How this looks like can best be seen in an example. The program `create(ParserFactory::PREFER_PHP7); ``` The factory accepts a kind argument, that determines how different PHP versions are treated: Kind | Behavior -----|--------- `ParserFactory::PREFER_PHP7` | Try to parse code as PHP 7. If this fails, try to parse it as PHP 5. `ParserFactory::PREFER_PHP5` | Try to parse code as PHP 5. If this fails, try to parse it as PHP 7. `ParserFactory::ONLY_PHP7` | Parse code as PHP 7. `ParserFactory::ONLY_PHP5` | Parse code as PHP 5. Unless you have strong reason to use something else, `PREFER_PHP7` is a reasonable default. The `create()` method optionally accepts a `Lexer` instance as the second argument. Some use cases that require customized lexers are discussed in the [lexer documentation](component/Lexer.markdown). Subsequently you can pass PHP code (including the opening `create(ParserFactory::PREFER_PHP7); try { $stmts = $parser->parse($code); // $stmts is an array of statement nodes } catch (Error $e) { echo 'Parse Error: ', $e->getMessage(); } ``` A parser instance can be reused to parse multiple files. Node tree --------- If you use the above code with `$code = "subNodeName`. The `Stmt\Echo_` node has only one subnode `exprs`. So in order to access it in the above example you would write `$stmts[0]->exprs`. If you wanted to access the name of the function call, you would write `$stmts[0]->exprs[1]->name`. All nodes also define a `getType()` method that returns the node type. The type is the class name without the `PhpParser\Node\` prefix and `\` replaced with `_`. It also does not contain a trailing `_` for reserved-keyword class names. It is possible to associate custom metadata with a node using the `setAttribute()` method. This data can then be retrieved using `hasAttribute()`, `getAttribute()` and `getAttributes()`. By default the lexer adds the `startLine`, `endLine` and `comments` attributes. `comments` is an array of `PhpParser\Comment[\Doc]` instances. The start line can also be accessed using `getLine()`/`setLine()` (instead of `getAttribute('startLine')`). The last doc comment from the `comments` attribute can be obtained using `getDocComment()`. Pretty printer -------------- The pretty printer component compiles the AST back to PHP code. As the parser does not retain formatting information the formatting is done using a specified scheme. Currently there is only one scheme available, namely `PhpParser\PrettyPrinter\Standard`. ```php use PhpParser\Error; use PhpParser\ParserFactory; use PhpParser\PrettyPrinter; $code = "create(ParserFactory::PREFER_PHP7); $prettyPrinter = new PrettyPrinter\Standard; try { // parse $stmts = $parser->parse($code); // change $stmts[0] // the echo statement ->exprs // sub expressions [0] // the first of them (the string node) ->value // it's value, i.e. 'Hi ' = 'Hello '; // change to 'Hello ' // pretty print $code = $prettyPrinter->prettyPrint($stmts); echo $code; } catch (Error $e) { echo 'Parse Error: ', $e->getMessage(); } ``` The above code will output: parse()`, then changed and then again converted to code using `PhpParser\PrettyPrinter\Standard->prettyPrint()`. The `prettyPrint()` method pretty prints a statements array. It is also possible to pretty print only a single expression using `prettyPrintExpr()`. The `prettyPrintFile()` method can be used to print an entire file. This will include the opening `create(ParserFactory::PREFER_PHP7); $traverser = new NodeTraverser; $prettyPrinter = new PrettyPrinter\Standard; // add your visitor $traverser->addVisitor(new MyNodeVisitor); try { $code = file_get_contents($fileName); // parse $stmts = $parser->parse($code); // traverse $stmts = $traverser->traverse($stmts); // pretty print $code = $prettyPrinter->prettyPrintFile($stmts); echo $code; } catch (PhpParser\Error $e) { echo 'Parse Error: ', $e->getMessage(); } ``` The corresponding node visitor might look like this: ```php use PhpParser\Node; use PhpParser\NodeVisitorAbstract; class MyNodeVisitor extends NodeVisitorAbstract { public function leaveNode(Node $node) { if ($node instanceof Node\Scalar\String_) { $node->value = 'foo'; } } } ``` The above node visitor would change all string literals in the program to `'foo'`. All visitors must implement the `PhpParser\NodeVisitor` interface, which defines the following four methods: ```php public function beforeTraverse(array $nodes); public function enterNode(\PhpParser\Node $node); public function leaveNode(\PhpParser\Node $node); public function afterTraverse(array $nodes); ``` The `beforeTraverse()` method is called once before the traversal begins and is passed the nodes the traverser was called with. This method can be used for resetting values before traversation or preparing the tree for traversal. The `afterTraverse()` method is similar to the `beforeTraverse()` method, with the only difference that it is called once after the traversal. The `enterNode()` and `leaveNode()` methods are called on every node, the former when it is entered, i.e. before its subnodes are traversed, the latter when it is left. All four methods can either return the changed node or not return at all (i.e. `null`) in which case the current node is not changed. The `enterNode()` method can additionally return the value `NodeTraverser::DONT_TRAVERSE_CHILDREN`, which instructs the traverser to skip all children of the current node. The `leaveNode()` method can additionally return the value `NodeTraverser::REMOVE_NODE`, in which case the current node will be removed from the parent array. Furthermore it is possible to return an array of nodes, which will be merged into the parent array at the offset of the current node. I.e. if in `array(A, B, C)` the node `B` should be replaced with `array(X, Y, Z)` the result will be `array(A, X, Y, Z, C)`. Instead of manually implementing the `NodeVisitor` interface you can also extend the `NodeVisitorAbstract` class, which will define empty default implementations for all the above methods. The NameResolver node visitor ----------------------------- One visitor is already bundled with the package: `PhpParser\NodeVisitor\NameResolver`. This visitor helps you work with namespaced code by trying to resolve most names to fully qualified ones. For example, consider the following code: use A as B; new B\C(); In order to know that `B\C` really is `A\C` you would need to track aliases and namespaces yourself. The `NameResolver` takes care of that and resolves names as far as possible. After running it most names will be fully qualified. The only names that will stay unqualified are unqualified function and constant names. These are resolved at runtime and thus the visitor can't know which function they are referring to. In most cases this is a non-issue as the global functions are meant. Also the `NameResolver` adds a `namespacedName` subnode to class, function and constant declarations that contains the namespaced name instead of only the shortname that is available via `name`. Example: Converting namespaced code to pseudo namespaces -------------------------------------------------------- A small example to understand the concept: We want to convert namespaced code to pseudo namespaces so it works on 5.2, i.e. names like `A\\B` should be converted to `A_B`. Note that such conversions are fairly complicated if you take PHP's dynamic features into account, so our conversion will assume that no dynamic features are used. We start off with the following base code: ```php use PhpParser\ParserFactory; use PhpParser\PrettyPrinter; use PhpParser\NodeTraverser; use PhpParser\NodeVisitor\NameResolver; $inDir = '/some/path'; $outDir = '/some/other/path'; $parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7); $traverser = new NodeTraverser; $prettyPrinter = new PrettyPrinter\Standard; $traverser->addVisitor(new NameResolver); // we will need resolved names $traverser->addVisitor(new NamespaceConverter); // our own node visitor // iterate over all .php files in the directory $files = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($inDir)); $files = new \RegexIterator($files, '/\.php$/'); foreach ($files as $file) { try { // read the file that should be converted $code = file_get_contents($file); // parse $stmts = $parser->parse($code); // traverse $stmts = $traverser->traverse($stmts); // pretty print $code = $prettyPrinter->prettyPrintFile($stmts); // write the converted file to the target directory file_put_contents( substr_replace($file->getPathname(), $outDir, 0, strlen($inDir)), $code ); } catch (PhpParser\Error $e) { echo 'Parse Error: ', $e->getMessage(); } } ``` Now lets start with the main code, the `NodeVisitor\NamespaceConverter`. One thing it needs to do is convert `A\\B` style names to `A_B` style ones. ```php use PhpParser\Node; class NamespaceConverter extends \PhpParser\NodeVisitorAbstract { public function leaveNode(Node $node) { if ($node instanceof Node\Name) { return new Node\Name($node->toString('_')); } } } ``` The above code profits from the fact that the `NameResolver` already resolved all names as far as possible, so we don't need to do that. We only need to create a string with the name parts separated by underscores instead of backslashes. This is what `$node->toString('_')` does. (If you want to create a name with backslashes either write `$node->toString()` or `(string) $node`.) Then we create a new name from the string and return it. Returning a new node replaces the old node. Another thing we need to do is change the class/function/const declarations. Currently they contain only the shortname (i.e. the last part of the name), but they need to contain the complete name including the namespace prefix: ```php use PhpParser\Node; use PhpParser\Node\Stmt; class NodeVisitor_NamespaceConverter extends \PhpParser\NodeVisitorAbstract { public function leaveNode(Node $node) { if ($node instanceof Node\Name) { return new Node\Name($node->toString('_')); } elseif ($node instanceof Stmt\Class_ || $node instanceof Stmt\Interface_ || $node instanceof Stmt\Function_) { $node->name = $node->namespacedName->toString('_'); } elseif ($node instanceof Stmt\Const_) { foreach ($node->consts as $const) { $const->name = $const->namespacedName->toString('_'); } } } } ``` There is not much more to it than converting the namespaced name to string with `_` as separator. The last thing we need to do is remove the `namespace` and `use` statements: ```php use PhpParser\Node; use PhpParser\Node\Stmt; class NodeVisitor_NamespaceConverter extends \PhpParser\NodeVisitorAbstract { public function leaveNode(Node $node) { if ($node instanceof Node\Name) { return new Node\Name($node->toString('_')); } elseif ($node instanceof Stmt\Class_ || $node instanceof Stmt\Interface_ || $node instanceof Stmt\Function_) { $node->name = $node->namespacedName->toString('_'); } elseif ($node instanceof Stmt\Const_) { foreach ($node->consts as $const) { $const->name = $const->namespacedName->toString('_'); } } elseif ($node instanceof Stmt\Namespace_) { // returning an array merges is into the parent array return $node->stmts; } elseif ($node instanceof Stmt\Use_) { // returning false removed the node altogether return false; } } } ``` That's all. PHP-Parser-3.1.4/doc/3_Other_node_tree_representations.markdown000066400000000000000000000200151323244626500245520ustar00rootroot00000000000000Other node tree representations =============================== It is possible to convert the AST into several textual representations, which serve different uses. Simple serialization -------------------- It is possible to serialize the node tree using `serialize()` and also unserialize it using `unserialize()`. The output is not human readable and not easily processable from anything but PHP, but it is compact and generates quickly. The main application thus is in caching. Human readable dumping ---------------------- Furthermore it is possible to dump nodes into a human readable format using the `dump` method of `PhpParser\NodeDumper`. This can be used for debugging. ```php $code = <<<'CODE' create(PhpParser\ParserFactory::PREFER_PHP7); $nodeDumper = new PhpParser\NodeDumper; try { $stmts = $parser->parse($code); echo $nodeDumper->dump($stmts), "\n"; } catch (PhpParser\Error $e) { echo 'Parse Error: ', $e->getMessage(); } ``` The above script will have an output looking roughly like this: ``` array( 0: Stmt_Function( byRef: false params: array( 0: Param( name: msg default: null type: null byRef: false ) ) stmts: array( 0: Stmt_Echo( exprs: array( 0: Expr_Variable( name: msg ) 1: Scalar_String( value: ) ) ) ) name: printLine ) 1: Expr_FuncCall( name: Name( parts: array( 0: printLine ) ) args: array( 0: Arg( value: Scalar_String( value: Hello World!!! ) byRef: false ) ) ) ) ``` JSON encoding ------------- Nodes (and comments) implement the `JsonSerializable` interface. As such, it is possible to JSON encode the AST directly using `json_encode()`: ```php $code = <<<'CODE' create(PhpParser\ParserFactory::PREFER_PHP7); $nodeDumper = new PhpParser\NodeDumper; try { $stmts = $parser->parse($code); echo json_encode($stmts, JSON_PRETTY_PRINT), "\n"; } catch (PhpParser\Error $e) { echo 'Parse Error: ', $e->getMessage(); } ``` This will result in the following output (which includes attributes): ```json [ { "nodeType": "Stmt_Function", "byRef": false, "name": "printLine", "params": [ { "nodeType": "Param", "type": null, "byRef": false, "variadic": false, "name": "msg", "default": null, "attributes": { "startLine": 3, "endLine": 3 } } ], "returnType": null, "stmts": [ { "nodeType": "Stmt_Echo", "exprs": [ { "nodeType": "Expr_Variable", "name": "msg", "attributes": { "startLine": 4, "endLine": 4 } }, { "nodeType": "Scalar_String", "value": "\n", "attributes": { "startLine": 4, "endLine": 4, "kind": 2 } } ], "attributes": { "startLine": 4, "endLine": 4 } } ], "attributes": { "startLine": 3, "endLine": 5 } }, { "nodeType": "Expr_FuncCall", "name": { "nodeType": "Name", "parts": [ "printLine" ], "attributes": { "startLine": 7, "endLine": 7 } }, "args": [ { "nodeType": "Arg", "value": { "nodeType": "Scalar_String", "value": "Hello World!!!", "attributes": { "startLine": 7, "endLine": 7, "kind": 1 } }, "byRef": false, "unpack": false, "attributes": { "startLine": 7, "endLine": 7 } } ], "attributes": { "startLine": 7, "endLine": 7 } } ] ``` There is currently no mechanism to convert JSON back into a node tree. Furthermore, not all ASTs can be JSON encoded. In particular, JSON only supports UTF-8 strings. Serialization to XML -------------------- It is also possible to serialize the node tree to XML using `PhpParser\Serializer\XML->serialize()` and to unserialize it using `PhpParser\Unserializer\XML->unserialize()`. This is useful for interfacing with other languages and applications or for doing transformation using XSLT. ```php create(PhpParser\ParserFactory::PREFER_PHP7); $serializer = new PhpParser\Serializer\XML; try { $stmts = $parser->parse($code); echo $serializer->serialize($stmts); } catch (PhpParser\Error $e) { echo 'Parse Error: ', $e->getMessage(); } ``` Produces: ```xml msg msg printLine printLine Hello World!!! ```PHP-Parser-3.1.4/doc/4_Code_generation.markdown000066400000000000000000000052751323244626500212410ustar00rootroot00000000000000Code generation =============== It is also possible to generate code using the parser, by first creating an Abstract Syntax Tree and then using the pretty printer to convert it to PHP code. To simplify code generation, the project comes with builders which allow creating node trees using a fluid interface, instead of instantiating all nodes manually. Builders are available for the following syntactic elements: * namespaces and use statements * classes, interfaces and traits * methods, functions and parameters * properties Here is an example: ```php use PhpParser\BuilderFactory; use PhpParser\PrettyPrinter; use PhpParser\Node; $factory = new BuilderFactory; $node = $factory->namespace('Name\Space') ->addStmt($factory->use('Some\Other\Thingy')->as('SomeOtherClass')) ->addStmt($factory->class('SomeClass') ->extend('SomeOtherClass') ->implement('A\Few', '\Interfaces') ->makeAbstract() // ->makeFinal() ->addStmt($factory->method('someMethod') ->makePublic() ->makeAbstract() // ->makeFinal() ->setReturnType('bool') ->addParam($factory->param('someParam')->setTypeHint('SomeClass')) ->setDocComment('/** * This method does something. * * @param SomeClass And takes a parameter */') ) ->addStmt($factory->method('anotherMethod') ->makeProtected() // ->makePublic() [default], ->makePrivate() ->addParam($factory->param('someParam')->setDefault('test')) // it is possible to add manually created nodes ->addStmt(new Node\Expr\Print_(new Node\Expr\Variable('someParam'))) ) // properties will be correctly reordered above the methods ->addStmt($factory->property('someProperty')->makeProtected()) ->addStmt($factory->property('anotherProperty')->makePrivate()->setDefault(array(1, 2, 3))) ) ->getNode() ; $stmts = array($node); $prettyPrinter = new PrettyPrinter\Standard(); echo $prettyPrinter->prettyPrintFile($stmts); ``` This will produce the following output with the standard pretty printer: ```php array('comments', 'startLine', 'endLine', 'startFilePos', 'endFilePos'), )); $parser = (new PhpParser\ParserFactory)->create(PhpParser\ParserFactory::PREFER_PHP7, $lexer); try { $stmts = $parser->parse($code); // ... } catch (PhpParser\Error $e) { // ... } ``` Before using column information its availability needs to be checked with `$e->hasColumnInfo()`, as the precise location of an error cannot always be determined. The methods for retrieving column information also have to be passed the source code of the parsed file. An example for printing an error: ```php if ($e->hasColumnInfo()) { echo $e->getRawMessage() . ' from ' . $e->getStartLine() . ':' . $e->getStartColumn($code) . ' to ' . $e->getEndLine() . ':' . $e->getEndColumn($code); // or: echo $e->getMessageWithColumnInfo(); } else { echo $e->getMessage(); } ``` Both line numbers and column numbers are 1-based. EOF errors will be located at the position one past the end of the file. Error recovery -------------- The error behavior of the parser (and other components) is controlled by an `ErrorHandler`. Whenever an error is encountered, `ErrorHandler::handleError()` is invoked. The default error handling strategy is `ErrorHandler\Throwing`, which will immediately throw when an error is encountered. To instead collect all encountered errors into an array, while trying to continue parsing the rest of the source code, an instance of `ErrorHandler\Collecting` can be passed to the `Parser::parse()` method. A usage example: ```php $parser = (new PhpParser\ParserFactory)->create(PhpParser\ParserFactory::ONLY_PHP7); $errorHandler = new PhpParser\ErrorHandler\Collecting; $stmts = $parser->parse($code, $errorHandler); if ($errorHandler->hasErrors()) { foreach ($errorHandler->getErrors() as $error) { // $error is an ordinary PhpParser\Error } } if (null !== $stmts) { // $stmts is a best-effort partial AST } ``` The `NameResolver` visitor also accepts an `ErrorHandler` as a constructor argument.PHP-Parser-3.1.4/doc/component/Lexer.markdown000066400000000000000000000155621323244626500210120ustar00rootroot00000000000000Lexer component documentation ============================= The lexer is responsible for providing tokens to the parser. The project comes with two lexers: `PhpParser\Lexer` and `PhpParser\Lexer\Emulative`. The latter is an extension of the former, which adds the ability to emulate tokens of newer PHP versions and thus allows parsing of new code on older versions. This documentation discusses options available for the default lexers and explains how lexers can be extended. Lexer options ------------- The two default lexers accept an `$options` array in the constructor. Currently only the `'usedAttributes'` option is supported, which allows you to specify which attributes will be added to the AST nodes. The attributes can then be accessed using `$node->getAttribute()`, `$node->setAttribute()`, `$node->hasAttribute()` and `$node->getAttributes()` methods. A sample options array: ```php $lexer = new PhpParser\Lexer(array( 'usedAttributes' => array( 'comments', 'startLine', 'endLine' ) )); ``` The attributes used in this example match the default behavior of the lexer. The following attributes are supported: * `comments`: Array of `PhpParser\Comment` or `PhpParser\Comment\Doc` instances, representing all comments that occurred between the previous non-discarded token and the current one. Use of this attribute is required for the `$node->getDocComment()` method to work. The attribute is also needed if you wish the pretty printer to retain comments present in the original code. * `startLine`: Line in which the node starts. This attribute is required for the `$node->getLine()` to work. It is also required if syntax errors should contain line number information. * `endLine`: Line in which the node ends. * `startTokenPos`: Offset into the token array of the first token in the node. * `endTokenPos`: Offset into the token array of the last token in the node. * `startFilePos`: Offset into the code string of the first character that is part of the node. * `endFilePos`: Offset into the code string of the last character that is part of the node. ### Using token positions The token offset information is useful if you wish to examine the exact formatting used for a node. For example the AST does not distinguish whether a property was declared using `public` or using `var`, but you can retrieve this information based on the token position: ```php function isDeclaredUsingVar(array $tokens, PhpParser\Node\Stmt\Property $prop) { $i = $prop->getAttribute('startTokenPos'); return $tokens[$i][0] === T_VAR; } ``` In order to make use of this function, you will have to provide the tokens from the lexer to your node visitor using code similar to the following: ```php class MyNodeVisitor extends PhpParser\NodeVisitorAbstract { private $tokens; public function setTokens(array $tokens) { $this->tokens = $tokens; } public function leaveNode(PhpParser\Node $node) { if ($node instanceof PhpParser\Node\Stmt\Property) { var_dump(isDeclaredUsingVar($this->tokens, $node)); } } } $lexer = new PhpParser\Lexer(array( 'usedAttributes' => array( 'comments', 'startLine', 'endLine', 'startTokenPos', 'endTokenPos' ) )); $parser = (new PhpParser\ParserFactory)->create(PhpParser\ParserFactory::PREFER_PHP7, $lexer); $visitor = new MyNodeVisitor(); $traverser = new PhpParser\NodeTraverser(); $traverser->addVisitor($visitor); try { $stmts = $parser->parse($code); $visitor->setTokens($lexer->getTokens()); $stmts = $traverser->traverse($stmts); } catch (PhpParser\Error $e) { echo 'Parse Error: ', $e->getMessage(); } ``` The same approach can also be used to perform specific modifications in the code, without changing the formatting in other places (which is the case when using the pretty printer). Lexer extension --------------- A lexer has to define the following public interface: void startLexing(string $code, ErrorHandler $errorHandler = null); array getTokens(); string handleHaltCompiler(); int getNextToken(string &$value = null, array &$startAttributes = null, array &$endAttributes = null); The `startLexing()` method is invoked with the source code that is to be lexed (including the opening tag) whenever the `parse()` method of the parser is called. It can be used to reset state or preprocess the source code or tokens. The passes `ErrorHandler` should be used to report lexing errors. The `getTokens()` method returns the current token array, in the usual `token_get_all()` format. This method is not used by the parser (which uses `getNextToken()`), but is useful in combination with the token position attributes. The `handleHaltCompiler()` method is called whenever a `T_HALT_COMPILER` token is encountered. It has to return the remaining string after the construct (not including `();`). The `getNextToken()` method returns the ID of the next token (as defined by the `Parser::T_*` constants). If no more tokens are available it must return `0`, which is the ID of the `EOF` token. Furthermore the string content of the token should be written into the by-reference `$value` parameter (which will then be available as `$n` in the parser). ### Attribute handling The other two by-ref variables `$startAttributes` and `$endAttributes` define which attributes will eventually be assigned to the generated nodes: The parser will take the `$startAttributes` from the first token which is part of the node and the `$endAttributes` from the last token that is part of the node. E.g. if the tokens `T_FUNCTION T_STRING ... '{' ... '}'` constitute a node, then the `$startAttributes` from the `T_FUNCTION` token will be taken and the `$endAttributes` from the `'}'` token. An application of custom attributes is storing the exact original formatting of literals: While the parser does retain some information about the formatting of integers (like decimal vs. hexadecimal) or strings (like used quote type), it does not preserve the exact original formatting (e.g. leading zeros for integers or escape sequences in strings). This can be remedied by storing the original value in an attribute: ```php use PhpParser\Lexer; use PhpParser\Parser\Tokens; class KeepOriginalValueLexer extends Lexer // or Lexer\Emulative { public function getNextToken(&$value = null, &$startAttributes = null, &$endAttributes = null) { $tokenId = parent::getNextToken($value, $startAttributes, $endAttributes); if ($tokenId == Tokens::T_CONSTANT_ENCAPSED_STRING // non-interpolated string || $tokenId == Tokens::T_ENCAPSED_AND_WHITESPACE // interpolated string || $tokenId == Tokens::T_LNUMBER // integer || $tokenId == Tokens::T_DNUMBER // floating point number ) { // could also use $startAttributes, doesn't really matter here $endAttributes['originalValue'] = $value; } return $tokenId; } } ``` PHP-Parser-3.1.4/grammar/000077500000000000000000000000001323244626500150355ustar00rootroot00000000000000PHP-Parser-3.1.4/grammar/README.md000066400000000000000000000024321323244626500163150ustar00rootroot00000000000000What do all those files mean? ============================= * `php5.y`: PHP 5 grammar written in a pseudo language * `php7.y`: PHP 7 grammar written in a pseudo language * `tokens.y`: Tokens definition shared between PHP 5 and PHP 7 grammars * `parser.template`: A `kmyacc` parser prototype file for PHP * `tokens.template`: A `kmyacc` prototype file for the `Tokens` class * `rebuildParsers.php`: Preprocesses the grammar and builds the parser using `kmyacc` .phpy pseudo language ===================== The `.y` file is a normal grammer in `kmyacc` (`yacc`) style, with some transformations applied to it: * Nodes are created using the syntax `Name[..., ...]`. This is transformed into `new Name(..., ..., attributes())` * Some function-like constructs are resolved (see `rebuildParsers.php` for a list) Building the parser =================== In order to rebuild the parser, you need [moriyoshi's fork of kmyacc](https://github.com/moriyoshi/kmyacc-forked). After you compiled/installed it, run the `rebuildParsers.php` script. By default only the `Parser.php` is built. If you want to additionally emit debug symbols and create `y.output`, run the script with `--debug`. If you want to retain the preprocessed grammar pass `--keep-tmp-grammar`. PHP-Parser-3.1.4/grammar/parser.template000066400000000000000000000042321323244626500200670ustar00rootroot00000000000000semValue #semval($,%t) $this->semValue #semval(%n) $this->stackPos-(%l-%n) #semval(%n,%t) $this->stackPos-(%l-%n) namespace PhpParser\Parser; use PhpParser\Error; use PhpParser\Node; use PhpParser\Node\Expr; use PhpParser\Node\Name; use PhpParser\Node\Scalar; use PhpParser\Node\Stmt; #include; /* This is an automatically GENERATED file, which should not be manually edited. * Instead edit one of the following: * * the grammar files grammar/php5.y or grammar/php7.y * * the skeleton file grammar/parser.template * * the preprocessing script grammar/rebuildParsers.php */ class #(-p) extends \PhpParser\ParserAbstract { protected $tokenToSymbolMapSize = #(YYMAXLEX); protected $actionTableSize = #(YYLAST); protected $gotoTableSize = #(YYGLAST); protected $invalidSymbol = #(YYBADCH); protected $errorSymbol = #(YYINTERRTOK); protected $defaultAction = #(YYDEFAULT); protected $unexpectedTokenRule = #(YYUNEXPECTED); protected $YY2TBLSTATE = #(YY2TBLSTATE); protected $YYNLSTATES = #(YYNLSTATES); protected $symbolToName = array( #listvar terminals ); protected $tokenToSymbol = array( #listvar yytranslate ); protected $action = array( #listvar yyaction ); protected $actionCheck = array( #listvar yycheck ); protected $actionBase = array( #listvar yybase ); protected $actionDefault = array( #listvar yydefault ); protected $goto = array( #listvar yygoto ); protected $gotoCheck = array( #listvar yygcheck ); protected $gotoBase = array( #listvar yygbase ); protected $gotoDefault = array( #listvar yygdefault ); protected $ruleToNonTerminal = array( #listvar yylhs ); protected $ruleToLength = array( #listvar yylen ); #if -t protected $productions = array( #production-strings; ); #endif #reduce protected function reduceRule%n() { %b } #noact protected function reduceRule%n() { $this->semValue = $this->semStack[$this->stackPos]; } #endreduce } #tailcode; PHP-Parser-3.1.4/grammar/php5.y000066400000000000000000001420361323244626500161110ustar00rootroot00000000000000%pure_parser %expect 6 %tokens %% start: top_statement_list { $$ = $this->handleNamespaces($1); } ; top_statement_list_ex: top_statement_list_ex top_statement { pushNormalizing($1, $2); } | /* empty */ { init(); } ; top_statement_list: top_statement_list_ex { makeNop($nop, $this->lookaheadStartAttributes); if ($nop !== null) { $1[] = $nop; } $$ = $1; } ; reserved_non_modifiers: T_INCLUDE | T_INCLUDE_ONCE | T_EVAL | T_REQUIRE | T_REQUIRE_ONCE | T_LOGICAL_OR | T_LOGICAL_XOR | T_LOGICAL_AND | T_INSTANCEOF | T_NEW | T_CLONE | T_EXIT | T_IF | T_ELSEIF | T_ELSE | T_ENDIF | T_ECHO | T_DO | T_WHILE | T_ENDWHILE | T_FOR | T_ENDFOR | T_FOREACH | T_ENDFOREACH | T_DECLARE | T_ENDDECLARE | T_AS | T_TRY | T_CATCH | T_FINALLY | T_THROW | T_USE | T_INSTEADOF | T_GLOBAL | T_VAR | T_UNSET | T_ISSET | T_EMPTY | T_CONTINUE | T_GOTO | T_FUNCTION | T_CONST | T_RETURN | T_PRINT | T_YIELD | T_LIST | T_SWITCH | T_ENDSWITCH | T_CASE | T_DEFAULT | T_BREAK | T_ARRAY | T_CALLABLE | T_EXTENDS | T_IMPLEMENTS | T_NAMESPACE | T_TRAIT | T_INTERFACE | T_CLASS | T_CLASS_C | T_TRAIT_C | T_FUNC_C | T_METHOD_C | T_LINE | T_FILE | T_DIR | T_NS_C | T_HALT_COMPILER ; semi_reserved: reserved_non_modifiers | T_STATIC | T_ABSTRACT | T_FINAL | T_PRIVATE | T_PROTECTED | T_PUBLIC ; identifier: T_STRING { $$ = $1; } | semi_reserved { $$ = $1; } ; namespace_name_parts: T_STRING { init($1); } | namespace_name_parts T_NS_SEPARATOR T_STRING { push($1, $3); } ; namespace_name: namespace_name_parts { $$ = Name[$1]; } ; top_statement: statement { $$ = $1; } | function_declaration_statement { $$ = $1; } | class_declaration_statement { $$ = $1; } | T_HALT_COMPILER { $$ = Stmt\HaltCompiler[$this->lexer->handleHaltCompiler()]; } | T_NAMESPACE namespace_name ';' { $$ = Stmt\Namespace_[$2, null]; $$->setAttribute('kind', Stmt\Namespace_::KIND_SEMICOLON); $this->checkNamespace($$); } | T_NAMESPACE namespace_name '{' top_statement_list '}' { $$ = Stmt\Namespace_[$2, $4]; $$->setAttribute('kind', Stmt\Namespace_::KIND_BRACED); $this->checkNamespace($$); } | T_NAMESPACE '{' top_statement_list '}' { $$ = Stmt\Namespace_[null, $3]; $$->setAttribute('kind', Stmt\Namespace_::KIND_BRACED); $this->checkNamespace($$); } | T_USE use_declarations ';' { $$ = Stmt\Use_[$2, Stmt\Use_::TYPE_NORMAL]; } | T_USE use_type use_declarations ';' { $$ = Stmt\Use_[$3, $2]; } | group_use_declaration ';' { $$ = $1; } | T_CONST constant_declaration_list ';' { $$ = Stmt\Const_[$2]; } ; use_type: T_FUNCTION { $$ = Stmt\Use_::TYPE_FUNCTION; } | T_CONST { $$ = Stmt\Use_::TYPE_CONSTANT; } ; /* Using namespace_name_parts here to avoid s/r conflict on T_NS_SEPARATOR */ group_use_declaration: T_USE use_type namespace_name_parts T_NS_SEPARATOR '{' unprefixed_use_declarations '}' { $$ = Stmt\GroupUse[new Name($3, stackAttributes(#3)), $6, $2]; } | T_USE use_type T_NS_SEPARATOR namespace_name_parts T_NS_SEPARATOR '{' unprefixed_use_declarations '}' { $$ = Stmt\GroupUse[new Name($4, stackAttributes(#4)), $7, $2]; } | T_USE namespace_name_parts T_NS_SEPARATOR '{' inline_use_declarations '}' { $$ = Stmt\GroupUse[new Name($2, stackAttributes(#2)), $5, Stmt\Use_::TYPE_UNKNOWN]; } | T_USE T_NS_SEPARATOR namespace_name_parts T_NS_SEPARATOR '{' inline_use_declarations '}' { $$ = Stmt\GroupUse[new Name($3, stackAttributes(#3)), $6, Stmt\Use_::TYPE_UNKNOWN]; } ; unprefixed_use_declarations: unprefixed_use_declarations ',' unprefixed_use_declaration { push($1, $3); } | unprefixed_use_declaration { init($1); } ; use_declarations: use_declarations ',' use_declaration { push($1, $3); } | use_declaration { init($1); } ; inline_use_declarations: inline_use_declarations ',' inline_use_declaration { push($1, $3); } | inline_use_declaration { init($1); } ; unprefixed_use_declaration: namespace_name { $$ = Stmt\UseUse[$1, null, Stmt\Use_::TYPE_UNKNOWN]; $this->checkUseUse($$, #1); } | namespace_name T_AS T_STRING { $$ = Stmt\UseUse[$1, $3, Stmt\Use_::TYPE_UNKNOWN]; $this->checkUseUse($$, #3); } ; use_declaration: unprefixed_use_declaration { $$ = $1; } | T_NS_SEPARATOR unprefixed_use_declaration { $$ = $2; } ; inline_use_declaration: unprefixed_use_declaration { $$ = $1; $$->type = Stmt\Use_::TYPE_NORMAL; } | use_type unprefixed_use_declaration { $$ = $2; $$->type = $1; } ; constant_declaration_list: constant_declaration_list ',' constant_declaration { push($1, $3); } | constant_declaration { init($1); } ; constant_declaration: T_STRING '=' static_scalar { $$ = Node\Const_[$1, $3]; } ; class_const_list: class_const_list ',' class_const { push($1, $3); } | class_const { init($1); } ; class_const: identifier '=' static_scalar { $$ = Node\Const_[$1, $3]; } ; inner_statement_list_ex: inner_statement_list_ex inner_statement { pushNormalizing($1, $2); } | /* empty */ { init(); } ; inner_statement_list: inner_statement_list_ex { makeNop($nop, $this->lookaheadStartAttributes); if ($nop !== null) { $1[] = $nop; } $$ = $1; } ; inner_statement: statement { $$ = $1; } | function_declaration_statement { $$ = $1; } | class_declaration_statement { $$ = $1; } | T_HALT_COMPILER { throw new Error('__HALT_COMPILER() can only be used from the outermost scope', attributes()); } ; non_empty_statement: '{' inner_statement_list '}' { if ($2) { $$ = $2; prependLeadingComments($$); } else { makeNop($$, $this->startAttributeStack[#1]); if (null === $$) { $$ = array(); } } } | T_IF parentheses_expr statement elseif_list else_single { $$ = Stmt\If_[$2, ['stmts' => toArray($3), 'elseifs' => $4, 'else' => $5]]; } | T_IF parentheses_expr ':' inner_statement_list new_elseif_list new_else_single T_ENDIF ';' { $$ = Stmt\If_[$2, ['stmts' => $4, 'elseifs' => $5, 'else' => $6]]; } | T_WHILE parentheses_expr while_statement { $$ = Stmt\While_[$2, $3]; } | T_DO statement T_WHILE parentheses_expr ';' { $$ = Stmt\Do_ [$4, toArray($2)]; } | T_FOR '(' for_expr ';' for_expr ';' for_expr ')' for_statement { $$ = Stmt\For_[['init' => $3, 'cond' => $5, 'loop' => $7, 'stmts' => $9]]; } | T_SWITCH parentheses_expr switch_case_list { $$ = Stmt\Switch_[$2, $3]; } | T_BREAK ';' { $$ = Stmt\Break_[null]; } | T_BREAK expr ';' { $$ = Stmt\Break_[$2]; } | T_CONTINUE ';' { $$ = Stmt\Continue_[null]; } | T_CONTINUE expr ';' { $$ = Stmt\Continue_[$2]; } | T_RETURN ';' { $$ = Stmt\Return_[null]; } | T_RETURN expr ';' { $$ = Stmt\Return_[$2]; } | yield_expr ';' { $$ = $1; } | T_GLOBAL global_var_list ';' { $$ = Stmt\Global_[$2]; } | T_STATIC static_var_list ';' { $$ = Stmt\Static_[$2]; } | T_ECHO expr_list ';' { $$ = Stmt\Echo_[$2]; } | T_INLINE_HTML { $$ = Stmt\InlineHTML[$1]; } | expr ';' { $$ = $1; } | T_UNSET '(' variables_list ')' ';' { $$ = Stmt\Unset_[$3]; } | T_FOREACH '(' expr T_AS foreach_variable ')' foreach_statement { $$ = Stmt\Foreach_[$3, $5[0], ['keyVar' => null, 'byRef' => $5[1], 'stmts' => $7]]; } | T_FOREACH '(' expr T_AS variable T_DOUBLE_ARROW foreach_variable ')' foreach_statement { $$ = Stmt\Foreach_[$3, $7[0], ['keyVar' => $5, 'byRef' => $7[1], 'stmts' => $9]]; } | T_DECLARE '(' declare_list ')' declare_statement { $$ = Stmt\Declare_[$3, $5]; } | T_TRY '{' inner_statement_list '}' catches optional_finally { $$ = Stmt\TryCatch[$3, $5, $6]; $this->checkTryCatch($$); } | T_THROW expr ';' { $$ = Stmt\Throw_[$2]; } | T_GOTO T_STRING ';' { $$ = Stmt\Goto_[$2]; } | T_STRING ':' { $$ = Stmt\Label[$1]; } | expr error { $$ = $1; } | error { $$ = array(); /* means: no statement */ } ; statement: non_empty_statement { $$ = $1; } | ';' { makeNop($$, $this->startAttributeStack[#1]); if ($$ === null) $$ = array(); /* means: no statement */ } ; catches: /* empty */ { init(); } | catches catch { push($1, $2); } ; catch: T_CATCH '(' name T_VARIABLE ')' '{' inner_statement_list '}' { $$ = Stmt\Catch_[array($3), parseVar($4), $7]; } ; optional_finally: /* empty */ { $$ = null; } | T_FINALLY '{' inner_statement_list '}' { $$ = Stmt\Finally_[$3]; } ; variables_list: variable { init($1); } | variables_list ',' variable { push($1, $3); } ; optional_ref: /* empty */ { $$ = false; } | '&' { $$ = true; } ; optional_ellipsis: /* empty */ { $$ = false; } | T_ELLIPSIS { $$ = true; } ; function_declaration_statement: T_FUNCTION optional_ref T_STRING '(' parameter_list ')' optional_return_type '{' inner_statement_list '}' { $$ = Stmt\Function_[$3, ['byRef' => $2, 'params' => $5, 'returnType' => $7, 'stmts' => $9]]; } ; class_declaration_statement: class_entry_type T_STRING extends_from implements_list '{' class_statement_list '}' { $$ = Stmt\Class_[$2, ['type' => $1, 'extends' => $3, 'implements' => $4, 'stmts' => $6]]; $this->checkClass($$, #2); } | T_INTERFACE T_STRING interface_extends_list '{' class_statement_list '}' { $$ = Stmt\Interface_[$2, ['extends' => $3, 'stmts' => $5]]; $this->checkInterface($$, #2); } | T_TRAIT T_STRING '{' class_statement_list '}' { $$ = Stmt\Trait_[$2, ['stmts' => $4]]; } ; class_entry_type: T_CLASS { $$ = 0; } | T_ABSTRACT T_CLASS { $$ = Stmt\Class_::MODIFIER_ABSTRACT; } | T_FINAL T_CLASS { $$ = Stmt\Class_::MODIFIER_FINAL; } ; extends_from: /* empty */ { $$ = null; } | T_EXTENDS class_name { $$ = $2; } ; interface_extends_list: /* empty */ { $$ = array(); } | T_EXTENDS class_name_list { $$ = $2; } ; implements_list: /* empty */ { $$ = array(); } | T_IMPLEMENTS class_name_list { $$ = $2; } ; class_name_list: class_name { init($1); } | class_name_list ',' class_name { push($1, $3); } ; for_statement: statement { $$ = toArray($1); } | ':' inner_statement_list T_ENDFOR ';' { $$ = $2; } ; foreach_statement: statement { $$ = toArray($1); } | ':' inner_statement_list T_ENDFOREACH ';' { $$ = $2; } ; declare_statement: non_empty_statement { $$ = toArray($1); } | ';' { $$ = null; } | ':' inner_statement_list T_ENDDECLARE ';' { $$ = $2; } ; declare_list: declare_list_element { init($1); } | declare_list ',' declare_list_element { push($1, $3); } ; declare_list_element: T_STRING '=' static_scalar { $$ = Stmt\DeclareDeclare[$1, $3]; } ; switch_case_list: '{' case_list '}' { $$ = $2; } | '{' ';' case_list '}' { $$ = $3; } | ':' case_list T_ENDSWITCH ';' { $$ = $2; } | ':' ';' case_list T_ENDSWITCH ';' { $$ = $3; } ; case_list: /* empty */ { init(); } | case_list case { push($1, $2); } ; case: T_CASE expr case_separator inner_statement_list { $$ = Stmt\Case_[$2, $4]; } | T_DEFAULT case_separator inner_statement_list { $$ = Stmt\Case_[null, $3]; } ; case_separator: ':' | ';' ; while_statement: statement { $$ = toArray($1); } | ':' inner_statement_list T_ENDWHILE ';' { $$ = $2; } ; elseif_list: /* empty */ { init(); } | elseif_list elseif { push($1, $2); } ; elseif: T_ELSEIF parentheses_expr statement { $$ = Stmt\ElseIf_[$2, toArray($3)]; } ; new_elseif_list: /* empty */ { init(); } | new_elseif_list new_elseif { push($1, $2); } ; new_elseif: T_ELSEIF parentheses_expr ':' inner_statement_list { $$ = Stmt\ElseIf_[$2, $4]; } ; else_single: /* empty */ { $$ = null; } | T_ELSE statement { $$ = Stmt\Else_[toArray($2)]; } ; new_else_single: /* empty */ { $$ = null; } | T_ELSE ':' inner_statement_list { $$ = Stmt\Else_[$3]; } ; foreach_variable: variable { $$ = array($1, false); } | '&' variable { $$ = array($2, true); } | list_expr { $$ = array($1, false); } ; parameter_list: non_empty_parameter_list { $$ = $1; } | /* empty */ { $$ = array(); } ; non_empty_parameter_list: parameter { init($1); } | non_empty_parameter_list ',' parameter { push($1, $3); } ; parameter: optional_param_type optional_ref optional_ellipsis T_VARIABLE { $$ = Node\Param[parseVar($4), null, $1, $2, $3]; $this->checkParam($$); } | optional_param_type optional_ref optional_ellipsis T_VARIABLE '=' static_scalar { $$ = Node\Param[parseVar($4), $6, $1, $2, $3]; $this->checkParam($$); } ; type: name { $$ = $1; } | T_ARRAY { $$ = 'array'; } | T_CALLABLE { $$ = 'callable'; } ; optional_param_type: /* empty */ { $$ = null; } | type { $$ = $1; } ; optional_return_type: /* empty */ { $$ = null; } | ':' type { $$ = $2; } ; argument_list: '(' ')' { $$ = array(); } | '(' non_empty_argument_list ')' { $$ = $2; } | '(' yield_expr ')' { $$ = array(Node\Arg[$2, false, false]); } ; non_empty_argument_list: argument { init($1); } | non_empty_argument_list ',' argument { push($1, $3); } ; argument: expr { $$ = Node\Arg[$1, false, false]; } | '&' variable { $$ = Node\Arg[$2, true, false]; } | T_ELLIPSIS expr { $$ = Node\Arg[$2, false, true]; } ; global_var_list: global_var_list ',' global_var { push($1, $3); } | global_var { init($1); } ; global_var: T_VARIABLE { $$ = Expr\Variable[parseVar($1)]; } | '$' variable { $$ = Expr\Variable[$2]; } | '$' '{' expr '}' { $$ = Expr\Variable[$3]; } ; static_var_list: static_var_list ',' static_var { push($1, $3); } | static_var { init($1); } ; static_var: T_VARIABLE { $$ = Stmt\StaticVar[parseVar($1), null]; } | T_VARIABLE '=' static_scalar { $$ = Stmt\StaticVar[parseVar($1), $3]; } ; class_statement_list: class_statement_list class_statement { push($1, $2); } | /* empty */ { init(); } ; class_statement: variable_modifiers property_declaration_list ';' { $$ = Stmt\Property[$1, $2]; $this->checkProperty($$, #1); } | T_CONST class_const_list ';' { $$ = Stmt\ClassConst[$2, 0]; } | method_modifiers T_FUNCTION optional_ref identifier '(' parameter_list ')' optional_return_type method_body { $$ = Stmt\ClassMethod[$4, ['type' => $1, 'byRef' => $3, 'params' => $6, 'returnType' => $8, 'stmts' => $9]]; $this->checkClassMethod($$, #1); } | T_USE class_name_list trait_adaptations { $$ = Stmt\TraitUse[$2, $3]; } ; trait_adaptations: ';' { $$ = array(); } | '{' trait_adaptation_list '}' { $$ = $2; } ; trait_adaptation_list: /* empty */ { init(); } | trait_adaptation_list trait_adaptation { push($1, $2); } ; trait_adaptation: trait_method_reference_fully_qualified T_INSTEADOF class_name_list ';' { $$ = Stmt\TraitUseAdaptation\Precedence[$1[0], $1[1], $3]; } | trait_method_reference T_AS member_modifier identifier ';' { $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], $3, $4]; } | trait_method_reference T_AS member_modifier ';' { $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], $3, null]; } | trait_method_reference T_AS T_STRING ';' { $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], null, $3]; } | trait_method_reference T_AS reserved_non_modifiers ';' { $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], null, $3]; } ; trait_method_reference_fully_qualified: name T_PAAMAYIM_NEKUDOTAYIM identifier { $$ = array($1, $3); } ; trait_method_reference: trait_method_reference_fully_qualified { $$ = $1; } | identifier { $$ = array(null, $1); } ; method_body: ';' /* abstract method */ { $$ = null; } | '{' inner_statement_list '}' { $$ = $2; } ; variable_modifiers: non_empty_member_modifiers { $$ = $1; } | T_VAR { $$ = 0; } ; method_modifiers: /* empty */ { $$ = 0; } | non_empty_member_modifiers { $$ = $1; } ; non_empty_member_modifiers: member_modifier { $$ = $1; } | non_empty_member_modifiers member_modifier { $this->checkModifier($1, $2, #2); $$ = $1 | $2; } ; member_modifier: T_PUBLIC { $$ = Stmt\Class_::MODIFIER_PUBLIC; } | T_PROTECTED { $$ = Stmt\Class_::MODIFIER_PROTECTED; } | T_PRIVATE { $$ = Stmt\Class_::MODIFIER_PRIVATE; } | T_STATIC { $$ = Stmt\Class_::MODIFIER_STATIC; } | T_ABSTRACT { $$ = Stmt\Class_::MODIFIER_ABSTRACT; } | T_FINAL { $$ = Stmt\Class_::MODIFIER_FINAL; } ; property_declaration_list: property_declaration { init($1); } | property_declaration_list ',' property_declaration { push($1, $3); } ; property_declaration: T_VARIABLE { $$ = Stmt\PropertyProperty[parseVar($1), null]; } | T_VARIABLE '=' static_scalar { $$ = Stmt\PropertyProperty[parseVar($1), $3]; } ; expr_list: expr_list ',' expr { push($1, $3); } | expr { init($1); } ; for_expr: /* empty */ { $$ = array(); } | expr_list { $$ = $1; } ; expr: variable { $$ = $1; } | list_expr '=' expr { $$ = Expr\Assign[$1, $3]; } | variable '=' expr { $$ = Expr\Assign[$1, $3]; } | variable '=' '&' variable { $$ = Expr\AssignRef[$1, $4]; } | variable '=' '&' new_expr { $$ = Expr\AssignRef[$1, $4]; } | new_expr { $$ = $1; } | T_CLONE expr { $$ = Expr\Clone_[$2]; } | variable T_PLUS_EQUAL expr { $$ = Expr\AssignOp\Plus [$1, $3]; } | variable T_MINUS_EQUAL expr { $$ = Expr\AssignOp\Minus [$1, $3]; } | variable T_MUL_EQUAL expr { $$ = Expr\AssignOp\Mul [$1, $3]; } | variable T_DIV_EQUAL expr { $$ = Expr\AssignOp\Div [$1, $3]; } | variable T_CONCAT_EQUAL expr { $$ = Expr\AssignOp\Concat [$1, $3]; } | variable T_MOD_EQUAL expr { $$ = Expr\AssignOp\Mod [$1, $3]; } | variable T_AND_EQUAL expr { $$ = Expr\AssignOp\BitwiseAnd[$1, $3]; } | variable T_OR_EQUAL expr { $$ = Expr\AssignOp\BitwiseOr [$1, $3]; } | variable T_XOR_EQUAL expr { $$ = Expr\AssignOp\BitwiseXor[$1, $3]; } | variable T_SL_EQUAL expr { $$ = Expr\AssignOp\ShiftLeft [$1, $3]; } | variable T_SR_EQUAL expr { $$ = Expr\AssignOp\ShiftRight[$1, $3]; } | variable T_POW_EQUAL expr { $$ = Expr\AssignOp\Pow [$1, $3]; } | variable T_INC { $$ = Expr\PostInc[$1]; } | T_INC variable { $$ = Expr\PreInc [$2]; } | variable T_DEC { $$ = Expr\PostDec[$1]; } | T_DEC variable { $$ = Expr\PreDec [$2]; } | expr T_BOOLEAN_OR expr { $$ = Expr\BinaryOp\BooleanOr [$1, $3]; } | expr T_BOOLEAN_AND expr { $$ = Expr\BinaryOp\BooleanAnd[$1, $3]; } | expr T_LOGICAL_OR expr { $$ = Expr\BinaryOp\LogicalOr [$1, $3]; } | expr T_LOGICAL_AND expr { $$ = Expr\BinaryOp\LogicalAnd[$1, $3]; } | expr T_LOGICAL_XOR expr { $$ = Expr\BinaryOp\LogicalXor[$1, $3]; } | expr '|' expr { $$ = Expr\BinaryOp\BitwiseOr [$1, $3]; } | expr '&' expr { $$ = Expr\BinaryOp\BitwiseAnd[$1, $3]; } | expr '^' expr { $$ = Expr\BinaryOp\BitwiseXor[$1, $3]; } | expr '.' expr { $$ = Expr\BinaryOp\Concat [$1, $3]; } | expr '+' expr { $$ = Expr\BinaryOp\Plus [$1, $3]; } | expr '-' expr { $$ = Expr\BinaryOp\Minus [$1, $3]; } | expr '*' expr { $$ = Expr\BinaryOp\Mul [$1, $3]; } | expr '/' expr { $$ = Expr\BinaryOp\Div [$1, $3]; } | expr '%' expr { $$ = Expr\BinaryOp\Mod [$1, $3]; } | expr T_SL expr { $$ = Expr\BinaryOp\ShiftLeft [$1, $3]; } | expr T_SR expr { $$ = Expr\BinaryOp\ShiftRight[$1, $3]; } | expr T_POW expr { $$ = Expr\BinaryOp\Pow [$1, $3]; } | '+' expr %prec T_INC { $$ = Expr\UnaryPlus [$2]; } | '-' expr %prec T_INC { $$ = Expr\UnaryMinus[$2]; } | '!' expr { $$ = Expr\BooleanNot[$2]; } | '~' expr { $$ = Expr\BitwiseNot[$2]; } | expr T_IS_IDENTICAL expr { $$ = Expr\BinaryOp\Identical [$1, $3]; } | expr T_IS_NOT_IDENTICAL expr { $$ = Expr\BinaryOp\NotIdentical [$1, $3]; } | expr T_IS_EQUAL expr { $$ = Expr\BinaryOp\Equal [$1, $3]; } | expr T_IS_NOT_EQUAL expr { $$ = Expr\BinaryOp\NotEqual [$1, $3]; } | expr T_SPACESHIP expr { $$ = Expr\BinaryOp\Spaceship [$1, $3]; } | expr '<' expr { $$ = Expr\BinaryOp\Smaller [$1, $3]; } | expr T_IS_SMALLER_OR_EQUAL expr { $$ = Expr\BinaryOp\SmallerOrEqual[$1, $3]; } | expr '>' expr { $$ = Expr\BinaryOp\Greater [$1, $3]; } | expr T_IS_GREATER_OR_EQUAL expr { $$ = Expr\BinaryOp\GreaterOrEqual[$1, $3]; } | expr T_INSTANCEOF class_name_reference { $$ = Expr\Instanceof_[$1, $3]; } | parentheses_expr { $$ = $1; } /* we need a separate '(' new_expr ')' rule to avoid problems caused by a s/r conflict */ | '(' new_expr ')' { $$ = $2; } | expr '?' expr ':' expr { $$ = Expr\Ternary[$1, $3, $5]; } | expr '?' ':' expr { $$ = Expr\Ternary[$1, null, $4]; } | expr T_COALESCE expr { $$ = Expr\BinaryOp\Coalesce[$1, $3]; } | T_ISSET '(' variables_list ')' { $$ = Expr\Isset_[$3]; } | T_EMPTY '(' expr ')' { $$ = Expr\Empty_[$3]; } | T_INCLUDE expr { $$ = Expr\Include_[$2, Expr\Include_::TYPE_INCLUDE]; } | T_INCLUDE_ONCE expr { $$ = Expr\Include_[$2, Expr\Include_::TYPE_INCLUDE_ONCE]; } | T_EVAL parentheses_expr { $$ = Expr\Eval_[$2]; } | T_REQUIRE expr { $$ = Expr\Include_[$2, Expr\Include_::TYPE_REQUIRE]; } | T_REQUIRE_ONCE expr { $$ = Expr\Include_[$2, Expr\Include_::TYPE_REQUIRE_ONCE]; } | T_INT_CAST expr { $$ = Expr\Cast\Int_ [$2]; } | T_DOUBLE_CAST expr { $$ = Expr\Cast\Double [$2]; } | T_STRING_CAST expr { $$ = Expr\Cast\String_ [$2]; } | T_ARRAY_CAST expr { $$ = Expr\Cast\Array_ [$2]; } | T_OBJECT_CAST expr { $$ = Expr\Cast\Object_ [$2]; } | T_BOOL_CAST expr { $$ = Expr\Cast\Bool_ [$2]; } | T_UNSET_CAST expr { $$ = Expr\Cast\Unset_ [$2]; } | T_EXIT exit_expr { $attrs = attributes(); $attrs['kind'] = strtolower($1) === 'exit' ? Expr\Exit_::KIND_EXIT : Expr\Exit_::KIND_DIE; $$ = new Expr\Exit_($2, $attrs); } | '@' expr { $$ = Expr\ErrorSuppress[$2]; } | scalar { $$ = $1; } | array_expr { $$ = $1; } | scalar_dereference { $$ = $1; } | '`' backticks_expr '`' { $$ = Expr\ShellExec[$2]; } | T_PRINT expr { $$ = Expr\Print_[$2]; } | T_YIELD { $$ = Expr\Yield_[null, null]; } | T_YIELD_FROM expr { $$ = Expr\YieldFrom[$2]; } | T_FUNCTION optional_ref '(' parameter_list ')' lexical_vars optional_return_type '{' inner_statement_list '}' { $$ = Expr\Closure[['static' => false, 'byRef' => $2, 'params' => $4, 'uses' => $6, 'returnType' => $7, 'stmts' => $9]]; } | T_STATIC T_FUNCTION optional_ref '(' parameter_list ')' lexical_vars optional_return_type '{' inner_statement_list '}' { $$ = Expr\Closure[['static' => true, 'byRef' => $3, 'params' => $5, 'uses' => $7, 'returnType' => $8, 'stmts' => $10]]; } ; parentheses_expr: '(' expr ')' { $$ = $2; } | '(' yield_expr ')' { $$ = $2; } ; yield_expr: T_YIELD expr { $$ = Expr\Yield_[$2, null]; } | T_YIELD expr T_DOUBLE_ARROW expr { $$ = Expr\Yield_[$4, $2]; } ; array_expr: T_ARRAY '(' array_pair_list ')' { $attrs = attributes(); $attrs['kind'] = Expr\Array_::KIND_LONG; $$ = new Expr\Array_($3, $attrs); } | '[' array_pair_list ']' { $attrs = attributes(); $attrs['kind'] = Expr\Array_::KIND_SHORT; $$ = new Expr\Array_($2, $attrs); } ; scalar_dereference: array_expr '[' dim_offset ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } | T_CONSTANT_ENCAPSED_STRING '[' dim_offset ']' { $attrs = attributes(); $attrs['kind'] = strKind($1); $$ = Expr\ArrayDimFetch[new Scalar\String_(Scalar\String_::parse($1), $attrs), $3]; } | constant '[' dim_offset ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } | scalar_dereference '[' dim_offset ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } /* alternative array syntax missing intentionally */ ; anonymous_class: T_CLASS ctor_arguments extends_from implements_list '{' class_statement_list '}' { $$ = array(Stmt\Class_[null, ['type' => 0, 'extends' => $3, 'implements' => $4, 'stmts' => $6]], $2); $this->checkClass($$[0], -1); } new_expr: T_NEW class_name_reference ctor_arguments { $$ = Expr\New_[$2, $3]; } | T_NEW anonymous_class { list($class, $ctorArgs) = $2; $$ = Expr\New_[$class, $ctorArgs]; } ; lexical_vars: /* empty */ { $$ = array(); } | T_USE '(' lexical_var_list ')' { $$ = $3; } ; lexical_var_list: lexical_var { init($1); } | lexical_var_list ',' lexical_var { push($1, $3); } ; lexical_var: optional_ref T_VARIABLE { $$ = Expr\ClosureUse[parseVar($2), $1]; } ; function_call: name argument_list { $$ = Expr\FuncCall[$1, $2]; } | class_name_or_var T_PAAMAYIM_NEKUDOTAYIM identifier argument_list { $$ = Expr\StaticCall[$1, $3, $4]; } | class_name_or_var T_PAAMAYIM_NEKUDOTAYIM '{' expr '}' argument_list { $$ = Expr\StaticCall[$1, $4, $6]; } | static_property argument_list { if ($1 instanceof Node\Expr\StaticPropertyFetch) { $$ = Expr\StaticCall[$1->class, Expr\Variable[$1->name], $2]; } elseif ($1 instanceof Node\Expr\ArrayDimFetch) { $tmp = $1; while ($tmp->var instanceof Node\Expr\ArrayDimFetch) { $tmp = $tmp->var; } $$ = Expr\StaticCall[$tmp->var->class, $1, $2]; $tmp->var = Expr\Variable[$tmp->var->name]; } else { throw new \Exception; } } | variable_without_objects argument_list { $$ = Expr\FuncCall[$1, $2]; } | function_call '[' dim_offset ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } /* alternative array syntax missing intentionally */ ; class_name: T_STATIC { $$ = Name[$1]; } | name { $$ = $1; } ; name: namespace_name_parts { $$ = Name[$1]; } | T_NS_SEPARATOR namespace_name_parts { $$ = Name\FullyQualified[$2]; } | T_NAMESPACE T_NS_SEPARATOR namespace_name_parts { $$ = Name\Relative[$3]; } ; class_name_reference: class_name { $$ = $1; } | dynamic_class_name_reference { $$ = $1; } ; dynamic_class_name_reference: object_access_for_dcnr { $$ = $1; } | base_variable { $$ = $1; } ; class_name_or_var: class_name { $$ = $1; } | reference_variable { $$ = $1; } ; object_access_for_dcnr: base_variable T_OBJECT_OPERATOR object_property { $$ = Expr\PropertyFetch[$1, $3]; } | object_access_for_dcnr T_OBJECT_OPERATOR object_property { $$ = Expr\PropertyFetch[$1, $3]; } | object_access_for_dcnr '[' dim_offset ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } | object_access_for_dcnr '{' expr '}' { $$ = Expr\ArrayDimFetch[$1, $3]; } ; exit_expr: /* empty */ { $$ = null; } | '(' ')' { $$ = null; } | parentheses_expr { $$ = $1; } ; backticks_expr: /* empty */ { $$ = array(); } | T_ENCAPSED_AND_WHITESPACE { $$ = array(Scalar\EncapsedStringPart[Scalar\String_::parseEscapeSequences($1, '`', false)]); } | encaps_list { parseEncapsed($1, '`', false); $$ = $1; } ; ctor_arguments: /* empty */ { $$ = array(); } | argument_list { $$ = $1; } ; common_scalar: T_LNUMBER { $$ = $this->parseLNumber($1, attributes(), true); } | T_DNUMBER { $$ = Scalar\DNumber[Scalar\DNumber::parse($1)]; } | T_CONSTANT_ENCAPSED_STRING { $attrs = attributes(); $attrs['kind'] = strKind($1); $$ = new Scalar\String_(Scalar\String_::parse($1, false), $attrs); } | T_LINE { $$ = Scalar\MagicConst\Line[]; } | T_FILE { $$ = Scalar\MagicConst\File[]; } | T_DIR { $$ = Scalar\MagicConst\Dir[]; } | T_CLASS_C { $$ = Scalar\MagicConst\Class_[]; } | T_TRAIT_C { $$ = Scalar\MagicConst\Trait_[]; } | T_METHOD_C { $$ = Scalar\MagicConst\Method[]; } | T_FUNC_C { $$ = Scalar\MagicConst\Function_[]; } | T_NS_C { $$ = Scalar\MagicConst\Namespace_[]; } | T_START_HEREDOC T_ENCAPSED_AND_WHITESPACE T_END_HEREDOC { $attrs = attributes(); setDocStringAttrs($attrs, $1); $$ = new Scalar\String_(Scalar\String_::parseDocString($1, $2, false), $attrs); } | T_START_HEREDOC T_END_HEREDOC { $attrs = attributes(); setDocStringAttrs($attrs, $1); $$ = new Scalar\String_('', $attrs); } ; static_scalar: common_scalar { $$ = $1; } | class_name T_PAAMAYIM_NEKUDOTAYIM identifier { $$ = Expr\ClassConstFetch[$1, $3]; } | name { $$ = Expr\ConstFetch[$1]; } | T_ARRAY '(' static_array_pair_list ')' { $$ = Expr\Array_[$3]; } | '[' static_array_pair_list ']' { $$ = Expr\Array_[$2]; } | static_operation { $$ = $1; } ; static_operation: static_scalar T_BOOLEAN_OR static_scalar { $$ = Expr\BinaryOp\BooleanOr [$1, $3]; } | static_scalar T_BOOLEAN_AND static_scalar { $$ = Expr\BinaryOp\BooleanAnd[$1, $3]; } | static_scalar T_LOGICAL_OR static_scalar { $$ = Expr\BinaryOp\LogicalOr [$1, $3]; } | static_scalar T_LOGICAL_AND static_scalar { $$ = Expr\BinaryOp\LogicalAnd[$1, $3]; } | static_scalar T_LOGICAL_XOR static_scalar { $$ = Expr\BinaryOp\LogicalXor[$1, $3]; } | static_scalar '|' static_scalar { $$ = Expr\BinaryOp\BitwiseOr [$1, $3]; } | static_scalar '&' static_scalar { $$ = Expr\BinaryOp\BitwiseAnd[$1, $3]; } | static_scalar '^' static_scalar { $$ = Expr\BinaryOp\BitwiseXor[$1, $3]; } | static_scalar '.' static_scalar { $$ = Expr\BinaryOp\Concat [$1, $3]; } | static_scalar '+' static_scalar { $$ = Expr\BinaryOp\Plus [$1, $3]; } | static_scalar '-' static_scalar { $$ = Expr\BinaryOp\Minus [$1, $3]; } | static_scalar '*' static_scalar { $$ = Expr\BinaryOp\Mul [$1, $3]; } | static_scalar '/' static_scalar { $$ = Expr\BinaryOp\Div [$1, $3]; } | static_scalar '%' static_scalar { $$ = Expr\BinaryOp\Mod [$1, $3]; } | static_scalar T_SL static_scalar { $$ = Expr\BinaryOp\ShiftLeft [$1, $3]; } | static_scalar T_SR static_scalar { $$ = Expr\BinaryOp\ShiftRight[$1, $3]; } | static_scalar T_POW static_scalar { $$ = Expr\BinaryOp\Pow [$1, $3]; } | '+' static_scalar %prec T_INC { $$ = Expr\UnaryPlus [$2]; } | '-' static_scalar %prec T_INC { $$ = Expr\UnaryMinus[$2]; } | '!' static_scalar { $$ = Expr\BooleanNot[$2]; } | '~' static_scalar { $$ = Expr\BitwiseNot[$2]; } | static_scalar T_IS_IDENTICAL static_scalar { $$ = Expr\BinaryOp\Identical [$1, $3]; } | static_scalar T_IS_NOT_IDENTICAL static_scalar { $$ = Expr\BinaryOp\NotIdentical [$1, $3]; } | static_scalar T_IS_EQUAL static_scalar { $$ = Expr\BinaryOp\Equal [$1, $3]; } | static_scalar T_IS_NOT_EQUAL static_scalar { $$ = Expr\BinaryOp\NotEqual [$1, $3]; } | static_scalar '<' static_scalar { $$ = Expr\BinaryOp\Smaller [$1, $3]; } | static_scalar T_IS_SMALLER_OR_EQUAL static_scalar { $$ = Expr\BinaryOp\SmallerOrEqual[$1, $3]; } | static_scalar '>' static_scalar { $$ = Expr\BinaryOp\Greater [$1, $3]; } | static_scalar T_IS_GREATER_OR_EQUAL static_scalar { $$ = Expr\BinaryOp\GreaterOrEqual[$1, $3]; } | static_scalar '?' static_scalar ':' static_scalar { $$ = Expr\Ternary[$1, $3, $5]; } | static_scalar '?' ':' static_scalar { $$ = Expr\Ternary[$1, null, $4]; } | static_scalar '[' static_scalar ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } | '(' static_scalar ')' { $$ = $2; } ; constant: name { $$ = Expr\ConstFetch[$1]; } | class_name_or_var T_PAAMAYIM_NEKUDOTAYIM identifier { $$ = Expr\ClassConstFetch[$1, $3]; } ; scalar: common_scalar { $$ = $1; } | constant { $$ = $1; } | '"' encaps_list '"' { $attrs = attributes(); $attrs['kind'] = Scalar\String_::KIND_DOUBLE_QUOTED; parseEncapsed($2, '"', true); $$ = new Scalar\Encapsed($2, $attrs); } | T_START_HEREDOC encaps_list T_END_HEREDOC { $attrs = attributes(); setDocStringAttrs($attrs, $1); parseEncapsedDoc($2, true); $$ = new Scalar\Encapsed($2, $attrs); } ; static_array_pair_list: /* empty */ { $$ = array(); } | non_empty_static_array_pair_list optional_comma { $$ = $1; } ; optional_comma: /* empty */ | ',' ; non_empty_static_array_pair_list: non_empty_static_array_pair_list ',' static_array_pair { push($1, $3); } | static_array_pair { init($1); } ; static_array_pair: static_scalar T_DOUBLE_ARROW static_scalar { $$ = Expr\ArrayItem[$3, $1, false]; } | static_scalar { $$ = Expr\ArrayItem[$1, null, false]; } ; variable: object_access { $$ = $1; } | base_variable { $$ = $1; } | function_call { $$ = $1; } | new_expr_array_deref { $$ = $1; } ; new_expr_array_deref: '(' new_expr ')' '[' dim_offset ']' { $$ = Expr\ArrayDimFetch[$2, $5]; } | new_expr_array_deref '[' dim_offset ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } /* alternative array syntax missing intentionally */ ; object_access: variable_or_new_expr T_OBJECT_OPERATOR object_property { $$ = Expr\PropertyFetch[$1, $3]; } | variable_or_new_expr T_OBJECT_OPERATOR object_property argument_list { $$ = Expr\MethodCall[$1, $3, $4]; } | object_access argument_list { $$ = Expr\FuncCall[$1, $2]; } | object_access '[' dim_offset ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } | object_access '{' expr '}' { $$ = Expr\ArrayDimFetch[$1, $3]; } ; variable_or_new_expr: variable { $$ = $1; } | '(' new_expr ')' { $$ = $2; } ; variable_without_objects: reference_variable { $$ = $1; } | '$' variable_without_objects { $$ = Expr\Variable[$2]; } ; base_variable: variable_without_objects { $$ = $1; } | static_property { $$ = $1; } ; static_property: class_name_or_var T_PAAMAYIM_NEKUDOTAYIM '$' reference_variable { $$ = Expr\StaticPropertyFetch[$1, $4]; } | static_property_with_arrays { $$ = $1; } ; static_property_with_arrays: class_name_or_var T_PAAMAYIM_NEKUDOTAYIM T_VARIABLE { $$ = Expr\StaticPropertyFetch[$1, parseVar($3)]; } | class_name_or_var T_PAAMAYIM_NEKUDOTAYIM '$' '{' expr '}' { $$ = Expr\StaticPropertyFetch[$1, $5]; } | static_property_with_arrays '[' dim_offset ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } | static_property_with_arrays '{' expr '}' { $$ = Expr\ArrayDimFetch[$1, $3]; } ; reference_variable: reference_variable '[' dim_offset ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } | reference_variable '{' expr '}' { $$ = Expr\ArrayDimFetch[$1, $3]; } | T_VARIABLE { $$ = Expr\Variable[parseVar($1)]; } | '$' '{' expr '}' { $$ = Expr\Variable[$3]; } ; dim_offset: /* empty */ { $$ = null; } | expr { $$ = $1; } ; object_property: T_STRING { $$ = $1; } | '{' expr '}' { $$ = $2; } | variable_without_objects { $$ = $1; } | error { $$ = Expr\Error[]; $this->errorState = 2; } ; list_expr: T_LIST '(' list_expr_elements ')' { $$ = Expr\List_[$3]; } ; list_expr_elements: list_expr_elements ',' list_expr_element { push($1, $3); } | list_expr_element { init($1); } ; list_expr_element: variable { $$ = Expr\ArrayItem[$1, null, false]; } | list_expr { $$ = Expr\ArrayItem[$1, null, false]; } | /* empty */ { $$ = null; } ; array_pair_list: /* empty */ { $$ = array(); } | non_empty_array_pair_list optional_comma { $$ = $1; } ; non_empty_array_pair_list: non_empty_array_pair_list ',' array_pair { push($1, $3); } | array_pair { init($1); } ; array_pair: expr T_DOUBLE_ARROW expr { $$ = Expr\ArrayItem[$3, $1, false]; } | expr { $$ = Expr\ArrayItem[$1, null, false]; } | expr T_DOUBLE_ARROW '&' variable { $$ = Expr\ArrayItem[$4, $1, true]; } | '&' variable { $$ = Expr\ArrayItem[$2, null, true]; } ; encaps_list: encaps_list encaps_var { push($1, $2); } | encaps_list encaps_string_part { push($1, $2); } | encaps_var { init($1); } | encaps_string_part encaps_var { init($1, $2); } ; encaps_string_part: T_ENCAPSED_AND_WHITESPACE { $$ = Scalar\EncapsedStringPart[$1]; } ; encaps_base_var: T_VARIABLE { $$ = Expr\Variable[parseVar($1)]; } ; encaps_var: encaps_base_var { $$ = $1; } | encaps_base_var '[' encaps_var_offset ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } | encaps_base_var T_OBJECT_OPERATOR T_STRING { $$ = Expr\PropertyFetch[$1, $3]; } | T_DOLLAR_OPEN_CURLY_BRACES expr '}' { $$ = Expr\Variable[$2]; } | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '}' { $$ = Expr\Variable[$2]; } | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '[' expr ']' '}' { $$ = Expr\ArrayDimFetch[Expr\Variable[$2], $4]; } | T_CURLY_OPEN variable '}' { $$ = $2; } ; encaps_var_offset: T_STRING { $$ = Scalar\String_[$1]; } | T_NUM_STRING { $$ = $this->parseNumString($1, attributes()); } | T_VARIABLE { $$ = Expr\Variable[parseVar($1)]; } ; %% PHP-Parser-3.1.4/grammar/php7.y000066400000000000000000001305321323244626500161110ustar00rootroot00000000000000%pure_parser %expect 2 %tokens %% start: top_statement_list { $$ = $this->handleNamespaces($1); } ; top_statement_list_ex: top_statement_list_ex top_statement { pushNormalizing($1, $2); } | /* empty */ { init(); } ; top_statement_list: top_statement_list_ex { makeNop($nop, $this->lookaheadStartAttributes); if ($nop !== null) { $1[] = $nop; } $$ = $1; } ; reserved_non_modifiers: T_INCLUDE | T_INCLUDE_ONCE | T_EVAL | T_REQUIRE | T_REQUIRE_ONCE | T_LOGICAL_OR | T_LOGICAL_XOR | T_LOGICAL_AND | T_INSTANCEOF | T_NEW | T_CLONE | T_EXIT | T_IF | T_ELSEIF | T_ELSE | T_ENDIF | T_ECHO | T_DO | T_WHILE | T_ENDWHILE | T_FOR | T_ENDFOR | T_FOREACH | T_ENDFOREACH | T_DECLARE | T_ENDDECLARE | T_AS | T_TRY | T_CATCH | T_FINALLY | T_THROW | T_USE | T_INSTEADOF | T_GLOBAL | T_VAR | T_UNSET | T_ISSET | T_EMPTY | T_CONTINUE | T_GOTO | T_FUNCTION | T_CONST | T_RETURN | T_PRINT | T_YIELD | T_LIST | T_SWITCH | T_ENDSWITCH | T_CASE | T_DEFAULT | T_BREAK | T_ARRAY | T_CALLABLE | T_EXTENDS | T_IMPLEMENTS | T_NAMESPACE | T_TRAIT | T_INTERFACE | T_CLASS | T_CLASS_C | T_TRAIT_C | T_FUNC_C | T_METHOD_C | T_LINE | T_FILE | T_DIR | T_NS_C | T_HALT_COMPILER ; semi_reserved: reserved_non_modifiers | T_STATIC | T_ABSTRACT | T_FINAL | T_PRIVATE | T_PROTECTED | T_PUBLIC ; identifier: T_STRING { $$ = $1; } | semi_reserved { $$ = $1; } ; namespace_name_parts: T_STRING { init($1); } | namespace_name_parts T_NS_SEPARATOR T_STRING { push($1, $3); } ; namespace_name: namespace_name_parts { $$ = Name[$1]; } ; semi: ';' { /* nothing */ } | error { /* nothing */ } ; no_comma: /* empty */ { /* nothing */ } | ',' { $this->emitError(new Error('A trailing comma is not allowed here', attributes())); } ; optional_comma: /* empty */ | ',' top_statement: statement { $$ = $1; } | function_declaration_statement { $$ = $1; } | class_declaration_statement { $$ = $1; } | T_HALT_COMPILER { $$ = Stmt\HaltCompiler[$this->lexer->handleHaltCompiler()]; } | T_NAMESPACE namespace_name semi { $$ = Stmt\Namespace_[$2, null]; $$->setAttribute('kind', Stmt\Namespace_::KIND_SEMICOLON); $this->checkNamespace($$); } | T_NAMESPACE namespace_name '{' top_statement_list '}' { $$ = Stmt\Namespace_[$2, $4]; $$->setAttribute('kind', Stmt\Namespace_::KIND_BRACED); $this->checkNamespace($$); } | T_NAMESPACE '{' top_statement_list '}' { $$ = Stmt\Namespace_[null, $3]; $$->setAttribute('kind', Stmt\Namespace_::KIND_BRACED); $this->checkNamespace($$); } | T_USE use_declarations semi { $$ = Stmt\Use_[$2, Stmt\Use_::TYPE_NORMAL]; } | T_USE use_type use_declarations semi { $$ = Stmt\Use_[$3, $2]; } | group_use_declaration semi { $$ = $1; } | T_CONST constant_declaration_list semi { $$ = Stmt\Const_[$2]; } ; use_type: T_FUNCTION { $$ = Stmt\Use_::TYPE_FUNCTION; } | T_CONST { $$ = Stmt\Use_::TYPE_CONSTANT; } ; /* Using namespace_name_parts here to avoid s/r conflict on T_NS_SEPARATOR */ group_use_declaration: T_USE use_type namespace_name_parts T_NS_SEPARATOR '{' unprefixed_use_declarations '}' { $$ = Stmt\GroupUse[new Name($3, stackAttributes(#3)), $6, $2]; } | T_USE use_type T_NS_SEPARATOR namespace_name_parts T_NS_SEPARATOR '{' unprefixed_use_declarations '}' { $$ = Stmt\GroupUse[new Name($4, stackAttributes(#4)), $7, $2]; } | T_USE namespace_name_parts T_NS_SEPARATOR '{' inline_use_declarations '}' { $$ = Stmt\GroupUse[new Name($2, stackAttributes(#2)), $5, Stmt\Use_::TYPE_UNKNOWN]; } | T_USE T_NS_SEPARATOR namespace_name_parts T_NS_SEPARATOR '{' inline_use_declarations '}' { $$ = Stmt\GroupUse[new Name($3, stackAttributes(#3)), $6, Stmt\Use_::TYPE_UNKNOWN]; } ; unprefixed_use_declarations: non_empty_unprefixed_use_declarations optional_comma { $$ = $1; } ; non_empty_unprefixed_use_declarations: non_empty_unprefixed_use_declarations ',' unprefixed_use_declaration { push($1, $3); } | unprefixed_use_declaration { init($1); } ; use_declarations: non_empty_use_declarations no_comma { $$ = $1; } ; non_empty_use_declarations: non_empty_use_declarations ',' use_declaration { push($1, $3); } | use_declaration { init($1); } ; inline_use_declarations: non_empty_inline_use_declarations optional_comma { $$ = $1; } ; non_empty_inline_use_declarations: non_empty_inline_use_declarations ',' inline_use_declaration { push($1, $3); } | inline_use_declaration { init($1); } ; unprefixed_use_declaration: namespace_name { $$ = Stmt\UseUse[$1, null, Stmt\Use_::TYPE_UNKNOWN]; $this->checkUseUse($$, #1); } | namespace_name T_AS T_STRING { $$ = Stmt\UseUse[$1, $3, Stmt\Use_::TYPE_UNKNOWN]; $this->checkUseUse($$, #3); } ; use_declaration: unprefixed_use_declaration { $$ = $1; } | T_NS_SEPARATOR unprefixed_use_declaration { $$ = $2; } ; inline_use_declaration: unprefixed_use_declaration { $$ = $1; $$->type = Stmt\Use_::TYPE_NORMAL; } | use_type unprefixed_use_declaration { $$ = $2; $$->type = $1; } ; constant_declaration_list: non_empty_constant_declaration_list no_comma { $$ = $1; } ; non_empty_constant_declaration_list: non_empty_constant_declaration_list ',' constant_declaration { push($1, $3); } | constant_declaration { init($1); } ; constant_declaration: T_STRING '=' expr { $$ = Node\Const_[$1, $3]; } ; class_const_list: non_empty_class_const_list no_comma { $$ = $1; } ; non_empty_class_const_list: non_empty_class_const_list ',' class_const { push($1, $3); } | class_const { init($1); } ; class_const: identifier '=' expr { $$ = Node\Const_[$1, $3]; } ; inner_statement_list_ex: inner_statement_list_ex inner_statement { pushNormalizing($1, $2); } | /* empty */ { init(); } ; inner_statement_list: inner_statement_list_ex { makeNop($nop, $this->lookaheadStartAttributes); if ($nop !== null) { $1[] = $nop; } $$ = $1; } ; inner_statement: statement { $$ = $1; } | function_declaration_statement { $$ = $1; } | class_declaration_statement { $$ = $1; } | T_HALT_COMPILER { throw new Error('__HALT_COMPILER() can only be used from the outermost scope', attributes()); } ; non_empty_statement: '{' inner_statement_list '}' { if ($2) { $$ = $2; prependLeadingComments($$); } else { makeNop($$, $this->startAttributeStack[#1]); if (null === $$) { $$ = array(); } } } | T_IF '(' expr ')' statement elseif_list else_single { $$ = Stmt\If_[$3, ['stmts' => toArray($5), 'elseifs' => $6, 'else' => $7]]; } | T_IF '(' expr ')' ':' inner_statement_list new_elseif_list new_else_single T_ENDIF ';' { $$ = Stmt\If_[$3, ['stmts' => $6, 'elseifs' => $7, 'else' => $8]]; } | T_WHILE '(' expr ')' while_statement { $$ = Stmt\While_[$3, $5]; } | T_DO statement T_WHILE '(' expr ')' ';' { $$ = Stmt\Do_ [$5, toArray($2)]; } | T_FOR '(' for_expr ';' for_expr ';' for_expr ')' for_statement { $$ = Stmt\For_[['init' => $3, 'cond' => $5, 'loop' => $7, 'stmts' => $9]]; } | T_SWITCH '(' expr ')' switch_case_list { $$ = Stmt\Switch_[$3, $5]; } | T_BREAK optional_expr semi { $$ = Stmt\Break_[$2]; } | T_CONTINUE optional_expr semi { $$ = Stmt\Continue_[$2]; } | T_RETURN optional_expr semi { $$ = Stmt\Return_[$2]; } | T_GLOBAL global_var_list semi { $$ = Stmt\Global_[$2]; } | T_STATIC static_var_list semi { $$ = Stmt\Static_[$2]; } | T_ECHO expr_list semi { $$ = Stmt\Echo_[$2]; } | T_INLINE_HTML { $$ = Stmt\InlineHTML[$1]; } | expr semi { $$ = $1; } | T_UNSET '(' variables_list ')' semi { $$ = Stmt\Unset_[$3]; } | T_FOREACH '(' expr T_AS foreach_variable ')' foreach_statement { $$ = Stmt\Foreach_[$3, $5[0], ['keyVar' => null, 'byRef' => $5[1], 'stmts' => $7]]; } | T_FOREACH '(' expr T_AS variable T_DOUBLE_ARROW foreach_variable ')' foreach_statement { $$ = Stmt\Foreach_[$3, $7[0], ['keyVar' => $5, 'byRef' => $7[1], 'stmts' => $9]]; } | T_DECLARE '(' declare_list ')' declare_statement { $$ = Stmt\Declare_[$3, $5]; } | T_TRY '{' inner_statement_list '}' catches optional_finally { $$ = Stmt\TryCatch[$3, $5, $6]; $this->checkTryCatch($$); } | T_THROW expr semi { $$ = Stmt\Throw_[$2]; } | T_GOTO T_STRING semi { $$ = Stmt\Goto_[$2]; } | T_STRING ':' { $$ = Stmt\Label[$1]; } | error { $$ = array(); /* means: no statement */ } ; statement: non_empty_statement { $$ = $1; } | ';' { makeNop($$, $this->startAttributeStack[#1]); if ($$ === null) $$ = array(); /* means: no statement */ } ; catches: /* empty */ { init(); } | catches catch { push($1, $2); } ; name_union: name { init($1); } | name_union '|' name { push($1, $3); } ; catch: T_CATCH '(' name_union T_VARIABLE ')' '{' inner_statement_list '}' { $$ = Stmt\Catch_[$3, parseVar($4), $7]; } ; optional_finally: /* empty */ { $$ = null; } | T_FINALLY '{' inner_statement_list '}' { $$ = Stmt\Finally_[$3]; } ; variables_list: non_empty_variables_list no_comma { $$ = $1; } ; non_empty_variables_list: variable { init($1); } | non_empty_variables_list ',' variable { push($1, $3); } ; optional_ref: /* empty */ { $$ = false; } | '&' { $$ = true; } ; optional_ellipsis: /* empty */ { $$ = false; } | T_ELLIPSIS { $$ = true; } ; function_declaration_statement: T_FUNCTION optional_ref T_STRING '(' parameter_list ')' optional_return_type '{' inner_statement_list '}' { $$ = Stmt\Function_[$3, ['byRef' => $2, 'params' => $5, 'returnType' => $7, 'stmts' => $9]]; } ; class_declaration_statement: class_entry_type T_STRING extends_from implements_list '{' class_statement_list '}' { $$ = Stmt\Class_[$2, ['type' => $1, 'extends' => $3, 'implements' => $4, 'stmts' => $6]]; $this->checkClass($$, #2); } | T_INTERFACE T_STRING interface_extends_list '{' class_statement_list '}' { $$ = Stmt\Interface_[$2, ['extends' => $3, 'stmts' => $5]]; $this->checkInterface($$, #2); } | T_TRAIT T_STRING '{' class_statement_list '}' { $$ = Stmt\Trait_[$2, ['stmts' => $4]]; } ; class_entry_type: T_CLASS { $$ = 0; } | T_ABSTRACT T_CLASS { $$ = Stmt\Class_::MODIFIER_ABSTRACT; } | T_FINAL T_CLASS { $$ = Stmt\Class_::MODIFIER_FINAL; } ; extends_from: /* empty */ { $$ = null; } | T_EXTENDS class_name { $$ = $2; } ; interface_extends_list: /* empty */ { $$ = array(); } | T_EXTENDS class_name_list { $$ = $2; } ; implements_list: /* empty */ { $$ = array(); } | T_IMPLEMENTS class_name_list { $$ = $2; } ; class_name_list: non_empty_class_name_list no_comma { $$ = $1; } ; non_empty_class_name_list: class_name { init($1); } | non_empty_class_name_list ',' class_name { push($1, $3); } ; for_statement: statement { $$ = toArray($1); } | ':' inner_statement_list T_ENDFOR ';' { $$ = $2; } ; foreach_statement: statement { $$ = toArray($1); } | ':' inner_statement_list T_ENDFOREACH ';' { $$ = $2; } ; declare_statement: non_empty_statement { $$ = toArray($1); } | ';' { $$ = null; } | ':' inner_statement_list T_ENDDECLARE ';' { $$ = $2; } ; declare_list: non_empty_declare_list no_comma { $$ = $1; } ; non_empty_declare_list: declare_list_element { init($1); } | non_empty_declare_list ',' declare_list_element { push($1, $3); } ; declare_list_element: T_STRING '=' expr { $$ = Stmt\DeclareDeclare[$1, $3]; } ; switch_case_list: '{' case_list '}' { $$ = $2; } | '{' ';' case_list '}' { $$ = $3; } | ':' case_list T_ENDSWITCH ';' { $$ = $2; } | ':' ';' case_list T_ENDSWITCH ';' { $$ = $3; } ; case_list: /* empty */ { init(); } | case_list case { push($1, $2); } ; case: T_CASE expr case_separator inner_statement_list { $$ = Stmt\Case_[$2, $4]; } | T_DEFAULT case_separator inner_statement_list { $$ = Stmt\Case_[null, $3]; } ; case_separator: ':' | ';' ; while_statement: statement { $$ = toArray($1); } | ':' inner_statement_list T_ENDWHILE ';' { $$ = $2; } ; elseif_list: /* empty */ { init(); } | elseif_list elseif { push($1, $2); } ; elseif: T_ELSEIF '(' expr ')' statement { $$ = Stmt\ElseIf_[$3, toArray($5)]; } ; new_elseif_list: /* empty */ { init(); } | new_elseif_list new_elseif { push($1, $2); } ; new_elseif: T_ELSEIF '(' expr ')' ':' inner_statement_list { $$ = Stmt\ElseIf_[$3, $6]; } ; else_single: /* empty */ { $$ = null; } | T_ELSE statement { $$ = Stmt\Else_[toArray($2)]; } ; new_else_single: /* empty */ { $$ = null; } | T_ELSE ':' inner_statement_list { $$ = Stmt\Else_[$3]; } ; foreach_variable: variable { $$ = array($1, false); } | '&' variable { $$ = array($2, true); } | list_expr { $$ = array($1, false); } | array_short_syntax { $$ = array($1, false); } ; parameter_list: non_empty_parameter_list no_comma { $$ = $1; } | /* empty */ { $$ = array(); } ; non_empty_parameter_list: parameter { init($1); } | non_empty_parameter_list ',' parameter { push($1, $3); } ; parameter: optional_param_type optional_ref optional_ellipsis T_VARIABLE { $$ = Node\Param[parseVar($4), null, $1, $2, $3]; $this->checkParam($$); } | optional_param_type optional_ref optional_ellipsis T_VARIABLE '=' expr { $$ = Node\Param[parseVar($4), $6, $1, $2, $3]; $this->checkParam($$); } ; type_expr: type { $$ = $1; } | '?' type { $$ = Node\NullableType[$2]; } ; type: name { $$ = $this->handleBuiltinTypes($1); } | T_ARRAY { $$ = 'array'; } | T_CALLABLE { $$ = 'callable'; } ; optional_param_type: /* empty */ { $$ = null; } | type_expr { $$ = $1; } ; optional_return_type: /* empty */ { $$ = null; } | ':' type_expr { $$ = $2; } ; argument_list: '(' ')' { $$ = array(); } | '(' non_empty_argument_list no_comma ')' { $$ = $2; } ; non_empty_argument_list: argument { init($1); } | non_empty_argument_list ',' argument { push($1, $3); } ; argument: expr { $$ = Node\Arg[$1, false, false]; } | '&' variable { $$ = Node\Arg[$2, true, false]; } | T_ELLIPSIS expr { $$ = Node\Arg[$2, false, true]; } ; global_var_list: non_empty_global_var_list no_comma { $$ = $1; } ; non_empty_global_var_list: non_empty_global_var_list ',' global_var { push($1, $3); } | global_var { init($1); } ; global_var: simple_variable { $$ = Expr\Variable[$1]; } ; static_var_list: non_empty_static_var_list no_comma { $$ = $1; } ; non_empty_static_var_list: non_empty_static_var_list ',' static_var { push($1, $3); } | static_var { init($1); } ; static_var: T_VARIABLE { $$ = Stmt\StaticVar[parseVar($1), null]; } | T_VARIABLE '=' expr { $$ = Stmt\StaticVar[parseVar($1), $3]; } ; class_statement_list: class_statement_list class_statement { push($1, $2); } | /* empty */ { init(); } ; class_statement: variable_modifiers property_declaration_list ';' { $$ = Stmt\Property[$1, $2]; $this->checkProperty($$, #1); } | method_modifiers T_CONST class_const_list ';' { $$ = Stmt\ClassConst[$3, $1]; $this->checkClassConst($$, #1); } | method_modifiers T_FUNCTION optional_ref identifier '(' parameter_list ')' optional_return_type method_body { $$ = Stmt\ClassMethod[$4, ['type' => $1, 'byRef' => $3, 'params' => $6, 'returnType' => $8, 'stmts' => $9]]; $this->checkClassMethod($$, #1); } | T_USE class_name_list trait_adaptations { $$ = Stmt\TraitUse[$2, $3]; } ; trait_adaptations: ';' { $$ = array(); } | '{' trait_adaptation_list '}' { $$ = $2; } ; trait_adaptation_list: /* empty */ { init(); } | trait_adaptation_list trait_adaptation { push($1, $2); } ; trait_adaptation: trait_method_reference_fully_qualified T_INSTEADOF class_name_list ';' { $$ = Stmt\TraitUseAdaptation\Precedence[$1[0], $1[1], $3]; } | trait_method_reference T_AS member_modifier identifier ';' { $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], $3, $4]; } | trait_method_reference T_AS member_modifier ';' { $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], $3, null]; } | trait_method_reference T_AS T_STRING ';' { $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], null, $3]; } | trait_method_reference T_AS reserved_non_modifiers ';' { $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], null, $3]; } ; trait_method_reference_fully_qualified: name T_PAAMAYIM_NEKUDOTAYIM identifier { $$ = array($1, $3); } ; trait_method_reference: trait_method_reference_fully_qualified { $$ = $1; } | identifier { $$ = array(null, $1); } ; method_body: ';' /* abstract method */ { $$ = null; } | '{' inner_statement_list '}' { $$ = $2; } ; variable_modifiers: non_empty_member_modifiers { $$ = $1; } | T_VAR { $$ = 0; } ; method_modifiers: /* empty */ { $$ = 0; } | non_empty_member_modifiers { $$ = $1; } ; non_empty_member_modifiers: member_modifier { $$ = $1; } | non_empty_member_modifiers member_modifier { $this->checkModifier($1, $2, #2); $$ = $1 | $2; } ; member_modifier: T_PUBLIC { $$ = Stmt\Class_::MODIFIER_PUBLIC; } | T_PROTECTED { $$ = Stmt\Class_::MODIFIER_PROTECTED; } | T_PRIVATE { $$ = Stmt\Class_::MODIFIER_PRIVATE; } | T_STATIC { $$ = Stmt\Class_::MODIFIER_STATIC; } | T_ABSTRACT { $$ = Stmt\Class_::MODIFIER_ABSTRACT; } | T_FINAL { $$ = Stmt\Class_::MODIFIER_FINAL; } ; property_declaration_list: non_empty_property_declaration_list no_comma { $$ = $1; } ; non_empty_property_declaration_list: property_declaration { init($1); } | non_empty_property_declaration_list ',' property_declaration { push($1, $3); } ; property_declaration: T_VARIABLE { $$ = Stmt\PropertyProperty[parseVar($1), null]; } | T_VARIABLE '=' expr { $$ = Stmt\PropertyProperty[parseVar($1), $3]; } ; expr_list: non_empty_expr_list no_comma { $$ = $1; } ; non_empty_expr_list: non_empty_expr_list ',' expr { push($1, $3); } | expr { init($1); } ; for_expr: /* empty */ { $$ = array(); } | expr_list { $$ = $1; } ; expr: variable { $$ = $1; } | list_expr '=' expr { $$ = Expr\Assign[$1, $3]; } | array_short_syntax '=' expr { $$ = Expr\Assign[$1, $3]; } | variable '=' expr { $$ = Expr\Assign[$1, $3]; } | variable '=' '&' variable { $$ = Expr\AssignRef[$1, $4]; } | new_expr { $$ = $1; } | T_CLONE expr { $$ = Expr\Clone_[$2]; } | variable T_PLUS_EQUAL expr { $$ = Expr\AssignOp\Plus [$1, $3]; } | variable T_MINUS_EQUAL expr { $$ = Expr\AssignOp\Minus [$1, $3]; } | variable T_MUL_EQUAL expr { $$ = Expr\AssignOp\Mul [$1, $3]; } | variable T_DIV_EQUAL expr { $$ = Expr\AssignOp\Div [$1, $3]; } | variable T_CONCAT_EQUAL expr { $$ = Expr\AssignOp\Concat [$1, $3]; } | variable T_MOD_EQUAL expr { $$ = Expr\AssignOp\Mod [$1, $3]; } | variable T_AND_EQUAL expr { $$ = Expr\AssignOp\BitwiseAnd[$1, $3]; } | variable T_OR_EQUAL expr { $$ = Expr\AssignOp\BitwiseOr [$1, $3]; } | variable T_XOR_EQUAL expr { $$ = Expr\AssignOp\BitwiseXor[$1, $3]; } | variable T_SL_EQUAL expr { $$ = Expr\AssignOp\ShiftLeft [$1, $3]; } | variable T_SR_EQUAL expr { $$ = Expr\AssignOp\ShiftRight[$1, $3]; } | variable T_POW_EQUAL expr { $$ = Expr\AssignOp\Pow [$1, $3]; } | variable T_INC { $$ = Expr\PostInc[$1]; } | T_INC variable { $$ = Expr\PreInc [$2]; } | variable T_DEC { $$ = Expr\PostDec[$1]; } | T_DEC variable { $$ = Expr\PreDec [$2]; } | expr T_BOOLEAN_OR expr { $$ = Expr\BinaryOp\BooleanOr [$1, $3]; } | expr T_BOOLEAN_AND expr { $$ = Expr\BinaryOp\BooleanAnd[$1, $3]; } | expr T_LOGICAL_OR expr { $$ = Expr\BinaryOp\LogicalOr [$1, $3]; } | expr T_LOGICAL_AND expr { $$ = Expr\BinaryOp\LogicalAnd[$1, $3]; } | expr T_LOGICAL_XOR expr { $$ = Expr\BinaryOp\LogicalXor[$1, $3]; } | expr '|' expr { $$ = Expr\BinaryOp\BitwiseOr [$1, $3]; } | expr '&' expr { $$ = Expr\BinaryOp\BitwiseAnd[$1, $3]; } | expr '^' expr { $$ = Expr\BinaryOp\BitwiseXor[$1, $3]; } | expr '.' expr { $$ = Expr\BinaryOp\Concat [$1, $3]; } | expr '+' expr { $$ = Expr\BinaryOp\Plus [$1, $3]; } | expr '-' expr { $$ = Expr\BinaryOp\Minus [$1, $3]; } | expr '*' expr { $$ = Expr\BinaryOp\Mul [$1, $3]; } | expr '/' expr { $$ = Expr\BinaryOp\Div [$1, $3]; } | expr '%' expr { $$ = Expr\BinaryOp\Mod [$1, $3]; } | expr T_SL expr { $$ = Expr\BinaryOp\ShiftLeft [$1, $3]; } | expr T_SR expr { $$ = Expr\BinaryOp\ShiftRight[$1, $3]; } | expr T_POW expr { $$ = Expr\BinaryOp\Pow [$1, $3]; } | '+' expr %prec T_INC { $$ = Expr\UnaryPlus [$2]; } | '-' expr %prec T_INC { $$ = Expr\UnaryMinus[$2]; } | '!' expr { $$ = Expr\BooleanNot[$2]; } | '~' expr { $$ = Expr\BitwiseNot[$2]; } | expr T_IS_IDENTICAL expr { $$ = Expr\BinaryOp\Identical [$1, $3]; } | expr T_IS_NOT_IDENTICAL expr { $$ = Expr\BinaryOp\NotIdentical [$1, $3]; } | expr T_IS_EQUAL expr { $$ = Expr\BinaryOp\Equal [$1, $3]; } | expr T_IS_NOT_EQUAL expr { $$ = Expr\BinaryOp\NotEqual [$1, $3]; } | expr T_SPACESHIP expr { $$ = Expr\BinaryOp\Spaceship [$1, $3]; } | expr '<' expr { $$ = Expr\BinaryOp\Smaller [$1, $3]; } | expr T_IS_SMALLER_OR_EQUAL expr { $$ = Expr\BinaryOp\SmallerOrEqual[$1, $3]; } | expr '>' expr { $$ = Expr\BinaryOp\Greater [$1, $3]; } | expr T_IS_GREATER_OR_EQUAL expr { $$ = Expr\BinaryOp\GreaterOrEqual[$1, $3]; } | expr T_INSTANCEOF class_name_reference { $$ = Expr\Instanceof_[$1, $3]; } | '(' expr ')' { $$ = $2; } | expr '?' expr ':' expr { $$ = Expr\Ternary[$1, $3, $5]; } | expr '?' ':' expr { $$ = Expr\Ternary[$1, null, $4]; } | expr T_COALESCE expr { $$ = Expr\BinaryOp\Coalesce[$1, $3]; } | T_ISSET '(' variables_list ')' { $$ = Expr\Isset_[$3]; } | T_EMPTY '(' expr ')' { $$ = Expr\Empty_[$3]; } | T_INCLUDE expr { $$ = Expr\Include_[$2, Expr\Include_::TYPE_INCLUDE]; } | T_INCLUDE_ONCE expr { $$ = Expr\Include_[$2, Expr\Include_::TYPE_INCLUDE_ONCE]; } | T_EVAL '(' expr ')' { $$ = Expr\Eval_[$3]; } | T_REQUIRE expr { $$ = Expr\Include_[$2, Expr\Include_::TYPE_REQUIRE]; } | T_REQUIRE_ONCE expr { $$ = Expr\Include_[$2, Expr\Include_::TYPE_REQUIRE_ONCE]; } | T_INT_CAST expr { $$ = Expr\Cast\Int_ [$2]; } | T_DOUBLE_CAST expr { $$ = Expr\Cast\Double [$2]; } | T_STRING_CAST expr { $$ = Expr\Cast\String_ [$2]; } | T_ARRAY_CAST expr { $$ = Expr\Cast\Array_ [$2]; } | T_OBJECT_CAST expr { $$ = Expr\Cast\Object_ [$2]; } | T_BOOL_CAST expr { $$ = Expr\Cast\Bool_ [$2]; } | T_UNSET_CAST expr { $$ = Expr\Cast\Unset_ [$2]; } | T_EXIT exit_expr { $attrs = attributes(); $attrs['kind'] = strtolower($1) === 'exit' ? Expr\Exit_::KIND_EXIT : Expr\Exit_::KIND_DIE; $$ = new Expr\Exit_($2, $attrs); } | '@' expr { $$ = Expr\ErrorSuppress[$2]; } | scalar { $$ = $1; } | '`' backticks_expr '`' { $$ = Expr\ShellExec[$2]; } | T_PRINT expr { $$ = Expr\Print_[$2]; } | T_YIELD { $$ = Expr\Yield_[null, null]; } | T_YIELD expr { $$ = Expr\Yield_[$2, null]; } | T_YIELD expr T_DOUBLE_ARROW expr { $$ = Expr\Yield_[$4, $2]; } | T_YIELD_FROM expr { $$ = Expr\YieldFrom[$2]; } | T_FUNCTION optional_ref '(' parameter_list ')' lexical_vars optional_return_type '{' inner_statement_list '}' { $$ = Expr\Closure[['static' => false, 'byRef' => $2, 'params' => $4, 'uses' => $6, 'returnType' => $7, 'stmts' => $9]]; } | T_STATIC T_FUNCTION optional_ref '(' parameter_list ')' lexical_vars optional_return_type '{' inner_statement_list '}' { $$ = Expr\Closure[['static' => true, 'byRef' => $3, 'params' => $5, 'uses' => $7, 'returnType' => $8, 'stmts' => $10]]; } ; anonymous_class: T_CLASS ctor_arguments extends_from implements_list '{' class_statement_list '}' { $$ = array(Stmt\Class_[null, ['type' => 0, 'extends' => $3, 'implements' => $4, 'stmts' => $6]], $2); $this->checkClass($$[0], -1); } new_expr: T_NEW class_name_reference ctor_arguments { $$ = Expr\New_[$2, $3]; } | T_NEW anonymous_class { list($class, $ctorArgs) = $2; $$ = Expr\New_[$class, $ctorArgs]; } ; lexical_vars: /* empty */ { $$ = array(); } | T_USE '(' lexical_var_list ')' { $$ = $3; } ; lexical_var_list: non_empty_lexical_var_list no_comma { $$ = $1; } ; non_empty_lexical_var_list: lexical_var { init($1); } | non_empty_lexical_var_list ',' lexical_var { push($1, $3); } ; lexical_var: optional_ref T_VARIABLE { $$ = Expr\ClosureUse[parseVar($2), $1]; } ; function_call: name argument_list { $$ = Expr\FuncCall[$1, $2]; } | callable_expr argument_list { $$ = Expr\FuncCall[$1, $2]; } | class_name_or_var T_PAAMAYIM_NEKUDOTAYIM member_name argument_list { $$ = Expr\StaticCall[$1, $3, $4]; } ; class_name: T_STATIC { $$ = Name[$1]; } | name { $$ = $1; } ; name: namespace_name_parts { $$ = Name[$1]; } | T_NS_SEPARATOR namespace_name_parts { $$ = Name\FullyQualified[$2]; } | T_NAMESPACE T_NS_SEPARATOR namespace_name_parts { $$ = Name\Relative[$3]; } ; class_name_reference: class_name { $$ = $1; } | new_variable { $$ = $1; } | error { $$ = Expr\Error[]; $this->errorState = 2; } ; class_name_or_var: class_name { $$ = $1; } | dereferencable { $$ = $1; } ; exit_expr: /* empty */ { $$ = null; } | '(' optional_expr ')' { $$ = $2; } ; backticks_expr: /* empty */ { $$ = array(); } | T_ENCAPSED_AND_WHITESPACE { $$ = array(Scalar\EncapsedStringPart[Scalar\String_::parseEscapeSequences($1, '`')]); } | encaps_list { parseEncapsed($1, '`', true); $$ = $1; } ; ctor_arguments: /* empty */ { $$ = array(); } | argument_list { $$ = $1; } ; constant: name { $$ = Expr\ConstFetch[$1]; } | class_name_or_var T_PAAMAYIM_NEKUDOTAYIM identifier { $$ = Expr\ClassConstFetch[$1, $3]; } /* We interpret and isolated FOO:: as an unfinished class constant fetch. It could also be an unfinished static property fetch or unfinished scoped call. */ | class_name_or_var T_PAAMAYIM_NEKUDOTAYIM error { $$ = Expr\ClassConstFetch[$1, new Expr\Error(stackAttributes(#3))]; $this->errorState = 2; } ; array_short_syntax: '[' array_pair_list ']' { $attrs = attributes(); $attrs['kind'] = Expr\Array_::KIND_SHORT; $$ = new Expr\Array_($2, $attrs); } ; dereferencable_scalar: T_ARRAY '(' array_pair_list ')' { $attrs = attributes(); $attrs['kind'] = Expr\Array_::KIND_LONG; $$ = new Expr\Array_($3, $attrs); } | array_short_syntax { $$ = $1; } | T_CONSTANT_ENCAPSED_STRING { $attrs = attributes(); $attrs['kind'] = strKind($1); $$ = new Scalar\String_(Scalar\String_::parse($1), $attrs); } ; scalar: T_LNUMBER { $$ = $this->parseLNumber($1, attributes()); } | T_DNUMBER { $$ = Scalar\DNumber[Scalar\DNumber::parse($1)]; } | T_LINE { $$ = Scalar\MagicConst\Line[]; } | T_FILE { $$ = Scalar\MagicConst\File[]; } | T_DIR { $$ = Scalar\MagicConst\Dir[]; } | T_CLASS_C { $$ = Scalar\MagicConst\Class_[]; } | T_TRAIT_C { $$ = Scalar\MagicConst\Trait_[]; } | T_METHOD_C { $$ = Scalar\MagicConst\Method[]; } | T_FUNC_C { $$ = Scalar\MagicConst\Function_[]; } | T_NS_C { $$ = Scalar\MagicConst\Namespace_[]; } | dereferencable_scalar { $$ = $1; } | constant { $$ = $1; } | T_START_HEREDOC T_ENCAPSED_AND_WHITESPACE T_END_HEREDOC { $attrs = attributes(); setDocStringAttrs($attrs, $1); $$ = new Scalar\String_(Scalar\String_::parseDocString($1, $2), $attrs); } | T_START_HEREDOC T_END_HEREDOC { $attrs = attributes(); setDocStringAttrs($attrs, $1); $$ = new Scalar\String_('', $attrs); } | '"' encaps_list '"' { $attrs = attributes(); $attrs['kind'] = Scalar\String_::KIND_DOUBLE_QUOTED; parseEncapsed($2, '"', true); $$ = new Scalar\Encapsed($2, $attrs); } | T_START_HEREDOC encaps_list T_END_HEREDOC { $attrs = attributes(); setDocStringAttrs($attrs, $1); parseEncapsedDoc($2, true); $$ = new Scalar\Encapsed($2, $attrs); } ; optional_expr: /* empty */ { $$ = null; } | expr { $$ = $1; } ; dereferencable: variable { $$ = $1; } | '(' expr ')' { $$ = $2; } | dereferencable_scalar { $$ = $1; } ; callable_expr: callable_variable { $$ = $1; } | '(' expr ')' { $$ = $2; } | dereferencable_scalar { $$ = $1; } ; callable_variable: simple_variable { $$ = Expr\Variable[$1]; } | dereferencable '[' optional_expr ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } | constant '[' optional_expr ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } | dereferencable '{' expr '}' { $$ = Expr\ArrayDimFetch[$1, $3]; } | function_call { $$ = $1; } | dereferencable T_OBJECT_OPERATOR property_name argument_list { $$ = Expr\MethodCall[$1, $3, $4]; } ; variable: callable_variable { $$ = $1; } | static_member { $$ = $1; } | dereferencable T_OBJECT_OPERATOR property_name { $$ = Expr\PropertyFetch[$1, $3]; } ; simple_variable: T_VARIABLE { $$ = parseVar($1); } | '$' '{' expr '}' { $$ = $3; } | '$' simple_variable { $$ = Expr\Variable[$2]; } | '$' error { $$ = Expr\Error[]; $this->errorState = 2; } ; static_member: class_name_or_var T_PAAMAYIM_NEKUDOTAYIM simple_variable { $$ = Expr\StaticPropertyFetch[$1, $3]; } ; new_variable: simple_variable { $$ = Expr\Variable[$1]; } | new_variable '[' optional_expr ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } | new_variable '{' expr '}' { $$ = Expr\ArrayDimFetch[$1, $3]; } | new_variable T_OBJECT_OPERATOR property_name { $$ = Expr\PropertyFetch[$1, $3]; } | class_name T_PAAMAYIM_NEKUDOTAYIM simple_variable { $$ = Expr\StaticPropertyFetch[$1, $3]; } | new_variable T_PAAMAYIM_NEKUDOTAYIM simple_variable { $$ = Expr\StaticPropertyFetch[$1, $3]; } ; member_name: identifier { $$ = $1; } | '{' expr '}' { $$ = $2; } | simple_variable { $$ = Expr\Variable[$1]; } ; property_name: T_STRING { $$ = $1; } | '{' expr '}' { $$ = $2; } | simple_variable { $$ = Expr\Variable[$1]; } | error { $$ = Expr\Error[]; $this->errorState = 2; } ; list_expr: T_LIST '(' list_expr_elements ')' { $$ = Expr\List_[$3]; } ; list_expr_elements: list_expr_elements ',' list_expr_element { push($1, $3); } | list_expr_element { init($1); } ; list_expr_element: variable { $$ = Expr\ArrayItem[$1, null, false]; } | list_expr { $$ = Expr\ArrayItem[$1, null, false]; } | expr T_DOUBLE_ARROW variable { $$ = Expr\ArrayItem[$3, $1, false]; } | expr T_DOUBLE_ARROW list_expr { $$ = Expr\ArrayItem[$3, $1, false]; } | /* empty */ { $$ = null; } ; array_pair_list: inner_array_pair_list { $$ = $1; $end = count($$)-1; if ($$[$end] === null) unset($$[$end]); } ; inner_array_pair_list: inner_array_pair_list ',' array_pair { push($1, $3); } | array_pair { init($1); } ; array_pair: expr T_DOUBLE_ARROW expr { $$ = Expr\ArrayItem[$3, $1, false]; } | expr { $$ = Expr\ArrayItem[$1, null, false]; } | expr T_DOUBLE_ARROW '&' variable { $$ = Expr\ArrayItem[$4, $1, true]; } | '&' variable { $$ = Expr\ArrayItem[$2, null, true]; } | /* empty */ { $$ = null; } ; encaps_list: encaps_list encaps_var { push($1, $2); } | encaps_list encaps_string_part { push($1, $2); } | encaps_var { init($1); } | encaps_string_part encaps_var { init($1, $2); } ; encaps_string_part: T_ENCAPSED_AND_WHITESPACE { $$ = Scalar\EncapsedStringPart[$1]; } ; encaps_base_var: T_VARIABLE { $$ = Expr\Variable[parseVar($1)]; } ; encaps_var: encaps_base_var { $$ = $1; } | encaps_base_var '[' encaps_var_offset ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } | encaps_base_var T_OBJECT_OPERATOR T_STRING { $$ = Expr\PropertyFetch[$1, $3]; } | T_DOLLAR_OPEN_CURLY_BRACES expr '}' { $$ = Expr\Variable[$2]; } | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '}' { $$ = Expr\Variable[$2]; } | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '[' expr ']' '}' { $$ = Expr\ArrayDimFetch[Expr\Variable[$2], $4]; } | T_CURLY_OPEN variable '}' { $$ = $2; } ; encaps_var_offset: T_STRING { $$ = Scalar\String_[$1]; } | T_NUM_STRING { $$ = $this->parseNumString($1, attributes()); } | '-' T_NUM_STRING { $$ = $this->parseNumString('-' . $2, attributes()); } | T_VARIABLE { $$ = Expr\Variable[parseVar($1)]; } ; %% PHP-Parser-3.1.4/grammar/rebuildParsers.php000066400000000000000000000212751323244626500205430ustar00rootroot00000000000000 'Php5', __DIR__ . '/php7.y' => 'Php7', ]; $tokensFile = __DIR__ . '/tokens.y'; $tokensTemplate = __DIR__ . '/tokens.template'; $skeletonFile = __DIR__ . '/parser.template'; $tmpGrammarFile = __DIR__ . '/tmp_parser.phpy'; $tmpResultFile = __DIR__ . '/tmp_parser.php'; $resultDir = __DIR__ . '/../lib/PhpParser/Parser'; $tokensResultsFile = $resultDir . '/Tokens.php'; // check for kmyacc.exe binary in this directory, otherwise fall back to global name $kmyacc = __DIR__ . '/kmyacc.exe'; if (!file_exists($kmyacc)) { $kmyacc = 'kmyacc'; } $options = array_flip($argv); $optionDebug = isset($options['--debug']); $optionKeepTmpGrammar = isset($options['--keep-tmp-grammar']); /////////////////////////////// /// Utility regex constants /// /////////////////////////////// const LIB = '(?(DEFINE) (?\'[^\\\\\']*+(?:\\\\.[^\\\\\']*+)*+\') (?"[^\\\\"]*+(?:\\\\.[^\\\\"]*+)*+") (?(?&singleQuotedString)|(?&doubleQuotedString)) (?/\*[^*]*+(?:\*(?!/)[^*]*+)*+\*/) (?\{[^\'"/{}]*+(?:(?:(?&string)|(?&comment)|(?&code)|/)[^\'"/{}]*+)*+}) )'; const PARAMS = '\[(?[^[\]]*+(?:\[(?¶ms)\][^[\]]*+)*+)\]'; const ARGS = '\((?[^()]*+(?:\((?&args)\)[^()]*+)*+)\)'; /////////////////// /// Main script /// /////////////////// $tokens = file_get_contents($tokensFile); foreach ($grammarFileToName as $grammarFile => $name) { echo "Building temporary $name grammar file.\n"; $grammarCode = file_get_contents($grammarFile); $grammarCode = str_replace('%tokens', $tokens, $grammarCode); $grammarCode = resolveNodes($grammarCode); $grammarCode = resolveMacros($grammarCode); $grammarCode = resolveStackAccess($grammarCode); file_put_contents($tmpGrammarFile, $grammarCode); $additionalArgs = $optionDebug ? '-t -v' : ''; echo "Building $name parser.\n"; $output = trim(shell_exec("$kmyacc $additionalArgs -l -m $skeletonFile -p $name $tmpGrammarFile 2>&1")); echo "Output: \"$output\"\n"; $resultCode = file_get_contents($tmpResultFile); $resultCode = removeTrailingWhitespace($resultCode); ensureDirExists($resultDir); file_put_contents("$resultDir/$name.php", $resultCode); unlink($tmpResultFile); echo "Building token definition.\n"; $output = trim(shell_exec("$kmyacc -l -m $tokensTemplate $tmpGrammarFile 2>&1")); assert($output === ''); rename($tmpResultFile, $tokensResultsFile); if (!$optionKeepTmpGrammar) { unlink($tmpGrammarFile); } } /////////////////////////////// /// Preprocessing functions /// /////////////////////////////// function resolveNodes($code) { return preg_replace_callback( '~\b(?[A-Z][a-zA-Z_\\\\]++)\s*' . PARAMS . '~', function($matches) { // recurse $matches['params'] = resolveNodes($matches['params']); $params = magicSplit( '(?:' . PARAMS . '|' . ARGS . ')(*SKIP)(*FAIL)|,', $matches['params'] ); $paramCode = ''; foreach ($params as $param) { $paramCode .= $param . ', '; } return 'new ' . $matches['name'] . '(' . $paramCode . 'attributes())'; }, $code ); } function resolveMacros($code) { return preg_replace_callback( '~\b(?)(?!array\()(?[a-z][A-Za-z]++)' . ARGS . '~', function($matches) { // recurse $matches['args'] = resolveMacros($matches['args']); $name = $matches['name']; $args = magicSplit( '(?:' . PARAMS . '|' . ARGS . ')(*SKIP)(*FAIL)|,', $matches['args'] ); if ('attributes' == $name) { assertArgs(0, $args, $name); return '$this->startAttributeStack[#1] + $this->endAttributes'; } if ('stackAttributes' == $name) { assertArgs(1, $args, $name); return '$this->startAttributeStack[' . $args[0] . ']' . ' + $this->endAttributeStack[' . $args[0] . ']'; } if ('init' == $name) { return '$$ = array(' . implode(', ', $args) . ')'; } if ('push' == $name) { assertArgs(2, $args, $name); return $args[0] . '[] = ' . $args[1] . '; $$ = ' . $args[0]; } if ('pushNormalizing' == $name) { assertArgs(2, $args, $name); return 'if (is_array(' . $args[1] . ')) { $$ = array_merge(' . $args[0] . ', ' . $args[1] . '); }' . ' else { ' . $args[0] . '[] = ' . $args[1] . '; $$ = ' . $args[0] . '; }'; } if ('toArray' == $name) { assertArgs(1, $args, $name); return 'is_array(' . $args[0] . ') ? ' . $args[0] . ' : array(' . $args[0] . ')'; } if ('parseVar' == $name) { assertArgs(1, $args, $name); return 'substr(' . $args[0] . ', 1)'; } if ('parseEncapsed' == $name) { assertArgs(3, $args, $name); return 'foreach (' . $args[0] . ' as $s) { if ($s instanceof Node\Scalar\EncapsedStringPart) {' . ' $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, ' . $args[1] . ', ' . $args[2] . '); } }'; } if ('parseEncapsedDoc' == $name) { assertArgs(2, $args, $name); return 'foreach (' . $args[0] . ' as $s) { if ($s instanceof Node\Scalar\EncapsedStringPart) {' . ' $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, null, ' . $args[1] . '); } }' . ' $s->value = preg_replace(\'~(\r\n|\n|\r)\z~\', \'\', $s->value);' . ' if (\'\' === $s->value) array_pop(' . $args[0] . ');'; } if ('makeNop' == $name) { assertArgs(2, $args, $name); return '$startAttributes = ' . $args[1] . ';' . ' if (isset($startAttributes[\'comments\']))' . ' { ' . $args[0] . ' = new Stmt\Nop([\'comments\' => $startAttributes[\'comments\']]); }' . ' else { ' . $args[0] . ' = null; }'; } if ('strKind' == $name) { assertArgs(1, $args, $name); return '(' . $args[0] . '[0] === "\'" || (' . $args[0] . '[1] === "\'" && ' . '(' . $args[0] . '[0] === \'b\' || ' . $args[0] . '[0] === \'B\')) ' . '? Scalar\String_::KIND_SINGLE_QUOTED : Scalar\String_::KIND_DOUBLE_QUOTED)'; } if ('setDocStringAttrs' == $name) { assertArgs(2, $args, $name); return $args[0] . '[\'kind\'] = strpos(' . $args[1] . ', "\'") === false ' . '? Scalar\String_::KIND_HEREDOC : Scalar\String_::KIND_NOWDOC; ' . 'preg_match(\'/\A[bB]?<<<[ \t]*[\\\'"]?([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)[\\\'"]?(?:\r\n|\n|\r)\z/\', ' . $args[1] . ', $matches); ' . $args[0] . '[\'docLabel\'] = $matches[1];'; } if ('prependLeadingComments' == $name) { assertArgs(1, $args, $name); return '$attrs = $this->startAttributeStack[#1]; $stmts = ' . $args[0] . '; ' . 'if (!empty($attrs[\'comments\'])) {' . '$stmts[0]->setAttribute(\'comments\', ' . 'array_merge($attrs[\'comments\'], $stmts[0]->getAttribute(\'comments\', []))); }'; } return $matches[0]; }, $code ); } function assertArgs($num, $args, $name) { if ($num != count($args)) { die('Wrong argument count for ' . $name . '().'); } } function resolveStackAccess($code) { $code = preg_replace('/\$\d+/', '$this->semStack[$0]', $code); $code = preg_replace('/#(\d+)/', '$$1', $code); return $code; } function removeTrailingWhitespace($code) { $lines = explode("\n", $code); $lines = array_map('rtrim', $lines); return implode("\n", $lines); } function ensureDirExists($dir) { if (!is_dir($dir)) { mkdir($dir, 0777, true); } } ////////////////////////////// /// Regex helper functions /// ////////////////////////////// function regex($regex) { return '~' . LIB . '(?:' . str_replace('~', '\~', $regex) . ')~'; } function magicSplit($regex, $string) { $pieces = preg_split(regex('(?:(?&string)|(?&comment)|(?&code))(*SKIP)(*FAIL)|' . $regex), $string); foreach ($pieces as &$piece) { $piece = trim($piece); } if ($pieces === ['']) { return []; } return $pieces; } PHP-Parser-3.1.4/grammar/tokens.template000066400000000000000000000004521323244626500200760ustar00rootroot00000000000000semValue #semval($,%t) $this->semValue #semval(%n) $this->stackPos-(%l-%n) #semval(%n,%t) $this->stackPos-(%l-%n) namespace PhpParser\Parser; #include; /* GENERATED file based on grammar/tokens.y */ final class Tokens { #tokenval const %s = %n; #endtokenval } PHP-Parser-3.1.4/grammar/tokens.y000066400000000000000000000047661323244626500165470ustar00rootroot00000000000000/* We currently rely on the token ID mapping to be the same between PHP 5 and PHP 7 - so the same lexer can be used for * both. This is enforced by sharing this token file. */ %left T_INCLUDE T_INCLUDE_ONCE T_EVAL T_REQUIRE T_REQUIRE_ONCE %left ',' %left T_LOGICAL_OR %left T_LOGICAL_XOR %left T_LOGICAL_AND %right T_PRINT %right T_YIELD %right T_DOUBLE_ARROW %right T_YIELD_FROM %left '=' T_PLUS_EQUAL T_MINUS_EQUAL T_MUL_EQUAL T_DIV_EQUAL T_CONCAT_EQUAL T_MOD_EQUAL T_AND_EQUAL T_OR_EQUAL T_XOR_EQUAL T_SL_EQUAL T_SR_EQUAL T_POW_EQUAL %left '?' ':' %right T_COALESCE %left T_BOOLEAN_OR %left T_BOOLEAN_AND %left '|' %left '^' %left '&' %nonassoc T_IS_EQUAL T_IS_NOT_EQUAL T_IS_IDENTICAL T_IS_NOT_IDENTICAL T_SPACESHIP %nonassoc '<' T_IS_SMALLER_OR_EQUAL '>' T_IS_GREATER_OR_EQUAL %left T_SL T_SR %left '+' '-' '.' %left '*' '/' '%' %right '!' %nonassoc T_INSTANCEOF %right '~' T_INC T_DEC T_INT_CAST T_DOUBLE_CAST T_STRING_CAST T_ARRAY_CAST T_OBJECT_CAST T_BOOL_CAST T_UNSET_CAST '@' %right T_POW %right '[' %nonassoc T_NEW T_CLONE %token T_EXIT %token T_IF %left T_ELSEIF %left T_ELSE %left T_ENDIF %token T_LNUMBER %token T_DNUMBER %token T_STRING %token T_STRING_VARNAME %token T_VARIABLE %token T_NUM_STRING %token T_INLINE_HTML %token T_CHARACTER %token T_BAD_CHARACTER %token T_ENCAPSED_AND_WHITESPACE %token T_CONSTANT_ENCAPSED_STRING %token T_ECHO %token T_DO %token T_WHILE %token T_ENDWHILE %token T_FOR %token T_ENDFOR %token T_FOREACH %token T_ENDFOREACH %token T_DECLARE %token T_ENDDECLARE %token T_AS %token T_SWITCH %token T_ENDSWITCH %token T_CASE %token T_DEFAULT %token T_BREAK %token T_CONTINUE %token T_GOTO %token T_FUNCTION %token T_CONST %token T_RETURN %token T_TRY %token T_CATCH %token T_FINALLY %token T_THROW %token T_USE %token T_INSTEADOF %token T_GLOBAL %right T_STATIC T_ABSTRACT T_FINAL T_PRIVATE T_PROTECTED T_PUBLIC %token T_VAR %token T_UNSET %token T_ISSET %token T_EMPTY %token T_HALT_COMPILER %token T_CLASS %token T_TRAIT %token T_INTERFACE %token T_EXTENDS %token T_IMPLEMENTS %token T_OBJECT_OPERATOR %token T_DOUBLE_ARROW %token T_LIST %token T_ARRAY %token T_CALLABLE %token T_CLASS_C %token T_TRAIT_C %token T_METHOD_C %token T_FUNC_C %token T_LINE %token T_FILE %token T_COMMENT %token T_DOC_COMMENT %token T_OPEN_TAG %token T_OPEN_TAG_WITH_ECHO %token T_CLOSE_TAG %token T_WHITESPACE %token T_START_HEREDOC %token T_END_HEREDOC %token T_DOLLAR_OPEN_CURLY_BRACES %token T_CURLY_OPEN %token T_PAAMAYIM_NEKUDOTAYIM %token T_NAMESPACE %token T_NS_C %token T_DIR %token T_NS_SEPARATOR %token T_ELLIPSIS PHP-Parser-3.1.4/lib/000077500000000000000000000000001323244626500141555ustar00rootroot00000000000000PHP-Parser-3.1.4/lib/PhpParser/000077500000000000000000000000001323244626500160615ustar00rootroot00000000000000PHP-Parser-3.1.4/lib/PhpParser/Autoloader.php000066400000000000000000000017341323244626500206760ustar00rootroot00000000000000name = $name; } /** * Extends a class. * * @param Name|string $class Name of class to extend * * @return $this The builder instance (for fluid interface) */ public function extend($class) { $this->extends = $this->normalizeName($class); return $this; } /** * Implements one or more interfaces. * * @param Name|string ...$interfaces Names of interfaces to implement * * @return $this The builder instance (for fluid interface) */ public function implement() { foreach (func_get_args() as $interface) { $this->implements[] = $this->normalizeName($interface); } return $this; } /** * Makes the class abstract. * * @return $this The builder instance (for fluid interface) */ public function makeAbstract() { $this->setModifier(Stmt\Class_::MODIFIER_ABSTRACT); return $this; } /** * Makes the class final. * * @return $this The builder instance (for fluid interface) */ public function makeFinal() { $this->setModifier(Stmt\Class_::MODIFIER_FINAL); return $this; } /** * Adds a statement. * * @param Stmt|PhpParser\Builder $stmt The statement to add * * @return $this The builder instance (for fluid interface) */ public function addStmt($stmt) { $stmt = $this->normalizeNode($stmt); $targets = array( 'Stmt_TraitUse' => &$this->uses, 'Stmt_ClassConst' => &$this->constants, 'Stmt_Property' => &$this->properties, 'Stmt_ClassMethod' => &$this->methods, ); $type = $stmt->getType(); if (!isset($targets[$type])) { throw new \LogicException(sprintf('Unexpected node of type "%s"', $type)); } $targets[$type][] = $stmt; return $this; } /** * Returns the built class node. * * @return Stmt\Class_ The built class node */ public function getNode() { return new Stmt\Class_($this->name, array( 'flags' => $this->flags, 'extends' => $this->extends, 'implements' => $this->implements, 'stmts' => array_merge($this->uses, $this->constants, $this->properties, $this->methods), ), $this->attributes); } }PHP-Parser-3.1.4/lib/PhpParser/Builder/Declaration.php000066400000000000000000000016461323244626500224140ustar00rootroot00000000000000addStmt($stmt); } return $this; } /** * Sets doc comment for the declaration. * * @param PhpParser\Comment\Doc|string $docComment Doc comment to set * * @return $this The builder instance (for fluid interface) */ public function setDocComment($docComment) { $this->attributes['comments'] = array( $this->normalizeDocComment($docComment) ); return $this; } }PHP-Parser-3.1.4/lib/PhpParser/Builder/FunctionLike.php000066400000000000000000000034051323244626500225540ustar00rootroot00000000000000returnByRef = true; return $this; } /** * Adds a parameter. * * @param Node\Param|Param $param The parameter to add * * @return $this The builder instance (for fluid interface) */ public function addParam($param) { $param = $this->normalizeNode($param); if (!$param instanceof Node\Param) { throw new \LogicException(sprintf('Expected parameter node, got "%s"', $param->getType())); } $this->params[] = $param; return $this; } /** * Adds multiple parameters. * * @param array $params The parameters to add * * @return $this The builder instance (for fluid interface) */ public function addParams(array $params) { foreach ($params as $param) { $this->addParam($param); } return $this; } /** * Sets the return type for PHP 7. * * @param string|Node\Name|Node\NullableType $type One of array, callable, string, int, float, bool, iterable, * or a class/interface name. * * @return $this The builder instance (for fluid interface) */ public function setReturnType($type) { $this->returnType = $this->normalizeType($type); return $this; } } PHP-Parser-3.1.4/lib/PhpParser/Builder/Function_.php000066400000000000000000000021141323244626500221020ustar00rootroot00000000000000name = $name; } /** * Adds a statement. * * @param Node|PhpParser\Builder $stmt The statement to add * * @return $this The builder instance (for fluid interface) */ public function addStmt($stmt) { $this->stmts[] = $this->normalizeNode($stmt); return $this; } /** * Returns the built function node. * * @return Stmt\Function_ The built function node */ public function getNode() { return new Stmt\Function_($this->name, array( 'byRef' => $this->returnByRef, 'params' => $this->params, 'returnType' => $this->returnType, 'stmts' => $this->stmts, ), $this->attributes); } } PHP-Parser-3.1.4/lib/PhpParser/Builder/Interface_.php000066400000000000000000000037171323244626500222270ustar00rootroot00000000000000name = $name; } /** * Extends one or more interfaces. * * @param Name|string ...$interfaces Names of interfaces to extend * * @return $this The builder instance (for fluid interface) */ public function extend() { foreach (func_get_args() as $interface) { $this->extends[] = $this->normalizeName($interface); } return $this; } /** * Adds a statement. * * @param Stmt|PhpParser\Builder $stmt The statement to add * * @return $this The builder instance (for fluid interface) */ public function addStmt($stmt) { $stmt = $this->normalizeNode($stmt); $type = $stmt->getType(); switch ($type) { case 'Stmt_ClassConst': $this->constants[] = $stmt; break; case 'Stmt_ClassMethod': // we erase all statements in the body of an interface method $stmt->stmts = null; $this->methods[] = $stmt; break; default: throw new \LogicException(sprintf('Unexpected node of type "%s"', $type)); } return $this; } /** * Returns the built interface node. * * @return Stmt\Interface_ The built interface node */ public function getNode() { return new Stmt\Interface_($this->name, array( 'extends' => $this->extends, 'stmts' => array_merge($this->constants, $this->methods), ), $this->attributes); } }PHP-Parser-3.1.4/lib/PhpParser/Builder/Method.php000066400000000000000000000056621323244626500214110ustar00rootroot00000000000000name = $name; } /** * Makes the method public. * * @return $this The builder instance (for fluid interface) */ public function makePublic() { $this->setModifier(Stmt\Class_::MODIFIER_PUBLIC); return $this; } /** * Makes the method protected. * * @return $this The builder instance (for fluid interface) */ public function makeProtected() { $this->setModifier(Stmt\Class_::MODIFIER_PROTECTED); return $this; } /** * Makes the method private. * * @return $this The builder instance (for fluid interface) */ public function makePrivate() { $this->setModifier(Stmt\Class_::MODIFIER_PRIVATE); return $this; } /** * Makes the method static. * * @return $this The builder instance (for fluid interface) */ public function makeStatic() { $this->setModifier(Stmt\Class_::MODIFIER_STATIC); return $this; } /** * Makes the method abstract. * * @return $this The builder instance (for fluid interface) */ public function makeAbstract() { if (!empty($this->stmts)) { throw new \LogicException('Cannot make method with statements abstract'); } $this->setModifier(Stmt\Class_::MODIFIER_ABSTRACT); $this->stmts = null; // abstract methods don't have statements return $this; } /** * Makes the method final. * * @return $this The builder instance (for fluid interface) */ public function makeFinal() { $this->setModifier(Stmt\Class_::MODIFIER_FINAL); return $this; } /** * Adds a statement. * * @param Node|PhpParser\Builder $stmt The statement to add * * @return $this The builder instance (for fluid interface) */ public function addStmt($stmt) { if (null === $this->stmts) { throw new \LogicException('Cannot add statements to an abstract method'); } $this->stmts[] = $this->normalizeNode($stmt); return $this; } /** * Returns the built method node. * * @return Stmt\ClassMethod The built method node */ public function getNode() { return new Stmt\ClassMethod($this->name, array( 'flags' => $this->flags, 'byRef' => $this->returnByRef, 'params' => $this->params, 'returnType' => $this->returnType, 'stmts' => $this->stmts, ), $this->attributes); } } PHP-Parser-3.1.4/lib/PhpParser/Builder/Namespace_.php000066400000000000000000000016641323244626500222220ustar00rootroot00000000000000name = null !== $name ? $this->normalizeName($name) : null; } /** * Adds a statement. * * @param Node|PhpParser\Builder $stmt The statement to add * * @return $this The builder instance (for fluid interface) */ public function addStmt($stmt) { $this->stmts[] = $this->normalizeNode($stmt); return $this; } /** * Returns the built node. * * @return Node The built node */ public function getNode() { return new Stmt\Namespace_($this->name, $this->stmts, $this->attributes); } } PHP-Parser-3.1.4/lib/PhpParser/Builder/Param.php000066400000000000000000000037341323244626500212270ustar00rootroot00000000000000name = $name; } /** * Sets default value for the parameter. * * @param mixed $value Default value to use * * @return $this The builder instance (for fluid interface) */ public function setDefault($value) { $this->default = $this->normalizeValue($value); return $this; } /** * Sets type hint for the parameter. * * @param string|Node\Name|Node\NullableType $type Type hint to use * * @return $this The builder instance (for fluid interface) */ public function setTypeHint($type) { $this->type = $this->normalizeType($type); if ($this->type === 'void') { throw new \LogicException('Parameter type cannot be void'); } return $this; } /** * Make the parameter accept the value by reference. * * @return $this The builder instance (for fluid interface) */ public function makeByRef() { $this->byRef = true; return $this; } /** * Make the parameter variadic * * @return $this The builder instance (for fluid interface) */ public function makeVariadic() { $this->variadic = true; return $this; } /** * Returns the built parameter node. * * @return Node\Param The built parameter node */ public function getNode() { return new Node\Param( $this->name, $this->default, $this->type, $this->byRef, $this->variadic ); } } PHP-Parser-3.1.4/lib/PhpParser/Builder/Property.php000066400000000000000000000047641323244626500220170ustar00rootroot00000000000000name = $name; } /** * Makes the property public. * * @return $this The builder instance (for fluid interface) */ public function makePublic() { $this->setModifier(Stmt\Class_::MODIFIER_PUBLIC); return $this; } /** * Makes the property protected. * * @return $this The builder instance (for fluid interface) */ public function makeProtected() { $this->setModifier(Stmt\Class_::MODIFIER_PROTECTED); return $this; } /** * Makes the property private. * * @return $this The builder instance (for fluid interface) */ public function makePrivate() { $this->setModifier(Stmt\Class_::MODIFIER_PRIVATE); return $this; } /** * Makes the property static. * * @return $this The builder instance (for fluid interface) */ public function makeStatic() { $this->setModifier(Stmt\Class_::MODIFIER_STATIC); return $this; } /** * Sets default value for the property. * * @param mixed $value Default value to use * * @return $this The builder instance (for fluid interface) */ public function setDefault($value) { $this->default = $this->normalizeValue($value); return $this; } /** * Sets doc comment for the property. * * @param PhpParser\Comment\Doc|string $docComment Doc comment to set * * @return $this The builder instance (for fluid interface) */ public function setDocComment($docComment) { $this->attributes = array( 'comments' => array($this->normalizeDocComment($docComment)) ); return $this; } /** * Returns the built class node. * * @return Stmt\Property The built property node */ public function getNode() { return new Stmt\Property( $this->flags !== 0 ? $this->flags : Stmt\Class_::MODIFIER_PUBLIC, array( new Stmt\PropertyProperty($this->name, $this->default) ), $this->attributes ); } }PHP-Parser-3.1.4/lib/PhpParser/Builder/Trait_.php000066400000000000000000000026641323244626500214120ustar00rootroot00000000000000name = $name; } /** * Adds a statement. * * @param Stmt|PhpParser\Builder $stmt The statement to add * * @return $this The builder instance (for fluid interface) */ public function addStmt($stmt) { $stmt = $this->normalizeNode($stmt); if ($stmt instanceof Stmt\Property) { $this->properties[] = $stmt; } else if ($stmt instanceof Stmt\ClassMethod) { $this->methods[] = $stmt; } else if ($stmt instanceof Stmt\TraitUse) { $this->uses[] = $stmt; } else { throw new \LogicException(sprintf('Unexpected node of type "%s"', $stmt->getType())); } return $this; } /** * Returns the built trait node. * * @return Stmt\Trait_ The built interface node */ public function getNode() { return new Stmt\Trait_( $this->name, array( 'stmts' => array_merge($this->uses, $this->properties, $this->methods) ), $this->attributes ); } } PHP-Parser-3.1.4/lib/PhpParser/Builder/Use_.php000066400000000000000000000030331323244626500210520ustar00rootroot00000000000000name = $this->normalizeName($name); $this->type = $type; } /** * Sets alias for used name. * * @param string $alias Alias to use (last component of full name by default) * * @return $this The builder instance (for fluid interface) */ protected function as_($alias) { $this->alias = $alias; return $this; } public function __call($name, $args) { if (method_exists($this, $name . '_')) { return call_user_func_array(array($this, $name . '_'), $args); } throw new \LogicException(sprintf('Method "%s" does not exist', $name)); } /** * Returns the built node. * * @return Node The built node */ public function getNode() { $alias = null !== $this->alias ? $this->alias : $this->name->getLast(); return new Stmt\Use_(array( new Stmt\UseUse($this->name, $alias) ), $this->type); } } PHP-Parser-3.1.4/lib/PhpParser/BuilderAbstract.php000066400000000000000000000130001323244626500216360ustar00rootroot00000000000000getNode(); } elseif ($node instanceof Node) { return $node; } throw new \LogicException('Expected node or builder object'); } /** * Normalizes a name: Converts plain string names to PhpParser\Node\Name. * * @param Name|string $name The name to normalize * * @return Name The normalized name */ protected function normalizeName($name) { if ($name instanceof Name) { return $name; } elseif (is_string($name)) { if (!$name) { throw new \LogicException('Name cannot be empty'); } if ($name[0] == '\\') { return new Name\FullyQualified(substr($name, 1)); } elseif (0 === strpos($name, 'namespace\\')) { return new Name\Relative(substr($name, strlen('namespace\\'))); } else { return new Name($name); } } throw new \LogicException('Name must be a string or an instance of PhpParser\Node\Name'); } /** * Normalizes a type: Converts plain-text type names into proper AST representation. * * In particular, builtin types are left as strings, custom types become Names and nullables * are wrapped in NullableType nodes. * * @param Name|string|NullableType $type The type to normalize * * @return Name|string|NullableType The normalized type */ protected function normalizeType($type) { if (!is_string($type)) { if (!$type instanceof Name && !$type instanceof NullableType) { throw new \LogicException( 'Type must be a string, or an instance of Name or NullableType'); } return $type; } $nullable = false; if (strlen($type) > 0 && $type[0] === '?') { $nullable = true; $type = substr($type, 1); } $builtinTypes = array( 'array', 'callable', 'string', 'int', 'float', 'bool', 'iterable', 'void', 'object' ); $lowerType = strtolower($type); if (in_array($lowerType, $builtinTypes)) { $type = $lowerType; } else { $type = $this->normalizeName($type); } if ($nullable && $type === 'void') { throw new \LogicException('void type cannot be nullable'); } return $nullable ? new Node\NullableType($type) : $type; } /** * Normalizes a value: Converts nulls, booleans, integers, * floats, strings and arrays into their respective nodes * * @param mixed $value The value to normalize * * @return Expr The normalized value */ protected function normalizeValue($value) { if ($value instanceof Node) { return $value; } elseif (is_null($value)) { return new Expr\ConstFetch( new Name('null') ); } elseif (is_bool($value)) { return new Expr\ConstFetch( new Name($value ? 'true' : 'false') ); } elseif (is_int($value)) { return new Scalar\LNumber($value); } elseif (is_float($value)) { return new Scalar\DNumber($value); } elseif (is_string($value)) { return new Scalar\String_($value); } elseif (is_array($value)) { $items = array(); $lastKey = -1; foreach ($value as $itemKey => $itemValue) { // for consecutive, numeric keys don't generate keys if (null !== $lastKey && ++$lastKey === $itemKey) { $items[] = new Expr\ArrayItem( $this->normalizeValue($itemValue) ); } else { $lastKey = null; $items[] = new Expr\ArrayItem( $this->normalizeValue($itemValue), $this->normalizeValue($itemKey) ); } } return new Expr\Array_($items); } else { throw new \LogicException('Invalid value'); } } /** * Normalizes a doc comment: Converts plain strings to PhpParser\Comment\Doc. * * @param Comment\Doc|string $docComment The doc comment to normalize * * @return Comment\Doc The normalized doc comment */ protected function normalizeDocComment($docComment) { if ($docComment instanceof Comment\Doc) { return $docComment; } else if (is_string($docComment)) { return new Comment\Doc($docComment); } else { throw new \LogicException('Doc comment must be a string or an instance of PhpParser\Comment\Doc'); } } /** * Sets a modifier in the $this->type property. * * @param int $modifier Modifier to set */ protected function setModifier($modifier) { Stmt\Class_::verifyModifier($this->flags, $modifier); $this->flags |= $modifier; } } PHP-Parser-3.1.4/lib/PhpParser/BuilderFactory.php000066400000000000000000000065641323244626500215230ustar00rootroot00000000000000text = $text; $this->line = $startLine; $this->filePos = $startFilePos; } /** * Gets the comment text. * * @return string The comment text (including comment delimiters like /*) */ public function getText() { return $this->text; } /** * Gets the line number the comment started on. * * @return int Line number */ public function getLine() { return $this->line; } /** * Gets the file offset the comment started on. * * @return int File offset */ public function getFilePos() { return $this->filePos; } /** * Gets the comment text. * * @return string The comment text (including comment delimiters like /*) */ public function __toString() { return $this->text; } /** * Gets the reformatted comment text. * * "Reformatted" here means that we try to clean up the whitespace at the * starts of the lines. This is necessary because we receive the comments * without trailing whitespace on the first line, but with trailing whitespace * on all subsequent lines. * * @return mixed|string */ public function getReformattedText() { $text = trim($this->text); $newlinePos = strpos($text, "\n"); if (false === $newlinePos) { // Single line comments don't need further processing return $text; } elseif (preg_match('((*BSR_ANYCRLF)(*ANYCRLF)^.*(?:\R\s+\*.*)+$)', $text)) { // Multi line comment of the type // // /* // * Some text. // * Some more text. // */ // // is handled by replacing the whitespace sequences before the * by a single space return preg_replace('(^\s+\*)m', ' *', $this->text); } elseif (preg_match('(^/\*\*?\s*[\r\n])', $text) && preg_match('(\n(\s*)\*/$)', $text, $matches)) { // Multi line comment of the type // // /* // Some text. // Some more text. // */ // // is handled by removing the whitespace sequence on the line before the closing // */ on all lines. So if the last line is " */", then " " is removed at the // start of all lines. return preg_replace('(^' . preg_quote($matches[1]) . ')m', '', $text); } elseif (preg_match('(^/\*\*?\s*(?!\s))', $text, $matches)) { // Multi line comment of the type // // /* Some text. // Some more text. // Indented text. // Even more text. */ // // is handled by removing the difference between the shortest whitespace prefix on all // lines and the length of the "/* " opening sequence. $prefixLen = $this->getShortestWhitespacePrefixLen(substr($text, $newlinePos + 1)); $removeLen = $prefixLen - strlen($matches[0]); return preg_replace('(^\s{' . $removeLen . '})m', '', $text); } // No idea how to format this comment, so simply return as is return $text; } private function getShortestWhitespacePrefixLen($str) { $lines = explode("\n", $str); $shortestPrefixLen = INF; foreach ($lines as $line) { preg_match('(^\s*)', $line, $matches); $prefixLen = strlen($matches[0]); if ($prefixLen < $shortestPrefixLen) { $shortestPrefixLen = $prefixLen; } } return $shortestPrefixLen; } public function jsonSerialize() { // Technically not a node, but we make it look like one anyway $type = $this instanceof Comment\Doc ? 'Comment_Doc' : 'Comment'; return [ 'nodeType' => $type, 'text' => $this->text, 'line' => $this->line, 'filePos' => $this->filePos, ]; } }PHP-Parser-3.1.4/lib/PhpParser/Comment/000077500000000000000000000000001323244626500174635ustar00rootroot00000000000000PHP-Parser-3.1.4/lib/PhpParser/Comment/Doc.php000066400000000000000000000001151323244626500206760ustar00rootroot00000000000000rawMessage = (string) $message; if (is_array($attributes)) { $this->attributes = $attributes; } else { $this->attributes = array('startLine' => $attributes); } $this->updateMessage(); } /** * Gets the error message * * @return string Error message */ public function getRawMessage() { return $this->rawMessage; } /** * Gets the line the error starts in. * * @return int Error start line */ public function getStartLine() { return isset($this->attributes['startLine']) ? $this->attributes['startLine'] : -1; } /** * Gets the line the error ends in. * * @return int Error end line */ public function getEndLine() { return isset($this->attributes['endLine']) ? $this->attributes['endLine'] : -1; } /** * Gets the attributes of the node/token the error occurred at. * * @return array */ public function getAttributes() { return $this->attributes; } /** * Sets the attributes of the node/token the error occured at. * * @param array $attributes */ public function setAttributes(array $attributes) { $this->attributes = $attributes; $this->updateMessage(); } /** * Sets the line of the PHP file the error occurred in. * * @param string $message Error message */ public function setRawMessage($message) { $this->rawMessage = (string) $message; $this->updateMessage(); } /** * Sets the line the error starts in. * * @param int $line Error start line */ public function setStartLine($line) { $this->attributes['startLine'] = (int) $line; $this->updateMessage(); } /** * Returns whether the error has start and end column information. * * For column information enable the startFilePos and endFilePos in the lexer options. * * @return bool */ public function hasColumnInfo() { return isset($this->attributes['startFilePos']) && isset($this->attributes['endFilePos']); } /** * Gets the start column (1-based) into the line where the error started. * * @param string $code Source code of the file * @return int */ public function getStartColumn($code) { if (!$this->hasColumnInfo()) { throw new \RuntimeException('Error does not have column information'); } return $this->toColumn($code, $this->attributes['startFilePos']); } /** * Gets the end column (1-based) into the line where the error ended. * * @param string $code Source code of the file * @return int */ public function getEndColumn($code) { if (!$this->hasColumnInfo()) { throw new \RuntimeException('Error does not have column information'); } return $this->toColumn($code, $this->attributes['endFilePos']); } public function getMessageWithColumnInfo($code) { return sprintf( '%s from %d:%d to %d:%d', $this->getRawMessage(), $this->getStartLine(), $this->getStartColumn($code), $this->getEndLine(), $this->getEndColumn($code) ); } private function toColumn($code, $pos) { if ($pos > strlen($code)) { throw new \RuntimeException('Invalid position information'); } $lineStartPos = strrpos($code, "\n", $pos - strlen($code)); if (false === $lineStartPos) { $lineStartPos = -1; } return $pos - $lineStartPos; } /** * Updates the exception message after a change to rawMessage or rawLine. */ protected function updateMessage() { $this->message = $this->rawMessage; if (-1 === $this->getStartLine()) { $this->message .= ' on unknown line'; } else { $this->message .= ' on line ' . $this->getStartLine(); } } } PHP-Parser-3.1.4/lib/PhpParser/ErrorHandler.php000066400000000000000000000004141323244626500211600ustar00rootroot00000000000000errors[] = $error; } /** * Get collected errors. * * @return Error[] */ public function getErrors() { return $this->errors; } /** * Check whether there are any errors. * * @return bool */ public function hasErrors() { return !empty($this->errors); } /** * Reset/clear collected errors. */ public function clearErrors() { $this->errors = []; } }PHP-Parser-3.1.4/lib/PhpParser/ErrorHandler/Throwing.php000066400000000000000000000005201323244626500227570ustar00rootroot00000000000000tokenMap = $this->createTokenMap(); // map of tokens to drop while lexing (the map is only used for isset lookup, // that's why the value is simply set to 1; the value is never actually used.) $this->dropTokens = array_fill_keys( array(T_WHITESPACE, T_OPEN_TAG, T_COMMENT, T_DOC_COMMENT), 1 ); // the usedAttributes member is a map of the used attribute names to a dummy // value (here "true") $options += array( 'usedAttributes' => array('comments', 'startLine', 'endLine'), ); $this->usedAttributes = array_fill_keys($options['usedAttributes'], true); } /** * Initializes the lexer for lexing the provided source code. * * This function does not throw if lexing errors occur. Instead, errors may be retrieved using * the getErrors() method. * * @param string $code The source code to lex * @param ErrorHandler|null $errorHandler Error handler to use for lexing errors. Defaults to * ErrorHandler\Throwing */ public function startLexing($code, ErrorHandler $errorHandler = null) { if (null === $errorHandler) { $errorHandler = new ErrorHandler\Throwing(); } $this->code = $code; // keep the code around for __halt_compiler() handling $this->pos = -1; $this->line = 1; $this->filePos = 0; // If inline HTML occurs without preceding code, treat it as if it had a leading newline. // This ensures proper composability, because having a newline is the "safe" assumption. $this->prevCloseTagHasNewline = true; $scream = ini_set('xdebug.scream', '0'); $this->resetErrors(); $this->tokens = @token_get_all($code); $this->handleErrors($errorHandler); if (false !== $scream) { ini_set('xdebug.scream', $scream); } } protected function resetErrors() { if (function_exists('error_clear_last')) { error_clear_last(); } else { // set error_get_last() to defined state by forcing an undefined variable error set_error_handler(function() { return false; }, 0); @$undefinedVariable; restore_error_handler(); } } private function handleInvalidCharacterRange($start, $end, $line, ErrorHandler $errorHandler) { for ($i = $start; $i < $end; $i++) { $chr = $this->code[$i]; if ($chr === 'b' || $chr === 'B') { // HHVM does not treat b" tokens correctly, so ignore these continue; } if ($chr === "\0") { // PHP cuts error message after null byte, so need special case $errorMsg = 'Unexpected null byte'; } else { $errorMsg = sprintf( 'Unexpected character "%s" (ASCII %d)', $chr, ord($chr) ); } $errorHandler->handleError(new Error($errorMsg, [ 'startLine' => $line, 'endLine' => $line, 'startFilePos' => $i, 'endFilePos' => $i, ])); } } private function isUnterminatedComment($token) { return ($token[0] === T_COMMENT || $token[0] === T_DOC_COMMENT) && substr($token[1], 0, 2) === '/*' && substr($token[1], -2) !== '*/'; } private function errorMayHaveOccurred() { if (defined('HHVM_VERSION')) { // In HHVM token_get_all() does not throw warnings, so we need to conservatively // assume that an error occurred return true; } $error = error_get_last(); return null !== $error && false === strpos($error['message'], 'Undefined variable'); } protected function handleErrors(ErrorHandler $errorHandler) { if (!$this->errorMayHaveOccurred()) { return; } // PHP's error handling for token_get_all() is rather bad, so if we want detailed // error information we need to compute it ourselves. Invalid character errors are // detected by finding "gaps" in the token array. Unterminated comments are detected // by checking if a trailing comment has a "*/" at the end. $filePos = 0; $line = 1; foreach ($this->tokens as $i => $token) { $tokenValue = \is_string($token) ? $token : $token[1]; $tokenLen = \strlen($tokenValue); if (substr($this->code, $filePos, $tokenLen) !== $tokenValue) { // Something is missing, must be an invalid character $nextFilePos = strpos($this->code, $tokenValue, $filePos); $this->handleInvalidCharacterRange( $filePos, $nextFilePos, $line, $errorHandler); $filePos = $nextFilePos; } $filePos += $tokenLen; $line += substr_count($tokenValue, "\n"); } if ($filePos !== \strlen($this->code)) { if (substr($this->code, $filePos, 2) === '/*') { // Unlike PHP, HHVM will drop unterminated comments entirely $comment = substr($this->code, $filePos); $errorHandler->handleError(new Error('Unterminated comment', [ 'startLine' => $line, 'endLine' => $line + substr_count($comment, "\n"), 'startFilePos' => $filePos, 'endFilePos' => $filePos + \strlen($comment), ])); // Emulate the PHP behavior $isDocComment = isset($comment[3]) && $comment[3] === '*'; $this->tokens[] = [$isDocComment ? T_DOC_COMMENT : T_COMMENT, $comment, $line]; } else { // Invalid characters at the end of the input $this->handleInvalidCharacterRange( $filePos, \strlen($this->code), $line, $errorHandler); } return; } if (count($this->tokens) > 0) { // Check for unterminated comment $lastToken = $this->tokens[count($this->tokens) - 1]; if ($this->isUnterminatedComment($lastToken)) { $errorHandler->handleError(new Error('Unterminated comment', [ 'startLine' => $line - substr_count($lastToken[1], "\n"), 'endLine' => $line, 'startFilePos' => $filePos - \strlen($lastToken[1]), 'endFilePos' => $filePos, ])); } } } /** * Fetches the next token. * * The available attributes are determined by the 'usedAttributes' option, which can * be specified in the constructor. The following attributes are supported: * * * 'comments' => Array of PhpParser\Comment or PhpParser\Comment\Doc instances, * representing all comments that occurred between the previous * non-discarded token and the current one. * * 'startLine' => Line in which the node starts. * * 'endLine' => Line in which the node ends. * * 'startTokenPos' => Offset into the token array of the first token in the node. * * 'endTokenPos' => Offset into the token array of the last token in the node. * * 'startFilePos' => Offset into the code string of the first character that is part of the node. * * 'endFilePos' => Offset into the code string of the last character that is part of the node. * * @param mixed $value Variable to store token content in * @param mixed $startAttributes Variable to store start attributes in * @param mixed $endAttributes Variable to store end attributes in * * @return int Token id */ public function getNextToken(&$value = null, &$startAttributes = null, &$endAttributes = null) { $startAttributes = array(); $endAttributes = array(); while (1) { if (isset($this->tokens[++$this->pos])) { $token = $this->tokens[$this->pos]; } else { // EOF token with ID 0 $token = "\0"; } if (isset($this->usedAttributes['startLine'])) { $startAttributes['startLine'] = $this->line; } if (isset($this->usedAttributes['startTokenPos'])) { $startAttributes['startTokenPos'] = $this->pos; } if (isset($this->usedAttributes['startFilePos'])) { $startAttributes['startFilePos'] = $this->filePos; } if (\is_string($token)) { $value = $token; if (isset($token[1])) { // bug in token_get_all $this->filePos += 2; $id = ord('"'); } else { $this->filePos += 1; $id = ord($token); } } elseif (!isset($this->dropTokens[$token[0]])) { $value = $token[1]; $id = $this->tokenMap[$token[0]]; if (T_CLOSE_TAG === $token[0]) { $this->prevCloseTagHasNewline = false !== strpos($token[1], "\n"); } else if (T_INLINE_HTML === $token[0]) { $startAttributes['hasLeadingNewline'] = $this->prevCloseTagHasNewline; } $this->line += substr_count($value, "\n"); $this->filePos += \strlen($value); } else { if (T_COMMENT === $token[0] || T_DOC_COMMENT === $token[0]) { if (isset($this->usedAttributes['comments'])) { $comment = T_DOC_COMMENT === $token[0] ? new Comment\Doc($token[1], $this->line, $this->filePos) : new Comment($token[1], $this->line, $this->filePos); $startAttributes['comments'][] = $comment; } } $this->line += substr_count($token[1], "\n"); $this->filePos += \strlen($token[1]); continue; } if (isset($this->usedAttributes['endLine'])) { $endAttributes['endLine'] = $this->line; } if (isset($this->usedAttributes['endTokenPos'])) { $endAttributes['endTokenPos'] = $this->pos; } if (isset($this->usedAttributes['endFilePos'])) { $endAttributes['endFilePos'] = $this->filePos - 1; } return $id; } throw new \RuntimeException('Reached end of lexer loop'); } /** * Returns the token array for current code. * * The token array is in the same format as provided by the * token_get_all() function and does not discard tokens (i.e. * whitespace and comments are included). The token position * attributes are against this token array. * * @return array Array of tokens in token_get_all() format */ public function getTokens() { return $this->tokens; } /** * Handles __halt_compiler() by returning the text after it. * * @return string Remaining text */ public function handleHaltCompiler() { // text after T_HALT_COMPILER, still including (); $textAfter = substr($this->code, $this->filePos); // ensure that it is followed by (); // this simplifies the situation, by not allowing any comments // in between of the tokens. if (!preg_match('~^\s*\(\s*\)\s*(?:;|\?>\r?\n?)~', $textAfter, $matches)) { throw new Error('__HALT_COMPILER must be followed by "();"'); } // prevent the lexer from returning any further tokens $this->pos = count($this->tokens); // return with (); removed return (string) substr($textAfter, strlen($matches[0])); // (string) converts false to '' } /** * Creates the token map. * * The token map maps the PHP internal token identifiers * to the identifiers used by the Parser. Additionally it * maps T_OPEN_TAG_WITH_ECHO to T_ECHO and T_CLOSE_TAG to ';'. * * @return array The token map */ protected function createTokenMap() { $tokenMap = array(); // 256 is the minimum possible token number, as everything below // it is an ASCII value for ($i = 256; $i < 1000; ++$i) { if (T_DOUBLE_COLON === $i) { // T_DOUBLE_COLON is equivalent to T_PAAMAYIM_NEKUDOTAYIM $tokenMap[$i] = Tokens::T_PAAMAYIM_NEKUDOTAYIM; } elseif(T_OPEN_TAG_WITH_ECHO === $i) { // T_OPEN_TAG_WITH_ECHO with dropped T_OPEN_TAG results in T_ECHO $tokenMap[$i] = Tokens::T_ECHO; } elseif(T_CLOSE_TAG === $i) { // T_CLOSE_TAG is equivalent to ';' $tokenMap[$i] = ord(';'); } elseif ('UNKNOWN' !== $name = token_name($i)) { if ('T_HASHBANG' === $name) { // HHVM uses a special token for #! hashbang lines $tokenMap[$i] = Tokens::T_INLINE_HTML; } else if (defined($name = Tokens::class . '::' . $name)) { // Other tokens can be mapped directly $tokenMap[$i] = constant($name); } } } // HHVM uses a special token for numbers that overflow to double if (defined('T_ONUMBER')) { $tokenMap[T_ONUMBER] = Tokens::T_DNUMBER; } // HHVM also has a separate token for the __COMPILER_HALT_OFFSET__ constant if (defined('T_COMPILER_HALT_OFFSET')) { $tokenMap[T_COMPILER_HALT_OFFSET] = Tokens::T_STRING; } return $tokenMap; } } PHP-Parser-3.1.4/lib/PhpParser/Lexer/000077500000000000000000000000001323244626500171405ustar00rootroot00000000000000PHP-Parser-3.1.4/lib/PhpParser/Lexer/Emulative.php000066400000000000000000000137611323244626500216140ustar00rootroot00000000000000newKeywords = array(); foreach ($newKeywordsPerVersion as $version => $newKeywords) { if (version_compare(PHP_VERSION, $version, '>=')) { break; } $this->newKeywords += $newKeywords; } if (version_compare(PHP_VERSION, self::PHP_7_0, '>=')) { return; } $this->tokenMap[self::T_COALESCE] = Tokens::T_COALESCE; $this->tokenMap[self::T_SPACESHIP] = Tokens::T_SPACESHIP; $this->tokenMap[self::T_YIELD_FROM] = Tokens::T_YIELD_FROM; if (version_compare(PHP_VERSION, self::PHP_5_6, '>=')) { return; } $this->tokenMap[self::T_ELLIPSIS] = Tokens::T_ELLIPSIS; $this->tokenMap[self::T_POW] = Tokens::T_POW; $this->tokenMap[self::T_POW_EQUAL] = Tokens::T_POW_EQUAL; } public function startLexing($code, ErrorHandler $errorHandler = null) { $this->inObjectAccess = false; parent::startLexing($code, $errorHandler); if ($this->requiresEmulation($code)) { $this->emulateTokens(); } } /* * Checks if the code is potentially using features that require emulation. */ protected function requiresEmulation($code) { if (version_compare(PHP_VERSION, self::PHP_7_0, '>=')) { return false; } if (preg_match('(\?\?|<=>|yield[ \n\r\t]+from)', $code)) { return true; } if (version_compare(PHP_VERSION, self::PHP_5_6, '>=')) { return false; } return preg_match('(\.\.\.|(?tokens); $i < $c; ++$i) { $replace = null; if (isset($this->tokens[$i + 1])) { if ($this->tokens[$i] === '?' && $this->tokens[$i + 1] === '?') { array_splice($this->tokens, $i, 2, array( array(self::T_COALESCE, '??', $line) )); $c--; continue; } if ($this->tokens[$i][0] === T_IS_SMALLER_OR_EQUAL && $this->tokens[$i + 1] === '>' ) { array_splice($this->tokens, $i, 2, array( array(self::T_SPACESHIP, '<=>', $line) )); $c--; continue; } if ($this->tokens[$i] === '*' && $this->tokens[$i + 1] === '*') { array_splice($this->tokens, $i, 2, array( array(self::T_POW, '**', $line) )); $c--; continue; } if ($this->tokens[$i] === '*' && $this->tokens[$i + 1][0] === T_MUL_EQUAL) { array_splice($this->tokens, $i, 2, array( array(self::T_POW_EQUAL, '**=', $line) )); $c--; continue; } } if (isset($this->tokens[$i + 2])) { if ($this->tokens[$i][0] === T_YIELD && $this->tokens[$i + 1][0] === T_WHITESPACE && $this->tokens[$i + 2][0] === T_STRING && !strcasecmp($this->tokens[$i + 2][1], 'from') ) { array_splice($this->tokens, $i, 3, array( array( self::T_YIELD_FROM, $this->tokens[$i][1] . $this->tokens[$i + 1][1] . $this->tokens[$i + 2][1], $line ) )); $c -= 2; $line += substr_count($this->tokens[$i][1], "\n"); continue; } if ($this->tokens[$i] === '.' && $this->tokens[$i + 1] === '.' && $this->tokens[$i + 2] === '.' ) { array_splice($this->tokens, $i, 3, array( array(self::T_ELLIPSIS, '...', $line) )); $c -= 2; continue; } } if (\is_array($this->tokens[$i])) { $line += substr_count($this->tokens[$i][1], "\n"); } } } public function getNextToken(&$value = null, &$startAttributes = null, &$endAttributes = null) { $token = parent::getNextToken($value, $startAttributes, $endAttributes); // replace new keywords by their respective tokens. This is not done // if we currently are in an object access (e.g. in $obj->namespace // "namespace" stays a T_STRING tokens and isn't converted to T_NAMESPACE) if (Tokens::T_STRING === $token && !$this->inObjectAccess) { if (isset($this->newKeywords[strtolower($value)])) { return $this->newKeywords[strtolower($value)]; } } else { // keep track of whether we currently are in an object access (after ->) $this->inObjectAccess = Tokens::T_OBJECT_OPERATOR === $token; } return $token; } } PHP-Parser-3.1.4/lib/PhpParser/Node.php000066400000000000000000000033541323244626500174640ustar00rootroot00000000000000value = $value; $this->byRef = $byRef; $this->unpack = $unpack; } public function getSubNodeNames() { return array('value', 'byRef', 'unpack'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Const_.php000066400000000000000000000013011323244626500206770ustar00rootroot00000000000000name = $name; $this->value = $value; } public function getSubNodeNames() { return array('name', 'value'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Expr.php000066400000000000000000000001531323244626500203740ustar00rootroot00000000000000var = $var; $this->dim = $dim; } public function getSubNodeNames() { return array('var', 'dim'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Expr/ArrayItem.php000066400000000000000000000015501323244626500222730ustar00rootroot00000000000000key = $key; $this->value = $value; $this->byRef = $byRef; } public function getSubNodeNames() { return array('key', 'value', 'byRef'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Expr/Array_.php000066400000000000000000000012551323244626500216150ustar00rootroot00000000000000items = $items; } public function getSubNodeNames() { return array('items'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Expr/Assign.php000066400000000000000000000012321323244626500216170ustar00rootroot00000000000000var = $var; $this->expr = $expr; } public function getSubNodeNames() { return array('var', 'expr'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Expr/AssignOp.php000066400000000000000000000012671323244626500221260ustar00rootroot00000000000000var = $var; $this->expr = $expr; } public function getSubNodeNames() { return array('var', 'expr'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Expr/AssignOp/000077500000000000000000000000001323244626500214075ustar00rootroot00000000000000PHP-Parser-3.1.4/lib/PhpParser/Node/Expr/AssignOp/BitwiseAnd.php000066400000000000000000000001701323244626500241470ustar00rootroot00000000000000var = $var; $this->expr = $expr; } public function getSubNodeNames() { return array('var', 'expr'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Expr/BinaryOp.php000066400000000000000000000014011323244626500221140ustar00rootroot00000000000000left = $left; $this->right = $right; } public function getSubNodeNames() { return array('left', 'right'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Expr/BinaryOp/000077500000000000000000000000001323244626500214075ustar00rootroot00000000000000PHP-Parser-3.1.4/lib/PhpParser/Node/Expr/BinaryOp/BitwiseAnd.php000066400000000000000000000001701323244626500241470ustar00rootroot00000000000000expr = $expr; } public function getSubNodeNames() { return array('expr'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Expr/BooleanNot.php000066400000000000000000000010461323244626500224360ustar00rootroot00000000000000expr = $expr; } public function getSubNodeNames() { return array('expr'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Expr/Cast.php000066400000000000000000000010251323244626500212650ustar00rootroot00000000000000expr = $expr; } public function getSubNodeNames() { return array('expr'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Expr/Cast/000077500000000000000000000000001323244626500205565ustar00rootroot00000000000000PHP-Parser-3.1.4/lib/PhpParser/Node/Expr/Cast/Array_.php000066400000000000000000000001501323244626500225000ustar00rootroot00000000000000class = $class; $this->name = $name; } public function getSubNodeNames() { return array('class', 'name'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Expr/Clone_.php000066400000000000000000000010171323244626500215730ustar00rootroot00000000000000expr = $expr; } public function getSubNodeNames() { return array('expr'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Expr/Closure.php000066400000000000000000000043341323244626500220150ustar00rootroot00000000000000 false : Whether the closure is static * 'byRef' => false : Whether to return by reference * 'params' => array(): Parameters * 'uses' => array(): use()s * 'returnType' => null : Return type * 'stmts' => array(): Statements * @param array $attributes Additional attributes */ public function __construct(array $subNodes = array(), array $attributes = array()) { parent::__construct($attributes); $this->static = isset($subNodes['static']) ? $subNodes['static'] : false; $this->byRef = isset($subNodes['byRef']) ? $subNodes['byRef'] : false; $this->params = isset($subNodes['params']) ? $subNodes['params'] : array(); $this->uses = isset($subNodes['uses']) ? $subNodes['uses'] : array(); $this->returnType = isset($subNodes['returnType']) ? $subNodes['returnType'] : null; $this->stmts = isset($subNodes['stmts']) ? $subNodes['stmts'] : array(); } public function getSubNodeNames() { return array('static', 'byRef', 'params', 'uses', 'returnType', 'stmts'); } public function returnsByRef() { return $this->byRef; } public function getParams() { return $this->params; } public function getReturnType() { return $this->returnType; } public function getStmts() { return $this->stmts; } } PHP-Parser-3.1.4/lib/PhpParser/Node/Expr/ClosureUse.php000066400000000000000000000013471323244626500224730ustar00rootroot00000000000000var = $var; $this->byRef = $byRef; } public function getSubNodeNames() { return array('var', 'byRef'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Expr/ConstFetch.php000066400000000000000000000010701323244626500224330ustar00rootroot00000000000000name = $name; } public function getSubNodeNames() { return array('name'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Expr/Empty_.php000066400000000000000000000010221323244626500216250ustar00rootroot00000000000000expr = $expr; } public function getSubNodeNames() { return array('expr'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Expr/Error.php000066400000000000000000000012051323244626500214640ustar00rootroot00000000000000expr = $expr; } public function getSubNodeNames() { return array('expr'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Expr/Eval_.php000066400000000000000000000010201323244626500214140ustar00rootroot00000000000000expr = $expr; } public function getSubNodeNames() { return array('expr'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Expr/Exit_.php000066400000000000000000000012131323244626500214420ustar00rootroot00000000000000expr = $expr; } public function getSubNodeNames() { return array('expr'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Expr/FuncCall.php000066400000000000000000000014301323244626500220620ustar00rootroot00000000000000name = $name; $this->args = $args; } public function getSubNodeNames() { return array('name', 'args'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Expr/Include_.php000066400000000000000000000014531323244626500221220ustar00rootroot00000000000000expr = $expr; $this->type = $type; } public function getSubNodeNames() { return array('expr', 'type'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Expr/Instanceof_.php000066400000000000000000000013301323244626500226220ustar00rootroot00000000000000expr = $expr; $this->class = $class; } public function getSubNodeNames() { return array('expr', 'class'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Expr/Isset_.php000066400000000000000000000010231323244626500216170ustar00rootroot00000000000000vars = $vars; } public function getSubNodeNames() { return array('vars'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Expr/List_.php000066400000000000000000000011261323244626500214470ustar00rootroot00000000000000items = $items; } public function getSubNodeNames() { return array('items'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Expr/MethodCall.php000066400000000000000000000016121323244626500224110ustar00rootroot00000000000000var = $var; $this->name = $name; $this->args = $args; } public function getSubNodeNames() { return array('var', 'name', 'args'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Expr/New_.php000066400000000000000000000015251323244626500212700ustar00rootroot00000000000000class = $class; $this->args = $args; } public function getSubNodeNames() { return array('class', 'args'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Expr/PostDec.php000066400000000000000000000010201323244626500217270ustar00rootroot00000000000000var = $var; } public function getSubNodeNames() { return array('var'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Expr/PostInc.php000066400000000000000000000010201323244626500217450ustar00rootroot00000000000000var = $var; } public function getSubNodeNames() { return array('var'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Expr/PreDec.php000066400000000000000000000010161323244626500215350ustar00rootroot00000000000000var = $var; } public function getSubNodeNames() { return array('var'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Expr/PreInc.php000066400000000000000000000010161323244626500215530ustar00rootroot00000000000000var = $var; } public function getSubNodeNames() { return array('var'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Expr/Print_.php000066400000000000000000000010221323244626500216230ustar00rootroot00000000000000expr = $expr; } public function getSubNodeNames() { return array('expr'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Expr/PropertyFetch.php000066400000000000000000000013331323244626500231730ustar00rootroot00000000000000var = $var; $this->name = $name; } public function getSubNodeNames() { return array('var', 'name'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Expr/ShellExec.php000066400000000000000000000010771323244626500222560ustar00rootroot00000000000000parts = $parts; } public function getSubNodeNames() { return array('parts'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Expr/StaticCall.php000066400000000000000000000016211323244626500224200ustar00rootroot00000000000000class = $class; $this->name = $name; $this->args = $args; } public function getSubNodeNames() { return array('class', 'name', 'args'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Expr/StaticPropertyFetch.php000066400000000000000000000013621323244626500243450ustar00rootroot00000000000000class = $class; $this->name = $name; } public function getSubNodeNames() { return array('class', 'name'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Expr/Ternary.php000066400000000000000000000015601323244626500220230ustar00rootroot00000000000000cond = $cond; $this->if = $if; $this->else = $else; } public function getSubNodeNames() { return array('cond', 'if', 'else'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Expr/UnaryMinus.php000066400000000000000000000010311323244626500225020ustar00rootroot00000000000000expr = $expr; } public function getSubNodeNames() { return array('expr'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Expr/UnaryPlus.php000066400000000000000000000010441323244626500223360ustar00rootroot00000000000000expr = $expr; } public function getSubNodeNames() { return array('expr'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Expr/Variable.php000066400000000000000000000010451323244626500221220ustar00rootroot00000000000000name = $name; } public function getSubNodeNames() { return array('name'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Expr/YieldFrom.php000066400000000000000000000010501323244626500222630ustar00rootroot00000000000000expr = $expr; } public function getSubNodeNames() { return array('expr'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Expr/Yield_.php000066400000000000000000000013401323244626500216000ustar00rootroot00000000000000key = $key; $this->value = $value; } public function getSubNodeNames() { return array('key', 'value'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/FunctionLike.php000066400000000000000000000011201323244626500220430ustar00rootroot00000000000000parts = self::prepareName($name); } public function getSubNodeNames() { return array('parts'); } /** * Gets the first part of the name, i.e. everything before the first namespace separator. * * @return string First part of the name */ public function getFirst() { return $this->parts[0]; } /** * Gets the last part of the name, i.e. everything after the last namespace separator. * * @return string Last part of the name */ public function getLast() { return $this->parts[count($this->parts) - 1]; } /** * Checks whether the name is unqualified. (E.g. Name) * * @return bool Whether the name is unqualified */ public function isUnqualified() { return 1 == count($this->parts); } /** * Checks whether the name is qualified. (E.g. Name\Name) * * @return bool Whether the name is qualified */ public function isQualified() { return 1 < count($this->parts); } /** * Checks whether the name is fully qualified. (E.g. \Name) * * @return bool Whether the name is fully qualified */ public function isFullyQualified() { return false; } /** * Checks whether the name is explicitly relative to the current namespace. (E.g. namespace\Name) * * @return bool Whether the name is relative */ public function isRelative() { return false; } /** * Returns a string representation of the name by imploding the namespace parts with the * namespace separator. * * @return string String representation */ public function toString() { return implode('\\', $this->parts); } /** * Returns a string representation of the name by imploding the namespace parts with the * namespace separator. * * @return string String representation */ public function __toString() { return implode('\\', $this->parts); } /** * Gets a slice of a name (similar to array_slice). * * This method returns a new instance of the same type as the original and with the same * attributes. * * If the slice is empty, null is returned. The null value will be correctly handled in * concatenations using concat(). * * Offset and length have the same meaning as in array_slice(). * * @param int $offset Offset to start the slice at (may be negative) * @param int|null $length Length of the slice (may be negative) * * @return static|null Sliced name */ public function slice($offset, $length = null) { $numParts = count($this->parts); $realOffset = $offset < 0 ? $offset + $numParts : $offset; if ($realOffset < 0 || $realOffset > $numParts) { throw new \OutOfBoundsException(sprintf('Offset %d is out of bounds', $offset)); } if (null === $length) { $realLength = $numParts - $realOffset; } else { $realLength = $length < 0 ? $length + $numParts - $realOffset : $length; if ($realLength < 0 || $realLength > $numParts) { throw new \OutOfBoundsException(sprintf('Length %d is out of bounds', $length)); } } if ($realLength === 0) { // Empty slice is represented as null return null; } return new static(array_slice($this->parts, $realOffset, $realLength), $this->attributes); } /** * Concatenate two names, yielding a new Name instance. * * The type of the generated instance depends on which class this method is called on, for * example Name\FullyQualified::concat() will yield a Name\FullyQualified instance. * * If one of the arguments is null, a new instance of the other name will be returned. If both * arguments are null, null will be returned. As such, writing * Name::concat($namespace, $shortName) * where $namespace is a Name node or null will work as expected. * * @param string|array|self|null $name1 The first name * @param string|array|self|null $name2 The second name * @param array $attributes Attributes to assign to concatenated name * * @return static|null Concatenated name */ public static function concat($name1, $name2, array $attributes = []) { if (null === $name1 && null === $name2) { return null; } elseif (null === $name1) { return new static(self::prepareName($name2), $attributes); } else if (null === $name2) { return new static(self::prepareName($name1), $attributes); } else { return new static( array_merge(self::prepareName($name1), self::prepareName($name2)), $attributes ); } } /** * Prepares a (string, array or Name node) name for use in name changing methods by converting * it to an array. * * @param string|array|self $name Name to prepare * * @return array Prepared name */ private static function prepareName($name) { if (\is_string($name)) { return explode('\\', $name); } elseif (\is_array($name)) { return $name; } elseif ($name instanceof self) { return $name->parts; } throw new \InvalidArgumentException( 'Expected string, array of parts or Name instance' ); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Name/000077500000000000000000000000001323244626500176265ustar00rootroot00000000000000PHP-Parser-3.1.4/lib/PhpParser/Node/Name/FullyQualified.php000066400000000000000000000016561323244626500232660ustar00rootroot00000000000000type = $type; } public function getSubNodeNames() { return array('type'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Param.php000066400000000000000000000026141323244626500205220ustar00rootroot00000000000000type = $type; $this->byRef = $byRef; $this->variadic = $variadic; $this->name = $name; $this->default = $default; } public function getSubNodeNames() { return array('type', 'byRef', 'variadic', 'name', 'default'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Scalar.php000066400000000000000000000001101323244626500206540ustar00rootroot00000000000000value = $value; } public function getSubNodeNames() { return array('value'); } /** * @internal * * Parses a DNUMBER token like PHP would. * * @param string $str A string number * * @return float The parsed number */ public static function parse($str) { // if string contains any of .eE just cast it to float if (false !== strpbrk($str, '.eE')) { return (float) $str; } // otherwise it's an integer notation that overflowed into a float // if it starts with 0 it's one of the special integer notations if ('0' === $str[0]) { // hex if ('x' === $str[1] || 'X' === $str[1]) { return hexdec($str); } // bin if ('b' === $str[1] || 'B' === $str[1]) { return bindec($str); } // oct // substr($str, 0, strcspn($str, '89')) cuts the string at the first invalid digit (8 or 9) // so that only the digits before that are used return octdec(substr($str, 0, strcspn($str, '89'))); } // dec return (float) $str; } } PHP-Parser-3.1.4/lib/PhpParser/Node/Scalar/Encapsed.php000066400000000000000000000011161323244626500224050ustar00rootroot00000000000000parts = $parts; } public function getSubNodeNames() { return array('parts'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Scalar/EncapsedStringPart.php000066400000000000000000000011241323244626500244220ustar00rootroot00000000000000value = $value; } public function getSubNodeNames() { return array('value'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Scalar/LNumber.php000066400000000000000000000040541323244626500222330ustar00rootroot00000000000000value = $value; } public function getSubNodeNames() { return array('value'); } /** * Constructs an LNumber node from a string number literal. * * @param string $str String number literal (decimal, octal, hex or binary) * @param array $attributes Additional attributes * @param bool $allowInvalidOctal Whether to allow invalid octal numbers (PHP 5) * * @return LNumber The constructed LNumber, including kind attribute */ public static function fromString($str, array $attributes = array(), $allowInvalidOctal = false) { if ('0' !== $str[0] || '0' === $str) { $attributes['kind'] = LNumber::KIND_DEC; return new LNumber((int) $str, $attributes); } if ('x' === $str[1] || 'X' === $str[1]) { $attributes['kind'] = LNumber::KIND_HEX; return new LNumber(hexdec($str), $attributes); } if ('b' === $str[1] || 'B' === $str[1]) { $attributes['kind'] = LNumber::KIND_BIN; return new LNumber(bindec($str), $attributes); } if (!$allowInvalidOctal && strpbrk($str, '89')) { throw new Error('Invalid numeric literal', $attributes); } // use intval instead of octdec to get proper cutting behavior with malformed numbers $attributes['kind'] = LNumber::KIND_OCT; return new LNumber(intval($str, 8), $attributes); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Scalar/MagicConst.php000066400000000000000000000010561323244626500227150ustar00rootroot00000000000000 '\\', '$' => '$', 'n' => "\n", 'r' => "\r", 't' => "\t", 'f' => "\f", 'v' => "\v", 'e' => "\x1B", ); /** * Constructs a string scalar node. * * @param string $value Value of the string * @param array $attributes Additional attributes */ public function __construct($value, array $attributes = array()) { parent::__construct($attributes); $this->value = $value; } public function getSubNodeNames() { return array('value'); } /** * @internal * * Parses a string token. * * @param string $str String token content * @param bool $parseUnicodeEscape Whether to parse PHP 7 \u escapes * * @return string The parsed string */ public static function parse($str, $parseUnicodeEscape = true) { $bLength = 0; if ('b' === $str[0] || 'B' === $str[0]) { $bLength = 1; } if ('\'' === $str[$bLength]) { return str_replace( array('\\\\', '\\\''), array( '\\', '\''), substr($str, $bLength + 1, -1) ); } else { return self::parseEscapeSequences( substr($str, $bLength + 1, -1), '"', $parseUnicodeEscape ); } } /** * @internal * * Parses escape sequences in strings (all string types apart from single quoted). * * @param string $str String without quotes * @param null|string $quote Quote type * @param bool $parseUnicodeEscape Whether to parse PHP 7 \u escapes * * @return string String with escape sequences parsed */ public static function parseEscapeSequences($str, $quote, $parseUnicodeEscape = true) { if (null !== $quote) { $str = str_replace('\\' . $quote, $quote, $str); } $extra = ''; if ($parseUnicodeEscape) { $extra = '|u\{([0-9a-fA-F]+)\}'; } return preg_replace_callback( '~\\\\([\\\\$nrtfve]|[xX][0-9a-fA-F]{1,2}|[0-7]{1,3}' . $extra . ')~', function($matches) { $str = $matches[1]; if (isset(self::$replacements[$str])) { return self::$replacements[$str]; } elseif ('x' === $str[0] || 'X' === $str[0]) { return chr(hexdec($str)); } elseif ('u' === $str[0]) { return self::codePointToUtf8(hexdec($matches[2])); } else { return chr(octdec($str)); } }, $str ); } private static function codePointToUtf8($num) { if ($num <= 0x7F) { return chr($num); } if ($num <= 0x7FF) { return chr(($num>>6) + 0xC0) . chr(($num&0x3F) + 0x80); } if ($num <= 0xFFFF) { return chr(($num>>12) + 0xE0) . chr((($num>>6)&0x3F) + 0x80) . chr(($num&0x3F) + 0x80); } if ($num <= 0x1FFFFF) { return chr(($num>>18) + 0xF0) . chr((($num>>12)&0x3F) + 0x80) . chr((($num>>6)&0x3F) + 0x80) . chr(($num&0x3F) + 0x80); } throw new Error('Invalid UTF-8 codepoint escape sequence: Codepoint too large'); } /** * @internal * * Parses a constant doc string. * * @param string $startToken Doc string start token content (<<num = $num; } public function getSubNodeNames() { return array('num'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Stmt/Case_.php000066400000000000000000000013671323244626500214270ustar00rootroot00000000000000cond = $cond; $this->stmts = $stmts; } public function getSubNodeNames() { return array('cond', 'stmts'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Stmt/Catch_.php000066400000000000000000000016261323244626500215740ustar00rootroot00000000000000types = $types; $this->var = $var; $this->stmts = $stmts; } public function getSubNodeNames() { return array('types', 'var', 'stmts'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Stmt/ClassConst.php000066400000000000000000000023351323244626500224650ustar00rootroot00000000000000flags = $flags; $this->consts = $consts; } public function getSubNodeNames() { return array('flags', 'consts'); } public function isPublic() { return ($this->flags & Class_::MODIFIER_PUBLIC) !== 0 || ($this->flags & Class_::VISIBILITY_MODIFIER_MASK) === 0; } public function isProtected() { return (bool) ($this->flags & Class_::MODIFIER_PROTECTED); } public function isPrivate() { return (bool) ($this->flags & Class_::MODIFIER_PRIVATE); } public function isStatic() { return (bool) ($this->flags & Class_::MODIFIER_STATIC); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Stmt/ClassLike.php000066400000000000000000000021721323244626500222620ustar00rootroot00000000000000stmts as $stmt) { if ($stmt instanceof ClassMethod) { $methods[] = $stmt; } } return $methods; } /** * Gets method with the given name defined directly in this class/interface/trait. * * @param string $name Name of the method (compared case-insensitively) * * @return ClassMethod|null Method node or null if the method does not exist */ public function getMethod($name) { $lowerName = strtolower($name); foreach ($this->stmts as $stmt) { if ($stmt instanceof ClassMethod && $lowerName === strtolower($stmt->name)) { return $stmt; } } return null; } } PHP-Parser-3.1.4/lib/PhpParser/Node/Stmt/ClassMethod.php000066400000000000000000000060121323244626500226130ustar00rootroot00000000000000 MODIFIER_PUBLIC: Flags * 'byRef' => false : Whether to return by reference * 'params' => array() : Parameters * 'returnType' => null : Return type * 'stmts' => array() : Statements * @param array $attributes Additional attributes */ public function __construct($name, array $subNodes = array(), array $attributes = array()) { parent::__construct($attributes); $this->flags = isset($subNodes['flags']) ? $subNodes['flags'] : (isset($subNodes['type']) ? $subNodes['type'] : 0); $this->type = $this->flags; $this->byRef = isset($subNodes['byRef']) ? $subNodes['byRef'] : false; $this->name = $name; $this->params = isset($subNodes['params']) ? $subNodes['params'] : array(); $this->returnType = isset($subNodes['returnType']) ? $subNodes['returnType'] : null; $this->stmts = array_key_exists('stmts', $subNodes) ? $subNodes['stmts'] : array(); } public function getSubNodeNames() { return array('flags', 'byRef', 'name', 'params', 'returnType', 'stmts'); } public function returnsByRef() { return $this->byRef; } public function getParams() { return $this->params; } public function getReturnType() { return $this->returnType; } public function getStmts() { return $this->stmts; } public function isPublic() { return ($this->flags & Class_::MODIFIER_PUBLIC) !== 0 || ($this->flags & Class_::VISIBILITY_MODIFIER_MASK) === 0; } public function isProtected() { return (bool) ($this->flags & Class_::MODIFIER_PROTECTED); } public function isPrivate() { return (bool) ($this->flags & Class_::MODIFIER_PRIVATE); } public function isAbstract() { return (bool) ($this->flags & Class_::MODIFIER_ABSTRACT); } public function isFinal() { return (bool) ($this->flags & Class_::MODIFIER_FINAL); } public function isStatic() { return (bool) ($this->flags & Class_::MODIFIER_STATIC); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Stmt/Class_.php000066400000000000000000000063721323244626500216220ustar00rootroot00000000000000 true, 'parent' => true, 'static' => true, ); /** * Constructs a class node. * * @param string|null $name Name * @param array $subNodes Array of the following optional subnodes: * 'flags' => 0 : Flags * 'extends' => null : Name of extended class * 'implements' => array(): Names of implemented interfaces * 'stmts' => array(): Statements * @param array $attributes Additional attributes */ public function __construct($name, array $subNodes = array(), array $attributes = array()) { parent::__construct($attributes); $this->flags = isset($subNodes['flags']) ? $subNodes['flags'] : (isset($subNodes['type']) ? $subNodes['type'] : 0); $this->type = $this->flags; $this->name = $name; $this->extends = isset($subNodes['extends']) ? $subNodes['extends'] : null; $this->implements = isset($subNodes['implements']) ? $subNodes['implements'] : array(); $this->stmts = isset($subNodes['stmts']) ? $subNodes['stmts'] : array(); } public function getSubNodeNames() { return array('flags', 'name', 'extends', 'implements', 'stmts'); } public function isAbstract() { return (bool) ($this->flags & self::MODIFIER_ABSTRACT); } public function isFinal() { return (bool) ($this->flags & self::MODIFIER_FINAL); } public function isAnonymous() { return null === $this->name; } /** * @internal */ public static function verifyModifier($a, $b) { if ($a & self::VISIBILITY_MODIFIER_MASK && $b & self::VISIBILITY_MODIFIER_MASK) { throw new Error('Multiple access type modifiers are not allowed'); } if ($a & self::MODIFIER_ABSTRACT && $b & self::MODIFIER_ABSTRACT) { throw new Error('Multiple abstract modifiers are not allowed'); } if ($a & self::MODIFIER_STATIC && $b & self::MODIFIER_STATIC) { throw new Error('Multiple static modifiers are not allowed'); } if ($a & self::MODIFIER_FINAL && $b & self::MODIFIER_FINAL) { throw new Error('Multiple final modifiers are not allowed'); } if ($a & 48 && $b & 48) { throw new Error('Cannot use the final modifier on an abstract class member'); } } } PHP-Parser-3.1.4/lib/PhpParser/Node/Stmt/Const_.php000066400000000000000000000011161323244626500216320ustar00rootroot00000000000000consts = $consts; } public function getSubNodeNames() { return array('consts'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Stmt/Continue_.php000066400000000000000000000011321323244626500223260ustar00rootroot00000000000000num = $num; } public function getSubNodeNames() { return array('num'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Stmt/DeclareDeclare.php000066400000000000000000000012621323244626500232260ustar00rootroot00000000000000value pair node. * * @param string $key Key * @param Node\Expr $value Value * @param array $attributes Additional attributes */ public function __construct($key, Node\Expr $value, array $attributes = array()) { parent::__construct($attributes); $this->key = $key; $this->value = $value; } public function getSubNodeNames() { return array('key', 'value'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Stmt/Declare_.php000066400000000000000000000013761323244626500221130ustar00rootroot00000000000000declares = $declares; $this->stmts = $stmts; } public function getSubNodeNames() { return array('declares', 'stmts'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Stmt/Do_.php000066400000000000000000000013031323244626500211040ustar00rootroot00000000000000cond = $cond; $this->stmts = $stmts; } public function getSubNodeNames() { return array('cond', 'stmts'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Stmt/Echo_.php000066400000000000000000000010511323244626500214200ustar00rootroot00000000000000exprs = $exprs; } public function getSubNodeNames() { return array('exprs'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Stmt/ElseIf_.php000066400000000000000000000013061323244626500217140ustar00rootroot00000000000000cond = $cond; $this->stmts = $stmts; } public function getSubNodeNames() { return array('cond', 'stmts'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Stmt/Else_.php000066400000000000000000000010421323244626500214320ustar00rootroot00000000000000stmts = $stmts; } public function getSubNodeNames() { return array('stmts'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Stmt/Finally_.php000066400000000000000000000010471323244626500221450ustar00rootroot00000000000000stmts = $stmts; } public function getSubNodeNames() { return array('stmts'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Stmt/For_.php000066400000000000000000000025011323244626500212710ustar00rootroot00000000000000 array(): Init expressions * 'cond' => array(): Loop conditions * 'loop' => array(): Loop expressions * 'stmts' => array(): Statements * @param array $attributes Additional attributes */ public function __construct(array $subNodes = array(), array $attributes = array()) { parent::__construct($attributes); $this->init = isset($subNodes['init']) ? $subNodes['init'] : array(); $this->cond = isset($subNodes['cond']) ? $subNodes['cond'] : array(); $this->loop = isset($subNodes['loop']) ? $subNodes['loop'] : array(); $this->stmts = isset($subNodes['stmts']) ? $subNodes['stmts'] : array(); } public function getSubNodeNames() { return array('init', 'cond', 'loop', 'stmts'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Stmt/Foreach_.php000066400000000000000000000031071323244626500221150ustar00rootroot00000000000000 null : Variable to assign key to * 'byRef' => false : Whether to assign value by reference * 'stmts' => array(): Statements * @param array $attributes Additional attributes */ public function __construct(Node\Expr $expr, Node\Expr $valueVar, array $subNodes = array(), array $attributes = array()) { parent::__construct($attributes); $this->expr = $expr; $this->keyVar = isset($subNodes['keyVar']) ? $subNodes['keyVar'] : null; $this->byRef = isset($subNodes['byRef']) ? $subNodes['byRef'] : false; $this->valueVar = $valueVar; $this->stmts = isset($subNodes['stmts']) ? $subNodes['stmts'] : array(); } public function getSubNodeNames() { return array('expr', 'keyVar', 'byRef', 'valueVar', 'stmts'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Stmt/Function_.php000066400000000000000000000036121323244626500223340ustar00rootroot00000000000000 false : Whether to return by reference * 'params' => array(): Parameters * 'returnType' => null : Return type * 'stmts' => array(): Statements * @param array $attributes Additional attributes */ public function __construct($name, array $subNodes = array(), array $attributes = array()) { parent::__construct($attributes); $this->byRef = isset($subNodes['byRef']) ? $subNodes['byRef'] : false; $this->name = $name; $this->params = isset($subNodes['params']) ? $subNodes['params'] : array(); $this->returnType = isset($subNodes['returnType']) ? $subNodes['returnType'] : null; $this->stmts = isset($subNodes['stmts']) ? $subNodes['stmts'] : array(); } public function getSubNodeNames() { return array('byRef', 'name', 'params', 'returnType', 'stmts'); } public function returnsByRef() { return $this->byRef; } public function getParams() { return $this->params; } public function getReturnType() { return $this->returnType; } public function getStmts() { return $this->stmts; } } PHP-Parser-3.1.4/lib/PhpParser/Node/Stmt/Global_.php000066400000000000000000000010731323244626500217460ustar00rootroot00000000000000vars = $vars; } public function getSubNodeNames() { return array('vars'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Stmt/Goto_.php000066400000000000000000000010501323244626500214510ustar00rootroot00000000000000name = $name; } public function getSubNodeNames() { return array('name'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Stmt/GroupUse.php000066400000000000000000000015771323244626500221710ustar00rootroot00000000000000type = $type; $this->prefix = $prefix; $this->uses = $uses; } public function getSubNodeNames() { return array('type', 'prefix', 'uses'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Stmt/HaltCompiler.php000066400000000000000000000011751323244626500227750ustar00rootroot00000000000000remaining = $remaining; } public function getSubNodeNames() { return array('remaining'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Stmt/If_.php000066400000000000000000000024351323244626500211070ustar00rootroot00000000000000 array(): Statements * 'elseifs' => array(): Elseif clauses * 'else' => null : Else clause * @param array $attributes Additional attributes */ public function __construct(Node\Expr $cond, array $subNodes = array(), array $attributes = array()) { parent::__construct($attributes); $this->cond = $cond; $this->stmts = isset($subNodes['stmts']) ? $subNodes['stmts'] : array(); $this->elseifs = isset($subNodes['elseifs']) ? $subNodes['elseifs'] : array(); $this->else = isset($subNodes['else']) ? $subNodes['else'] : null; } public function getSubNodeNames() { return array('cond', 'stmts', 'elseifs', 'else'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Stmt/InlineHTML.php000066400000000000000000000010261323244626500223100ustar00rootroot00000000000000value = $value; } public function getSubNodeNames() { return array('value'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Stmt/Interface_.php000066400000000000000000000017241323244626500224510ustar00rootroot00000000000000 array(): Name of extended interfaces * 'stmts' => array(): Statements * @param array $attributes Additional attributes */ public function __construct($name, array $subNodes = array(), array $attributes = array()) { parent::__construct($attributes); $this->name = $name; $this->extends = isset($subNodes['extends']) ? $subNodes['extends'] : array(); $this->stmts = isset($subNodes['stmts']) ? $subNodes['stmts'] : array(); } public function getSubNodeNames() { return array('name', 'extends', 'stmts'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Stmt/Label.php000066400000000000000000000010011323244626500214150ustar00rootroot00000000000000name = $name; } public function getSubNodeNames() { return array('name'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Stmt/Namespace_.php000066400000000000000000000014721323244626500224450ustar00rootroot00000000000000name = $name; $this->stmts = $stmts; } public function getSubNodeNames() { return array('name', 'stmts'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Stmt/Nop.php000066400000000000000000000003021323244626500211350ustar00rootroot00000000000000flags = $flags; $this->type = $flags; $this->props = $props; } public function getSubNodeNames() { return array('flags', 'props'); } public function isPublic() { return ($this->flags & Class_::MODIFIER_PUBLIC) !== 0 || ($this->flags & Class_::VISIBILITY_MODIFIER_MASK) === 0; } public function isProtected() { return (bool) ($this->flags & Class_::MODIFIER_PROTECTED); } public function isPrivate() { return (bool) ($this->flags & Class_::MODIFIER_PRIVATE); } public function isStatic() { return (bool) ($this->flags & Class_::MODIFIER_STATIC); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Stmt/PropertyProperty.php000066400000000000000000000013411323244626500237760ustar00rootroot00000000000000name = $name; $this->default = $default; } public function getSubNodeNames() { return array('name', 'default'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Stmt/Return_.php000066400000000000000000000010711323244626500220230ustar00rootroot00000000000000expr = $expr; } public function getSubNodeNames() { return array('expr'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Stmt/StaticVar.php000066400000000000000000000013411323244626500223050ustar00rootroot00000000000000name = $name; $this->default = $default; } public function getSubNodeNames() { return array('name', 'default'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Stmt/Static_.php000066400000000000000000000011101323244626500217650ustar00rootroot00000000000000vars = $vars; } public function getSubNodeNames() { return array('vars'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Stmt/Switch_.php000066400000000000000000000012701323244626500220060ustar00rootroot00000000000000cond = $cond; $this->cases = $cases; } public function getSubNodeNames() { return array('cond', 'cases'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Stmt/Throw_.php000066400000000000000000000010411323244626500216440ustar00rootroot00000000000000expr = $expr; } public function getSubNodeNames() { return array('expr'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Stmt/TraitUse.php000066400000000000000000000014361323244626500221520ustar00rootroot00000000000000traits = $traits; $this->adaptations = $adaptations; } public function getSubNodeNames() { return array('traits', 'adaptations'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Stmt/TraitUseAdaptation.php000066400000000000000000000003431323244626500241530ustar00rootroot00000000000000trait = $trait; $this->method = $method; $this->newModifier = $newModifier; $this->newName = $newName; } public function getSubNodeNames() { return array('trait', 'method', 'newModifier', 'newName'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Stmt/TraitUseAdaptation/Precedence.php000066400000000000000000000015451323244626500262150ustar00rootroot00000000000000trait = $trait; $this->method = $method; $this->insteadof = $insteadof; } public function getSubNodeNames() { return array('trait', 'method', 'insteadof'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Stmt/Trait_.php000066400000000000000000000013231323244626500216270ustar00rootroot00000000000000 array(): Statements * @param array $attributes Additional attributes */ public function __construct($name, array $subNodes = array(), array $attributes = array()) { parent::__construct($attributes); $this->name = $name; $this->stmts = isset($subNodes['stmts']) ? $subNodes['stmts'] : array(); } public function getSubNodeNames() { return array('name', 'stmts'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Stmt/TryCatch.php000066400000000000000000000016411323244626500221310ustar00rootroot00000000000000stmts = $stmts; $this->catches = $catches; $this->finally = $finally; } public function getSubNodeNames() { return array('stmts', 'catches', 'finally'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Stmt/Unset_.php000066400000000000000000000010641323244626500216440ustar00rootroot00000000000000vars = $vars; } public function getSubNodeNames() { return array('vars'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Stmt/UseUse.php000066400000000000000000000021601323244626500216160ustar00rootroot00000000000000getLast(); } parent::__construct($attributes); $this->type = $type; $this->name = $name; $this->alias = $alias; } public function getSubNodeNames() { return array('type', 'name', 'alias'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Stmt/Use_.php000066400000000000000000000023571323244626500213100ustar00rootroot00000000000000type = $type; $this->uses = $uses; } public function getSubNodeNames() { return array('type', 'uses'); } } PHP-Parser-3.1.4/lib/PhpParser/Node/Stmt/While_.php000066400000000000000000000013031323244626500216120ustar00rootroot00000000000000cond = $cond; $this->stmts = $stmts; } public function getSubNodeNames() { return array('cond', 'stmts'); } } PHP-Parser-3.1.4/lib/PhpParser/NodeAbstract.php000066400000000000000000000056511323244626500211520ustar00rootroot00000000000000attributes = $attributes; } /** * Gets the type of the node. * * @return string Type of the node */ public function getType() { $className = rtrim(get_class($this), '_'); return strtr( substr( $className, strpos($className, 'PhpParser\Node') + 15 ), '\\', '_' ); } /** * Gets line the node started in. * * @return int Line */ public function getLine() { return $this->getAttribute('startLine', -1); } /** * Sets line the node started in. * * @param int $line Line * * @deprecated */ public function setLine($line) { $this->setAttribute('startLine', (int) $line); } /** * Gets the doc comment of the node. * * The doc comment has to be the last comment associated with the node. * * @return null|Comment\Doc Doc comment object or null */ public function getDocComment() { $comments = $this->getAttribute('comments'); if (!$comments) { return null; } $lastComment = $comments[count($comments) - 1]; if (!$lastComment instanceof Comment\Doc) { return null; } return $lastComment; } /** * Sets the doc comment of the node. * * This will either replace an existing doc comment or add it to the comments array. * * @param Comment\Doc $docComment Doc comment to set */ public function setDocComment(Comment\Doc $docComment) { $comments = $this->getAttribute('comments', []); $numComments = count($comments); if ($numComments > 0 && $comments[$numComments - 1] instanceof Comment\Doc) { // Replace existing doc comment $comments[$numComments - 1] = $docComment; } else { // Append new comment $comments[] = $docComment; } $this->setAttribute('comments', $comments); } public function setAttribute($key, $value) { $this->attributes[$key] = $value; } public function hasAttribute($key) { return array_key_exists($key, $this->attributes); } public function &getAttribute($key, $default = null) { if (!array_key_exists($key, $this->attributes)) { return $default; } else { return $this->attributes[$key]; } } public function getAttributes() { return $this->attributes; } public function jsonSerialize() { return ['nodeType' => $this->getType()] + get_object_vars($this); } } PHP-Parser-3.1.4/lib/PhpParser/NodeDumper.php000066400000000000000000000146211323244626500206400ustar00rootroot00000000000000dumpComments = !empty($options['dumpComments']); $this->dumpPositions = !empty($options['dumpPositions']); } /** * Dumps a node or array. * * @param array|Node $node Node or array to dump * @param string|null $code Code corresponding to dumped AST. This only needs to be passed if * the dumpPositions option is enabled and the dumping of node offsets * is desired. * * @return string Dumped value */ public function dump($node, $code = null) { $this->code = $code; return $this->dumpRecursive($node); } protected function dumpRecursive($node) { if ($node instanceof Node) { $r = $node->getType(); if ($this->dumpPositions && null !== $p = $this->dumpPosition($node)) { $r .= $p; } $r .= '('; foreach ($node->getSubNodeNames() as $key) { $r .= "\n " . $key . ': '; $value = $node->$key; if (null === $value) { $r .= 'null'; } elseif (false === $value) { $r .= 'false'; } elseif (true === $value) { $r .= 'true'; } elseif (is_scalar($value)) { if ('flags' === $key || 'newModifier' === $key) { $r .= $this->dumpFlags($value); } else if ('type' === $key && $node instanceof Include_) { $r .= $this->dumpIncludeType($value); } else if ('type' === $key && ($node instanceof Use_ || $node instanceof UseUse || $node instanceof GroupUse)) { $r .= $this->dumpUseType($value); } else { $r .= $value; } } else { $r .= str_replace("\n", "\n ", $this->dumpRecursive($value)); } } if ($this->dumpComments && $comments = $node->getAttribute('comments')) { $r .= "\n comments: " . str_replace("\n", "\n ", $this->dumpRecursive($comments)); } } elseif (is_array($node)) { $r = 'array('; foreach ($node as $key => $value) { $r .= "\n " . $key . ': '; if (null === $value) { $r .= 'null'; } elseif (false === $value) { $r .= 'false'; } elseif (true === $value) { $r .= 'true'; } elseif (is_scalar($value)) { $r .= $value; } else { $r .= str_replace("\n", "\n ", $this->dumpRecursive($value)); } } } elseif ($node instanceof Comment) { return $node->getReformattedText(); } else { throw new \InvalidArgumentException('Can only dump nodes and arrays.'); } return $r . "\n)"; } protected function dumpFlags($flags) { $strs = []; if ($flags & Class_::MODIFIER_PUBLIC) { $strs[] = 'MODIFIER_PUBLIC'; } if ($flags & Class_::MODIFIER_PROTECTED) { $strs[] = 'MODIFIER_PROTECTED'; } if ($flags & Class_::MODIFIER_PRIVATE) { $strs[] = 'MODIFIER_PRIVATE'; } if ($flags & Class_::MODIFIER_ABSTRACT) { $strs[] = 'MODIFIER_ABSTRACT'; } if ($flags & Class_::MODIFIER_STATIC) { $strs[] = 'MODIFIER_STATIC'; } if ($flags & Class_::MODIFIER_FINAL) { $strs[] = 'MODIFIER_FINAL'; } if ($strs) { return implode(' | ', $strs) . ' (' . $flags . ')'; } else { return $flags; } } protected function dumpIncludeType($type) { $map = [ Include_::TYPE_INCLUDE => 'TYPE_INCLUDE', Include_::TYPE_INCLUDE_ONCE => 'TYPE_INCLUDE_ONCE', Include_::TYPE_REQUIRE => 'TYPE_REQUIRE', Include_::TYPE_REQUIRE_ONCE => 'TYPE_REQURE_ONCE', ]; if (!isset($map[$type])) { return $type; } return $map[$type] . ' (' . $type . ')'; } protected function dumpUseType($type) { $map = [ Use_::TYPE_UNKNOWN => 'TYPE_UNKNOWN', Use_::TYPE_NORMAL => 'TYPE_NORMAL', Use_::TYPE_FUNCTION => 'TYPE_FUNCTION', Use_::TYPE_CONSTANT => 'TYPE_CONSTANT', ]; if (!isset($map[$type])) { return $type; } return $map[$type] . ' (' . $type . ')'; } protected function dumpPosition(Node $node) { if (!$node->hasAttribute('startLine') || !$node->hasAttribute('endLine')) { return null; } $start = $node->getAttribute('startLine'); $end = $node->getAttribute('endLine'); if ($node->hasAttribute('startFilePos') && $node->hasAttribute('endFilePos') && null !== $this->code ) { $start .= ':' . $this->toColumn($this->code, $node->getAttribute('startFilePos')); $end .= ':' . $this->toColumn($this->code, $node->getAttribute('endFilePos')); } return "[$start - $end]"; } // Copied from Error class private function toColumn($code, $pos) { if ($pos > strlen($code)) { throw new \RuntimeException('Invalid position information'); } $lineStartPos = strrpos($code, "\n", $pos - strlen($code)); if (false === $lineStartPos) { $lineStartPos = -1; } return $pos - $lineStartPos; } } PHP-Parser-3.1.4/lib/PhpParser/NodeTraverser.php000066400000000000000000000144771323244626500213720ustar00rootroot00000000000000visitors = array(); } /** * Adds a visitor. * * @param NodeVisitor $visitor Visitor to add */ public function addVisitor(NodeVisitor $visitor) { $this->visitors[] = $visitor; } /** * Removes an added visitor. * * @param NodeVisitor $visitor */ public function removeVisitor(NodeVisitor $visitor) { foreach ($this->visitors as $index => $storedVisitor) { if ($storedVisitor === $visitor) { unset($this->visitors[$index]); break; } } } /** * Traverses an array of nodes using the registered visitors. * * @param Node[] $nodes Array of nodes * * @return Node[] Traversed array of nodes */ public function traverse(array $nodes) { $this->stopTraversal = false; foreach ($this->visitors as $visitor) { if (null !== $return = $visitor->beforeTraverse($nodes)) { $nodes = $return; } } $nodes = $this->traverseArray($nodes); foreach ($this->visitors as $visitor) { if (null !== $return = $visitor->afterTraverse($nodes)) { $nodes = $return; } } return $nodes; } protected function traverseNode(Node $node) { foreach ($node->getSubNodeNames() as $name) { $subNode =& $node->$name; if (is_array($subNode)) { $subNode = $this->traverseArray($subNode); if ($this->stopTraversal) { break; } } elseif ($subNode instanceof Node) { $traverseChildren = true; foreach ($this->visitors as $visitor) { $return = $visitor->enterNode($subNode); if (self::DONT_TRAVERSE_CHILDREN === $return) { $traverseChildren = false; } else if (self::STOP_TRAVERSAL === $return) { $this->stopTraversal = true; break 2; } else if (null !== $return) { $subNode = $return; } } if ($traverseChildren) { $subNode = $this->traverseNode($subNode); if ($this->stopTraversal) { break; } } foreach ($this->visitors as $visitor) { $return = $visitor->leaveNode($subNode); if (self::STOP_TRAVERSAL === $return) { $this->stopTraversal = true; break 2; } else if (null !== $return) { if (is_array($return)) { throw new \LogicException( 'leaveNode() may only return an array ' . 'if the parent structure is an array' ); } $subNode = $return; } } } } return $node; } protected function traverseArray(array $nodes) { $doNodes = array(); foreach ($nodes as $i => &$node) { if (is_array($node)) { $node = $this->traverseArray($node); if ($this->stopTraversal) { break; } } elseif ($node instanceof Node) { $traverseChildren = true; foreach ($this->visitors as $visitor) { $return = $visitor->enterNode($node); if (self::DONT_TRAVERSE_CHILDREN === $return) { $traverseChildren = false; } else if (self::STOP_TRAVERSAL === $return) { $this->stopTraversal = true; break 2; } else if (null !== $return) { $node = $return; } } if ($traverseChildren) { $node = $this->traverseNode($node); if ($this->stopTraversal) { break; } } foreach ($this->visitors as $visitor) { $return = $visitor->leaveNode($node); if (self::REMOVE_NODE === $return) { $doNodes[] = array($i, array()); break; } else if (self::STOP_TRAVERSAL === $return) { $this->stopTraversal = true; break 2; } elseif (is_array($return)) { $doNodes[] = array($i, $return); break; } elseif (null !== $return) { $node = $return; } } } } if (!empty($doNodes)) { while (list($i, $replace) = array_pop($doNodes)) { array_splice($nodes, $i, 1, $replace); } } return $nodes; } } PHP-Parser-3.1.4/lib/PhpParser/NodeTraverserInterface.php000066400000000000000000000011001323244626500231660ustar00rootroot00000000000000 $node stays as-is * * NodeTraverser::DONT_TRAVERSE_CHILDREN * => Children of $node are not traversed. $node stays as-is * * NodeTraverser::STOP_TRAVERSAL * => Traversal is aborted. $node stays as-is * * otherwise * => $node is set to the return value * * @param Node $node Node * * @return null|int|Node Node */ public function enterNode(Node $node); /** * Called when leaving a node. * * Return value semantics: * * null * => $node stays as-is * * NodeTraverser::REMOVE_NODE * => $node is removed from the parent array * * NodeTraverser::STOP_TRAVERSAL * => Traversal is aborted. $node stays as-is * * array (of Nodes) * => The return value is merged into the parent array (at the position of the $node) * * otherwise * => $node is set to the return value * * @param Node $node Node * * @return null|false|int|Node|Node[] Node */ public function leaveNode(Node $node); /** * Called once after traversal. * * Return value semantics: * * null: $nodes stays as-is * * otherwise: $nodes is set to the return value * * @param Node[] $nodes Array of nodes * * @return null|Node[] Array of nodes */ public function afterTraverse(array $nodes); }PHP-Parser-3.1.4/lib/PhpParser/NodeVisitor/000077500000000000000000000000001323244626500203265ustar00rootroot00000000000000PHP-Parser-3.1.4/lib/PhpParser/NodeVisitor/NameResolver.php000066400000000000000000000240121323244626500234400ustar00rootroot00000000000000 [aliasName => originalName]] */ protected $aliases; /** @var ErrorHandler Error handler */ protected $errorHandler; /** @var bool Whether to preserve original names */ protected $preserveOriginalNames; /** * Constructs a name resolution visitor. * * Options: If "preserveOriginalNames" is enabled, an "originalName" attribute will be added to * all name nodes that underwent resolution. * * @param ErrorHandler|null $errorHandler Error handler * @param array $options Options */ public function __construct(ErrorHandler $errorHandler = null, array $options = []) { $this->errorHandler = $errorHandler ?: new ErrorHandler\Throwing; $this->preserveOriginalNames = !empty($options['preserveOriginalNames']); } public function beforeTraverse(array $nodes) { $this->resetState(); } public function enterNode(Node $node) { if ($node instanceof Stmt\Namespace_) { $this->resetState($node->name); } elseif ($node instanceof Stmt\Use_) { foreach ($node->uses as $use) { $this->addAlias($use, $node->type, null); } } elseif ($node instanceof Stmt\GroupUse) { foreach ($node->uses as $use) { $this->addAlias($use, $node->type, $node->prefix); } } elseif ($node instanceof Stmt\Class_) { if (null !== $node->extends) { $node->extends = $this->resolveClassName($node->extends); } foreach ($node->implements as &$interface) { $interface = $this->resolveClassName($interface); } if (null !== $node->name) { $this->addNamespacedName($node); } } elseif ($node instanceof Stmt\Interface_) { foreach ($node->extends as &$interface) { $interface = $this->resolveClassName($interface); } $this->addNamespacedName($node); } elseif ($node instanceof Stmt\Trait_) { $this->addNamespacedName($node); } elseif ($node instanceof Stmt\Function_) { $this->addNamespacedName($node); $this->resolveSignature($node); } elseif ($node instanceof Stmt\ClassMethod || $node instanceof Expr\Closure ) { $this->resolveSignature($node); } elseif ($node instanceof Stmt\Const_) { foreach ($node->consts as $const) { $this->addNamespacedName($const); } } elseif ($node instanceof Expr\StaticCall || $node instanceof Expr\StaticPropertyFetch || $node instanceof Expr\ClassConstFetch || $node instanceof Expr\New_ || $node instanceof Expr\Instanceof_ ) { if ($node->class instanceof Name) { $node->class = $this->resolveClassName($node->class); } } elseif ($node instanceof Stmt\Catch_) { foreach ($node->types as &$type) { $type = $this->resolveClassName($type); } } elseif ($node instanceof Expr\FuncCall) { if ($node->name instanceof Name) { $node->name = $this->resolveOtherName($node->name, Stmt\Use_::TYPE_FUNCTION); } } elseif ($node instanceof Expr\ConstFetch) { $node->name = $this->resolveOtherName($node->name, Stmt\Use_::TYPE_CONSTANT); } elseif ($node instanceof Stmt\TraitUse) { foreach ($node->traits as &$trait) { $trait = $this->resolveClassName($trait); } foreach ($node->adaptations as $adaptation) { if (null !== $adaptation->trait) { $adaptation->trait = $this->resolveClassName($adaptation->trait); } if ($adaptation instanceof Stmt\TraitUseAdaptation\Precedence) { foreach ($adaptation->insteadof as &$insteadof) { $insteadof = $this->resolveClassName($insteadof); } } } } } protected function resetState(Name $namespace = null) { $this->namespace = $namespace; $this->aliases = array( Stmt\Use_::TYPE_NORMAL => array(), Stmt\Use_::TYPE_FUNCTION => array(), Stmt\Use_::TYPE_CONSTANT => array(), ); } protected function addAlias(Stmt\UseUse $use, $type, Name $prefix = null) { // Add prefix for group uses $name = $prefix ? Name::concat($prefix, $use->name) : $use->name; // Type is determined either by individual element or whole use declaration $type |= $use->type; // Constant names are case sensitive, everything else case insensitive if ($type === Stmt\Use_::TYPE_CONSTANT) { $aliasName = $use->alias; } else { $aliasName = strtolower($use->alias); } if (isset($this->aliases[$type][$aliasName])) { $typeStringMap = array( Stmt\Use_::TYPE_NORMAL => '', Stmt\Use_::TYPE_FUNCTION => 'function ', Stmt\Use_::TYPE_CONSTANT => 'const ', ); $this->errorHandler->handleError(new Error( sprintf( 'Cannot use %s%s as %s because the name is already in use', $typeStringMap[$type], $name, $use->alias ), $use->getAttributes() )); return; } $this->aliases[$type][$aliasName] = $name; } /** @param Stmt\Function_|Stmt\ClassMethod|Expr\Closure $node */ private function resolveSignature($node) { foreach ($node->params as $param) { $param->type = $this->resolveType($param->type); } $node->returnType = $this->resolveType($node->returnType); } private function resolveType($node) { if ($node instanceof Node\NullableType) { $node->type = $this->resolveType($node->type); return $node; } if ($node instanceof Name) { return $this->resolveClassName($node); } return $node; } protected function resolveClassName(Name $name) { if ($this->preserveOriginalNames) { // Save the original name $originalName = $name; $name = clone $originalName; $name->setAttribute('originalName', $originalName); } // don't resolve special class names if (in_array(strtolower($name->toString()), array('self', 'parent', 'static'))) { if (!$name->isUnqualified()) { $this->errorHandler->handleError(new Error( sprintf("'\\%s' is an invalid class name", $name->toString()), $name->getAttributes() )); } return $name; } // fully qualified names are already resolved if ($name->isFullyQualified()) { return $name; } $aliasName = strtolower($name->getFirst()); if (!$name->isRelative() && isset($this->aliases[Stmt\Use_::TYPE_NORMAL][$aliasName])) { // resolve aliases (for non-relative names) $alias = $this->aliases[Stmt\Use_::TYPE_NORMAL][$aliasName]; return FullyQualified::concat($alias, $name->slice(1), $name->getAttributes()); } // if no alias exists prepend current namespace return FullyQualified::concat($this->namespace, $name, $name->getAttributes()); } protected function resolveOtherName(Name $name, $type) { if ($this->preserveOriginalNames) { // Save the original name $originalName = $name; $name = clone $originalName; $name->setAttribute('originalName', $originalName); } // fully qualified names are already resolved if ($name->isFullyQualified()) { return $name; } // resolve aliases for qualified names $aliasName = strtolower($name->getFirst()); if ($name->isQualified() && isset($this->aliases[Stmt\Use_::TYPE_NORMAL][$aliasName])) { $alias = $this->aliases[Stmt\Use_::TYPE_NORMAL][$aliasName]; return FullyQualified::concat($alias, $name->slice(1), $name->getAttributes()); } if ($name->isUnqualified()) { if ($type === Stmt\Use_::TYPE_CONSTANT) { // constant aliases are case-sensitive, function aliases case-insensitive $aliasName = $name->getFirst(); } if (isset($this->aliases[$type][$aliasName])) { // resolve unqualified aliases return new FullyQualified($this->aliases[$type][$aliasName], $name->getAttributes()); } if (null === $this->namespace) { // outside of a namespace unaliased unqualified is same as fully qualified return new FullyQualified($name, $name->getAttributes()); } // unqualified names inside a namespace cannot be resolved at compile-time // add the namespaced version of the name as an attribute $name->setAttribute('namespacedName', FullyQualified::concat($this->namespace, $name, $name->getAttributes())); return $name; } // if no alias exists prepend current namespace return FullyQualified::concat($this->namespace, $name, $name->getAttributes()); } protected function addNamespacedName(Node $node) { $node->namespacedName = Name::concat($this->namespace, $node->name); } } PHP-Parser-3.1.4/lib/PhpParser/NodeVisitorAbstract.php000066400000000000000000000004741323244626500225300ustar00rootroot00000000000000parsers = $parsers; } public function parse($code, ErrorHandler $errorHandler = null) { if (null === $errorHandler) { $errorHandler = new ErrorHandler\Throwing; } list($firstStmts, $firstError) = $this->tryParse($this->parsers[0], $errorHandler, $code); if ($firstError === null) { return $firstStmts; } for ($i = 1, $c = count($this->parsers); $i < $c; ++$i) { list($stmts, $error) = $this->tryParse($this->parsers[$i], $errorHandler, $code); if ($error === null) { return $stmts; } } throw $firstError; } private function tryParse(Parser $parser, ErrorHandler $errorHandler, $code) { $stmts = null; $error = null; try { $stmts = $parser->parse($code, $errorHandler); } catch (Error $error) {} return [$stmts, $error]; } } PHP-Parser-3.1.4/lib/PhpParser/Parser/Php5.php000066400000000000000000004655101323244626500206550ustar00rootroot00000000000000'", "T_IS_GREATER_OR_EQUAL", "T_SL", "T_SR", "'+'", "'-'", "'.'", "'*'", "'/'", "'%'", "'!'", "T_INSTANCEOF", "'~'", "T_INC", "T_DEC", "T_INT_CAST", "T_DOUBLE_CAST", "T_STRING_CAST", "T_ARRAY_CAST", "T_OBJECT_CAST", "T_BOOL_CAST", "T_UNSET_CAST", "'@'", "T_POW", "'['", "T_NEW", "T_CLONE", "T_EXIT", "T_IF", "T_ELSEIF", "T_ELSE", "T_ENDIF", "T_LNUMBER", "T_DNUMBER", "T_STRING", "T_STRING_VARNAME", "T_VARIABLE", "T_NUM_STRING", "T_INLINE_HTML", "T_ENCAPSED_AND_WHITESPACE", "T_CONSTANT_ENCAPSED_STRING", "T_ECHO", "T_DO", "T_WHILE", "T_ENDWHILE", "T_FOR", "T_ENDFOR", "T_FOREACH", "T_ENDFOREACH", "T_DECLARE", "T_ENDDECLARE", "T_AS", "T_SWITCH", "T_ENDSWITCH", "T_CASE", "T_DEFAULT", "T_BREAK", "T_CONTINUE", "T_GOTO", "T_FUNCTION", "T_CONST", "T_RETURN", "T_TRY", "T_CATCH", "T_FINALLY", "T_THROW", "T_USE", "T_INSTEADOF", "T_GLOBAL", "T_STATIC", "T_ABSTRACT", "T_FINAL", "T_PRIVATE", "T_PROTECTED", "T_PUBLIC", "T_VAR", "T_UNSET", "T_ISSET", "T_EMPTY", "T_HALT_COMPILER", "T_CLASS", "T_TRAIT", "T_INTERFACE", "T_EXTENDS", "T_IMPLEMENTS", "T_OBJECT_OPERATOR", "T_LIST", "T_ARRAY", "T_CALLABLE", "T_CLASS_C", "T_TRAIT_C", "T_METHOD_C", "T_FUNC_C", "T_LINE", "T_FILE", "T_START_HEREDOC", "T_END_HEREDOC", "T_DOLLAR_OPEN_CURLY_BRACES", "T_CURLY_OPEN", "T_PAAMAYIM_NEKUDOTAYIM", "T_NAMESPACE", "T_NS_C", "T_DIR", "T_NS_SEPARATOR", "T_ELLIPSIS", "';'", "'{'", "'}'", "'('", "')'", "'$'", "'`'", "']'", "'\"'" ); protected $tokenToSymbol = array( 0, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 53, 156, 157, 153, 52, 35, 157, 151, 152, 50, 47, 7, 48, 49, 51, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 29, 148, 41, 15, 43, 28, 65, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 67, 157, 155, 34, 157, 154, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 149, 33, 150, 55, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 30, 31, 32, 36, 37, 38, 39, 40, 42, 44, 45, 46, 54, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 157, 157, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 157, 157, 157, 157, 157, 157, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147 ); protected $action = array( 672, 673, 674, 675, 676,-32766, 677, 678, 679, 715, 716, 216, 217, 218, 219, 220, 221, 222, 223, 224, 0, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236,-32766,-32766,-32766,-32766,-32766,-32766,-32766, -32766,-32767,-32767,-32767,-32767, 441, 237, 238,-32766,-32766, -32766,-32766, 680,-32766, 1036,-32766,-32766,-32766,-32766,-32766, -32766,-32767,-32767,-32767,-32767,-32767, 681, 682, 683, 684, 685, 686, 687, 909, 329, 747,-32766,-32766,-32766,-32766, -32766, 282, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 718, 719, 720, 721, 722, 710, 711, 712, 713, 714, 699, 700, 701, 702, 703, 704, 705, 741, 742, 743, 744, 745, 746, 706, 707, 708, 709, 739, 730, 728, 729, 725, 726, 1178, 717, 723, 724, 731, 732, 734, 733, 735, 736, 52, 53, 420, 54, 55, 727, 738, 737, 23, 56, 57, 284, 58,-32766, -32766,-32766,-32766,-32766,-32766,-32766,-32766,-32766, 7,-32767, -32767,-32767,-32767, 50, 325,-32766, 585, 945, 946, 947, 944, 943, 942, 937, 1213, 27, 1215, 1214, 763, 764, 821, 59, 60,-32766,-32766,-32766, 809, 61, 1172, 62, 291, 292, 63, 64, 65, 66, 67, 68, 69, 70, 334, 24, 299, 71, 413,-32766,-32766,-32766, 1185, 1087, 1088, 749, 633, 1178, 213, 214, 215, 464,-32766,-32766, -32766, 822, 407, 1099, 311,-32766, 1186,-32766,-32766,-32766, -32766,-32766,-32766, 1036, 200, -269, 428,-32766,-32766,-32766, -32766,-32766,-32766,-32766,-32766, 120, 491, 945, 946, 947, 944, 943, 942, 306, 473, 474, 293, 623, 125,-32766, 893, 894, 339, 477, 478,-32766, 1093, 1094, 1095, 1096, 1090, 1091, 307, 492,-32766, 440, 425, 492, 1097, 1092, 425, 121, -220, 869, 1182, 39, 280, 334, 321, 900, 322, 421, -122, -122, -122, -4, 822, 463, 99, 100, 101, 811, 301, 119, 38, 19, 422, -122, 465, -122, 466, -122, 467, -122, 102, 423, -122, -122, -122, 28, 29, 468, 424, 624, 30, 469, 425, 812, 72, 297, 923, 349, 350, 470, 471,-32766,-32766,-32766, 419, 472, 1036, 447, 793, 840, 475, 476,-32767,-32767,-32767,-32767, 94, 95, 96, 97, 98,-32766, 126,-32766,-32766,-32766, -32766, 1137, 213, 214, 215, 295, 421, 239, 824, 638, -122, 1036, 463, 893, 894, 1205, 811, 1036, 1204, 38, 19, 422, 200, 465, 356, 466, 492, 467, 127, 425, 423, 213, 214, 215, 28, 29, 468, 424, 414, 30, 469, 1036, 870, 72, 320, 822, 349, 350, 470, 471, 34, 200, 214, 215, 472, 460, 762, 755, 840, 475, 476, 213, 214, 215, 295, -216, 76, 77, 78, 46, 298, 200, 412, 653, 338, 438, 31, 294, 333, 8, 348, 200, 241, 824, 638, -4, 32, 332, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 1210, 301, 204, 822, 421, 805, 124,-32766,-32766, -32766, 463, 899, 1054, 102, 811, 18, 206, 38, 19, 422, 518, 465, 1172, 466, 546, 467, 47,-32766, 423, -32766,-32766, 647, 28, 29, 468, 822, 801, 30, 469, 415, 116, 72, 803, 49, 349, 350,-32766,-32766,-32766, -32766,-32766,-32766, 472, 477, 808, 234, 235, 236, 213, 214, 215, 1036, 215, 644, 1138, 124,-32766,-32766,-32766, -32766,-32766, 237, 238, 421, 231, 232, 233, 1099, 200, 463, 200, 824, 638, 811, 439, 918, 38, 19, 422, 1036, 465, 242, 466, 749, 467, 1178, 339, 423, 96, 97, 98, 28, 29, 468, 822, 421, 30, 469, 117, 919, 72, 463, 283, 349, 350, 811, 244, 1036, 38, 19, 422, 472, 465, 243, 466, 118, 467, 377, 1064, 423, 1036, 207, 642, 28, 29, 468, 822, 129, 30, 469, 296, 576, 72,-32766,-32766, 349, 350, 123, 205, 492, 824, 638, 425, 472, 115,-32766,-32766,-32766, 434, 492, 200, 640, 425, 820, 641,-32766,-32766, 429,-32766, 334, 237, 238, 454, 591, 421,-32766, 130, 357, 449, 20, 463, 128, 856, 638, 811, 763, 764, 38, 19, 422, 313, 465, 646, 466, 650, 467, 599, 600, 423, 833, 301, 605, 28, 29, 468, 822, 421, 30, 469, 756, 643, 72, 463, 299, 349, 350, 811, 922, 666, 38, 19, 422, 472, 465, 102, 466, 51, 467, 934, 656, 423, 512, 433, 48, 28, 29, 468, 41, 42, 30, 469, 43, 44, 72, 45, 435, 349, 350, 1057, 750, 1208, 824, 638, 776, 472, 749, 33, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 534, 533, 517, 513, 524, 437, 421, 602, 516, 622, 612, 619, 463, 582, 824, 638, 811, 595,-32766, 38, 19, 422, 632, 465, 579, 466, 240, 467, 975, 977, 423, 609, 1144, 279, 28, 29, 468, 12, -80, 30, 469, 537, 432, 72, 208, 209, 349, 350, 458, 1098, 210, 596, 211, 328, 472, 326, 11, 842, 323, 393, 4, 385, 408, 303, 202, 1034, 0, 0, 324, 208, 209, 841, 1087, 1088, 0, 210,-32766, 211, -497, -498, 1089, 312, 310, 824, 638, 477, 0, 0, 0, 202, 0, -398, 0, 0, 9, 0, 0, 1087, 1088, 3, -497,-32766, -406, 370, -407, 1089, 835, 639, 0, 384, 372, 409, 526, 434, 0, 0, 864, 857, 863, 872, 0, 813, 798, 819, 807, 761, 661, 565, 760, 1093, 1094, 1095, 1096, 1090, 1091, 383, 37, 36, 759, 926, 810, 1097, 1092, 854, 852, 302, 806, 929, 212, 818, -32766, 930, 565, 928, 1093, 1094, 1095, 1096, 1090, 1091, 383, 927, 796, 804, 660, 802, 1097, 1092, 649, 651, 75, 0, 652, 212, 654,-32766, 655, 658, 663, 664, 665, 405, 122, 330, 331, 406, 0, 1211, 757, 758, 839, 838, 766, 453, 1209, 1179, 1177, 1163, 1175, 1078, 911, 1183, 1173, 829, 836, 1038, 1039, 827, 935, 1212, 765, 837, 794, 662, 1050, 768, 767, 861, 862, 0, 304, 290, 289, 25, 26, 281, 203, 74, 305, 336, 411, 417, 35, 73,-32766, 40, 22, 0, 1015, 569, -217, 1016, 1103, 1080, 901, 1040, 1044, 1041, 629, 559, 461, 457, 455, 450, 378, 16, 15, 14, -216, 0, 0, -416, 0, 1045, 603, 1157, 1104, 1207, 1077, 1174, 1158, 1162, 1176, 1063, 1048, 1049, 1046, 1047, 0, 1143 ); protected $actionCheck = array( 2, 3, 4, 5, 6, 8, 8, 9, 10, 11, 12, 31, 32, 33, 34, 35, 36, 37, 38, 39, 0, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 8, 9, 10, 31, 32, 33, 34, 35, 36, 37, 38, 39, 7, 66, 67, 31, 32, 33, 34, 54, 28, 12, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 68, 69, 70, 71, 72, 73, 74, 79, 7, 77, 31, 32, 33, 34, 35, 7, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 79, 129, 130, 131, 132, 133, 134, 135, 136, 137, 2, 3, 4, 5, 6, 143, 144, 145, 7, 11, 12, 153, 14, 31, 32, 33, 34, 35, 36, 37, 38, 39, 103, 41, 42, 43, 44, 67, 109, 79, 82, 112, 113, 114, 115, 116, 117, 118, 77, 7, 79, 80, 102, 103, 1, 47, 48, 8, 9, 10, 148, 53, 79, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 153, 67, 68, 69, 70, 8, 9, 10, 1, 75, 76, 77, 77, 79, 8, 9, 10, 83, 8, 9, 10, 1, 146, 139, 128, 28, 152, 30, 31, 32, 33, 34, 35, 12, 28, 79, 102, 151, 28, 153, 30, 31, 32, 33, 34, 149, 112, 112, 113, 114, 115, 116, 117, 7, 120, 121, 35, 77, 149, 103, 130, 131, 153, 129, 130, 109, 132, 133, 134, 135, 136, 137, 138, 143, 118, 7, 146, 143, 144, 145, 146, 7, 152, 29, 77, 151, 13, 153, 154, 152, 156, 71, 72, 73, 74, 0, 1, 77, 50, 51, 52, 81, 54, 13, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 66, 95, 96, 97, 98, 99, 100, 101, 102, 143, 104, 105, 146, 148, 108, 7, 150, 111, 112, 113, 114, 8, 9, 10, 7, 119, 12, 7, 122, 123, 124, 125, 41, 42, 43, 44, 45, 46, 47, 48, 49, 28, 149, 30, 31, 32, 33, 155, 8, 9, 10, 35, 71, 13, 148, 149, 150, 12, 77, 130, 131, 79, 81, 12, 82, 84, 85, 86, 28, 88, 7, 90, 143, 92, 67, 146, 95, 8, 9, 10, 99, 100, 101, 102, 103, 104, 105, 12, 148, 108, 109, 1, 111, 112, 113, 114, 13, 28, 9, 10, 119, 7, 148, 122, 123, 124, 125, 8, 9, 10, 35, 152, 8, 9, 10, 67, 35, 28, 7, 29, 67, 29, 140, 141, 143, 7, 7, 28, 29, 148, 149, 150, 28, 7, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 150, 54, 7, 1, 71, 148, 147, 8, 9, 10, 77, 152, 152, 66, 81, 152, 15, 84, 85, 86, 82, 88, 79, 90, 128, 92, 67, 28, 95, 30, 31, 29, 99, 100, 101, 1, 148, 104, 105, 123, 149, 108, 148, 67, 111, 112, 8, 9, 10, 31, 32, 33, 119, 129, 148, 50, 51, 52, 8, 9, 10, 12, 10, 29, 152, 147, 28, 151, 30, 31, 32, 66, 67, 71, 47, 48, 49, 139, 28, 77, 28, 148, 149, 81, 149, 148, 84, 85, 86, 12, 88, 15, 90, 77, 92, 79, 153, 95, 47, 48, 49, 99, 100, 101, 1, 71, 104, 105, 149, 148, 108, 77, 35, 111, 112, 81, 15, 12, 84, 85, 86, 119, 88, 15, 90, 149, 92, 78, 112, 95, 12, 15, 29, 99, 100, 101, 1, 149, 104, 105, 35, 153, 108, 31, 32, 111, 112, 29, 15, 143, 148, 149, 146, 119, 15, 8, 9, 10, 146, 143, 28, 149, 146, 29, 29, 8, 9, 151, 31, 153, 66, 67, 72, 73, 71, 28, 97, 98, 72, 73, 77, 29, 148, 149, 81, 102, 103, 84, 85, 86, 29, 88, 29, 90, 29, 92, 106, 107, 95, 35, 54, 74, 99, 100, 101, 1, 71, 104, 105, 148, 149, 108, 77, 68, 111, 112, 81, 148, 149, 84, 85, 86, 119, 88, 66, 90, 67, 92, 148, 149, 95, 77, 77, 67, 99, 100, 101, 67, 67, 104, 105, 67, 67, 108, 67, 77, 111, 112, 79, 77, 77, 148, 149, 77, 119, 77, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 77, 77, 77, 77, 82, 86, 71, 79, 79, 79, 79, 91, 77, 96, 148, 149, 81, 96, 82, 84, 85, 86, 89, 88, 87, 90, 29, 92, 56, 57, 95, 93, 139, 94, 99, 100, 101, 94, 94, 104, 105, 94, 102, 108, 47, 48, 111, 112, 102, 139, 53, 109, 55, 126, 119, 110, 142, 123, 126, 146, 142, 146, 146, 151, 67, 154, -1, -1, 127, 47, 48, 123, 75, 76, -1, 53, 79, 55, 128, 128, 83, 128, 128, 148, 149, 129, -1, -1, -1, 67, -1, 142, -1, -1, 142, -1, -1, 75, 76, 142, 128, 79, 142, 142, 142, 83, 147, 149, -1, 146, 146, 146, 146, 146, -1, -1, 148, 148, 148, 148, -1, 148, 148, 148, 148, 148, 148, 130, 148, 132, 133, 134, 135, 136, 137, 138, 148, 148, 148, 148, 148, 144, 145, 148, 148, 151, 148, 148, 151, 148, 153, 148, 130, 148, 132, 133, 134, 135, 136, 137, 138, 148, 148, 148, 148, 148, 144, 145, 149, 149, 149, -1, 149, 151, 149, 153, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, -1, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, -1, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, -1, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, -1, -1, 154, -1, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, -1, 156 ); protected $actionBase = array( 0, 220, 295, 109, 109, 180, 745, -2, -2, -2, -2, -2, 135, 574, 473, 404, 473, 606, 505, 675, 675, 675, 330, 389, 221, 221, 831, 221, 359, 365, 328, 520, 589, 548, 576, 42, 42, 42, 42, 134, 134, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 254, 179, 290, 397, 757, 755, 738, 741, 833, 679, 829, 784, 785, 623, 786, 787, 788, 789, 790, 783, 791, 849, 792, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, -3, 354, 383, 413, 206, 628, 521, 521, 521, 521, 521, 521, 521, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 403, 618, 618, 618, 523, 737, 603, 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, 470, -20, -20, 509, 608, 327, 583, 210, 489, 197, 25, 25, 25, 25, 25, 17, 45, 5, 5, 5, 5, 712, 305, 305, 305, 305, 118, 118, 118, 118, 780, 781, 801, 804, 395, 395, 696, 696, 616, 773, 522, 522, 498, 498, 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, 387, 156, 823, 130, 130, 130, 130, 243, 409, 633, 863, 207, 207, 207, 243, 248, 248, 248, 476, 476, 476, 76, 662, 296, 86, 86, 86, 86, 296, 86, 86, 554, 554, 554, 483, 761, 676, 477, 430, 97, 459, 657, 807, 661, 808, 540, 702, 96, 656, 705, -6, 680, 577, 571, 561, 689, 406, -6, 254, 551, 447, 617, 732, 663, 268, 730, 377, 38, 367, 532, 362, 414, 334, 774, 720, 827, 826, 74, 321, 691, 617, 617, 617, 137, 84, 775, 772, 362, 273, 575, 575, 575, 575, 806, 776, 575, 575, 575, 575, 805, 800, 432, 408, 782, 331, 731, 649, 649, 649, 649, 649, 649, 635, 649, 813, 666, 825, 825, 664, 668, 635, 824, 824, 824, 824, 635, 649, 825, 825, 635, 616, 825, 168, 635, 672, 649, 667, 667, 824, 756, 718, 666, 669, 681, 825, 825, 825, 681, 664, 635, 824, 682, 699, 466, 825, 824, 632, 632, 682, 635, 632, 668, 632, 20, 605, 641, 821, 822, 820, 625, 698, 688, 674, 811, 810, 816, 665, 626, 814, 812, 706, 717, 716, 639, 610, 642, 645, 646, 648, 697, 637, 694, 680, 707, 629, 629, 629, 690, 658, 690, 629, 629, 629, 629, 629, 629, 629, 629, 848, 700, 701, 693, 659, 715, 604, 704, 687, 472, 768, 650, 706, 706, 802, 835, 842, 847, 651, 643, 734, 837, 690, 862, 729, 274, 587, 652, 803, 703, 647, 655, 690, 809, 690, 769, 690, 834, 799, 644, 706, 779, 629, 832, 861, 860, 859, 858, 857, 856, 855, 854, 630, 853, 714, 677, 841, 246, 815, 689, 692, 653, 713, 67, 852, 778, 690, 690, 770, 761, 690, 771, 711, 728, 845, 710, 840, 851, 650, 839, 690, 686, 850, 67, 634, 598, 828, 678, 708, 819, 671, 830, 818, 759, 547, 579, 777, 636, 754, 844, 843, 846, 709, 760, 763, 572, 660, 640, 670, 793, 765, 817, 735, 794, 795, 836, 684, 707, 654, 685, 683, 673, 767, 796, 838, 736, 739, 743, 797, 753, 798, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 134, 134, -2, -2, -2, -2, 0, 0, 0, 0, 0, -2, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 0, 0, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, -20, -20, -20, -20, 418, -20, -20, -20, -20, -20, -20, -20, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, -20, 418, 418, 418, -20, 487, -20, 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, 418, 0, 0, 418, -20, 418, -20, 418, -20, 418, 418, 418, 418, 418, 418, -20, -20, -20, -20, -20, -20, 0, 248, 248, 248, 248, -20, -20, -20, -20, 55, 55, 55, 55, 487, 487, 487, 487, 487, 487, 248, 248, 476, 476, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 487, 55, 487, 649, 649, 649, 649, 649, 296, 296, 296, 47, 47, 47, 649, 0, 0, 0, 0, 0, 0, 649, 296, 0, 487, 487, 487, 487, 0, 487, 487, 649, 649, 649, 649, 47, 296, 649, 825, 0, 47, 550, 550, 550, 550, 67, 362, 0, 649, 649, 0, 669, 0, 0, 0, 825, 0, 0, 0, 0, 0, 629, 274, 734, 0, 433, 0, 0, 0, 0, 0, 0, 0, 643, 433, 322, 322, 0, 0, 630, 629, 629, 629, 0, 0, 643, 643, 0, 0, 0, 0, 0, 0, 440, 643, 0, 0, 0, 0, 440, 425, 0, 0, 425, 0, 67 ); protected $actionDefault = array( 3,32767,32767,32767,32767,32767,32767,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, 32767,32767,32767,32767, 525, 525,32767, 481,32767,32767, 32767,32767,32767,32767,32767, 287, 287, 287,32767,32767, 32767, 513, 513, 513, 513, 513, 513, 513, 513, 513, 513, 513,32767,32767,32767,32767,32767, 369,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, 32767,32767,32767, 375, 530,32767,32767,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, 32767,32767,32767,32767, 350, 351, 353, 354, 286, 514, 237, 376, 529, 285, 239, 314, 485,32767,32767,32767, 316, 116, 248, 193, 484, 119, 284, 224, 368, 370, 315, 291, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 290, 441, 347, 346, 345, 443, 32767, 442, 478, 478, 481,32767,32767,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, 32767,32767,32767,32767,32767, 312, 469, 468, 313, 439, 317, 440, 319, 444, 318, 335, 336, 333, 334, 337, 446, 445, 462, 463, 460, 461, 289, 338, 339, 340, 341, 464, 465, 466, 467, 271, 271, 271, 271,32767, 32767, 524, 524,32767,32767, 326, 327, 453, 454,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, 272,32767, 228, 228, 228, 228, 228,32767,32767,32767, 32767,32767,32767,32767, 321, 322, 320, 448, 449, 447, 32767, 415,32767,32767,32767,32767,32767, 417,32767,32767, 32767,32767,32767,32767,32767,32767,32767, 486,32767,32767, 32767,32767,32767,32767,32767, 499, 404,32767,32767,32767, 397, 212, 214, 161, 472,32767,32767,32767,32767, 504, 331,32767,32767,32767,32767,32767,32767, 539,32767, 499, 32767,32767,32767,32767,32767,32767,32767,32767, 344, 323, 324, 325,32767,32767,32767,32767, 503, 497, 456, 457, 458, 459,32767,32767, 450, 451, 452, 455,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, 32767, 165,32767, 412,32767, 418, 418,32767,32767, 165, 32767,32767,32767,32767, 165,32767, 502, 501, 165,32767, 398, 480, 165, 178,32767, 176, 176,32767, 198, 198, 32767,32767, 180, 473, 492,32767, 180,32767, 165,32767, 386, 167, 480,32767,32767, 230, 230, 386, 165, 230, 32767, 230,32767, 82, 422,32767,32767,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767, 399, 32767,32767,32767,32767, 365, 366, 475, 488,32767, 489, 32767, 397,32767, 329, 330, 332, 309,32767, 311, 355, 356, 357, 358, 359, 360, 361, 363,32767, 402,32767, 405,32767,32767,32767, 84, 108, 247,32767, 537, 84, 400,32767,32767, 294, 537,32767,32767,32767,32767, 532, 32767,32767, 288,32767,32767,32767, 84,32767, 84, 243, 32767, 163,32767, 522,32767, 497,32767, 401,32767, 328, 32767,32767,32767,32767,32767,32767,32767,32767,32767, 498, 32767,32767,32767,32767, 219,32767, 435,32767, 84,32767, 179,32767,32767, 292, 238,32767,32767, 531,32767,32767, 32767,32767,32767,32767,32767,32767,32767, 164,32767,32767, 181,32767,32767, 497,32767,32767,32767,32767,32767,32767, 32767,32767, 283,32767,32767,32767,32767,32767, 497,32767, 32767,32767, 223,32767,32767,32767,32767,32767,32767,32767, 32767,32767,32767, 82, 60,32767, 265,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767, 121, 121, 3, 121, 121, 3, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 206, 250, 209, 198, 198, 158, 250, 250, 250, 257 ); protected $goto = array( 160, 160, 134, 134, 139, 134, 135, 136, 137, 142, 144, 181, 162, 158, 158, 158, 158, 139, 139, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 154, 155, 156, 157, 178, 133, 179, 493, 494, 360, 495, 499, 500, 501, 502, 503, 504, 505, 506, 962, 138, 140, 141, 143, 165, 170, 180, 196, 245, 248, 250, 252, 254, 255, 256, 257, 258, 259, 267, 268, 269, 270, 285, 286, 314, 315, 316, 379, 380, 381, 549, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 145, 146, 147, 161, 148, 163, 149, 197, 164, 150, 151, 152, 198, 153, 131, 625, 567, 754, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 1100, 753, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 523, 784, 497, 497, 497, 497, 497, 497, 6, 508, 634, 508, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 509, 550, 509, 580, 606, 522, 885, 885, 1190, 1190, 815, 849, 849, 849, 849, 168, 844, 850, 522, 522, 171, 172, 173, 388, 389, 390, 391, 167, 195, 199, 201, 249, 251, 253, 260, 261, 262, 263, 264, 265, 271, 272, 273, 274, 287, 288, 317, 318, 319, 394, 395, 396, 397, 169, 174, 246, 247, 175, 176, 177, 387, 608, 543, 543, 573, 539, 583, 586, 631, 855, 541, 541, 496, 498, 529, 545, 574, 577, 587, 593, 341, 1169, 566, 1169, 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, 514, 443, 445, 933, 636, 327, 309, 1101, 618, 931, 519, 519, 519, 519, 777, 551, 552, 553, 554, 555, 556, 557, 558, 560, 589, 903, 611, 538, 519, 617, 548, 358, 544, 572, 430, 430, 430, 430, 430, 430, 1194, 777, 777, 361, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 1065, 1161, 1065, 892, 892, 892, 892, 892, 1168, 598, 1168, 590, 344, 404, 892, 369, 369, 369, 1058, 1184, 1184, 1184, 1076, 1075, 1065, 1065, 1065, 1065, 1149, 1065, 1065, 519, 519, 536, 568, 519, 519, 615, 519, 369, 510, 960, 510, 1167, 386, 770, 770, 778, 778, 778, 780, 520, 769, 276, 277, 278, 535, 607, 659, 562, 547, 594, 868, 882, 613, 867, 616, 878, 620, 621, 628, 630, 635, 637, 1081, 375, 1201, 1201, 1187, 1009, 889, 1019, 17, 13, 355, 790, 752, 1200, 1200, 898, 1061, 1062, 362, 941, 1058, 1201, 527, 871, 561, 851, 540, 657, 347, 511, 880, 875, 1200, 1059, 1160, 1059, 21, 398, 373, 773, 1203, 604, 451, 1060, 771, 907, 342, 343, 368, 645, 402, 446, 10, 1056, 1051, 912, 781, 578, 1146, 859, 459, 949, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 528 ); protected $gotoCheck = array( 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 53, 63, 12, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 119, 11, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 94, 25, 110, 110, 110, 110, 110, 110, 91, 63, 5, 63, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 40, 110, 36, 36, 40, 71, 71, 71, 71, 46, 63, 63, 63, 63, 23, 63, 63, 40, 40, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 47, 47, 47, 47, 47, 47, 56, 56, 56, 29, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 66, 111, 53, 111, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 8, 7, 7, 7, 7, 118, 118, 7, 7, 7, 8, 8, 8, 8, 19, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 78, 57, 8, 8, 57, 2, 57, 102, 2, 53, 53, 53, 53, 53, 53, 132, 19, 19, 43, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 76, 53, 53, 53, 53, 53, 53, 112, 120, 112, 64, 64, 64, 53, 116, 116, 116, 76, 112, 112, 112, 117, 117, 53, 53, 53, 53, 124, 53, 53, 8, 8, 8, 8, 8, 8, 53, 8, 116, 115, 94, 115, 112, 116, 19, 19, 19, 19, 19, 19, 8, 19, 61, 61, 61, 28, 45, 28, 28, 8, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 30, 44, 134, 134, 130, 95, 73, 30, 30, 30, 30, 10, 10, 133, 133, 75, 76, 76, 54, 91, 76, 134, 54, 10, 30, 10, 54, 10, 14, 10, 10, 10, 133, 76, 76, 76, 30, 18, 13, 21, 133, 30, 54, 76, 20, 79, 66, 66, 9, 68, 17, 59, 54, 108, 106, 80, 22, 60, 123, 65, 101, 93, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 94 ); protected $gotoBase = array( 0, 0, -261, 0, 0, 198, 0, 347, 29, 192, 487, 154, 109, 168, 185, 0, 0, 121, 183, 43, 173, 184, 93, 37, 0, 193, 0, 0, -180, 273, 64, 0, 0, 0, 0, 0, 189, 0, 0, -22, 201, 0, 0, 354, 188, 180, 216, 3, 0, 0, 0, 0, 0, 104, 71, 0, -15, -81, 0, 92, 88, -207, 0, -90, 90, 89, -137, 0, 169, 0, 0, -51, 0, 177, 0, 179, 67, 0, 351, 166, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 196, 0, 78, 161, 181, 0, 0, 0, 0, 0, 80, 356, 322, 0, 0, 115, 0, 111, 0, -77, 4, 112, 0, 0, 144, 108, 114, 33, -45, 209, 0, 0, 83, 227, 0, 0, 0, 0, 0, 199, 0, 362, 182, 171, 0, 0 ); protected $gotoDefault = array( -32768, 462, 668, 2, 669, 740, 748, 601, 479, 515, 853, 791, 792, 364, 410, 480, 363, 399, 392, 779, 772, 774, 782, 166, 400, 785, 1, 787, 521, 823, 1010, 351, 795, 352, 592, 797, 531, 799, 800, 132, 481, 365, 366, 532, 374, 581, 814, 266, 371, 816, 353, 817, 826, 354, 614, 597, 563, 610, 482, 442, 575, 275, 542, 1073, 570, 858, 340, 866, 648, 874, 877, 483, 564, 888, 448, 896, 1086, 382, 902, 908, 913, 916, 418, 401, 588, 920, 921, 5, 925, 626, 627, 940, 300, 948, 961, 416, 1029, 1031, 484, 485, 525, 456, 507, 530, 486, 1052, 436, 403, 1055, 487, 488, 426, 427, 1070, 346, 1154, 345, 444, 308, 1141, 584, 1105, 452, 1193, 1150, 337, 489, 490, 359, 376, 1188, 431, 1195, 1202, 335, 367, 571 ); protected $ruleToNonTerminal = array( 0, 1, 3, 3, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 7, 8, 8, 9, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 14, 14, 15, 15, 15, 15, 17, 17, 13, 13, 18, 18, 19, 19, 20, 20, 21, 21, 16, 16, 22, 24, 24, 25, 26, 26, 28, 27, 27, 27, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 10, 10, 50, 50, 52, 51, 51, 44, 44, 54, 54, 55, 55, 11, 12, 12, 12, 58, 58, 58, 59, 59, 62, 62, 60, 60, 64, 64, 37, 37, 46, 46, 49, 49, 49, 48, 48, 65, 38, 38, 38, 38, 66, 66, 67, 67, 68, 68, 35, 35, 31, 31, 69, 33, 33, 70, 32, 32, 34, 34, 45, 45, 45, 56, 56, 72, 72, 73, 73, 75, 75, 75, 74, 74, 57, 57, 76, 76, 76, 77, 77, 78, 78, 78, 41, 41, 79, 79, 79, 42, 42, 80, 80, 61, 61, 81, 81, 81, 81, 86, 86, 87, 87, 88, 88, 88, 88, 88, 89, 90, 90, 85, 85, 82, 82, 84, 84, 92, 92, 91, 91, 91, 91, 91, 91, 83, 83, 93, 93, 43, 43, 36, 36, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 30, 30, 40, 40, 98, 98, 99, 99, 99, 99, 105, 94, 94, 101, 101, 107, 107, 108, 109, 109, 109, 109, 109, 109, 63, 63, 53, 53, 53, 95, 95, 113, 113, 110, 110, 114, 114, 114, 114, 96, 96, 96, 100, 100, 100, 106, 106, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 23, 23, 23, 23, 23, 23, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 104, 104, 97, 97, 97, 97, 120, 120, 123, 123, 122, 122, 124, 124, 47, 47, 47, 47, 126, 126, 125, 125, 125, 125, 125, 127, 127, 112, 112, 115, 115, 111, 111, 128, 128, 128, 128, 116, 116, 116, 116, 103, 103, 117, 117, 117, 117, 71, 129, 129, 130, 130, 130, 102, 102, 131, 131, 132, 132, 132, 132, 118, 118, 118, 118, 134, 135, 133, 133, 133, 133, 133, 133, 133, 136, 136, 136 ); protected $ruleToLength = array( 1, 1, 2, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 3, 5, 4, 3, 4, 2, 3, 1, 1, 7, 8, 6, 7, 3, 1, 3, 1, 3, 1, 1, 3, 1, 2, 1, 2, 3, 1, 3, 3, 1, 3, 2, 0, 1, 1, 1, 1, 1, 3, 5, 8, 3, 5, 9, 3, 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 1, 2, 5, 7, 9, 5, 6, 3, 3, 2, 2, 1, 1, 1, 0, 2, 8, 0, 4, 1, 3, 0, 1, 0, 1, 10, 7, 6, 5, 1, 2, 2, 0, 2, 0, 2, 0, 2, 1, 3, 1, 4, 1, 4, 1, 1, 4, 1, 3, 3, 3, 4, 4, 5, 0, 2, 4, 3, 1, 1, 1, 4, 0, 2, 3, 0, 2, 4, 0, 2, 0, 3, 1, 2, 1, 1, 0, 1, 3, 4, 6, 1, 1, 1, 0, 1, 0, 2, 2, 3, 3, 1, 3, 1, 2, 2, 3, 1, 1, 2, 4, 3, 1, 1, 3, 2, 0, 3, 3, 9, 3, 1, 3, 0, 2, 4, 5, 4, 4, 4, 3, 1, 1, 1, 3, 1, 1, 0, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 3, 1, 0, 1, 1, 3, 3, 4, 4, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 3, 5, 4, 3, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 3, 2, 1, 2, 10, 11, 3, 3, 2, 4, 4, 3, 4, 4, 4, 4, 7, 3, 2, 0, 4, 1, 3, 2, 2, 4, 6, 2, 2, 4, 1, 1, 1, 2, 3, 1, 1, 1, 1, 1, 1, 3, 3, 4, 4, 0, 2, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 2, 1, 3, 1, 4, 3, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 5, 4, 4, 3, 1, 3, 1, 1, 3, 3, 0, 2, 0, 1, 3, 1, 3, 1, 1, 1, 1, 1, 6, 4, 3, 4, 2, 4, 4, 1, 3, 1, 2, 1, 1, 4, 1, 3, 6, 4, 4, 4, 4, 1, 4, 0, 1, 1, 3, 1, 1, 4, 3, 1, 1, 1, 0, 0, 2, 3, 1, 3, 1, 4, 2, 2, 2, 1, 2, 1, 1, 1, 4, 3, 3, 3, 6, 3, 1, 1, 1 ); protected function reduceRule0() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule1() { $this->semValue = $this->handleNamespaces($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule2() { if (is_array($this->semStack[$this->stackPos-(2-2)])) { $this->semValue = array_merge($this->semStack[$this->stackPos-(2-1)], $this->semStack[$this->stackPos-(2-2)]); } else { $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; }; } protected function reduceRule3() { $this->semValue = array(); } protected function reduceRule4() { $startAttributes = $this->lookaheadStartAttributes; if (isset($startAttributes['comments'])) { $nop = new Stmt\Nop(['comments' => $startAttributes['comments']]); } else { $nop = null; }; if ($nop !== null) { $this->semStack[$this->stackPos-(1-1)][] = $nop; } $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule5() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule6() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule7() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule8() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule9() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule10() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule11() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule12() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule13() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule14() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule15() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule16() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule17() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule18() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule19() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule20() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule21() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule22() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule23() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule24() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule25() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule26() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule27() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule28() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule29() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule30() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule31() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule32() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule33() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule34() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule35() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule36() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule37() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule38() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule39() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule40() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule41() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule42() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule43() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule44() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule45() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule46() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule47() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule48() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule49() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule50() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule51() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule52() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule53() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule54() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule55() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule56() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule57() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule58() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule59() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule60() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule61() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule62() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule63() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule64() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule65() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule66() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule67() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule68() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule69() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule70() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule71() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule72() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule73() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule74() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule75() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule76() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule77() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule78() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule79() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule80() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule81() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule82() { $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule83() { $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; } protected function reduceRule84() { $this->semValue = new Name($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule85() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule86() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule87() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule88() { $this->semValue = new Stmt\HaltCompiler($this->lexer->handleHaltCompiler(), $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule89() { $this->semValue = new Stmt\Namespace_($this->semStack[$this->stackPos-(3-2)], null, $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); $this->semValue->setAttribute('kind', Stmt\Namespace_::KIND_SEMICOLON); $this->checkNamespace($this->semValue); } protected function reduceRule90() { $this->semValue = new Stmt\Namespace_($this->semStack[$this->stackPos-(5-2)], $this->semStack[$this->stackPos-(5-4)], $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); $this->semValue->setAttribute('kind', Stmt\Namespace_::KIND_BRACED); $this->checkNamespace($this->semValue); } protected function reduceRule91() { $this->semValue = new Stmt\Namespace_(null, $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); $this->semValue->setAttribute('kind', Stmt\Namespace_::KIND_BRACED); $this->checkNamespace($this->semValue); } protected function reduceRule92() { $this->semValue = new Stmt\Use_($this->semStack[$this->stackPos-(3-2)], Stmt\Use_::TYPE_NORMAL, $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule93() { $this->semValue = new Stmt\Use_($this->semStack[$this->stackPos-(4-3)], $this->semStack[$this->stackPos-(4-2)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule94() { $this->semValue = $this->semStack[$this->stackPos-(2-1)]; } protected function reduceRule95() { $this->semValue = new Stmt\Const_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule96() { $this->semValue = Stmt\Use_::TYPE_FUNCTION; } protected function reduceRule97() { $this->semValue = Stmt\Use_::TYPE_CONSTANT; } protected function reduceRule98() { $this->semValue = new Stmt\GroupUse(new Name($this->semStack[$this->stackPos-(7-3)], $this->startAttributeStack[$this->stackPos-(7-3)] + $this->endAttributeStack[$this->stackPos-(7-3)]), $this->semStack[$this->stackPos-(7-6)], $this->semStack[$this->stackPos-(7-2)], $this->startAttributeStack[$this->stackPos-(7-1)] + $this->endAttributes); } protected function reduceRule99() { $this->semValue = new Stmt\GroupUse(new Name($this->semStack[$this->stackPos-(8-4)], $this->startAttributeStack[$this->stackPos-(8-4)] + $this->endAttributeStack[$this->stackPos-(8-4)]), $this->semStack[$this->stackPos-(8-7)], $this->semStack[$this->stackPos-(8-2)], $this->startAttributeStack[$this->stackPos-(8-1)] + $this->endAttributes); } protected function reduceRule100() { $this->semValue = new Stmt\GroupUse(new Name($this->semStack[$this->stackPos-(6-2)], $this->startAttributeStack[$this->stackPos-(6-2)] + $this->endAttributeStack[$this->stackPos-(6-2)]), $this->semStack[$this->stackPos-(6-5)], Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$this->stackPos-(6-1)] + $this->endAttributes); } protected function reduceRule101() { $this->semValue = new Stmt\GroupUse(new Name($this->semStack[$this->stackPos-(7-3)], $this->startAttributeStack[$this->stackPos-(7-3)] + $this->endAttributeStack[$this->stackPos-(7-3)]), $this->semStack[$this->stackPos-(7-6)], Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$this->stackPos-(7-1)] + $this->endAttributes); } protected function reduceRule102() { $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; } protected function reduceRule103() { $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule104() { $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; } protected function reduceRule105() { $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule106() { $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; } protected function reduceRule107() { $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule108() { $this->semValue = new Stmt\UseUse($this->semStack[$this->stackPos-(1-1)], null, Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); $this->checkUseUse($this->semValue, $this->stackPos-(1-1)); } protected function reduceRule109() { $this->semValue = new Stmt\UseUse($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); $this->checkUseUse($this->semValue, $this->stackPos-(3-3)); } protected function reduceRule110() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule111() { $this->semValue = $this->semStack[$this->stackPos-(2-2)]; } protected function reduceRule112() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; $this->semValue->type = Stmt\Use_::TYPE_NORMAL; } protected function reduceRule113() { $this->semValue = $this->semStack[$this->stackPos-(2-2)]; $this->semValue->type = $this->semStack[$this->stackPos-(2-1)]; } protected function reduceRule114() { $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; } protected function reduceRule115() { $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule116() { $this->semValue = new Node\Const_($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule117() { $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; } protected function reduceRule118() { $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule119() { $this->semValue = new Node\Const_($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule120() { if (is_array($this->semStack[$this->stackPos-(2-2)])) { $this->semValue = array_merge($this->semStack[$this->stackPos-(2-1)], $this->semStack[$this->stackPos-(2-2)]); } else { $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; }; } protected function reduceRule121() { $this->semValue = array(); } protected function reduceRule122() { $startAttributes = $this->lookaheadStartAttributes; if (isset($startAttributes['comments'])) { $nop = new Stmt\Nop(['comments' => $startAttributes['comments']]); } else { $nop = null; }; if ($nop !== null) { $this->semStack[$this->stackPos-(1-1)][] = $nop; } $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule123() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule124() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule125() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule126() { throw new Error('__HALT_COMPILER() can only be used from the outermost scope', $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule127() { if ($this->semStack[$this->stackPos-(3-2)]) { $this->semValue = $this->semStack[$this->stackPos-(3-2)]; $attrs = $this->startAttributeStack[$this->stackPos-(3-1)]; $stmts = $this->semValue; if (!empty($attrs['comments'])) {$stmts[0]->setAttribute('comments', array_merge($attrs['comments'], $stmts[0]->getAttribute('comments', []))); }; } else { $startAttributes = $this->startAttributeStack[$this->stackPos-(3-1)]; if (isset($startAttributes['comments'])) { $this->semValue = new Stmt\Nop(['comments' => $startAttributes['comments']]); } else { $this->semValue = null; }; if (null === $this->semValue) { $this->semValue = array(); } } } protected function reduceRule128() { $this->semValue = new Stmt\If_($this->semStack[$this->stackPos-(5-2)], ['stmts' => is_array($this->semStack[$this->stackPos-(5-3)]) ? $this->semStack[$this->stackPos-(5-3)] : array($this->semStack[$this->stackPos-(5-3)]), 'elseifs' => $this->semStack[$this->stackPos-(5-4)], 'else' => $this->semStack[$this->stackPos-(5-5)]], $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); } protected function reduceRule129() { $this->semValue = new Stmt\If_($this->semStack[$this->stackPos-(8-2)], ['stmts' => $this->semStack[$this->stackPos-(8-4)], 'elseifs' => $this->semStack[$this->stackPos-(8-5)], 'else' => $this->semStack[$this->stackPos-(8-6)]], $this->startAttributeStack[$this->stackPos-(8-1)] + $this->endAttributes); } protected function reduceRule130() { $this->semValue = new Stmt\While_($this->semStack[$this->stackPos-(3-2)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule131() { $this->semValue = new Stmt\Do_($this->semStack[$this->stackPos-(5-4)], is_array($this->semStack[$this->stackPos-(5-2)]) ? $this->semStack[$this->stackPos-(5-2)] : array($this->semStack[$this->stackPos-(5-2)]), $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); } protected function reduceRule132() { $this->semValue = new Stmt\For_(['init' => $this->semStack[$this->stackPos-(9-3)], 'cond' => $this->semStack[$this->stackPos-(9-5)], 'loop' => $this->semStack[$this->stackPos-(9-7)], 'stmts' => $this->semStack[$this->stackPos-(9-9)]], $this->startAttributeStack[$this->stackPos-(9-1)] + $this->endAttributes); } protected function reduceRule133() { $this->semValue = new Stmt\Switch_($this->semStack[$this->stackPos-(3-2)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule134() { $this->semValue = new Stmt\Break_(null, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule135() { $this->semValue = new Stmt\Break_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule136() { $this->semValue = new Stmt\Continue_(null, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule137() { $this->semValue = new Stmt\Continue_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule138() { $this->semValue = new Stmt\Return_(null, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule139() { $this->semValue = new Stmt\Return_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule140() { $this->semValue = $this->semStack[$this->stackPos-(2-1)]; } protected function reduceRule141() { $this->semValue = new Stmt\Global_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule142() { $this->semValue = new Stmt\Static_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule143() { $this->semValue = new Stmt\Echo_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule144() { $this->semValue = new Stmt\InlineHTML($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule145() { $this->semValue = $this->semStack[$this->stackPos-(2-1)]; } protected function reduceRule146() { $this->semValue = new Stmt\Unset_($this->semStack[$this->stackPos-(5-3)], $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); } protected function reduceRule147() { $this->semValue = new Stmt\Foreach_($this->semStack[$this->stackPos-(7-3)], $this->semStack[$this->stackPos-(7-5)][0], ['keyVar' => null, 'byRef' => $this->semStack[$this->stackPos-(7-5)][1], 'stmts' => $this->semStack[$this->stackPos-(7-7)]], $this->startAttributeStack[$this->stackPos-(7-1)] + $this->endAttributes); } protected function reduceRule148() { $this->semValue = new Stmt\Foreach_($this->semStack[$this->stackPos-(9-3)], $this->semStack[$this->stackPos-(9-7)][0], ['keyVar' => $this->semStack[$this->stackPos-(9-5)], 'byRef' => $this->semStack[$this->stackPos-(9-7)][1], 'stmts' => $this->semStack[$this->stackPos-(9-9)]], $this->startAttributeStack[$this->stackPos-(9-1)] + $this->endAttributes); } protected function reduceRule149() { $this->semValue = new Stmt\Declare_($this->semStack[$this->stackPos-(5-3)], $this->semStack[$this->stackPos-(5-5)], $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); } protected function reduceRule150() { $this->semValue = new Stmt\TryCatch($this->semStack[$this->stackPos-(6-3)], $this->semStack[$this->stackPos-(6-5)], $this->semStack[$this->stackPos-(6-6)], $this->startAttributeStack[$this->stackPos-(6-1)] + $this->endAttributes); $this->checkTryCatch($this->semValue); } protected function reduceRule151() { $this->semValue = new Stmt\Throw_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule152() { $this->semValue = new Stmt\Goto_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule153() { $this->semValue = new Stmt\Label($this->semStack[$this->stackPos-(2-1)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule154() { $this->semValue = $this->semStack[$this->stackPos-(2-1)]; } protected function reduceRule155() { $this->semValue = array(); /* means: no statement */ } protected function reduceRule156() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule157() { $startAttributes = $this->startAttributeStack[$this->stackPos-(1-1)]; if (isset($startAttributes['comments'])) { $this->semValue = new Stmt\Nop(['comments' => $startAttributes['comments']]); } else { $this->semValue = null; }; if ($this->semValue === null) $this->semValue = array(); /* means: no statement */ } protected function reduceRule158() { $this->semValue = array(); } protected function reduceRule159() { $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; } protected function reduceRule160() { $this->semValue = new Stmt\Catch_(array($this->semStack[$this->stackPos-(8-3)]), substr($this->semStack[$this->stackPos-(8-4)], 1), $this->semStack[$this->stackPos-(8-7)], $this->startAttributeStack[$this->stackPos-(8-1)] + $this->endAttributes); } protected function reduceRule161() { $this->semValue = null; } protected function reduceRule162() { $this->semValue = new Stmt\Finally_($this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule163() { $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule164() { $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; } protected function reduceRule165() { $this->semValue = false; } protected function reduceRule166() { $this->semValue = true; } protected function reduceRule167() { $this->semValue = false; } protected function reduceRule168() { $this->semValue = true; } protected function reduceRule169() { $this->semValue = new Stmt\Function_($this->semStack[$this->stackPos-(10-3)], ['byRef' => $this->semStack[$this->stackPos-(10-2)], 'params' => $this->semStack[$this->stackPos-(10-5)], 'returnType' => $this->semStack[$this->stackPos-(10-7)], 'stmts' => $this->semStack[$this->stackPos-(10-9)]], $this->startAttributeStack[$this->stackPos-(10-1)] + $this->endAttributes); } protected function reduceRule170() { $this->semValue = new Stmt\Class_($this->semStack[$this->stackPos-(7-2)], ['type' => $this->semStack[$this->stackPos-(7-1)], 'extends' => $this->semStack[$this->stackPos-(7-3)], 'implements' => $this->semStack[$this->stackPos-(7-4)], 'stmts' => $this->semStack[$this->stackPos-(7-6)]], $this->startAttributeStack[$this->stackPos-(7-1)] + $this->endAttributes); $this->checkClass($this->semValue, $this->stackPos-(7-2)); } protected function reduceRule171() { $this->semValue = new Stmt\Interface_($this->semStack[$this->stackPos-(6-2)], ['extends' => $this->semStack[$this->stackPos-(6-3)], 'stmts' => $this->semStack[$this->stackPos-(6-5)]], $this->startAttributeStack[$this->stackPos-(6-1)] + $this->endAttributes); $this->checkInterface($this->semValue, $this->stackPos-(6-2)); } protected function reduceRule172() { $this->semValue = new Stmt\Trait_($this->semStack[$this->stackPos-(5-2)], ['stmts' => $this->semStack[$this->stackPos-(5-4)]], $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); } protected function reduceRule173() { $this->semValue = 0; } protected function reduceRule174() { $this->semValue = Stmt\Class_::MODIFIER_ABSTRACT; } protected function reduceRule175() { $this->semValue = Stmt\Class_::MODIFIER_FINAL; } protected function reduceRule176() { $this->semValue = null; } protected function reduceRule177() { $this->semValue = $this->semStack[$this->stackPos-(2-2)]; } protected function reduceRule178() { $this->semValue = array(); } protected function reduceRule179() { $this->semValue = $this->semStack[$this->stackPos-(2-2)]; } protected function reduceRule180() { $this->semValue = array(); } protected function reduceRule181() { $this->semValue = $this->semStack[$this->stackPos-(2-2)]; } protected function reduceRule182() { $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule183() { $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; } protected function reduceRule184() { $this->semValue = is_array($this->semStack[$this->stackPos-(1-1)]) ? $this->semStack[$this->stackPos-(1-1)] : array($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule185() { $this->semValue = $this->semStack[$this->stackPos-(4-2)]; } protected function reduceRule186() { $this->semValue = is_array($this->semStack[$this->stackPos-(1-1)]) ? $this->semStack[$this->stackPos-(1-1)] : array($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule187() { $this->semValue = $this->semStack[$this->stackPos-(4-2)]; } protected function reduceRule188() { $this->semValue = is_array($this->semStack[$this->stackPos-(1-1)]) ? $this->semStack[$this->stackPos-(1-1)] : array($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule189() { $this->semValue = null; } protected function reduceRule190() { $this->semValue = $this->semStack[$this->stackPos-(4-2)]; } protected function reduceRule191() { $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule192() { $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; } protected function reduceRule193() { $this->semValue = new Stmt\DeclareDeclare($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule194() { $this->semValue = $this->semStack[$this->stackPos-(3-2)]; } protected function reduceRule195() { $this->semValue = $this->semStack[$this->stackPos-(4-3)]; } protected function reduceRule196() { $this->semValue = $this->semStack[$this->stackPos-(4-2)]; } protected function reduceRule197() { $this->semValue = $this->semStack[$this->stackPos-(5-3)]; } protected function reduceRule198() { $this->semValue = array(); } protected function reduceRule199() { $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; } protected function reduceRule200() { $this->semValue = new Stmt\Case_($this->semStack[$this->stackPos-(4-2)], $this->semStack[$this->stackPos-(4-4)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule201() { $this->semValue = new Stmt\Case_(null, $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule202() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule203() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule204() { $this->semValue = is_array($this->semStack[$this->stackPos-(1-1)]) ? $this->semStack[$this->stackPos-(1-1)] : array($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule205() { $this->semValue = $this->semStack[$this->stackPos-(4-2)]; } protected function reduceRule206() { $this->semValue = array(); } protected function reduceRule207() { $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; } protected function reduceRule208() { $this->semValue = new Stmt\ElseIf_($this->semStack[$this->stackPos-(3-2)], is_array($this->semStack[$this->stackPos-(3-3)]) ? $this->semStack[$this->stackPos-(3-3)] : array($this->semStack[$this->stackPos-(3-3)]), $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule209() { $this->semValue = array(); } protected function reduceRule210() { $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; } protected function reduceRule211() { $this->semValue = new Stmt\ElseIf_($this->semStack[$this->stackPos-(4-2)], $this->semStack[$this->stackPos-(4-4)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule212() { $this->semValue = null; } protected function reduceRule213() { $this->semValue = new Stmt\Else_(is_array($this->semStack[$this->stackPos-(2-2)]) ? $this->semStack[$this->stackPos-(2-2)] : array($this->semStack[$this->stackPos-(2-2)]), $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule214() { $this->semValue = null; } protected function reduceRule215() { $this->semValue = new Stmt\Else_($this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule216() { $this->semValue = array($this->semStack[$this->stackPos-(1-1)], false); } protected function reduceRule217() { $this->semValue = array($this->semStack[$this->stackPos-(2-2)], true); } protected function reduceRule218() { $this->semValue = array($this->semStack[$this->stackPos-(1-1)], false); } protected function reduceRule219() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule220() { $this->semValue = array(); } protected function reduceRule221() { $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule222() { $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; } protected function reduceRule223() { $this->semValue = new Node\Param(substr($this->semStack[$this->stackPos-(4-4)], 1), null, $this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-2)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); $this->checkParam($this->semValue); } protected function reduceRule224() { $this->semValue = new Node\Param(substr($this->semStack[$this->stackPos-(6-4)], 1), $this->semStack[$this->stackPos-(6-6)], $this->semStack[$this->stackPos-(6-1)], $this->semStack[$this->stackPos-(6-2)], $this->semStack[$this->stackPos-(6-3)], $this->startAttributeStack[$this->stackPos-(6-1)] + $this->endAttributes); $this->checkParam($this->semValue); } protected function reduceRule225() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule226() { $this->semValue = 'array'; } protected function reduceRule227() { $this->semValue = 'callable'; } protected function reduceRule228() { $this->semValue = null; } protected function reduceRule229() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule230() { $this->semValue = null; } protected function reduceRule231() { $this->semValue = $this->semStack[$this->stackPos-(2-2)]; } protected function reduceRule232() { $this->semValue = array(); } protected function reduceRule233() { $this->semValue = $this->semStack[$this->stackPos-(3-2)]; } protected function reduceRule234() { $this->semValue = array(new Node\Arg($this->semStack[$this->stackPos-(3-2)], false, false, $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes)); } protected function reduceRule235() { $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule236() { $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; } protected function reduceRule237() { $this->semValue = new Node\Arg($this->semStack[$this->stackPos-(1-1)], false, false, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule238() { $this->semValue = new Node\Arg($this->semStack[$this->stackPos-(2-2)], true, false, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule239() { $this->semValue = new Node\Arg($this->semStack[$this->stackPos-(2-2)], false, true, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule240() { $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; } protected function reduceRule241() { $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule242() { $this->semValue = new Expr\Variable(substr($this->semStack[$this->stackPos-(1-1)], 1), $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule243() { $this->semValue = new Expr\Variable($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule244() { $this->semValue = new Expr\Variable($this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule245() { $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; } protected function reduceRule246() { $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule247() { $this->semValue = new Stmt\StaticVar(substr($this->semStack[$this->stackPos-(1-1)], 1), null, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule248() { $this->semValue = new Stmt\StaticVar(substr($this->semStack[$this->stackPos-(3-1)], 1), $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule249() { $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; } protected function reduceRule250() { $this->semValue = array(); } protected function reduceRule251() { $this->semValue = new Stmt\Property($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); $this->checkProperty($this->semValue, $this->stackPos-(3-1)); } protected function reduceRule252() { $this->semValue = new Stmt\ClassConst($this->semStack[$this->stackPos-(3-2)], 0, $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule253() { $this->semValue = new Stmt\ClassMethod($this->semStack[$this->stackPos-(9-4)], ['type' => $this->semStack[$this->stackPos-(9-1)], 'byRef' => $this->semStack[$this->stackPos-(9-3)], 'params' => $this->semStack[$this->stackPos-(9-6)], 'returnType' => $this->semStack[$this->stackPos-(9-8)], 'stmts' => $this->semStack[$this->stackPos-(9-9)]], $this->startAttributeStack[$this->stackPos-(9-1)] + $this->endAttributes); $this->checkClassMethod($this->semValue, $this->stackPos-(9-1)); } protected function reduceRule254() { $this->semValue = new Stmt\TraitUse($this->semStack[$this->stackPos-(3-2)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule255() { $this->semValue = array(); } protected function reduceRule256() { $this->semValue = $this->semStack[$this->stackPos-(3-2)]; } protected function reduceRule257() { $this->semValue = array(); } protected function reduceRule258() { $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; } protected function reduceRule259() { $this->semValue = new Stmt\TraitUseAdaptation\Precedence($this->semStack[$this->stackPos-(4-1)][0], $this->semStack[$this->stackPos-(4-1)][1], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule260() { $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$this->stackPos-(5-1)][0], $this->semStack[$this->stackPos-(5-1)][1], $this->semStack[$this->stackPos-(5-3)], $this->semStack[$this->stackPos-(5-4)], $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); } protected function reduceRule261() { $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$this->stackPos-(4-1)][0], $this->semStack[$this->stackPos-(4-1)][1], $this->semStack[$this->stackPos-(4-3)], null, $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule262() { $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$this->stackPos-(4-1)][0], $this->semStack[$this->stackPos-(4-1)][1], null, $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule263() { $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$this->stackPos-(4-1)][0], $this->semStack[$this->stackPos-(4-1)][1], null, $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule264() { $this->semValue = array($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)]); } protected function reduceRule265() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule266() { $this->semValue = array(null, $this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule267() { $this->semValue = null; } protected function reduceRule268() { $this->semValue = $this->semStack[$this->stackPos-(3-2)]; } protected function reduceRule269() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule270() { $this->semValue = 0; } protected function reduceRule271() { $this->semValue = 0; } protected function reduceRule272() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule273() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule274() { $this->checkModifier($this->semStack[$this->stackPos-(2-1)], $this->semStack[$this->stackPos-(2-2)], $this->stackPos-(2-2)); $this->semValue = $this->semStack[$this->stackPos-(2-1)] | $this->semStack[$this->stackPos-(2-2)]; } protected function reduceRule275() { $this->semValue = Stmt\Class_::MODIFIER_PUBLIC; } protected function reduceRule276() { $this->semValue = Stmt\Class_::MODIFIER_PROTECTED; } protected function reduceRule277() { $this->semValue = Stmt\Class_::MODIFIER_PRIVATE; } protected function reduceRule278() { $this->semValue = Stmt\Class_::MODIFIER_STATIC; } protected function reduceRule279() { $this->semValue = Stmt\Class_::MODIFIER_ABSTRACT; } protected function reduceRule280() { $this->semValue = Stmt\Class_::MODIFIER_FINAL; } protected function reduceRule281() { $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule282() { $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; } protected function reduceRule283() { $this->semValue = new Stmt\PropertyProperty(substr($this->semStack[$this->stackPos-(1-1)], 1), null, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule284() { $this->semValue = new Stmt\PropertyProperty(substr($this->semStack[$this->stackPos-(3-1)], 1), $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule285() { $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; } protected function reduceRule286() { $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule287() { $this->semValue = array(); } protected function reduceRule288() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule289() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule290() { $this->semValue = new Expr\Assign($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule291() { $this->semValue = new Expr\Assign($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule292() { $this->semValue = new Expr\AssignRef($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-4)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule293() { $this->semValue = new Expr\AssignRef($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-4)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule294() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule295() { $this->semValue = new Expr\Clone_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule296() { $this->semValue = new Expr\AssignOp\Plus($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule297() { $this->semValue = new Expr\AssignOp\Minus($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule298() { $this->semValue = new Expr\AssignOp\Mul($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule299() { $this->semValue = new Expr\AssignOp\Div($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule300() { $this->semValue = new Expr\AssignOp\Concat($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule301() { $this->semValue = new Expr\AssignOp\Mod($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule302() { $this->semValue = new Expr\AssignOp\BitwiseAnd($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule303() { $this->semValue = new Expr\AssignOp\BitwiseOr($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule304() { $this->semValue = new Expr\AssignOp\BitwiseXor($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule305() { $this->semValue = new Expr\AssignOp\ShiftLeft($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule306() { $this->semValue = new Expr\AssignOp\ShiftRight($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule307() { $this->semValue = new Expr\AssignOp\Pow($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule308() { $this->semValue = new Expr\PostInc($this->semStack[$this->stackPos-(2-1)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule309() { $this->semValue = new Expr\PreInc($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule310() { $this->semValue = new Expr\PostDec($this->semStack[$this->stackPos-(2-1)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule311() { $this->semValue = new Expr\PreDec($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule312() { $this->semValue = new Expr\BinaryOp\BooleanOr($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule313() { $this->semValue = new Expr\BinaryOp\BooleanAnd($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule314() { $this->semValue = new Expr\BinaryOp\LogicalOr($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule315() { $this->semValue = new Expr\BinaryOp\LogicalAnd($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule316() { $this->semValue = new Expr\BinaryOp\LogicalXor($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule317() { $this->semValue = new Expr\BinaryOp\BitwiseOr($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule318() { $this->semValue = new Expr\BinaryOp\BitwiseAnd($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule319() { $this->semValue = new Expr\BinaryOp\BitwiseXor($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule320() { $this->semValue = new Expr\BinaryOp\Concat($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule321() { $this->semValue = new Expr\BinaryOp\Plus($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule322() { $this->semValue = new Expr\BinaryOp\Minus($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule323() { $this->semValue = new Expr\BinaryOp\Mul($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule324() { $this->semValue = new Expr\BinaryOp\Div($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule325() { $this->semValue = new Expr\BinaryOp\Mod($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule326() { $this->semValue = new Expr\BinaryOp\ShiftLeft($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule327() { $this->semValue = new Expr\BinaryOp\ShiftRight($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule328() { $this->semValue = new Expr\BinaryOp\Pow($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule329() { $this->semValue = new Expr\UnaryPlus($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule330() { $this->semValue = new Expr\UnaryMinus($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule331() { $this->semValue = new Expr\BooleanNot($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule332() { $this->semValue = new Expr\BitwiseNot($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule333() { $this->semValue = new Expr\BinaryOp\Identical($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule334() { $this->semValue = new Expr\BinaryOp\NotIdentical($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule335() { $this->semValue = new Expr\BinaryOp\Equal($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule336() { $this->semValue = new Expr\BinaryOp\NotEqual($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule337() { $this->semValue = new Expr\BinaryOp\Spaceship($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule338() { $this->semValue = new Expr\BinaryOp\Smaller($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule339() { $this->semValue = new Expr\BinaryOp\SmallerOrEqual($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule340() { $this->semValue = new Expr\BinaryOp\Greater($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule341() { $this->semValue = new Expr\BinaryOp\GreaterOrEqual($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule342() { $this->semValue = new Expr\Instanceof_($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule343() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule344() { $this->semValue = $this->semStack[$this->stackPos-(3-2)]; } protected function reduceRule345() { $this->semValue = new Expr\Ternary($this->semStack[$this->stackPos-(5-1)], $this->semStack[$this->stackPos-(5-3)], $this->semStack[$this->stackPos-(5-5)], $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); } protected function reduceRule346() { $this->semValue = new Expr\Ternary($this->semStack[$this->stackPos-(4-1)], null, $this->semStack[$this->stackPos-(4-4)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule347() { $this->semValue = new Expr\BinaryOp\Coalesce($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule348() { $this->semValue = new Expr\Isset_($this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule349() { $this->semValue = new Expr\Empty_($this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule350() { $this->semValue = new Expr\Include_($this->semStack[$this->stackPos-(2-2)], Expr\Include_::TYPE_INCLUDE, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule351() { $this->semValue = new Expr\Include_($this->semStack[$this->stackPos-(2-2)], Expr\Include_::TYPE_INCLUDE_ONCE, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule352() { $this->semValue = new Expr\Eval_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule353() { $this->semValue = new Expr\Include_($this->semStack[$this->stackPos-(2-2)], Expr\Include_::TYPE_REQUIRE, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule354() { $this->semValue = new Expr\Include_($this->semStack[$this->stackPos-(2-2)], Expr\Include_::TYPE_REQUIRE_ONCE, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule355() { $this->semValue = new Expr\Cast\Int_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule356() { $this->semValue = new Expr\Cast\Double($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule357() { $this->semValue = new Expr\Cast\String_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule358() { $this->semValue = new Expr\Cast\Array_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule359() { $this->semValue = new Expr\Cast\Object_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule360() { $this->semValue = new Expr\Cast\Bool_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule361() { $this->semValue = new Expr\Cast\Unset_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule362() { $attrs = $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes; $attrs['kind'] = strtolower($this->semStack[$this->stackPos-(2-1)]) === 'exit' ? Expr\Exit_::KIND_EXIT : Expr\Exit_::KIND_DIE; $this->semValue = new Expr\Exit_($this->semStack[$this->stackPos-(2-2)], $attrs); } protected function reduceRule363() { $this->semValue = new Expr\ErrorSuppress($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule364() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule365() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule366() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule367() { $this->semValue = new Expr\ShellExec($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule368() { $this->semValue = new Expr\Print_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule369() { $this->semValue = new Expr\Yield_(null, null, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule370() { $this->semValue = new Expr\YieldFrom($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule371() { $this->semValue = new Expr\Closure(['static' => false, 'byRef' => $this->semStack[$this->stackPos-(10-2)], 'params' => $this->semStack[$this->stackPos-(10-4)], 'uses' => $this->semStack[$this->stackPos-(10-6)], 'returnType' => $this->semStack[$this->stackPos-(10-7)], 'stmts' => $this->semStack[$this->stackPos-(10-9)]], $this->startAttributeStack[$this->stackPos-(10-1)] + $this->endAttributes); } protected function reduceRule372() { $this->semValue = new Expr\Closure(['static' => true, 'byRef' => $this->semStack[$this->stackPos-(11-3)], 'params' => $this->semStack[$this->stackPos-(11-5)], 'uses' => $this->semStack[$this->stackPos-(11-7)], 'returnType' => $this->semStack[$this->stackPos-(11-8)], 'stmts' => $this->semStack[$this->stackPos-(11-10)]], $this->startAttributeStack[$this->stackPos-(11-1)] + $this->endAttributes); } protected function reduceRule373() { $this->semValue = $this->semStack[$this->stackPos-(3-2)]; } protected function reduceRule374() { $this->semValue = $this->semStack[$this->stackPos-(3-2)]; } protected function reduceRule375() { $this->semValue = new Expr\Yield_($this->semStack[$this->stackPos-(2-2)], null, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule376() { $this->semValue = new Expr\Yield_($this->semStack[$this->stackPos-(4-4)], $this->semStack[$this->stackPos-(4-2)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule377() { $attrs = $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes; $attrs['kind'] = Expr\Array_::KIND_LONG; $this->semValue = new Expr\Array_($this->semStack[$this->stackPos-(4-3)], $attrs); } protected function reduceRule378() { $attrs = $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes; $attrs['kind'] = Expr\Array_::KIND_SHORT; $this->semValue = new Expr\Array_($this->semStack[$this->stackPos-(3-2)], $attrs); } protected function reduceRule379() { $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule380() { $attrs = $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes; $attrs['kind'] = ($this->semStack[$this->stackPos-(4-1)][0] === "'" || ($this->semStack[$this->stackPos-(4-1)][1] === "'" && ($this->semStack[$this->stackPos-(4-1)][0] === 'b' || $this->semStack[$this->stackPos-(4-1)][0] === 'B')) ? Scalar\String_::KIND_SINGLE_QUOTED : Scalar\String_::KIND_DOUBLE_QUOTED); $this->semValue = new Expr\ArrayDimFetch(new Scalar\String_(Scalar\String_::parse($this->semStack[$this->stackPos-(4-1)]), $attrs), $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule381() { $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule382() { $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule383() { $this->semValue = array(new Stmt\Class_(null, ['type' => 0, 'extends' => $this->semStack[$this->stackPos-(7-3)], 'implements' => $this->semStack[$this->stackPos-(7-4)], 'stmts' => $this->semStack[$this->stackPos-(7-6)]], $this->startAttributeStack[$this->stackPos-(7-1)] + $this->endAttributes), $this->semStack[$this->stackPos-(7-2)]); $this->checkClass($this->semValue[0], -1); } protected function reduceRule384() { $this->semValue = new Expr\New_($this->semStack[$this->stackPos-(3-2)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule385() { list($class, $ctorArgs) = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = new Expr\New_($class, $ctorArgs, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule386() { $this->semValue = array(); } protected function reduceRule387() { $this->semValue = $this->semStack[$this->stackPos-(4-3)]; } protected function reduceRule388() { $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule389() { $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; } protected function reduceRule390() { $this->semValue = new Expr\ClosureUse(substr($this->semStack[$this->stackPos-(2-2)], 1), $this->semStack[$this->stackPos-(2-1)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule391() { $this->semValue = new Expr\FuncCall($this->semStack[$this->stackPos-(2-1)], $this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule392() { $this->semValue = new Expr\StaticCall($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->semStack[$this->stackPos-(4-4)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule393() { $this->semValue = new Expr\StaticCall($this->semStack[$this->stackPos-(6-1)], $this->semStack[$this->stackPos-(6-4)], $this->semStack[$this->stackPos-(6-6)], $this->startAttributeStack[$this->stackPos-(6-1)] + $this->endAttributes); } protected function reduceRule394() { if ($this->semStack[$this->stackPos-(2-1)] instanceof Node\Expr\StaticPropertyFetch) { $this->semValue = new Expr\StaticCall($this->semStack[$this->stackPos-(2-1)]->class, new Expr\Variable($this->semStack[$this->stackPos-(2-1)]->name, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes), $this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } elseif ($this->semStack[$this->stackPos-(2-1)] instanceof Node\Expr\ArrayDimFetch) { $tmp = $this->semStack[$this->stackPos-(2-1)]; while ($tmp->var instanceof Node\Expr\ArrayDimFetch) { $tmp = $tmp->var; } $this->semValue = new Expr\StaticCall($tmp->var->class, $this->semStack[$this->stackPos-(2-1)], $this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); $tmp->var = new Expr\Variable($tmp->var->name, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } else { throw new \Exception; } } protected function reduceRule395() { $this->semValue = new Expr\FuncCall($this->semStack[$this->stackPos-(2-1)], $this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule396() { $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule397() { $this->semValue = new Name($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule398() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule399() { $this->semValue = new Name($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule400() { $this->semValue = new Name\FullyQualified($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule401() { $this->semValue = new Name\Relative($this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule402() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule403() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule404() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule405() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule406() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule407() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule408() { $this->semValue = new Expr\PropertyFetch($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule409() { $this->semValue = new Expr\PropertyFetch($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule410() { $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule411() { $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule412() { $this->semValue = null; } protected function reduceRule413() { $this->semValue = null; } protected function reduceRule414() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule415() { $this->semValue = array(); } protected function reduceRule416() { $this->semValue = array(new Scalar\EncapsedStringPart(Scalar\String_::parseEscapeSequences($this->semStack[$this->stackPos-(1-1)], '`', false), $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes)); } protected function reduceRule417() { foreach ($this->semStack[$this->stackPos-(1-1)] as $s) { if ($s instanceof Node\Scalar\EncapsedStringPart) { $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '`', false); } }; $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule418() { $this->semValue = array(); } protected function reduceRule419() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule420() { $this->semValue = $this->parseLNumber($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes, true); } protected function reduceRule421() { $this->semValue = new Scalar\DNumber(Scalar\DNumber::parse($this->semStack[$this->stackPos-(1-1)]), $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule422() { $attrs = $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes; $attrs['kind'] = ($this->semStack[$this->stackPos-(1-1)][0] === "'" || ($this->semStack[$this->stackPos-(1-1)][1] === "'" && ($this->semStack[$this->stackPos-(1-1)][0] === 'b' || $this->semStack[$this->stackPos-(1-1)][0] === 'B')) ? Scalar\String_::KIND_SINGLE_QUOTED : Scalar\String_::KIND_DOUBLE_QUOTED); $this->semValue = new Scalar\String_(Scalar\String_::parse($this->semStack[$this->stackPos-(1-1)], false), $attrs); } protected function reduceRule423() { $this->semValue = new Scalar\MagicConst\Line($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule424() { $this->semValue = new Scalar\MagicConst\File($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule425() { $this->semValue = new Scalar\MagicConst\Dir($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule426() { $this->semValue = new Scalar\MagicConst\Class_($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule427() { $this->semValue = new Scalar\MagicConst\Trait_($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule428() { $this->semValue = new Scalar\MagicConst\Method($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule429() { $this->semValue = new Scalar\MagicConst\Function_($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule430() { $this->semValue = new Scalar\MagicConst\Namespace_($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule431() { $attrs = $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes; $attrs['kind'] = strpos($this->semStack[$this->stackPos-(3-1)], "'") === false ? Scalar\String_::KIND_HEREDOC : Scalar\String_::KIND_NOWDOC; preg_match('/\A[bB]?<<<[ \t]*[\'"]?([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)[\'"]?(?:\r\n|\n|\r)\z/', $this->semStack[$this->stackPos-(3-1)], $matches); $attrs['docLabel'] = $matches[1];; $this->semValue = new Scalar\String_(Scalar\String_::parseDocString($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-2)], false), $attrs); } protected function reduceRule432() { $attrs = $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes; $attrs['kind'] = strpos($this->semStack[$this->stackPos-(2-1)], "'") === false ? Scalar\String_::KIND_HEREDOC : Scalar\String_::KIND_NOWDOC; preg_match('/\A[bB]?<<<[ \t]*[\'"]?([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)[\'"]?(?:\r\n|\n|\r)\z/', $this->semStack[$this->stackPos-(2-1)], $matches); $attrs['docLabel'] = $matches[1];; $this->semValue = new Scalar\String_('', $attrs); } protected function reduceRule433() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule434() { $this->semValue = new Expr\ClassConstFetch($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule435() { $this->semValue = new Expr\ConstFetch($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule436() { $this->semValue = new Expr\Array_($this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule437() { $this->semValue = new Expr\Array_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule438() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule439() { $this->semValue = new Expr\BinaryOp\BooleanOr($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule440() { $this->semValue = new Expr\BinaryOp\BooleanAnd($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule441() { $this->semValue = new Expr\BinaryOp\LogicalOr($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule442() { $this->semValue = new Expr\BinaryOp\LogicalAnd($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule443() { $this->semValue = new Expr\BinaryOp\LogicalXor($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule444() { $this->semValue = new Expr\BinaryOp\BitwiseOr($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule445() { $this->semValue = new Expr\BinaryOp\BitwiseAnd($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule446() { $this->semValue = new Expr\BinaryOp\BitwiseXor($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule447() { $this->semValue = new Expr\BinaryOp\Concat($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule448() { $this->semValue = new Expr\BinaryOp\Plus($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule449() { $this->semValue = new Expr\BinaryOp\Minus($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule450() { $this->semValue = new Expr\BinaryOp\Mul($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule451() { $this->semValue = new Expr\BinaryOp\Div($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule452() { $this->semValue = new Expr\BinaryOp\Mod($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule453() { $this->semValue = new Expr\BinaryOp\ShiftLeft($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule454() { $this->semValue = new Expr\BinaryOp\ShiftRight($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule455() { $this->semValue = new Expr\BinaryOp\Pow($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule456() { $this->semValue = new Expr\UnaryPlus($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule457() { $this->semValue = new Expr\UnaryMinus($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule458() { $this->semValue = new Expr\BooleanNot($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule459() { $this->semValue = new Expr\BitwiseNot($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule460() { $this->semValue = new Expr\BinaryOp\Identical($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule461() { $this->semValue = new Expr\BinaryOp\NotIdentical($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule462() { $this->semValue = new Expr\BinaryOp\Equal($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule463() { $this->semValue = new Expr\BinaryOp\NotEqual($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule464() { $this->semValue = new Expr\BinaryOp\Smaller($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule465() { $this->semValue = new Expr\BinaryOp\SmallerOrEqual($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule466() { $this->semValue = new Expr\BinaryOp\Greater($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule467() { $this->semValue = new Expr\BinaryOp\GreaterOrEqual($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule468() { $this->semValue = new Expr\Ternary($this->semStack[$this->stackPos-(5-1)], $this->semStack[$this->stackPos-(5-3)], $this->semStack[$this->stackPos-(5-5)], $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); } protected function reduceRule469() { $this->semValue = new Expr\Ternary($this->semStack[$this->stackPos-(4-1)], null, $this->semStack[$this->stackPos-(4-4)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule470() { $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule471() { $this->semValue = $this->semStack[$this->stackPos-(3-2)]; } protected function reduceRule472() { $this->semValue = new Expr\ConstFetch($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule473() { $this->semValue = new Expr\ClassConstFetch($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule474() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule475() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule476() { $attrs = $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes; $attrs['kind'] = Scalar\String_::KIND_DOUBLE_QUOTED; foreach ($this->semStack[$this->stackPos-(3-2)] as $s) { if ($s instanceof Node\Scalar\EncapsedStringPart) { $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '"', true); } }; $this->semValue = new Scalar\Encapsed($this->semStack[$this->stackPos-(3-2)], $attrs); } protected function reduceRule477() { $attrs = $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes; $attrs['kind'] = strpos($this->semStack[$this->stackPos-(3-1)], "'") === false ? Scalar\String_::KIND_HEREDOC : Scalar\String_::KIND_NOWDOC; preg_match('/\A[bB]?<<<[ \t]*[\'"]?([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)[\'"]?(?:\r\n|\n|\r)\z/', $this->semStack[$this->stackPos-(3-1)], $matches); $attrs['docLabel'] = $matches[1];; foreach ($this->semStack[$this->stackPos-(3-2)] as $s) { if ($s instanceof Node\Scalar\EncapsedStringPart) { $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, null, true); } } $s->value = preg_replace('~(\r\n|\n|\r)\z~', '', $s->value); if ('' === $s->value) array_pop($this->semStack[$this->stackPos-(3-2)]);; $this->semValue = new Scalar\Encapsed($this->semStack[$this->stackPos-(3-2)], $attrs); } protected function reduceRule478() { $this->semValue = array(); } protected function reduceRule479() { $this->semValue = $this->semStack[$this->stackPos-(2-1)]; } protected function reduceRule480() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule481() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule482() { $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; } protected function reduceRule483() { $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule484() { $this->semValue = new Expr\ArrayItem($this->semStack[$this->stackPos-(3-3)], $this->semStack[$this->stackPos-(3-1)], false, $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule485() { $this->semValue = new Expr\ArrayItem($this->semStack[$this->stackPos-(1-1)], null, false, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule486() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule487() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule488() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule489() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule490() { $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(6-2)], $this->semStack[$this->stackPos-(6-5)], $this->startAttributeStack[$this->stackPos-(6-1)] + $this->endAttributes); } protected function reduceRule491() { $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule492() { $this->semValue = new Expr\PropertyFetch($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule493() { $this->semValue = new Expr\MethodCall($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->semStack[$this->stackPos-(4-4)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule494() { $this->semValue = new Expr\FuncCall($this->semStack[$this->stackPos-(2-1)], $this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule495() { $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule496() { $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule497() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule498() { $this->semValue = $this->semStack[$this->stackPos-(3-2)]; } protected function reduceRule499() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule500() { $this->semValue = new Expr\Variable($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule501() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule502() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule503() { $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-4)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule504() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule505() { $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$this->stackPos-(3-1)], substr($this->semStack[$this->stackPos-(3-3)], 1), $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule506() { $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$this->stackPos-(6-1)], $this->semStack[$this->stackPos-(6-5)], $this->startAttributeStack[$this->stackPos-(6-1)] + $this->endAttributes); } protected function reduceRule507() { $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule508() { $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule509() { $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule510() { $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule511() { $this->semValue = new Expr\Variable(substr($this->semStack[$this->stackPos-(1-1)], 1), $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule512() { $this->semValue = new Expr\Variable($this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule513() { $this->semValue = null; } protected function reduceRule514() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule515() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule516() { $this->semValue = $this->semStack[$this->stackPos-(3-2)]; } protected function reduceRule517() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule518() { $this->semValue = new Expr\Error($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); $this->errorState = 2; } protected function reduceRule519() { $this->semValue = new Expr\List_($this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule520() { $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; } protected function reduceRule521() { $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule522() { $this->semValue = new Expr\ArrayItem($this->semStack[$this->stackPos-(1-1)], null, false, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule523() { $this->semValue = new Expr\ArrayItem($this->semStack[$this->stackPos-(1-1)], null, false, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule524() { $this->semValue = null; } protected function reduceRule525() { $this->semValue = array(); } protected function reduceRule526() { $this->semValue = $this->semStack[$this->stackPos-(2-1)]; } protected function reduceRule527() { $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; } protected function reduceRule528() { $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule529() { $this->semValue = new Expr\ArrayItem($this->semStack[$this->stackPos-(3-3)], $this->semStack[$this->stackPos-(3-1)], false, $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule530() { $this->semValue = new Expr\ArrayItem($this->semStack[$this->stackPos-(1-1)], null, false, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule531() { $this->semValue = new Expr\ArrayItem($this->semStack[$this->stackPos-(4-4)], $this->semStack[$this->stackPos-(4-1)], true, $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule532() { $this->semValue = new Expr\ArrayItem($this->semStack[$this->stackPos-(2-2)], null, true, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule533() { $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; } protected function reduceRule534() { $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; } protected function reduceRule535() { $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule536() { $this->semValue = array($this->semStack[$this->stackPos-(2-1)], $this->semStack[$this->stackPos-(2-2)]); } protected function reduceRule537() { $this->semValue = new Scalar\EncapsedStringPart($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule538() { $this->semValue = new Expr\Variable(substr($this->semStack[$this->stackPos-(1-1)], 1), $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule539() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule540() { $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule541() { $this->semValue = new Expr\PropertyFetch($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule542() { $this->semValue = new Expr\Variable($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule543() { $this->semValue = new Expr\Variable($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule544() { $this->semValue = new Expr\ArrayDimFetch(new Expr\Variable($this->semStack[$this->stackPos-(6-2)], $this->startAttributeStack[$this->stackPos-(6-1)] + $this->endAttributes), $this->semStack[$this->stackPos-(6-4)], $this->startAttributeStack[$this->stackPos-(6-1)] + $this->endAttributes); } protected function reduceRule545() { $this->semValue = $this->semStack[$this->stackPos-(3-2)]; } protected function reduceRule546() { $this->semValue = new Scalar\String_($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule547() { $this->semValue = $this->parseNumString($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule548() { $this->semValue = new Expr\Variable(substr($this->semStack[$this->stackPos-(1-1)], 1), $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } } PHP-Parser-3.1.4/lib/PhpParser/Parser/Php7.php000066400000000000000000004207111323244626500206510ustar00rootroot00000000000000'", "T_IS_GREATER_OR_EQUAL", "T_SL", "T_SR", "'+'", "'-'", "'.'", "'*'", "'/'", "'%'", "'!'", "T_INSTANCEOF", "'~'", "T_INC", "T_DEC", "T_INT_CAST", "T_DOUBLE_CAST", "T_STRING_CAST", "T_ARRAY_CAST", "T_OBJECT_CAST", "T_BOOL_CAST", "T_UNSET_CAST", "'@'", "T_POW", "'['", "T_NEW", "T_CLONE", "T_EXIT", "T_IF", "T_ELSEIF", "T_ELSE", "T_ENDIF", "T_LNUMBER", "T_DNUMBER", "T_STRING", "T_STRING_VARNAME", "T_VARIABLE", "T_NUM_STRING", "T_INLINE_HTML", "T_ENCAPSED_AND_WHITESPACE", "T_CONSTANT_ENCAPSED_STRING", "T_ECHO", "T_DO", "T_WHILE", "T_ENDWHILE", "T_FOR", "T_ENDFOR", "T_FOREACH", "T_ENDFOREACH", "T_DECLARE", "T_ENDDECLARE", "T_AS", "T_SWITCH", "T_ENDSWITCH", "T_CASE", "T_DEFAULT", "T_BREAK", "T_CONTINUE", "T_GOTO", "T_FUNCTION", "T_CONST", "T_RETURN", "T_TRY", "T_CATCH", "T_FINALLY", "T_THROW", "T_USE", "T_INSTEADOF", "T_GLOBAL", "T_STATIC", "T_ABSTRACT", "T_FINAL", "T_PRIVATE", "T_PROTECTED", "T_PUBLIC", "T_VAR", "T_UNSET", "T_ISSET", "T_EMPTY", "T_HALT_COMPILER", "T_CLASS", "T_TRAIT", "T_INTERFACE", "T_EXTENDS", "T_IMPLEMENTS", "T_OBJECT_OPERATOR", "T_LIST", "T_ARRAY", "T_CALLABLE", "T_CLASS_C", "T_TRAIT_C", "T_METHOD_C", "T_FUNC_C", "T_LINE", "T_FILE", "T_START_HEREDOC", "T_END_HEREDOC", "T_DOLLAR_OPEN_CURLY_BRACES", "T_CURLY_OPEN", "T_PAAMAYIM_NEKUDOTAYIM", "T_NAMESPACE", "T_NS_C", "T_DIR", "T_NS_SEPARATOR", "T_ELLIPSIS", "';'", "'{'", "'}'", "'('", "')'", "'`'", "']'", "'\"'", "'$'" ); protected $tokenToSymbol = array( 0, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 53, 155, 157, 156, 52, 35, 157, 151, 152, 50, 47, 7, 48, 49, 51, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 29, 148, 41, 15, 43, 28, 65, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 67, 157, 154, 34, 157, 153, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 149, 33, 150, 55, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 30, 31, 32, 36, 37, 38, 39, 40, 42, 44, 45, 46, 54, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 157, 157, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 157, 157, 157, 157, 157, 157, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147 ); protected $action = array( 581, 582, 583, 584, 585, 0, 586, 587, 588, 624, 625, 477, 27, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110,-32766,-32766,-32766, 95, 96, 97, 361, 239, 263, -282,-32766,-32766,-32766, -488, -487, 1079, 542, 1082, 1080, 98,-32766, 272,-32766,-32766,-32766, -32766,-32766, 589, 899, 901,-32766,-32766,-32766,-32766,-32766, -32766,-32766,-32766, 240,-32766, 662, 590, 591, 592, 593, 594, 595, 596,-32766, 289, 656, 867, 868, 869, 866, 865, 864, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 627, 628, 629, 630, 631, 619, 620, 621, 622, 623, 608, 609, 610, 611, 612, 613, 614, 650, 651, 652, 653, 654, 655, 615, 616, 617, 618, 648, 639, 637, 638, 634, 635, 215, 626, 632, 633, 640, 641, 643, 642, 644, 645, 42, 43, 390, 44, 45, 636, 647, 646, 224, 46, 47, 982, 48,-32767, -32767,-32767,-32767, 90, 91, 92, 93, 94, 258, 440, 22, 867, 868, 869, 866, 865, 864, 859,-32766,-32766, -32766, 1071, 1032, 1032, 1070, 1049, 998, 293, -443, 246, 287, 49, 50, -488, -487, -488, -487, 51,-32766, 52, 219, 220, 53, 54, 55, 56, 57, 58, 59, 60, 125, 22, 232, 61, 345, 975,-32766,-32766,-32766, 999, 1000, 658, 661, 1032, 28, -477, 1012, 998,-32766,-32766, -32766, 737, 407, 408, 246, 1032,-32766, 246,-32766,-32766, -32766,-32766, 25, 222, 373, 385, 349, 226,-32766, -443, -32766,-32766,-32766, 1035, 65, 342, 416, 216, 41, 264, 264, 1046, 7, -443, 403, 404, 120, 21, 975, 24, -443, 822, -446, 407, 408, -227, 1004, 1005, 1006, 1007, 1001, 1002, 243, 116, -442, -441, 265, 417, 1008, 1003, 347, 816, 817, 1076, 994, 63, 369, 255, 362, 260, 264, 391, -133, -133, -133, -4, 737, 392, 658, 224, -441, 727, 264, -88, 32, 17, 393, -133, 394, -133, 395, -133, 396, -133, 128, 397, -133, -133, -133, 34, 35, 398, 346, 122, 36, 399, 816, 817, 62, 816, 817, 286, 288, 400, 401, -442, -441, 465, -251, 402, 38, 40, 713, 758, 405, 406, -172, 22, -232, -442, -441,-32766,-32766,-32766, 374, -173, -442, -441, -445, 1032, -477, -441, 1032, 998, 417, -479, 391, 347, 739, 547, -133,-32766, 392,-32766,-32766, -441, 727, 678, 679, 32, 17, 393, -441, 394, 276, 395, 357, 396, 789, 549, 397, 71, 975, 1050, 34, 35, 398, 346, 335, 36, 399, 247, 248, 62, 254, 737, 286, 288, 400, 401, 408, 120, 131, 530, 402, 982, 306, 670, 758, 405, 406, 337, 113, 115,-32766,-32766, 72, 73, 74, 242, 529, 65, 121, 553, 502, 18, 264, 126, 274, 264, -32766,-32766,-32766, 739, 547, -4, 26, 751, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 111, 239, 118, 737, 391, 92, 93, 94, 531, 112, 392, 347, -251, 98, 727, 845, 124, 32, 17, 393, -172, 394, 1032, 395, 130, 396, 515, 516, 397, -173, 117, 554, 34, 35, 398, 737, 790, 36, 399, -479, 736, 62, 383, 6, 286, 288,-32766,-32766,-32766, 127, 311, 114, 402, 678, 679, 975, 495, 496, 816, 817, 856, 565, 119, 552, 844, 575, 343, 223, 564, 559, 221, 225, 239, 391, 98, 658, 439, 39, 525, 392, 659, 775, 547, 727, 435, 971, 32, 17, 393, 358, 394, 356, 395, 299, 396, 319, 694, 397, 1074, 264, 451, 34, 35, 398, 737, 391, 36, 399, 453, 511, 62, 392, 449, 286, 288, 727, 499, 540, 32, 17, 393, 402, 394, 438, 395, 1081, 396, 354, 444, 397,-32766, 493, 551, 34, 35, 398, 737, 503, 36, 399, 526, -80, 62, 759, 507, 286, 288, 214, 456, 10, 739, 547, 519, 402, 508, 975, 257, 15, 0, 338, 0, 0, 259, 1011, 560, 760, 1014, 262, 0, 0, 0, 0, 0, 0, 391, 0, 0, 0, 0, 0, 392, 0, 739, 547, 727, 227, 256, 32, 17, 393, 0, 394, 0, 395, 0, 396, 0, 0, 397, 3, 0, 9, 34, 35, 398, 737, 391, 36, 399, 305, -400, 62, 392, 753, 286, 288, 727, 22, 339, 32, 17, 393, 402, 394, 327, 395, 324, 396, 316, 1032, 397, 323, 357, 998, 34, 35, 398, 446, 773, 36, 399, 31, 573, 62, 574, 718, 286, 288, 840, 850, 792, 739, 547, 30, 402, 849, 852, 851, 848, 771, 776, 716, 975, 784, 841, 783, 19, 548, 333, 550, 555, 557, 558, 270, 271, 391, 332, 571, 570, 407, 408, 392, 568, 739, 547, 727, 566, 563, 32, 17, 393, 562, 394, 757, 395, 756, 396, 755, 963, 397, -444, 65, 857, 34, 35, 398, 264, 744, 36, 399, 962, 961, 62, 754, 746, 286, 288,-32766,-32766, -32766, 681, 1077, 680, 402, 683, 682, 672, 673, 782, 567, 714, 1078, 781, 1047, 1044, 1039, 1026,-32766, 1033, -32766,-32766,-32766,-32766,-32766,-32766,-32767,-32767,-32767,-32767, -32767, 1075, 250, 739, 547, -467, 955, -446, -445, 20, 23, 29, 33, 37, 64, 336, 334, 273, 238, 237, 236, 235, 218, 217, 132, 129, 123, 70, 69, 68, 67, 66, -469, 0, 308, 473, 939, 489, 539, -230, 942, 11, 967, 823, 996, 938, 986, 536, 388, -88, 381, 378, 375, 309, 16, 14, 13, 12, -227, -228, 0, -412, 0, 995, 501, 1073, 1038, 1025, 1024, 0, 1013 ); protected $actionCheck = array( 2, 3, 4, 5, 6, 0, 8, 9, 10, 11, 12, 48, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 8, 9, 10, 50, 51, 52, 7, 54, 7, 79, 8, 9, 10, 7, 7, 77, 77, 79, 80, 66, 28, 7, 30, 31, 32, 33, 34, 54, 56, 57, 28, 8, 30, 31, 32, 33, 34, 35, 7, 109, 1, 68, 69, 70, 71, 72, 73, 74, 118, 7, 77, 112, 113, 114, 115, 116, 117, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 13, 129, 130, 131, 132, 133, 134, 135, 136, 137, 2, 3, 4, 5, 6, 143, 144, 145, 35, 11, 12, 1, 14, 41, 42, 43, 44, 45, 46, 47, 48, 49, 109, 82, 67, 112, 113, 114, 115, 116, 117, 118, 8, 9, 10, 79, 79, 79, 82, 1, 83, 7, 67, 28, 7, 47, 48, 152, 152, 154, 154, 53, 28, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 67, 67, 68, 69, 70, 112, 8, 9, 10, 75, 76, 77, 148, 79, 13, 7, 139, 83, 8, 9, 10, 1, 129, 130, 28, 79, 28, 28, 30, 31, 32, 33, 140, 141, 29, 7, 102, 7, 28, 128, 30, 31, 32, 1, 151, 7, 112, 13, 7, 156, 156, 77, 7, 142, 120, 121, 147, 7, 112, 7, 149, 152, 151, 129, 130, 152, 132, 133, 134, 135, 136, 137, 138, 7, 67, 67, 67, 143, 144, 145, 146, 130, 131, 150, 1, 151, 7, 153, 7, 155, 156, 71, 72, 73, 74, 0, 1, 77, 77, 35, 67, 81, 156, 152, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 15, 95, 96, 97, 98, 99, 100, 101, 102, 149, 104, 105, 130, 131, 108, 130, 131, 111, 112, 113, 114, 128, 128, 128, 7, 119, 67, 67, 122, 123, 124, 125, 7, 67, 152, 142, 142, 8, 9, 10, 149, 7, 149, 149, 151, 79, 152, 128, 79, 83, 143, 7, 71, 146, 148, 149, 150, 28, 77, 30, 31, 142, 81, 102, 103, 84, 85, 86, 149, 88, 33, 90, 146, 92, 29, 149, 95, 149, 112, 152, 99, 100, 101, 102, 103, 104, 105, 128, 128, 108, 109, 1, 111, 112, 113, 114, 130, 147, 15, 77, 119, 1, 142, 122, 123, 124, 125, 146, 149, 149, 8, 9, 8, 9, 10, 29, 79, 151, 149, 29, 72, 73, 156, 29, 143, 156, 8, 9, 10, 148, 149, 150, 28, 35, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 15, 54, 15, 1, 71, 47, 48, 49, 143, 15, 77, 146, 152, 66, 81, 150, 15, 84, 85, 86, 152, 88, 79, 90, 15, 92, 72, 73, 95, 152, 15, 29, 99, 100, 101, 1, 148, 104, 105, 152, 29, 108, 102, 103, 111, 112, 8, 9, 10, 97, 98, 13, 119, 102, 103, 112, 106, 107, 130, 131, 148, 149, 29, 29, 148, 149, 123, 35, 29, 29, 35, 35, 54, 71, 66, 77, 77, 67, 74, 77, 77, 148, 149, 81, 77, 79, 84, 85, 86, 77, 88, 77, 90, 77, 92, 78, 77, 95, 77, 156, 77, 99, 100, 101, 1, 71, 104, 105, 77, 79, 108, 77, 86, 111, 112, 81, 79, 89, 84, 85, 86, 119, 88, 79, 90, 80, 92, 102, 82, 95, 82, 109, 29, 99, 100, 101, 1, 87, 104, 105, 91, 94, 108, 123, 93, 111, 112, 94, 94, 94, 148, 149, 96, 119, 96, 112, 127, 152, -1, 146, -1, -1, 110, 139, 29, 123, 139, 126, -1, -1, -1, -1, -1, -1, 71, -1, -1, -1, -1, -1, 77, -1, 148, 149, 81, 35, 126, 84, 85, 86, -1, 88, -1, 90, -1, 92, -1, -1, 95, 142, -1, 142, 99, 100, 101, 1, 71, 104, 105, 142, 142, 108, 77, 147, 111, 112, 81, 67, 146, 84, 85, 86, 119, 88, 146, 90, 146, 92, 146, 79, 95, 146, 146, 83, 99, 100, 101, 146, 148, 104, 105, 148, 148, 108, 148, 148, 111, 112, 148, 148, 148, 148, 149, 148, 119, 148, 148, 148, 148, 148, 148, 148, 112, 148, 148, 148, 152, 149, 149, 149, 149, 149, 149, 149, 149, 71, 149, 149, 149, 129, 130, 77, 149, 148, 149, 81, 149, 149, 84, 85, 86, 149, 88, 150, 90, 150, 92, 150, 150, 95, 151, 151, 150, 99, 100, 101, 156, 150, 104, 105, 150, 150, 108, 150, 150, 111, 112, 8, 9, 10, 150, 150, 150, 119, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 28, 150, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 150, 152, 148, 149, 151, 153, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, -1, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, -1, 153, -1, 154, 154, 154, 154, 154, 154, -1, 155 ); protected $actionBase = array( 0, 220, 295, 283, 336, 572, -2, -2, -2, -2, -36, 505, 473, 606, 473, 574, 404, 675, 675, 675, 109, 264, 506, 506, 506, 488, 504, 503, 507, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 64, 64, 359, 201, 670, 708, 703, 476, 709, 524, 702, 704, 234, 671, 659, 408, 657, 656, 655, 654, 705, 730, 585, 706, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 48, 509, 416, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 160, 160, 160, 343, 210, 208, 198, 17, 233, 27, 780, 780, 780, 780, 780, 108, 108, 108, 108, 621, 621, 93, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 614, 616, 618, 619, 414, 429, 429, 196, 196, 196, 196, 146, 151, -45, 199, 77, 498, 735, 399, 174, 174, 111, 207, -22, -22, -22, 275, 517, 514, 514, 514, 514, 92, 92, 514, 514, 242, -37, 233, 233, 274, 233, 422, 422, 422, 221, 240, 519, 221, 591, 529, 653, 527, 649, 273, 31, 32, 484, 94, 543, 496, 94, 421, 362, 425, 717, 64, 539, 64, 64, 64, 64, 64, 64, 64, 64, 64, 94, 94, 64, 205, 64, 387, 359, 383, 489, 502, 209, 595, 339, 241, 133, 489, 489, 489, 596, 598, 331, 113, 590, 348, 411, 358, 351, 469, 469, 412, 478, 494, 469, 469, 469, 469, 508, 469, 678, 678, 682, 412, 469, 678, 412, 266, 24, 173, 67, 412, 281, 531, 469, 512, 512, 279, 478, 515, 230, 250, 500, 678, 678, 500, 494, 56, 412, 26, 565, 567, 493, 537, 39, 400, 400, 238, 493, 228, 412, 400, 508, 245, 170, 400, 5, 683, 700, 482, 699, 680, 698, 684, 697, 487, 589, 491, 513, 692, 691, 696, 470, 485, 681, 679, 562, 483, 456, 465, 528, 481, 620, 496, 557, 479, 479, 479, 481, 676, 479, 479, 479, 479, 479, 479, 479, 479, 729, 252, 538, 497, 486, 553, 525, 458, 608, 495, 562, 562, 651, 728, 673, 474, 690, 714, 695, 576, 472, 722, 689, 650, 556, 490, 551, 688, 721, 713, 604, 456, 712, 652, 492, 562, 648, 479, 674, 701, 734, 733, 677, 732, 720, 549, 516, 731, 647, 711, 600, 599, 564, 725, 707, 719, 646, 718, 568, 521, 727, 522, 685, 501, 686, 592, 645, 643, 299, 571, 642, 694, 573, 724, 723, 726, 583, 588, 593, 594, 480, 641, 397, 587, 693, 511, 475, 520, 586, 477, 710, 635, 613, 687, 584, 561, 634, 632, 715, 518, 557, 530, 523, 526, 499, 609, 631, 716, 510, 582, 581, 580, 579, 628, 578, 623, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 134, 134, -2, -2, -2, 0, 0, 0, 0, -2, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, -3, 418, 418, -3, 418, 418, 418, 418, 418, 418, -22, -22, -22, -22, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 49, 49, 49, 49, 221, -22, -22, 221, 221, 221, 221, 221, 221, 49, 221, 92, 92, 92, 221, 94, 94, 0, 0, 0, 0, 0, 469, 92, 221, 221, 221, 221, 0, 0, 221, 221, 94, 0, 0, 0, 0, 0, 469, 469, 469, 0, 469, 92, 0, 64, 423, 423, 423, 423, 0, 0, 0, 469, 0, 469, 515, 0, 0, 0, 0, 412, 0, 678, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 479, 690, 0, 474, 0, 0, 0, 479, 479, 479, 474, 474, 0, 0, 474 ); protected $actionDefault = array( 3,32767,32767,32767,32767,32767,32767, 88,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, 32767, 88, 489, 489, 489,32767,32767,32767,32767, 302, 302, 302,32767, 481, 439, 439, 439, 439, 439, 439, 439, 481,32767,32767,32767,32767,32767, 381,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, 32767,32767,32767,32767,32767,32767, 88,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, 32767,32767,32767,32767,32767,32767, 486,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767, 364, 365, 367, 368, 301, 440, 250, 485, 300, 126, 261, 252, 204, 298, 236, 130, 329, 382, 331, 380, 384, 330, 307, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 305, 306, 383, 361, 360, 359, 327, 328, 304, 332, 334, 304, 333, 350, 351, 348, 349, 352, 353, 354, 355, 356,32767,32767,32767,32767,32767,32767, 32767,32767,32767,32767,32767,32767, 88,32767, 284, 284, 284, 284,32767, 341, 342, 242, 242, 242, 242,32767, 242, 285,32767,32767,32767,32767,32767,32767,32767, 433, 358, 336, 337, 335,32767, 411,32767,32767,32767,32767, 32767, 413,32767, 88,32767,32767, 324, 326, 405, 308, 32767,32767, 90,32767,32767,32767,32767,32767,32767,32767, 32767,32767, 408, 441, 441,32767,32767, 88, 399, 88, 169, 223, 225, 174,32767, 416,32767,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, 32767,32767,32767, 346,32767, 496,32767, 441,32767,32767, 338, 339, 340,32767,32767, 441, 441,32767, 441,32767, 441,32767,32767,32767, 174,32767,32767,32767,32767,32767, 32767,32767, 90, 414, 414, 409, 174,32767,32767, 174, 87, 87, 87, 87, 174, 87, 187,32767, 185, 185, 87, 88, 88, 87, 87, 189,32767, 455, 189, 88, 87, 174, 87, 209, 209, 390, 176, 89, 244, 244, 89, 390, 87, 174, 244, 88, 87, 87, 244,32767, 32767,32767, 82,32767,32767,32767,32767,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767, 401, 32767,32767, 421,32767, 434, 453, 399,32767, 344, 345, 347,32767, 443, 369, 370, 371, 372, 373, 374, 375, 377,32767, 482, 404,32767,32767, 84, 117, 260,32767, 494, 84, 402,32767, 494,32767,32767,32767,32767,32767, 32767,32767,32767,32767,32767, 84,32767, 84,32767,32767, 32767,32767, 478,32767, 441,32767, 403,32767, 343, 417, 460,32767,32767, 442,32767,32767, 84,32767,32767,32767, 32767,32767,32767,32767,32767, 421,32767,32767,32767,32767, 32767, 441,32767,32767,32767,32767,32767,32767,32767, 297, 32767,32767,32767,32767,32767,32767, 441,32767,32767,32767, 32767, 235,32767,32767,32767,32767,32767,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, 82, 60,32767, 278,32767,32767,32767,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767, 132, 132, 3, 3, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 263, 164, 263, 217, 263, 263, 220, 209, 209, 270 ); protected $goto = array( 163, 163, 136, 136, 136, 146, 148, 179, 164, 161, 161, 161, 161, 145, 162, 162, 162, 162, 162, 162, 162, 145, 157, 158, 159, 160, 176, 174, 177, 418, 419, 313, 420, 423, 424, 425, 426, 427, 428, 429, 430, 886, 134, 137, 138, 139, 140, 141, 142, 143, 144, 147, 173, 175, 178, 195, 198, 199, 201, 202, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 233, 234, 251, 252, 253, 320, 321, 322, 468, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 149, 194, 150, 165, 166, 167, 196, 168, 151, 152, 153, 169, 154, 197, 135, 170, 155, 171, 172, 156, 532, 200, 436, 734, 704, 469, 855, 545, 279, 200, 524, 853, 470, 710, 667, 5, 462, 669, 441, 441, 441, 261, 441, 791, 462, 770, 245, 569, 668, 434, 800, 795, 543, 457, 454, 441, 774, 572, 490, 492, 518, 522, 788, 527, 528, 802, 535, 787, 537, 544, 798, 546, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 441, 441, 486, 488, 538, 455, 476, 441, 441, 972, 441, 229, 731, 230, 231, 442, 298, 301, 448, 471, 472, 474, 766, 310, 541, 466, 485, 485, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 699, 687, 829, 433, 833, 463, 695, 1066, 1066, 777, 433, 825, 747, 480, 483, 504, 1059, 314, 296, 807, 447, 767, 973, 505, 1066, 458, 671, 768, 768, 768, 768, 870, 1051, 762, 769, 703, 968, 695, 1069, 695, 974, 1028, 376, 676, 460, 726, 721, 722, 735, 677, 723, 674, 724, 725, 8, 933, 675, 810, 729, 1067, 1067, 821, 326, 506, 330, 317, 317, 266, 267, 283, 464, 269, 325, 284, 328, 491, 1067, 805, 805, 1056, 467, 479, 814, 1040, 686, 686, 285, 280, 281, 696, 696, 696, 698, 510, 685, 497, 277, 691, 523, 307, 688, 830, 312, 556, 969, 964, 512, 368, 976, 482, 684, 815, 815, 815, 815, 976, 815, 700, 815, 834, 779, 1037, 815, 384, 872, 0, 863, 0, 1037, 0, 0, 0, 976, 976, 976, 976, 1048, 1048, 976, 976, 0, 0, 0, 0, 0, 0, 0, 0, 0, 742, 0, 0, 743, 1034, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 832, 0, 0, 832, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1041, 1042 ); protected $gotoCheck = array( 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 60, 53, 8, 10, 33, 7, 7, 7, 76, 53, 7, 7, 93, 13, 13, 106, 81, 15, 8, 8, 8, 128, 8, 13, 81, 13, 128, 13, 14, 13, 13, 13, 5, 8, 36, 8, 37, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 8, 8, 64, 64, 64, 8, 8, 8, 8, 88, 8, 69, 52, 69, 69, 8, 46, 46, 46, 46, 46, 46, 72, 72, 72, 8, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 11, 11, 11, 71, 11, 130, 23, 139, 139, 11, 71, 90, 11, 11, 43, 43, 138, 62, 49, 11, 62, 11, 88, 51, 139, 62, 10, 71, 71, 71, 71, 11, 136, 71, 71, 11, 11, 23, 139, 23, 88, 88, 62, 10, 50, 10, 10, 10, 10, 10, 10, 10, 10, 10, 62, 112, 10, 84, 10, 140, 140, 86, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 140, 81, 81, 81, 2, 2, 87, 133, 23, 23, 17, 76, 76, 23, 23, 23, 23, 65, 23, 21, 9, 27, 65, 16, 25, 92, 65, 78, 121, 118, 20, 67, 60, 68, 12, 60, 60, 60, 60, 60, 60, 29, 60, 95, 75, 93, 60, 116, 109, -1, 106, -1, 93, -1, -1, -1, 60, 60, 60, 60, 93, 93, 60, 60, -1, -1, -1, -1, -1, -1, -1, -1, -1, 60, -1, -1, 60, 93, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 93, -1, -1, 93, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 93, 93 ); protected $gotoBase = array( 0, 0, -236, 0, 0, 135, 0, 115, -139, 55, -18, -118, -37, 125, 139, 128, 47, 65, 0, 0, 6, 57, 0, -15, 0, 46, 0, 58, 0, -11, -20, 0, 0, 110, 0, 0, -401, 133, 0, 0, 0, 0, 0, 217, 0, 0, 174, 0, 0, 219, 59, 41, 191, 81, 0, 0, 0, 0, 0, 0, 109, 0, -96, 0, -41, -53, 0, -19, -26, -364, 0, 4, -42, 0, 0, -16, -253, 0, 25, 0, 0, 96, 5, 0, 50, 0, 52, 69, -93, 0, 223, 0, 45, 122, 0, -10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 118, 0, 0, -28, 0, 0, 49, 0, 0, 0, -25, 0, -6, 0, 0, 3, 0, 0, 0, 0, 0, 0, -121, -35, 215, -49, 0, 68, 0, 0, 224, 0, 225, -4, 48, 0, 0 ); protected $gotoDefault = array( -32768, 389, 577, 2, 578, 649, 657, 513, 409, 437, 728, 875, 690, 772, 711, 712, 302, 340, 294, 300, 498, 487, 380, 697, 352, 689, 377, 692, 351, 701, 133, 514, 386, 705, 1, 707, 443, 738, 291, 715, 292, 517, 717, 450, 719, 720, 297, 303, 304, 879, 459, 484, 730, 203, 452, 732, 290, 733, 741, 331, 295, 363, 520, 494, 475, 509, 410, 365, 481, 228, 461, 983, 764, 372, 360, 778, 278, 786, 561, 794, 797, 411, 412, 370, 809, 371, 819, 813, 991, 364, 824, 353, 831, 1023, 355, 835, 838, 341, 500, 329, 842, 843, 4, 847, 533, 534, 862, 241, 382, 871, 350, 885, 344, 952, 954, 445, 379, 965, 359, 521, 387, 970, 1027, 348, 413, 366, 268, 282, 244, 414, 431, 249, 415, 367, 1030, 318, 1052, 432, 1060, 1068, 275, 315, 478 ); protected $ruleToNonTerminal = array( 0, 1, 3, 3, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 7, 8, 8, 9, 10, 10, 11, 11, 12, 12, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 17, 17, 18, 18, 18, 18, 20, 22, 22, 16, 24, 24, 21, 26, 26, 23, 23, 25, 25, 27, 27, 19, 28, 28, 29, 31, 32, 32, 33, 34, 34, 36, 35, 35, 35, 35, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 13, 13, 56, 56, 59, 59, 58, 57, 57, 50, 61, 61, 62, 62, 63, 63, 14, 15, 15, 15, 66, 66, 66, 67, 67, 70, 70, 68, 68, 72, 73, 73, 44, 44, 52, 52, 55, 55, 55, 54, 74, 74, 75, 45, 45, 45, 45, 76, 76, 77, 77, 78, 78, 42, 42, 38, 38, 79, 40, 40, 80, 39, 39, 41, 41, 51, 51, 51, 51, 64, 64, 83, 83, 84, 84, 86, 86, 87, 87, 87, 85, 85, 65, 65, 88, 88, 89, 89, 90, 90, 90, 47, 91, 91, 92, 48, 94, 94, 95, 95, 69, 69, 96, 96, 96, 96, 101, 101, 102, 102, 103, 103, 103, 103, 103, 104, 105, 105, 100, 100, 97, 97, 99, 99, 107, 107, 106, 106, 106, 106, 106, 106, 98, 108, 108, 109, 109, 49, 110, 110, 43, 43, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 117, 111, 111, 116, 116, 119, 120, 120, 121, 122, 122, 122, 71, 71, 60, 60, 60, 112, 112, 112, 124, 124, 113, 113, 115, 115, 115, 118, 118, 129, 129, 129, 82, 131, 131, 131, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 46, 46, 127, 127, 127, 123, 123, 123, 132, 132, 132, 132, 132, 132, 53, 53, 53, 93, 93, 93, 93, 134, 126, 126, 126, 126, 126, 126, 125, 125, 125, 133, 133, 133, 133, 81, 135, 135, 136, 136, 136, 136, 136, 130, 137, 137, 138, 138, 138, 138, 138, 128, 128, 128, 128, 140, 141, 139, 139, 139, 139, 139, 139, 139, 142, 142, 142, 142 ); protected $ruleToLength = array( 1, 1, 2, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 3, 5, 4, 3, 4, 2, 3, 1, 1, 7, 8, 6, 7, 2, 3, 1, 2, 3, 1, 2, 3, 1, 1, 3, 1, 2, 1, 2, 2, 3, 1, 3, 2, 3, 1, 3, 2, 0, 1, 1, 1, 1, 1, 3, 7, 10, 5, 7, 9, 5, 3, 3, 3, 3, 3, 3, 1, 2, 5, 7, 9, 5, 6, 3, 3, 2, 1, 1, 1, 0, 2, 1, 3, 8, 0, 4, 2, 1, 3, 0, 1, 0, 1, 10, 7, 6, 5, 1, 2, 2, 0, 2, 0, 2, 0, 2, 2, 1, 3, 1, 4, 1, 4, 1, 1, 4, 2, 1, 3, 3, 3, 4, 4, 5, 0, 2, 4, 3, 1, 1, 1, 4, 0, 2, 5, 0, 2, 6, 0, 2, 0, 3, 1, 2, 1, 1, 2, 0, 1, 3, 4, 6, 1, 2, 1, 1, 1, 0, 1, 0, 2, 2, 4, 1, 3, 1, 2, 2, 2, 3, 1, 1, 2, 3, 1, 1, 3, 2, 0, 3, 4, 9, 3, 1, 3, 0, 2, 4, 5, 4, 4, 4, 3, 1, 1, 1, 3, 1, 1, 0, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 3, 1, 3, 2, 3, 1, 0, 1, 1, 3, 3, 3, 4, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 4, 3, 4, 4, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 2, 1, 2, 4, 2, 10, 11, 7, 3, 2, 0, 4, 2, 1, 3, 2, 2, 2, 4, 1, 1, 1, 2, 3, 1, 1, 1, 1, 1, 0, 3, 0, 1, 1, 0, 1, 1, 3, 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 2, 3, 3, 0, 1, 1, 3, 1, 1, 3, 1, 1, 4, 4, 4, 1, 4, 1, 1, 3, 1, 4, 2, 2, 3, 1, 4, 4, 3, 3, 3, 1, 3, 1, 1, 3, 1, 1, 4, 3, 1, 1, 1, 3, 3, 0, 1, 3, 1, 3, 1, 4, 2, 0, 2, 2, 1, 2, 1, 1, 1, 4, 3, 3, 3, 6, 3, 1, 1, 2, 1 ); protected function reduceRule0() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule1() { $this->semValue = $this->handleNamespaces($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule2() { if (is_array($this->semStack[$this->stackPos-(2-2)])) { $this->semValue = array_merge($this->semStack[$this->stackPos-(2-1)], $this->semStack[$this->stackPos-(2-2)]); } else { $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; }; } protected function reduceRule3() { $this->semValue = array(); } protected function reduceRule4() { $startAttributes = $this->lookaheadStartAttributes; if (isset($startAttributes['comments'])) { $nop = new Stmt\Nop(['comments' => $startAttributes['comments']]); } else { $nop = null; }; if ($nop !== null) { $this->semStack[$this->stackPos-(1-1)][] = $nop; } $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule5() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule6() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule7() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule8() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule9() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule10() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule11() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule12() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule13() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule14() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule15() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule16() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule17() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule18() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule19() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule20() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule21() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule22() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule23() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule24() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule25() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule26() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule27() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule28() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule29() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule30() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule31() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule32() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule33() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule34() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule35() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule36() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule37() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule38() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule39() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule40() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule41() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule42() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule43() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule44() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule45() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule46() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule47() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule48() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule49() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule50() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule51() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule52() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule53() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule54() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule55() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule56() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule57() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule58() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule59() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule60() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule61() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule62() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule63() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule64() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule65() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule66() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule67() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule68() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule69() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule70() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule71() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule72() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule73() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule74() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule75() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule76() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule77() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule78() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule79() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule80() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule81() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule82() { $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule83() { $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; } protected function reduceRule84() { $this->semValue = new Name($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule85() { /* nothing */ } protected function reduceRule86() { /* nothing */ } protected function reduceRule87() { /* nothing */ } protected function reduceRule88() { $this->emitError(new Error('A trailing comma is not allowed here', $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes)); } protected function reduceRule89() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule90() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule91() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule92() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule93() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule94() { $this->semValue = new Stmt\HaltCompiler($this->lexer->handleHaltCompiler(), $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule95() { $this->semValue = new Stmt\Namespace_($this->semStack[$this->stackPos-(3-2)], null, $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); $this->semValue->setAttribute('kind', Stmt\Namespace_::KIND_SEMICOLON); $this->checkNamespace($this->semValue); } protected function reduceRule96() { $this->semValue = new Stmt\Namespace_($this->semStack[$this->stackPos-(5-2)], $this->semStack[$this->stackPos-(5-4)], $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); $this->semValue->setAttribute('kind', Stmt\Namespace_::KIND_BRACED); $this->checkNamespace($this->semValue); } protected function reduceRule97() { $this->semValue = new Stmt\Namespace_(null, $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); $this->semValue->setAttribute('kind', Stmt\Namespace_::KIND_BRACED); $this->checkNamespace($this->semValue); } protected function reduceRule98() { $this->semValue = new Stmt\Use_($this->semStack[$this->stackPos-(3-2)], Stmt\Use_::TYPE_NORMAL, $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule99() { $this->semValue = new Stmt\Use_($this->semStack[$this->stackPos-(4-3)], $this->semStack[$this->stackPos-(4-2)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule100() { $this->semValue = $this->semStack[$this->stackPos-(2-1)]; } protected function reduceRule101() { $this->semValue = new Stmt\Const_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule102() { $this->semValue = Stmt\Use_::TYPE_FUNCTION; } protected function reduceRule103() { $this->semValue = Stmt\Use_::TYPE_CONSTANT; } protected function reduceRule104() { $this->semValue = new Stmt\GroupUse(new Name($this->semStack[$this->stackPos-(7-3)], $this->startAttributeStack[$this->stackPos-(7-3)] + $this->endAttributeStack[$this->stackPos-(7-3)]), $this->semStack[$this->stackPos-(7-6)], $this->semStack[$this->stackPos-(7-2)], $this->startAttributeStack[$this->stackPos-(7-1)] + $this->endAttributes); } protected function reduceRule105() { $this->semValue = new Stmt\GroupUse(new Name($this->semStack[$this->stackPos-(8-4)], $this->startAttributeStack[$this->stackPos-(8-4)] + $this->endAttributeStack[$this->stackPos-(8-4)]), $this->semStack[$this->stackPos-(8-7)], $this->semStack[$this->stackPos-(8-2)], $this->startAttributeStack[$this->stackPos-(8-1)] + $this->endAttributes); } protected function reduceRule106() { $this->semValue = new Stmt\GroupUse(new Name($this->semStack[$this->stackPos-(6-2)], $this->startAttributeStack[$this->stackPos-(6-2)] + $this->endAttributeStack[$this->stackPos-(6-2)]), $this->semStack[$this->stackPos-(6-5)], Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$this->stackPos-(6-1)] + $this->endAttributes); } protected function reduceRule107() { $this->semValue = new Stmt\GroupUse(new Name($this->semStack[$this->stackPos-(7-3)], $this->startAttributeStack[$this->stackPos-(7-3)] + $this->endAttributeStack[$this->stackPos-(7-3)]), $this->semStack[$this->stackPos-(7-6)], Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$this->stackPos-(7-1)] + $this->endAttributes); } protected function reduceRule108() { $this->semValue = $this->semStack[$this->stackPos-(2-1)]; } protected function reduceRule109() { $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; } protected function reduceRule110() { $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule111() { $this->semValue = $this->semStack[$this->stackPos-(2-1)]; } protected function reduceRule112() { $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; } protected function reduceRule113() { $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule114() { $this->semValue = $this->semStack[$this->stackPos-(2-1)]; } protected function reduceRule115() { $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; } protected function reduceRule116() { $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule117() { $this->semValue = new Stmt\UseUse($this->semStack[$this->stackPos-(1-1)], null, Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); $this->checkUseUse($this->semValue, $this->stackPos-(1-1)); } protected function reduceRule118() { $this->semValue = new Stmt\UseUse($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); $this->checkUseUse($this->semValue, $this->stackPos-(3-3)); } protected function reduceRule119() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule120() { $this->semValue = $this->semStack[$this->stackPos-(2-2)]; } protected function reduceRule121() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; $this->semValue->type = Stmt\Use_::TYPE_NORMAL; } protected function reduceRule122() { $this->semValue = $this->semStack[$this->stackPos-(2-2)]; $this->semValue->type = $this->semStack[$this->stackPos-(2-1)]; } protected function reduceRule123() { $this->semValue = $this->semStack[$this->stackPos-(2-1)]; } protected function reduceRule124() { $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; } protected function reduceRule125() { $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule126() { $this->semValue = new Node\Const_($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule127() { $this->semValue = $this->semStack[$this->stackPos-(2-1)]; } protected function reduceRule128() { $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; } protected function reduceRule129() { $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule130() { $this->semValue = new Node\Const_($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule131() { if (is_array($this->semStack[$this->stackPos-(2-2)])) { $this->semValue = array_merge($this->semStack[$this->stackPos-(2-1)], $this->semStack[$this->stackPos-(2-2)]); } else { $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; }; } protected function reduceRule132() { $this->semValue = array(); } protected function reduceRule133() { $startAttributes = $this->lookaheadStartAttributes; if (isset($startAttributes['comments'])) { $nop = new Stmt\Nop(['comments' => $startAttributes['comments']]); } else { $nop = null; }; if ($nop !== null) { $this->semStack[$this->stackPos-(1-1)][] = $nop; } $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule134() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule135() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule136() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule137() { throw new Error('__HALT_COMPILER() can only be used from the outermost scope', $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule138() { if ($this->semStack[$this->stackPos-(3-2)]) { $this->semValue = $this->semStack[$this->stackPos-(3-2)]; $attrs = $this->startAttributeStack[$this->stackPos-(3-1)]; $stmts = $this->semValue; if (!empty($attrs['comments'])) {$stmts[0]->setAttribute('comments', array_merge($attrs['comments'], $stmts[0]->getAttribute('comments', []))); }; } else { $startAttributes = $this->startAttributeStack[$this->stackPos-(3-1)]; if (isset($startAttributes['comments'])) { $this->semValue = new Stmt\Nop(['comments' => $startAttributes['comments']]); } else { $this->semValue = null; }; if (null === $this->semValue) { $this->semValue = array(); } } } protected function reduceRule139() { $this->semValue = new Stmt\If_($this->semStack[$this->stackPos-(7-3)], ['stmts' => is_array($this->semStack[$this->stackPos-(7-5)]) ? $this->semStack[$this->stackPos-(7-5)] : array($this->semStack[$this->stackPos-(7-5)]), 'elseifs' => $this->semStack[$this->stackPos-(7-6)], 'else' => $this->semStack[$this->stackPos-(7-7)]], $this->startAttributeStack[$this->stackPos-(7-1)] + $this->endAttributes); } protected function reduceRule140() { $this->semValue = new Stmt\If_($this->semStack[$this->stackPos-(10-3)], ['stmts' => $this->semStack[$this->stackPos-(10-6)], 'elseifs' => $this->semStack[$this->stackPos-(10-7)], 'else' => $this->semStack[$this->stackPos-(10-8)]], $this->startAttributeStack[$this->stackPos-(10-1)] + $this->endAttributes); } protected function reduceRule141() { $this->semValue = new Stmt\While_($this->semStack[$this->stackPos-(5-3)], $this->semStack[$this->stackPos-(5-5)], $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); } protected function reduceRule142() { $this->semValue = new Stmt\Do_($this->semStack[$this->stackPos-(7-5)], is_array($this->semStack[$this->stackPos-(7-2)]) ? $this->semStack[$this->stackPos-(7-2)] : array($this->semStack[$this->stackPos-(7-2)]), $this->startAttributeStack[$this->stackPos-(7-1)] + $this->endAttributes); } protected function reduceRule143() { $this->semValue = new Stmt\For_(['init' => $this->semStack[$this->stackPos-(9-3)], 'cond' => $this->semStack[$this->stackPos-(9-5)], 'loop' => $this->semStack[$this->stackPos-(9-7)], 'stmts' => $this->semStack[$this->stackPos-(9-9)]], $this->startAttributeStack[$this->stackPos-(9-1)] + $this->endAttributes); } protected function reduceRule144() { $this->semValue = new Stmt\Switch_($this->semStack[$this->stackPos-(5-3)], $this->semStack[$this->stackPos-(5-5)], $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); } protected function reduceRule145() { $this->semValue = new Stmt\Break_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule146() { $this->semValue = new Stmt\Continue_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule147() { $this->semValue = new Stmt\Return_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule148() { $this->semValue = new Stmt\Global_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule149() { $this->semValue = new Stmt\Static_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule150() { $this->semValue = new Stmt\Echo_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule151() { $this->semValue = new Stmt\InlineHTML($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule152() { $this->semValue = $this->semStack[$this->stackPos-(2-1)]; } protected function reduceRule153() { $this->semValue = new Stmt\Unset_($this->semStack[$this->stackPos-(5-3)], $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); } protected function reduceRule154() { $this->semValue = new Stmt\Foreach_($this->semStack[$this->stackPos-(7-3)], $this->semStack[$this->stackPos-(7-5)][0], ['keyVar' => null, 'byRef' => $this->semStack[$this->stackPos-(7-5)][1], 'stmts' => $this->semStack[$this->stackPos-(7-7)]], $this->startAttributeStack[$this->stackPos-(7-1)] + $this->endAttributes); } protected function reduceRule155() { $this->semValue = new Stmt\Foreach_($this->semStack[$this->stackPos-(9-3)], $this->semStack[$this->stackPos-(9-7)][0], ['keyVar' => $this->semStack[$this->stackPos-(9-5)], 'byRef' => $this->semStack[$this->stackPos-(9-7)][1], 'stmts' => $this->semStack[$this->stackPos-(9-9)]], $this->startAttributeStack[$this->stackPos-(9-1)] + $this->endAttributes); } protected function reduceRule156() { $this->semValue = new Stmt\Declare_($this->semStack[$this->stackPos-(5-3)], $this->semStack[$this->stackPos-(5-5)], $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); } protected function reduceRule157() { $this->semValue = new Stmt\TryCatch($this->semStack[$this->stackPos-(6-3)], $this->semStack[$this->stackPos-(6-5)], $this->semStack[$this->stackPos-(6-6)], $this->startAttributeStack[$this->stackPos-(6-1)] + $this->endAttributes); $this->checkTryCatch($this->semValue); } protected function reduceRule158() { $this->semValue = new Stmt\Throw_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule159() { $this->semValue = new Stmt\Goto_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule160() { $this->semValue = new Stmt\Label($this->semStack[$this->stackPos-(2-1)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule161() { $this->semValue = array(); /* means: no statement */ } protected function reduceRule162() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule163() { $startAttributes = $this->startAttributeStack[$this->stackPos-(1-1)]; if (isset($startAttributes['comments'])) { $this->semValue = new Stmt\Nop(['comments' => $startAttributes['comments']]); } else { $this->semValue = null; }; if ($this->semValue === null) $this->semValue = array(); /* means: no statement */ } protected function reduceRule164() { $this->semValue = array(); } protected function reduceRule165() { $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; } protected function reduceRule166() { $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule167() { $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; } protected function reduceRule168() { $this->semValue = new Stmt\Catch_($this->semStack[$this->stackPos-(8-3)], substr($this->semStack[$this->stackPos-(8-4)], 1), $this->semStack[$this->stackPos-(8-7)], $this->startAttributeStack[$this->stackPos-(8-1)] + $this->endAttributes); } protected function reduceRule169() { $this->semValue = null; } protected function reduceRule170() { $this->semValue = new Stmt\Finally_($this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule171() { $this->semValue = $this->semStack[$this->stackPos-(2-1)]; } protected function reduceRule172() { $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule173() { $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; } protected function reduceRule174() { $this->semValue = false; } protected function reduceRule175() { $this->semValue = true; } protected function reduceRule176() { $this->semValue = false; } protected function reduceRule177() { $this->semValue = true; } protected function reduceRule178() { $this->semValue = new Stmt\Function_($this->semStack[$this->stackPos-(10-3)], ['byRef' => $this->semStack[$this->stackPos-(10-2)], 'params' => $this->semStack[$this->stackPos-(10-5)], 'returnType' => $this->semStack[$this->stackPos-(10-7)], 'stmts' => $this->semStack[$this->stackPos-(10-9)]], $this->startAttributeStack[$this->stackPos-(10-1)] + $this->endAttributes); } protected function reduceRule179() { $this->semValue = new Stmt\Class_($this->semStack[$this->stackPos-(7-2)], ['type' => $this->semStack[$this->stackPos-(7-1)], 'extends' => $this->semStack[$this->stackPos-(7-3)], 'implements' => $this->semStack[$this->stackPos-(7-4)], 'stmts' => $this->semStack[$this->stackPos-(7-6)]], $this->startAttributeStack[$this->stackPos-(7-1)] + $this->endAttributes); $this->checkClass($this->semValue, $this->stackPos-(7-2)); } protected function reduceRule180() { $this->semValue = new Stmt\Interface_($this->semStack[$this->stackPos-(6-2)], ['extends' => $this->semStack[$this->stackPos-(6-3)], 'stmts' => $this->semStack[$this->stackPos-(6-5)]], $this->startAttributeStack[$this->stackPos-(6-1)] + $this->endAttributes); $this->checkInterface($this->semValue, $this->stackPos-(6-2)); } protected function reduceRule181() { $this->semValue = new Stmt\Trait_($this->semStack[$this->stackPos-(5-2)], ['stmts' => $this->semStack[$this->stackPos-(5-4)]], $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); } protected function reduceRule182() { $this->semValue = 0; } protected function reduceRule183() { $this->semValue = Stmt\Class_::MODIFIER_ABSTRACT; } protected function reduceRule184() { $this->semValue = Stmt\Class_::MODIFIER_FINAL; } protected function reduceRule185() { $this->semValue = null; } protected function reduceRule186() { $this->semValue = $this->semStack[$this->stackPos-(2-2)]; } protected function reduceRule187() { $this->semValue = array(); } protected function reduceRule188() { $this->semValue = $this->semStack[$this->stackPos-(2-2)]; } protected function reduceRule189() { $this->semValue = array(); } protected function reduceRule190() { $this->semValue = $this->semStack[$this->stackPos-(2-2)]; } protected function reduceRule191() { $this->semValue = $this->semStack[$this->stackPos-(2-1)]; } protected function reduceRule192() { $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule193() { $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; } protected function reduceRule194() { $this->semValue = is_array($this->semStack[$this->stackPos-(1-1)]) ? $this->semStack[$this->stackPos-(1-1)] : array($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule195() { $this->semValue = $this->semStack[$this->stackPos-(4-2)]; } protected function reduceRule196() { $this->semValue = is_array($this->semStack[$this->stackPos-(1-1)]) ? $this->semStack[$this->stackPos-(1-1)] : array($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule197() { $this->semValue = $this->semStack[$this->stackPos-(4-2)]; } protected function reduceRule198() { $this->semValue = is_array($this->semStack[$this->stackPos-(1-1)]) ? $this->semStack[$this->stackPos-(1-1)] : array($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule199() { $this->semValue = null; } protected function reduceRule200() { $this->semValue = $this->semStack[$this->stackPos-(4-2)]; } protected function reduceRule201() { $this->semValue = $this->semStack[$this->stackPos-(2-1)]; } protected function reduceRule202() { $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule203() { $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; } protected function reduceRule204() { $this->semValue = new Stmt\DeclareDeclare($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule205() { $this->semValue = $this->semStack[$this->stackPos-(3-2)]; } protected function reduceRule206() { $this->semValue = $this->semStack[$this->stackPos-(4-3)]; } protected function reduceRule207() { $this->semValue = $this->semStack[$this->stackPos-(4-2)]; } protected function reduceRule208() { $this->semValue = $this->semStack[$this->stackPos-(5-3)]; } protected function reduceRule209() { $this->semValue = array(); } protected function reduceRule210() { $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; } protected function reduceRule211() { $this->semValue = new Stmt\Case_($this->semStack[$this->stackPos-(4-2)], $this->semStack[$this->stackPos-(4-4)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule212() { $this->semValue = new Stmt\Case_(null, $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule213() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule214() { $this->semValue = $this->semStack[$this->stackPos]; } protected function reduceRule215() { $this->semValue = is_array($this->semStack[$this->stackPos-(1-1)]) ? $this->semStack[$this->stackPos-(1-1)] : array($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule216() { $this->semValue = $this->semStack[$this->stackPos-(4-2)]; } protected function reduceRule217() { $this->semValue = array(); } protected function reduceRule218() { $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; } protected function reduceRule219() { $this->semValue = new Stmt\ElseIf_($this->semStack[$this->stackPos-(5-3)], is_array($this->semStack[$this->stackPos-(5-5)]) ? $this->semStack[$this->stackPos-(5-5)] : array($this->semStack[$this->stackPos-(5-5)]), $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); } protected function reduceRule220() { $this->semValue = array(); } protected function reduceRule221() { $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; } protected function reduceRule222() { $this->semValue = new Stmt\ElseIf_($this->semStack[$this->stackPos-(6-3)], $this->semStack[$this->stackPos-(6-6)], $this->startAttributeStack[$this->stackPos-(6-1)] + $this->endAttributes); } protected function reduceRule223() { $this->semValue = null; } protected function reduceRule224() { $this->semValue = new Stmt\Else_(is_array($this->semStack[$this->stackPos-(2-2)]) ? $this->semStack[$this->stackPos-(2-2)] : array($this->semStack[$this->stackPos-(2-2)]), $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule225() { $this->semValue = null; } protected function reduceRule226() { $this->semValue = new Stmt\Else_($this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule227() { $this->semValue = array($this->semStack[$this->stackPos-(1-1)], false); } protected function reduceRule228() { $this->semValue = array($this->semStack[$this->stackPos-(2-2)], true); } protected function reduceRule229() { $this->semValue = array($this->semStack[$this->stackPos-(1-1)], false); } protected function reduceRule230() { $this->semValue = array($this->semStack[$this->stackPos-(1-1)], false); } protected function reduceRule231() { $this->semValue = $this->semStack[$this->stackPos-(2-1)]; } protected function reduceRule232() { $this->semValue = array(); } protected function reduceRule233() { $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule234() { $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; } protected function reduceRule235() { $this->semValue = new Node\Param(substr($this->semStack[$this->stackPos-(4-4)], 1), null, $this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-2)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); $this->checkParam($this->semValue); } protected function reduceRule236() { $this->semValue = new Node\Param(substr($this->semStack[$this->stackPos-(6-4)], 1), $this->semStack[$this->stackPos-(6-6)], $this->semStack[$this->stackPos-(6-1)], $this->semStack[$this->stackPos-(6-2)], $this->semStack[$this->stackPos-(6-3)], $this->startAttributeStack[$this->stackPos-(6-1)] + $this->endAttributes); $this->checkParam($this->semValue); } protected function reduceRule237() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule238() { $this->semValue = new Node\NullableType($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule239() { $this->semValue = $this->handleBuiltinTypes($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule240() { $this->semValue = 'array'; } protected function reduceRule241() { $this->semValue = 'callable'; } protected function reduceRule242() { $this->semValue = null; } protected function reduceRule243() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule244() { $this->semValue = null; } protected function reduceRule245() { $this->semValue = $this->semStack[$this->stackPos-(2-2)]; } protected function reduceRule246() { $this->semValue = array(); } protected function reduceRule247() { $this->semValue = $this->semStack[$this->stackPos-(4-2)]; } protected function reduceRule248() { $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule249() { $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; } protected function reduceRule250() { $this->semValue = new Node\Arg($this->semStack[$this->stackPos-(1-1)], false, false, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule251() { $this->semValue = new Node\Arg($this->semStack[$this->stackPos-(2-2)], true, false, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule252() { $this->semValue = new Node\Arg($this->semStack[$this->stackPos-(2-2)], false, true, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule253() { $this->semValue = $this->semStack[$this->stackPos-(2-1)]; } protected function reduceRule254() { $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; } protected function reduceRule255() { $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule256() { $this->semValue = new Expr\Variable($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule257() { $this->semValue = $this->semStack[$this->stackPos-(2-1)]; } protected function reduceRule258() { $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; } protected function reduceRule259() { $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule260() { $this->semValue = new Stmt\StaticVar(substr($this->semStack[$this->stackPos-(1-1)], 1), null, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule261() { $this->semValue = new Stmt\StaticVar(substr($this->semStack[$this->stackPos-(3-1)], 1), $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule262() { $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; } protected function reduceRule263() { $this->semValue = array(); } protected function reduceRule264() { $this->semValue = new Stmt\Property($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); $this->checkProperty($this->semValue, $this->stackPos-(3-1)); } protected function reduceRule265() { $this->semValue = new Stmt\ClassConst($this->semStack[$this->stackPos-(4-3)], $this->semStack[$this->stackPos-(4-1)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); $this->checkClassConst($this->semValue, $this->stackPos-(4-1)); } protected function reduceRule266() { $this->semValue = new Stmt\ClassMethod($this->semStack[$this->stackPos-(9-4)], ['type' => $this->semStack[$this->stackPos-(9-1)], 'byRef' => $this->semStack[$this->stackPos-(9-3)], 'params' => $this->semStack[$this->stackPos-(9-6)], 'returnType' => $this->semStack[$this->stackPos-(9-8)], 'stmts' => $this->semStack[$this->stackPos-(9-9)]], $this->startAttributeStack[$this->stackPos-(9-1)] + $this->endAttributes); $this->checkClassMethod($this->semValue, $this->stackPos-(9-1)); } protected function reduceRule267() { $this->semValue = new Stmt\TraitUse($this->semStack[$this->stackPos-(3-2)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule268() { $this->semValue = array(); } protected function reduceRule269() { $this->semValue = $this->semStack[$this->stackPos-(3-2)]; } protected function reduceRule270() { $this->semValue = array(); } protected function reduceRule271() { $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; } protected function reduceRule272() { $this->semValue = new Stmt\TraitUseAdaptation\Precedence($this->semStack[$this->stackPos-(4-1)][0], $this->semStack[$this->stackPos-(4-1)][1], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule273() { $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$this->stackPos-(5-1)][0], $this->semStack[$this->stackPos-(5-1)][1], $this->semStack[$this->stackPos-(5-3)], $this->semStack[$this->stackPos-(5-4)], $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); } protected function reduceRule274() { $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$this->stackPos-(4-1)][0], $this->semStack[$this->stackPos-(4-1)][1], $this->semStack[$this->stackPos-(4-3)], null, $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule275() { $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$this->stackPos-(4-1)][0], $this->semStack[$this->stackPos-(4-1)][1], null, $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule276() { $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$this->stackPos-(4-1)][0], $this->semStack[$this->stackPos-(4-1)][1], null, $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule277() { $this->semValue = array($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)]); } protected function reduceRule278() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule279() { $this->semValue = array(null, $this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule280() { $this->semValue = null; } protected function reduceRule281() { $this->semValue = $this->semStack[$this->stackPos-(3-2)]; } protected function reduceRule282() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule283() { $this->semValue = 0; } protected function reduceRule284() { $this->semValue = 0; } protected function reduceRule285() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule286() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule287() { $this->checkModifier($this->semStack[$this->stackPos-(2-1)], $this->semStack[$this->stackPos-(2-2)], $this->stackPos-(2-2)); $this->semValue = $this->semStack[$this->stackPos-(2-1)] | $this->semStack[$this->stackPos-(2-2)]; } protected function reduceRule288() { $this->semValue = Stmt\Class_::MODIFIER_PUBLIC; } protected function reduceRule289() { $this->semValue = Stmt\Class_::MODIFIER_PROTECTED; } protected function reduceRule290() { $this->semValue = Stmt\Class_::MODIFIER_PRIVATE; } protected function reduceRule291() { $this->semValue = Stmt\Class_::MODIFIER_STATIC; } protected function reduceRule292() { $this->semValue = Stmt\Class_::MODIFIER_ABSTRACT; } protected function reduceRule293() { $this->semValue = Stmt\Class_::MODIFIER_FINAL; } protected function reduceRule294() { $this->semValue = $this->semStack[$this->stackPos-(2-1)]; } protected function reduceRule295() { $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule296() { $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; } protected function reduceRule297() { $this->semValue = new Stmt\PropertyProperty(substr($this->semStack[$this->stackPos-(1-1)], 1), null, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule298() { $this->semValue = new Stmt\PropertyProperty(substr($this->semStack[$this->stackPos-(3-1)], 1), $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule299() { $this->semValue = $this->semStack[$this->stackPos-(2-1)]; } protected function reduceRule300() { $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; } protected function reduceRule301() { $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule302() { $this->semValue = array(); } protected function reduceRule303() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule304() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule305() { $this->semValue = new Expr\Assign($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule306() { $this->semValue = new Expr\Assign($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule307() { $this->semValue = new Expr\Assign($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule308() { $this->semValue = new Expr\AssignRef($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-4)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule309() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule310() { $this->semValue = new Expr\Clone_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule311() { $this->semValue = new Expr\AssignOp\Plus($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule312() { $this->semValue = new Expr\AssignOp\Minus($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule313() { $this->semValue = new Expr\AssignOp\Mul($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule314() { $this->semValue = new Expr\AssignOp\Div($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule315() { $this->semValue = new Expr\AssignOp\Concat($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule316() { $this->semValue = new Expr\AssignOp\Mod($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule317() { $this->semValue = new Expr\AssignOp\BitwiseAnd($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule318() { $this->semValue = new Expr\AssignOp\BitwiseOr($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule319() { $this->semValue = new Expr\AssignOp\BitwiseXor($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule320() { $this->semValue = new Expr\AssignOp\ShiftLeft($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule321() { $this->semValue = new Expr\AssignOp\ShiftRight($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule322() { $this->semValue = new Expr\AssignOp\Pow($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule323() { $this->semValue = new Expr\PostInc($this->semStack[$this->stackPos-(2-1)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule324() { $this->semValue = new Expr\PreInc($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule325() { $this->semValue = new Expr\PostDec($this->semStack[$this->stackPos-(2-1)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule326() { $this->semValue = new Expr\PreDec($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule327() { $this->semValue = new Expr\BinaryOp\BooleanOr($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule328() { $this->semValue = new Expr\BinaryOp\BooleanAnd($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule329() { $this->semValue = new Expr\BinaryOp\LogicalOr($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule330() { $this->semValue = new Expr\BinaryOp\LogicalAnd($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule331() { $this->semValue = new Expr\BinaryOp\LogicalXor($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule332() { $this->semValue = new Expr\BinaryOp\BitwiseOr($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule333() { $this->semValue = new Expr\BinaryOp\BitwiseAnd($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule334() { $this->semValue = new Expr\BinaryOp\BitwiseXor($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule335() { $this->semValue = new Expr\BinaryOp\Concat($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule336() { $this->semValue = new Expr\BinaryOp\Plus($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule337() { $this->semValue = new Expr\BinaryOp\Minus($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule338() { $this->semValue = new Expr\BinaryOp\Mul($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule339() { $this->semValue = new Expr\BinaryOp\Div($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule340() { $this->semValue = new Expr\BinaryOp\Mod($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule341() { $this->semValue = new Expr\BinaryOp\ShiftLeft($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule342() { $this->semValue = new Expr\BinaryOp\ShiftRight($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule343() { $this->semValue = new Expr\BinaryOp\Pow($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule344() { $this->semValue = new Expr\UnaryPlus($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule345() { $this->semValue = new Expr\UnaryMinus($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule346() { $this->semValue = new Expr\BooleanNot($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule347() { $this->semValue = new Expr\BitwiseNot($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule348() { $this->semValue = new Expr\BinaryOp\Identical($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule349() { $this->semValue = new Expr\BinaryOp\NotIdentical($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule350() { $this->semValue = new Expr\BinaryOp\Equal($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule351() { $this->semValue = new Expr\BinaryOp\NotEqual($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule352() { $this->semValue = new Expr\BinaryOp\Spaceship($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule353() { $this->semValue = new Expr\BinaryOp\Smaller($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule354() { $this->semValue = new Expr\BinaryOp\SmallerOrEqual($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule355() { $this->semValue = new Expr\BinaryOp\Greater($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule356() { $this->semValue = new Expr\BinaryOp\GreaterOrEqual($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule357() { $this->semValue = new Expr\Instanceof_($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule358() { $this->semValue = $this->semStack[$this->stackPos-(3-2)]; } protected function reduceRule359() { $this->semValue = new Expr\Ternary($this->semStack[$this->stackPos-(5-1)], $this->semStack[$this->stackPos-(5-3)], $this->semStack[$this->stackPos-(5-5)], $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); } protected function reduceRule360() { $this->semValue = new Expr\Ternary($this->semStack[$this->stackPos-(4-1)], null, $this->semStack[$this->stackPos-(4-4)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule361() { $this->semValue = new Expr\BinaryOp\Coalesce($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule362() { $this->semValue = new Expr\Isset_($this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule363() { $this->semValue = new Expr\Empty_($this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule364() { $this->semValue = new Expr\Include_($this->semStack[$this->stackPos-(2-2)], Expr\Include_::TYPE_INCLUDE, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule365() { $this->semValue = new Expr\Include_($this->semStack[$this->stackPos-(2-2)], Expr\Include_::TYPE_INCLUDE_ONCE, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule366() { $this->semValue = new Expr\Eval_($this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule367() { $this->semValue = new Expr\Include_($this->semStack[$this->stackPos-(2-2)], Expr\Include_::TYPE_REQUIRE, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule368() { $this->semValue = new Expr\Include_($this->semStack[$this->stackPos-(2-2)], Expr\Include_::TYPE_REQUIRE_ONCE, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule369() { $this->semValue = new Expr\Cast\Int_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule370() { $this->semValue = new Expr\Cast\Double($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule371() { $this->semValue = new Expr\Cast\String_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule372() { $this->semValue = new Expr\Cast\Array_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule373() { $this->semValue = new Expr\Cast\Object_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule374() { $this->semValue = new Expr\Cast\Bool_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule375() { $this->semValue = new Expr\Cast\Unset_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule376() { $attrs = $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes; $attrs['kind'] = strtolower($this->semStack[$this->stackPos-(2-1)]) === 'exit' ? Expr\Exit_::KIND_EXIT : Expr\Exit_::KIND_DIE; $this->semValue = new Expr\Exit_($this->semStack[$this->stackPos-(2-2)], $attrs); } protected function reduceRule377() { $this->semValue = new Expr\ErrorSuppress($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule378() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule379() { $this->semValue = new Expr\ShellExec($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule380() { $this->semValue = new Expr\Print_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule381() { $this->semValue = new Expr\Yield_(null, null, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule382() { $this->semValue = new Expr\Yield_($this->semStack[$this->stackPos-(2-2)], null, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule383() { $this->semValue = new Expr\Yield_($this->semStack[$this->stackPos-(4-4)], $this->semStack[$this->stackPos-(4-2)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule384() { $this->semValue = new Expr\YieldFrom($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule385() { $this->semValue = new Expr\Closure(['static' => false, 'byRef' => $this->semStack[$this->stackPos-(10-2)], 'params' => $this->semStack[$this->stackPos-(10-4)], 'uses' => $this->semStack[$this->stackPos-(10-6)], 'returnType' => $this->semStack[$this->stackPos-(10-7)], 'stmts' => $this->semStack[$this->stackPos-(10-9)]], $this->startAttributeStack[$this->stackPos-(10-1)] + $this->endAttributes); } protected function reduceRule386() { $this->semValue = new Expr\Closure(['static' => true, 'byRef' => $this->semStack[$this->stackPos-(11-3)], 'params' => $this->semStack[$this->stackPos-(11-5)], 'uses' => $this->semStack[$this->stackPos-(11-7)], 'returnType' => $this->semStack[$this->stackPos-(11-8)], 'stmts' => $this->semStack[$this->stackPos-(11-10)]], $this->startAttributeStack[$this->stackPos-(11-1)] + $this->endAttributes); } protected function reduceRule387() { $this->semValue = array(new Stmt\Class_(null, ['type' => 0, 'extends' => $this->semStack[$this->stackPos-(7-3)], 'implements' => $this->semStack[$this->stackPos-(7-4)], 'stmts' => $this->semStack[$this->stackPos-(7-6)]], $this->startAttributeStack[$this->stackPos-(7-1)] + $this->endAttributes), $this->semStack[$this->stackPos-(7-2)]); $this->checkClass($this->semValue[0], -1); } protected function reduceRule388() { $this->semValue = new Expr\New_($this->semStack[$this->stackPos-(3-2)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule389() { list($class, $ctorArgs) = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = new Expr\New_($class, $ctorArgs, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule390() { $this->semValue = array(); } protected function reduceRule391() { $this->semValue = $this->semStack[$this->stackPos-(4-3)]; } protected function reduceRule392() { $this->semValue = $this->semStack[$this->stackPos-(2-1)]; } protected function reduceRule393() { $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule394() { $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; } protected function reduceRule395() { $this->semValue = new Expr\ClosureUse(substr($this->semStack[$this->stackPos-(2-2)], 1), $this->semStack[$this->stackPos-(2-1)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule396() { $this->semValue = new Expr\FuncCall($this->semStack[$this->stackPos-(2-1)], $this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule397() { $this->semValue = new Expr\FuncCall($this->semStack[$this->stackPos-(2-1)], $this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule398() { $this->semValue = new Expr\StaticCall($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->semStack[$this->stackPos-(4-4)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule399() { $this->semValue = new Name($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule400() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule401() { $this->semValue = new Name($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule402() { $this->semValue = new Name\FullyQualified($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule403() { $this->semValue = new Name\Relative($this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule404() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule405() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule406() { $this->semValue = new Expr\Error($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); $this->errorState = 2; } protected function reduceRule407() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule408() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule409() { $this->semValue = null; } protected function reduceRule410() { $this->semValue = $this->semStack[$this->stackPos-(3-2)]; } protected function reduceRule411() { $this->semValue = array(); } protected function reduceRule412() { $this->semValue = array(new Scalar\EncapsedStringPart(Scalar\String_::parseEscapeSequences($this->semStack[$this->stackPos-(1-1)], '`'), $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes)); } protected function reduceRule413() { foreach ($this->semStack[$this->stackPos-(1-1)] as $s) { if ($s instanceof Node\Scalar\EncapsedStringPart) { $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '`', true); } }; $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule414() { $this->semValue = array(); } protected function reduceRule415() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule416() { $this->semValue = new Expr\ConstFetch($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule417() { $this->semValue = new Expr\ClassConstFetch($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule418() { $this->semValue = new Expr\ClassConstFetch($this->semStack[$this->stackPos-(3-1)], new Expr\Error($this->startAttributeStack[$this->stackPos-(3-3)] + $this->endAttributeStack[$this->stackPos-(3-3)]), $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); $this->errorState = 2; } protected function reduceRule419() { $attrs = $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes; $attrs['kind'] = Expr\Array_::KIND_SHORT; $this->semValue = new Expr\Array_($this->semStack[$this->stackPos-(3-2)], $attrs); } protected function reduceRule420() { $attrs = $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes; $attrs['kind'] = Expr\Array_::KIND_LONG; $this->semValue = new Expr\Array_($this->semStack[$this->stackPos-(4-3)], $attrs); } protected function reduceRule421() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule422() { $attrs = $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes; $attrs['kind'] = ($this->semStack[$this->stackPos-(1-1)][0] === "'" || ($this->semStack[$this->stackPos-(1-1)][1] === "'" && ($this->semStack[$this->stackPos-(1-1)][0] === 'b' || $this->semStack[$this->stackPos-(1-1)][0] === 'B')) ? Scalar\String_::KIND_SINGLE_QUOTED : Scalar\String_::KIND_DOUBLE_QUOTED); $this->semValue = new Scalar\String_(Scalar\String_::parse($this->semStack[$this->stackPos-(1-1)]), $attrs); } protected function reduceRule423() { $this->semValue = $this->parseLNumber($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule424() { $this->semValue = new Scalar\DNumber(Scalar\DNumber::parse($this->semStack[$this->stackPos-(1-1)]), $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule425() { $this->semValue = new Scalar\MagicConst\Line($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule426() { $this->semValue = new Scalar\MagicConst\File($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule427() { $this->semValue = new Scalar\MagicConst\Dir($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule428() { $this->semValue = new Scalar\MagicConst\Class_($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule429() { $this->semValue = new Scalar\MagicConst\Trait_($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule430() { $this->semValue = new Scalar\MagicConst\Method($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule431() { $this->semValue = new Scalar\MagicConst\Function_($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule432() { $this->semValue = new Scalar\MagicConst\Namespace_($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule433() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule434() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule435() { $attrs = $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes; $attrs['kind'] = strpos($this->semStack[$this->stackPos-(3-1)], "'") === false ? Scalar\String_::KIND_HEREDOC : Scalar\String_::KIND_NOWDOC; preg_match('/\A[bB]?<<<[ \t]*[\'"]?([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)[\'"]?(?:\r\n|\n|\r)\z/', $this->semStack[$this->stackPos-(3-1)], $matches); $attrs['docLabel'] = $matches[1];; $this->semValue = new Scalar\String_(Scalar\String_::parseDocString($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-2)]), $attrs); } protected function reduceRule436() { $attrs = $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes; $attrs['kind'] = strpos($this->semStack[$this->stackPos-(2-1)], "'") === false ? Scalar\String_::KIND_HEREDOC : Scalar\String_::KIND_NOWDOC; preg_match('/\A[bB]?<<<[ \t]*[\'"]?([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)[\'"]?(?:\r\n|\n|\r)\z/', $this->semStack[$this->stackPos-(2-1)], $matches); $attrs['docLabel'] = $matches[1];; $this->semValue = new Scalar\String_('', $attrs); } protected function reduceRule437() { $attrs = $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes; $attrs['kind'] = Scalar\String_::KIND_DOUBLE_QUOTED; foreach ($this->semStack[$this->stackPos-(3-2)] as $s) { if ($s instanceof Node\Scalar\EncapsedStringPart) { $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '"', true); } }; $this->semValue = new Scalar\Encapsed($this->semStack[$this->stackPos-(3-2)], $attrs); } protected function reduceRule438() { $attrs = $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes; $attrs['kind'] = strpos($this->semStack[$this->stackPos-(3-1)], "'") === false ? Scalar\String_::KIND_HEREDOC : Scalar\String_::KIND_NOWDOC; preg_match('/\A[bB]?<<<[ \t]*[\'"]?([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)[\'"]?(?:\r\n|\n|\r)\z/', $this->semStack[$this->stackPos-(3-1)], $matches); $attrs['docLabel'] = $matches[1];; foreach ($this->semStack[$this->stackPos-(3-2)] as $s) { if ($s instanceof Node\Scalar\EncapsedStringPart) { $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, null, true); } } $s->value = preg_replace('~(\r\n|\n|\r)\z~', '', $s->value); if ('' === $s->value) array_pop($this->semStack[$this->stackPos-(3-2)]);; $this->semValue = new Scalar\Encapsed($this->semStack[$this->stackPos-(3-2)], $attrs); } protected function reduceRule439() { $this->semValue = null; } protected function reduceRule440() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule441() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule442() { $this->semValue = $this->semStack[$this->stackPos-(3-2)]; } protected function reduceRule443() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule444() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule445() { $this->semValue = $this->semStack[$this->stackPos-(3-2)]; } protected function reduceRule446() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule447() { $this->semValue = new Expr\Variable($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule448() { $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule449() { $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule450() { $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule451() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule452() { $this->semValue = new Expr\MethodCall($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->semStack[$this->stackPos-(4-4)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule453() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule454() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule455() { $this->semValue = new Expr\PropertyFetch($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule456() { $this->semValue = substr($this->semStack[$this->stackPos-(1-1)], 1); } protected function reduceRule457() { $this->semValue = $this->semStack[$this->stackPos-(4-3)]; } protected function reduceRule458() { $this->semValue = new Expr\Variable($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule459() { $this->semValue = new Expr\Error($this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); $this->errorState = 2; } protected function reduceRule460() { $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule461() { $this->semValue = new Expr\Variable($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule462() { $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule463() { $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule464() { $this->semValue = new Expr\PropertyFetch($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule465() { $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule466() { $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule467() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule468() { $this->semValue = $this->semStack[$this->stackPos-(3-2)]; } protected function reduceRule469() { $this->semValue = new Expr\Variable($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule470() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule471() { $this->semValue = $this->semStack[$this->stackPos-(3-2)]; } protected function reduceRule472() { $this->semValue = new Expr\Variable($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule473() { $this->semValue = new Expr\Error($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); $this->errorState = 2; } protected function reduceRule474() { $this->semValue = new Expr\List_($this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule475() { $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; } protected function reduceRule476() { $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule477() { $this->semValue = new Expr\ArrayItem($this->semStack[$this->stackPos-(1-1)], null, false, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule478() { $this->semValue = new Expr\ArrayItem($this->semStack[$this->stackPos-(1-1)], null, false, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule479() { $this->semValue = new Expr\ArrayItem($this->semStack[$this->stackPos-(3-3)], $this->semStack[$this->stackPos-(3-1)], false, $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule480() { $this->semValue = new Expr\ArrayItem($this->semStack[$this->stackPos-(3-3)], $this->semStack[$this->stackPos-(3-1)], false, $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule481() { $this->semValue = null; } protected function reduceRule482() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; $end = count($this->semValue)-1; if ($this->semValue[$end] === null) unset($this->semValue[$end]); } protected function reduceRule483() { $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; } protected function reduceRule484() { $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule485() { $this->semValue = new Expr\ArrayItem($this->semStack[$this->stackPos-(3-3)], $this->semStack[$this->stackPos-(3-1)], false, $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule486() { $this->semValue = new Expr\ArrayItem($this->semStack[$this->stackPos-(1-1)], null, false, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule487() { $this->semValue = new Expr\ArrayItem($this->semStack[$this->stackPos-(4-4)], $this->semStack[$this->stackPos-(4-1)], true, $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule488() { $this->semValue = new Expr\ArrayItem($this->semStack[$this->stackPos-(2-2)], null, true, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule489() { $this->semValue = null; } protected function reduceRule490() { $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; } protected function reduceRule491() { $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; } protected function reduceRule492() { $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); } protected function reduceRule493() { $this->semValue = array($this->semStack[$this->stackPos-(2-1)], $this->semStack[$this->stackPos-(2-2)]); } protected function reduceRule494() { $this->semValue = new Scalar\EncapsedStringPart($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule495() { $this->semValue = new Expr\Variable(substr($this->semStack[$this->stackPos-(1-1)], 1), $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule496() { $this->semValue = $this->semStack[$this->stackPos-(1-1)]; } protected function reduceRule497() { $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); } protected function reduceRule498() { $this->semValue = new Expr\PropertyFetch($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule499() { $this->semValue = new Expr\Variable($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule500() { $this->semValue = new Expr\Variable($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); } protected function reduceRule501() { $this->semValue = new Expr\ArrayDimFetch(new Expr\Variable($this->semStack[$this->stackPos-(6-2)], $this->startAttributeStack[$this->stackPos-(6-1)] + $this->endAttributes), $this->semStack[$this->stackPos-(6-4)], $this->startAttributeStack[$this->stackPos-(6-1)] + $this->endAttributes); } protected function reduceRule502() { $this->semValue = $this->semStack[$this->stackPos-(3-2)]; } protected function reduceRule503() { $this->semValue = new Scalar\String_($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule504() { $this->semValue = $this->parseNumString($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule505() { $this->semValue = $this->parseNumString('-' . $this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); } protected function reduceRule506() { $this->semValue = new Expr\Variable(substr($this->semStack[$this->stackPos-(1-1)], 1), $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } } PHP-Parser-3.1.4/lib/PhpParser/Parser/Tokens.php000066400000000000000000000075501323244626500213000ustar00rootroot00000000000000lexer = $lexer; $this->errors = array(); if (isset($options['throwOnError'])) { throw new \LogicException( '"throwOnError" is no longer supported, use "errorHandler" instead'); } } /** * Parses PHP code into a node tree. * * If a non-throwing error handler is used, the parser will continue parsing after an error * occurred and attempt to build a partial AST. * * @param string $code The source code to parse * @param ErrorHandler|null $errorHandler Error handler to use for lexer/parser errors, defaults * to ErrorHandler\Throwing. * * @return Node[]|null Array of statements (or null if the 'throwOnError' option is disabled and the parser was * unable to recover from an error). */ public function parse($code, ErrorHandler $errorHandler = null) { $this->errorHandler = $errorHandler ?: new ErrorHandler\Throwing; // Initialize the lexer $this->lexer->startLexing($code, $this->errorHandler); // We start off with no lookahead-token $symbol = self::SYMBOL_NONE; // The attributes for a node are taken from the first and last token of the node. // From the first token only the startAttributes are taken and from the last only // the endAttributes. Both are merged using the array union operator (+). $startAttributes = '*POISON'; $endAttributes = '*POISON'; $this->endAttributes = $endAttributes; // Keep stack of start and end attributes $this->startAttributeStack = array(); $this->endAttributeStack = array($endAttributes); // Start off in the initial state and keep a stack of previous states $state = 0; $stateStack = array($state); // Semantic value stack (contains values of tokens and semantic action results) $this->semStack = array(); // Current position in the stack(s) $this->stackPos = 0; $this->errorState = 0; for (;;) { //$this->traceNewState($state, $symbol); if ($this->actionBase[$state] == 0) { $rule = $this->actionDefault[$state]; } else { if ($symbol === self::SYMBOL_NONE) { // Fetch the next token id from the lexer and fetch additional info by-ref. // The end attributes are fetched into a temporary variable and only set once the token is really // shifted (not during read). Otherwise you would sometimes get off-by-one errors, when a rule is // reduced after a token was read but not yet shifted. $tokenId = $this->lexer->getNextToken($tokenValue, $startAttributes, $endAttributes); // map the lexer token id to the internally used symbols $symbol = $tokenId >= 0 && $tokenId < $this->tokenToSymbolMapSize ? $this->tokenToSymbol[$tokenId] : $this->invalidSymbol; if ($symbol === $this->invalidSymbol) { throw new \RangeException(sprintf( 'The lexer returned an invalid token (id=%d, value=%s)', $tokenId, $tokenValue )); } // This is necessary to assign some meaningful attributes to /* empty */ productions. They'll get // the attributes of the next token, even though they don't contain it themselves. $this->startAttributeStack[$this->stackPos+1] = $startAttributes; $this->endAttributeStack[$this->stackPos+1] = $endAttributes; $this->lookaheadStartAttributes = $startAttributes; //$this->traceRead($symbol); } $idx = $this->actionBase[$state] + $symbol; if ((($idx >= 0 && $idx < $this->actionTableSize && $this->actionCheck[$idx] == $symbol) || ($state < $this->YY2TBLSTATE && ($idx = $this->actionBase[$state + $this->YYNLSTATES] + $symbol) >= 0 && $idx < $this->actionTableSize && $this->actionCheck[$idx] == $symbol)) && ($action = $this->action[$idx]) != $this->defaultAction) { /* * >= YYNLSTATES: shift and reduce * > 0: shift * = 0: accept * < 0: reduce * = -YYUNEXPECTED: error */ if ($action > 0) { /* shift */ //$this->traceShift($symbol); ++$this->stackPos; $stateStack[$this->stackPos] = $state = $action; $this->semStack[$this->stackPos] = $tokenValue; $this->startAttributeStack[$this->stackPos] = $startAttributes; $this->endAttributeStack[$this->stackPos] = $endAttributes; $this->endAttributes = $endAttributes; $symbol = self::SYMBOL_NONE; if ($this->errorState) { --$this->errorState; } if ($action < $this->YYNLSTATES) { continue; } /* $yyn >= YYNLSTATES means shift-and-reduce */ $rule = $action - $this->YYNLSTATES; } else { $rule = -$action; } } else { $rule = $this->actionDefault[$state]; } } for (;;) { if ($rule === 0) { /* accept */ //$this->traceAccept(); return $this->semValue; } elseif ($rule !== $this->unexpectedTokenRule) { /* reduce */ //$this->traceReduce($rule); try { $this->{'reduceRule' . $rule}(); } catch (Error $e) { if (-1 === $e->getStartLine() && isset($startAttributes['startLine'])) { $e->setStartLine($startAttributes['startLine']); } $this->emitError($e); // Can't recover from this type of error return null; } /* Goto - shift nonterminal */ $lastEndAttributes = $this->endAttributeStack[$this->stackPos]; $this->stackPos -= $this->ruleToLength[$rule]; $nonTerminal = $this->ruleToNonTerminal[$rule]; $idx = $this->gotoBase[$nonTerminal] + $stateStack[$this->stackPos]; if ($idx >= 0 && $idx < $this->gotoTableSize && $this->gotoCheck[$idx] == $nonTerminal) { $state = $this->goto[$idx]; } else { $state = $this->gotoDefault[$nonTerminal]; } ++$this->stackPos; $stateStack[$this->stackPos] = $state; $this->semStack[$this->stackPos] = $this->semValue; $this->endAttributeStack[$this->stackPos] = $lastEndAttributes; } else { /* error */ switch ($this->errorState) { case 0: $msg = $this->getErrorMessage($symbol, $state); $this->emitError(new Error($msg, $startAttributes + $endAttributes)); // Break missing intentionally case 1: case 2: $this->errorState = 3; // Pop until error-expecting state uncovered while (!( (($idx = $this->actionBase[$state] + $this->errorSymbol) >= 0 && $idx < $this->actionTableSize && $this->actionCheck[$idx] == $this->errorSymbol) || ($state < $this->YY2TBLSTATE && ($idx = $this->actionBase[$state + $this->YYNLSTATES] + $this->errorSymbol) >= 0 && $idx < $this->actionTableSize && $this->actionCheck[$idx] == $this->errorSymbol) ) || ($action = $this->action[$idx]) == $this->defaultAction) { // Not totally sure about this if ($this->stackPos <= 0) { // Could not recover from error return null; } $state = $stateStack[--$this->stackPos]; //$this->tracePop($state); } //$this->traceShift($this->errorSymbol); ++$this->stackPos; $stateStack[$this->stackPos] = $state = $action; // We treat the error symbol as being empty, so we reset the end attributes // to the end attributes of the last non-error symbol $this->endAttributeStack[$this->stackPos] = $this->endAttributeStack[$this->stackPos - 1]; $this->endAttributes = $this->endAttributeStack[$this->stackPos - 1]; break; case 3: if ($symbol === 0) { // Reached EOF without recovering from error return null; } //$this->traceDiscard($symbol); $symbol = self::SYMBOL_NONE; break 2; } } if ($state < $this->YYNLSTATES) { break; } /* >= YYNLSTATES means shift-and-reduce */ $rule = $state - $this->YYNLSTATES; } } throw new \RuntimeException('Reached end of parser loop'); } protected function emitError(Error $error) { $this->errorHandler->handleError($error); } protected function getErrorMessage($symbol, $state) { $expectedString = ''; if ($expected = $this->getExpectedTokens($state)) { $expectedString = ', expecting ' . implode(' or ', $expected); } return 'Syntax error, unexpected ' . $this->symbolToName[$symbol] . $expectedString; } protected function getExpectedTokens($state) { $expected = array(); $base = $this->actionBase[$state]; foreach ($this->symbolToName as $symbol => $name) { $idx = $base + $symbol; if ($idx >= 0 && $idx < $this->actionTableSize && $this->actionCheck[$idx] === $symbol || $state < $this->YY2TBLSTATE && ($idx = $this->actionBase[$state + $this->YYNLSTATES] + $symbol) >= 0 && $idx < $this->actionTableSize && $this->actionCheck[$idx] === $symbol ) { if ($this->action[$idx] != $this->unexpectedTokenRule && $this->action[$idx] != $this->defaultAction && $symbol != $this->errorSymbol ) { if (count($expected) == 4) { /* Too many expected tokens */ return array(); } $expected[] = $name; } } } return $expected; } /* * Tracing functions used for debugging the parser. */ /* protected function traceNewState($state, $symbol) { echo '% State ' . $state . ', Lookahead ' . ($symbol == self::SYMBOL_NONE ? '--none--' : $this->symbolToName[$symbol]) . "\n"; } protected function traceRead($symbol) { echo '% Reading ' . $this->symbolToName[$symbol] . "\n"; } protected function traceShift($symbol) { echo '% Shift ' . $this->symbolToName[$symbol] . "\n"; } protected function traceAccept() { echo "% Accepted.\n"; } protected function traceReduce($n) { echo '% Reduce by (' . $n . ') ' . $this->productions[$n] . "\n"; } protected function tracePop($state) { echo '% Recovering, uncovered state ' . $state . "\n"; } protected function traceDiscard($symbol) { echo '% Discard ' . $this->symbolToName[$symbol] . "\n"; } */ /* * Helper functions invoked by semantic actions */ /** * Moves statements of semicolon-style namespaces into $ns->stmts and checks various error conditions. * * @param Node[] $stmts * @return Node[] */ protected function handleNamespaces(array $stmts) { $hasErrored = false; $style = $this->getNamespacingStyle($stmts); if (null === $style) { // not namespaced, nothing to do return $stmts; } elseif ('brace' === $style) { // For braced namespaces we only have to check that there are no invalid statements between the namespaces $afterFirstNamespace = false; foreach ($stmts as $stmt) { if ($stmt instanceof Node\Stmt\Namespace_) { $afterFirstNamespace = true; } elseif (!$stmt instanceof Node\Stmt\HaltCompiler && !$stmt instanceof Node\Stmt\Nop && $afterFirstNamespace && !$hasErrored) { $this->emitError(new Error( 'No code may exist outside of namespace {}', $stmt->getAttributes())); $hasErrored = true; // Avoid one error for every statement } } return $stmts; } else { // For semicolon namespaces we have to move the statements after a namespace declaration into ->stmts $resultStmts = array(); $targetStmts =& $resultStmts; foreach ($stmts as $stmt) { if ($stmt instanceof Node\Stmt\Namespace_) { if ($stmt->stmts === null) { $stmt->stmts = array(); $targetStmts =& $stmt->stmts; $resultStmts[] = $stmt; } else { // This handles the invalid case of mixed style namespaces $resultStmts[] = $stmt; $targetStmts =& $resultStmts; } } elseif ($stmt instanceof Node\Stmt\HaltCompiler) { // __halt_compiler() is not moved into the namespace $resultStmts[] = $stmt; } else { $targetStmts[] = $stmt; } } return $resultStmts; } } private function getNamespacingStyle(array $stmts) { $style = null; $hasNotAllowedStmts = false; foreach ($stmts as $i => $stmt) { if ($stmt instanceof Node\Stmt\Namespace_) { $currentStyle = null === $stmt->stmts ? 'semicolon' : 'brace'; if (null === $style) { $style = $currentStyle; if ($hasNotAllowedStmts) { $this->emitError(new Error( 'Namespace declaration statement has to be the very first statement in the script', $stmt->getLine() // Avoid marking the entire namespace as an error )); } } elseif ($style !== $currentStyle) { $this->emitError(new Error( 'Cannot mix bracketed namespace declarations with unbracketed namespace declarations', $stmt->getLine() // Avoid marking the entire namespace as an error )); // Treat like semicolon style for namespace normalization return 'semicolon'; } continue; } /* declare(), __halt_compiler() and nops can be used before a namespace declaration */ if ($stmt instanceof Node\Stmt\Declare_ || $stmt instanceof Node\Stmt\HaltCompiler || $stmt instanceof Node\Stmt\Nop) { continue; } /* There may be a hashbang line at the very start of the file */ if ($i == 0 && $stmt instanceof Node\Stmt\InlineHTML && preg_match('/\A#!.*\r?\n\z/', $stmt->value)) { continue; } /* Everything else if forbidden before namespace declarations */ $hasNotAllowedStmts = true; } return $style; } protected function handleBuiltinTypes(Name $name) { $scalarTypes = [ 'bool' => true, 'int' => true, 'float' => true, 'string' => true, 'iterable' => true, 'void' => true, 'object' => true, ]; if (!$name->isUnqualified()) { return $name; } $lowerName = strtolower($name->toString()); return isset($scalarTypes[$lowerName]) ? $lowerName : $name; } protected static $specialNames = array( 'self' => true, 'parent' => true, 'static' => true, ); protected function getAttributesAt($pos) { return $this->startAttributeStack[$pos] + $this->endAttributeStack[$pos]; } protected function parseLNumber($str, $attributes, $allowInvalidOctal = false) { try { return LNumber::fromString($str, $attributes, $allowInvalidOctal); } catch (Error $error) { $this->emitError($error); // Use dummy value return new LNumber(0, $attributes); } } protected function parseNumString($str, $attributes) { if (!preg_match('/^(?:0|-?[1-9][0-9]*)$/', $str)) { return new String_($str, $attributes); } $num = +$str; if (!is_int($num)) { return new String_($str, $attributes); } return new LNumber($num, $attributes); } protected function checkModifier($a, $b, $modifierPos) { // Jumping through some hoops here because verifyModifier() is also used elsewhere try { Class_::verifyModifier($a, $b); } catch (Error $error) { $error->setAttributes($this->getAttributesAt($modifierPos)); $this->emitError($error); } } protected function checkParam(Param $node) { if ($node->variadic && null !== $node->default) { $this->emitError(new Error( 'Variadic parameter cannot have a default value', $node->default->getAttributes() )); } } protected function checkTryCatch(TryCatch $node) { if (empty($node->catches) && null === $node->finally) { $this->emitError(new Error( 'Cannot use try without catch or finally', $node->getAttributes() )); } } protected function checkNamespace(Namespace_ $node) { if (isset(self::$specialNames[strtolower($node->name)])) { $this->emitError(new Error( sprintf('Cannot use \'%s\' as namespace name', $node->name), $node->name->getAttributes() )); } if (null !== $node->stmts) { foreach ($node->stmts as $stmt) { if ($stmt instanceof Namespace_) { $this->emitError(new Error( 'Namespace declarations cannot be nested', $stmt->getAttributes() )); } } } } protected function checkClass(Class_ $node, $namePos) { if (null !== $node->name && isset(self::$specialNames[strtolower($node->name)])) { $this->emitError(new Error( sprintf('Cannot use \'%s\' as class name as it is reserved', $node->name), $this->getAttributesAt($namePos) )); } if (isset(self::$specialNames[strtolower($node->extends)])) { $this->emitError(new Error( sprintf('Cannot use \'%s\' as class name as it is reserved', $node->extends), $node->extends->getAttributes() )); } foreach ($node->implements as $interface) { if (isset(self::$specialNames[strtolower($interface)])) { $this->emitError(new Error( sprintf('Cannot use \'%s\' as interface name as it is reserved', $interface), $interface->getAttributes() )); } } } protected function checkInterface(Interface_ $node, $namePos) { if (null !== $node->name && isset(self::$specialNames[strtolower($node->name)])) { $this->emitError(new Error( sprintf('Cannot use \'%s\' as class name as it is reserved', $node->name), $this->getAttributesAt($namePos) )); } foreach ($node->extends as $interface) { if (isset(self::$specialNames[strtolower($interface)])) { $this->emitError(new Error( sprintf('Cannot use \'%s\' as interface name as it is reserved', $interface), $interface->getAttributes() )); } } } protected function checkClassMethod(ClassMethod $node, $modifierPos) { if ($node->flags & Class_::MODIFIER_STATIC) { switch (strtolower($node->name)) { case '__construct': $this->emitError(new Error( sprintf('Constructor %s() cannot be static', $node->name), $this->getAttributesAt($modifierPos))); break; case '__destruct': $this->emitError(new Error( sprintf('Destructor %s() cannot be static', $node->name), $this->getAttributesAt($modifierPos))); break; case '__clone': $this->emitError(new Error( sprintf('Clone method %s() cannot be static', $node->name), $this->getAttributesAt($modifierPos))); break; } } } protected function checkClassConst(ClassConst $node, $modifierPos) { if ($node->flags & Class_::MODIFIER_STATIC) { $this->emitError(new Error( "Cannot use 'static' as constant modifier", $this->getAttributesAt($modifierPos))); } if ($node->flags & Class_::MODIFIER_ABSTRACT) { $this->emitError(new Error( "Cannot use 'abstract' as constant modifier", $this->getAttributesAt($modifierPos))); } if ($node->flags & Class_::MODIFIER_FINAL) { $this->emitError(new Error( "Cannot use 'final' as constant modifier", $this->getAttributesAt($modifierPos))); } } protected function checkProperty(Property $node, $modifierPos) { if ($node->flags & Class_::MODIFIER_ABSTRACT) { $this->emitError(new Error('Properties cannot be declared abstract', $this->getAttributesAt($modifierPos))); } if ($node->flags & Class_::MODIFIER_FINAL) { $this->emitError(new Error('Properties cannot be declared final', $this->getAttributesAt($modifierPos))); } } protected function checkUseUse(UseUse $node, $namePos) { if ('self' == strtolower($node->alias) || 'parent' == strtolower($node->alias)) { $this->emitError(new Error( sprintf( 'Cannot use %s as %s because \'%2$s\' is a special class name', $node->name, $node->alias ), $this->getAttributesAt($namePos) )); } } } PHP-Parser-3.1.4/lib/PhpParser/ParserFactory.php000066400000000000000000000030551323244626500213610ustar00rootroot00000000000000type ? $this->pType($node->type) . ' ' : '') . ($node->byRef ? '&' : '') . ($node->variadic ? '...' : '') . '$' . $node->name . ($node->default ? ' = ' . $this->p($node->default) : ''); } protected function pArg(Node\Arg $node) { return ($node->byRef ? '&' : '') . ($node->unpack ? '...' : '') . $this->p($node->value); } protected function pConst(Node\Const_ $node) { return $node->name . ' = ' . $this->p($node->value); } protected function pNullableType(Node\NullableType $node) { return '?' . $this->pType($node->type); } // Names protected function pName(Name $node) { return implode('\\', $node->parts); } protected function pName_FullyQualified(Name\FullyQualified $node) { return '\\' . implode('\\', $node->parts); } protected function pName_Relative(Name\Relative $node) { return 'namespace\\' . implode('\\', $node->parts); } // Magic Constants protected function pScalar_MagicConst_Class(MagicConst\Class_ $node) { return '__CLASS__'; } protected function pScalar_MagicConst_Dir(MagicConst\Dir $node) { return '__DIR__'; } protected function pScalar_MagicConst_File(MagicConst\File $node) { return '__FILE__'; } protected function pScalar_MagicConst_Function(MagicConst\Function_ $node) { return '__FUNCTION__'; } protected function pScalar_MagicConst_Line(MagicConst\Line $node) { return '__LINE__'; } protected function pScalar_MagicConst_Method(MagicConst\Method $node) { return '__METHOD__'; } protected function pScalar_MagicConst_Namespace(MagicConst\Namespace_ $node) { return '__NAMESPACE__'; } protected function pScalar_MagicConst_Trait(MagicConst\Trait_ $node) { return '__TRAIT__'; } // Scalars protected function pScalar_String(Scalar\String_ $node) { $kind = $node->getAttribute('kind', Scalar\String_::KIND_SINGLE_QUOTED); switch ($kind) { case Scalar\String_::KIND_NOWDOC: $label = $node->getAttribute('docLabel'); if ($label && !$this->containsEndLabel($node->value, $label)) { if ($node->value === '') { return $this->pNoIndent("<<<'$label'\n$label") . $this->docStringEndToken; } return $this->pNoIndent("<<<'$label'\n$node->value\n$label") . $this->docStringEndToken; } /* break missing intentionally */ case Scalar\String_::KIND_SINGLE_QUOTED: return '\'' . $this->pNoIndent(addcslashes($node->value, '\'\\')) . '\''; case Scalar\String_::KIND_HEREDOC: $label = $node->getAttribute('docLabel'); if ($label && !$this->containsEndLabel($node->value, $label)) { if ($node->value === '') { return $this->pNoIndent("<<<$label\n$label") . $this->docStringEndToken; } $escaped = $this->escapeString($node->value, null); return $this->pNoIndent("<<<$label\n" . $escaped ."\n$label") . $this->docStringEndToken; } /* break missing intentionally */ case Scalar\String_::KIND_DOUBLE_QUOTED: return '"' . $this->escapeString($node->value, '"') . '"'; } throw new \Exception('Invalid string kind'); } protected function pScalar_Encapsed(Scalar\Encapsed $node) { if ($node->getAttribute('kind') === Scalar\String_::KIND_HEREDOC) { $label = $node->getAttribute('docLabel'); if ($label && !$this->encapsedContainsEndLabel($node->parts, $label)) { if (count($node->parts) === 1 && $node->parts[0] instanceof Scalar\EncapsedStringPart && $node->parts[0]->value === '' ) { return $this->pNoIndent("<<<$label\n$label") . $this->docStringEndToken; } return $this->pNoIndent( "<<<$label\n" . $this->pEncapsList($node->parts, null) . "\n$label" ) . $this->docStringEndToken; } } return '"' . $this->pEncapsList($node->parts, '"') . '"'; } protected function pScalar_LNumber(Scalar\LNumber $node) { if ($node->value === -\PHP_INT_MAX-1) { // PHP_INT_MIN cannot be represented as a literal, // because the sign is not part of the literal return '(-' . \PHP_INT_MAX . '-1)'; } $kind = $node->getAttribute('kind', Scalar\LNumber::KIND_DEC); if (Scalar\LNumber::KIND_DEC === $kind) { return (string) $node->value; } $sign = $node->value < 0 ? '-' : ''; $str = (string) $node->value; switch ($kind) { case Scalar\LNumber::KIND_BIN: return $sign . '0b' . base_convert($str, 10, 2); case Scalar\LNumber::KIND_OCT: return $sign . '0' . base_convert($str, 10, 8); case Scalar\LNumber::KIND_HEX: return $sign . '0x' . base_convert($str, 10, 16); } throw new \Exception('Invalid number kind'); } protected function pScalar_DNumber(Scalar\DNumber $node) { if (!is_finite($node->value)) { if ($node->value === \INF) { return '\INF'; } elseif ($node->value === -\INF) { return '-\INF'; } else { return '\NAN'; } } // Try to find a short full-precision representation $stringValue = sprintf('%.16G', $node->value); if ($node->value !== (double) $stringValue) { $stringValue = sprintf('%.17G', $node->value); } // %G is locale dependent and there exists no locale-independent alternative. We don't want // mess with switching locales here, so let's assume that a comma is the only non-standard // decimal separator we may encounter... $stringValue = str_replace(',', '.', $stringValue); // ensure that number is really printed as float return preg_match('/^-?[0-9]+$/', $stringValue) ? $stringValue . '.0' : $stringValue; } // Assignments protected function pExpr_Assign(Expr\Assign $node) { return $this->pInfixOp('Expr_Assign', $node->var, ' = ', $node->expr); } protected function pExpr_AssignRef(Expr\AssignRef $node) { return $this->pInfixOp('Expr_AssignRef', $node->var, ' =& ', $node->expr); } protected function pExpr_AssignOp_Plus(AssignOp\Plus $node) { return $this->pInfixOp('Expr_AssignOp_Plus', $node->var, ' += ', $node->expr); } protected function pExpr_AssignOp_Minus(AssignOp\Minus $node) { return $this->pInfixOp('Expr_AssignOp_Minus', $node->var, ' -= ', $node->expr); } protected function pExpr_AssignOp_Mul(AssignOp\Mul $node) { return $this->pInfixOp('Expr_AssignOp_Mul', $node->var, ' *= ', $node->expr); } protected function pExpr_AssignOp_Div(AssignOp\Div $node) { return $this->pInfixOp('Expr_AssignOp_Div', $node->var, ' /= ', $node->expr); } protected function pExpr_AssignOp_Concat(AssignOp\Concat $node) { return $this->pInfixOp('Expr_AssignOp_Concat', $node->var, ' .= ', $node->expr); } protected function pExpr_AssignOp_Mod(AssignOp\Mod $node) { return $this->pInfixOp('Expr_AssignOp_Mod', $node->var, ' %= ', $node->expr); } protected function pExpr_AssignOp_BitwiseAnd(AssignOp\BitwiseAnd $node) { return $this->pInfixOp('Expr_AssignOp_BitwiseAnd', $node->var, ' &= ', $node->expr); } protected function pExpr_AssignOp_BitwiseOr(AssignOp\BitwiseOr $node) { return $this->pInfixOp('Expr_AssignOp_BitwiseOr', $node->var, ' |= ', $node->expr); } protected function pExpr_AssignOp_BitwiseXor(AssignOp\BitwiseXor $node) { return $this->pInfixOp('Expr_AssignOp_BitwiseXor', $node->var, ' ^= ', $node->expr); } protected function pExpr_AssignOp_ShiftLeft(AssignOp\ShiftLeft $node) { return $this->pInfixOp('Expr_AssignOp_ShiftLeft', $node->var, ' <<= ', $node->expr); } protected function pExpr_AssignOp_ShiftRight(AssignOp\ShiftRight $node) { return $this->pInfixOp('Expr_AssignOp_ShiftRight', $node->var, ' >>= ', $node->expr); } protected function pExpr_AssignOp_Pow(AssignOp\Pow $node) { return $this->pInfixOp('Expr_AssignOp_Pow', $node->var, ' **= ', $node->expr); } // Binary expressions protected function pExpr_BinaryOp_Plus(BinaryOp\Plus $node) { return $this->pInfixOp('Expr_BinaryOp_Plus', $node->left, ' + ', $node->right); } protected function pExpr_BinaryOp_Minus(BinaryOp\Minus $node) { return $this->pInfixOp('Expr_BinaryOp_Minus', $node->left, ' - ', $node->right); } protected function pExpr_BinaryOp_Mul(BinaryOp\Mul $node) { return $this->pInfixOp('Expr_BinaryOp_Mul', $node->left, ' * ', $node->right); } protected function pExpr_BinaryOp_Div(BinaryOp\Div $node) { return $this->pInfixOp('Expr_BinaryOp_Div', $node->left, ' / ', $node->right); } protected function pExpr_BinaryOp_Concat(BinaryOp\Concat $node) { return $this->pInfixOp('Expr_BinaryOp_Concat', $node->left, ' . ', $node->right); } protected function pExpr_BinaryOp_Mod(BinaryOp\Mod $node) { return $this->pInfixOp('Expr_BinaryOp_Mod', $node->left, ' % ', $node->right); } protected function pExpr_BinaryOp_BooleanAnd(BinaryOp\BooleanAnd $node) { return $this->pInfixOp('Expr_BinaryOp_BooleanAnd', $node->left, ' && ', $node->right); } protected function pExpr_BinaryOp_BooleanOr(BinaryOp\BooleanOr $node) { return $this->pInfixOp('Expr_BinaryOp_BooleanOr', $node->left, ' || ', $node->right); } protected function pExpr_BinaryOp_BitwiseAnd(BinaryOp\BitwiseAnd $node) { return $this->pInfixOp('Expr_BinaryOp_BitwiseAnd', $node->left, ' & ', $node->right); } protected function pExpr_BinaryOp_BitwiseOr(BinaryOp\BitwiseOr $node) { return $this->pInfixOp('Expr_BinaryOp_BitwiseOr', $node->left, ' | ', $node->right); } protected function pExpr_BinaryOp_BitwiseXor(BinaryOp\BitwiseXor $node) { return $this->pInfixOp('Expr_BinaryOp_BitwiseXor', $node->left, ' ^ ', $node->right); } protected function pExpr_BinaryOp_ShiftLeft(BinaryOp\ShiftLeft $node) { return $this->pInfixOp('Expr_BinaryOp_ShiftLeft', $node->left, ' << ', $node->right); } protected function pExpr_BinaryOp_ShiftRight(BinaryOp\ShiftRight $node) { return $this->pInfixOp('Expr_BinaryOp_ShiftRight', $node->left, ' >> ', $node->right); } protected function pExpr_BinaryOp_Pow(BinaryOp\Pow $node) { return $this->pInfixOp('Expr_BinaryOp_Pow', $node->left, ' ** ', $node->right); } protected function pExpr_BinaryOp_LogicalAnd(BinaryOp\LogicalAnd $node) { return $this->pInfixOp('Expr_BinaryOp_LogicalAnd', $node->left, ' and ', $node->right); } protected function pExpr_BinaryOp_LogicalOr(BinaryOp\LogicalOr $node) { return $this->pInfixOp('Expr_BinaryOp_LogicalOr', $node->left, ' or ', $node->right); } protected function pExpr_BinaryOp_LogicalXor(BinaryOp\LogicalXor $node) { return $this->pInfixOp('Expr_BinaryOp_LogicalXor', $node->left, ' xor ', $node->right); } protected function pExpr_BinaryOp_Equal(BinaryOp\Equal $node) { return $this->pInfixOp('Expr_BinaryOp_Equal', $node->left, ' == ', $node->right); } protected function pExpr_BinaryOp_NotEqual(BinaryOp\NotEqual $node) { return $this->pInfixOp('Expr_BinaryOp_NotEqual', $node->left, ' != ', $node->right); } protected function pExpr_BinaryOp_Identical(BinaryOp\Identical $node) { return $this->pInfixOp('Expr_BinaryOp_Identical', $node->left, ' === ', $node->right); } protected function pExpr_BinaryOp_NotIdentical(BinaryOp\NotIdentical $node) { return $this->pInfixOp('Expr_BinaryOp_NotIdentical', $node->left, ' !== ', $node->right); } protected function pExpr_BinaryOp_Spaceship(BinaryOp\Spaceship $node) { return $this->pInfixOp('Expr_BinaryOp_Spaceship', $node->left, ' <=> ', $node->right); } protected function pExpr_BinaryOp_Greater(BinaryOp\Greater $node) { return $this->pInfixOp('Expr_BinaryOp_Greater', $node->left, ' > ', $node->right); } protected function pExpr_BinaryOp_GreaterOrEqual(BinaryOp\GreaterOrEqual $node) { return $this->pInfixOp('Expr_BinaryOp_GreaterOrEqual', $node->left, ' >= ', $node->right); } protected function pExpr_BinaryOp_Smaller(BinaryOp\Smaller $node) { return $this->pInfixOp('Expr_BinaryOp_Smaller', $node->left, ' < ', $node->right); } protected function pExpr_BinaryOp_SmallerOrEqual(BinaryOp\SmallerOrEqual $node) { return $this->pInfixOp('Expr_BinaryOp_SmallerOrEqual', $node->left, ' <= ', $node->right); } protected function pExpr_BinaryOp_Coalesce(BinaryOp\Coalesce $node) { return $this->pInfixOp('Expr_BinaryOp_Coalesce', $node->left, ' ?? ', $node->right); } protected function pExpr_Instanceof(Expr\Instanceof_ $node) { return $this->pInfixOp('Expr_Instanceof', $node->expr, ' instanceof ', $node->class); } // Unary expressions protected function pExpr_BooleanNot(Expr\BooleanNot $node) { return $this->pPrefixOp('Expr_BooleanNot', '!', $node->expr); } protected function pExpr_BitwiseNot(Expr\BitwiseNot $node) { return $this->pPrefixOp('Expr_BitwiseNot', '~', $node->expr); } protected function pExpr_UnaryMinus(Expr\UnaryMinus $node) { if ($node->expr instanceof Expr\UnaryMinus || $node->expr instanceof Expr\PreDec) { // Enforce -(-$expr) instead of --$expr return '-(' . $this->p($node->expr) . ')'; } return $this->pPrefixOp('Expr_UnaryMinus', '-', $node->expr); } protected function pExpr_UnaryPlus(Expr\UnaryPlus $node) { if ($node->expr instanceof Expr\UnaryPlus || $node->expr instanceof Expr\PreInc) { // Enforce +(+$expr) instead of ++$expr return '+(' . $this->p($node->expr) . ')'; } return $this->pPrefixOp('Expr_UnaryPlus', '+', $node->expr); } protected function pExpr_PreInc(Expr\PreInc $node) { return $this->pPrefixOp('Expr_PreInc', '++', $node->var); } protected function pExpr_PreDec(Expr\PreDec $node) { return $this->pPrefixOp('Expr_PreDec', '--', $node->var); } protected function pExpr_PostInc(Expr\PostInc $node) { return $this->pPostfixOp('Expr_PostInc', $node->var, '++'); } protected function pExpr_PostDec(Expr\PostDec $node) { return $this->pPostfixOp('Expr_PostDec', $node->var, '--'); } protected function pExpr_ErrorSuppress(Expr\ErrorSuppress $node) { return $this->pPrefixOp('Expr_ErrorSuppress', '@', $node->expr); } protected function pExpr_YieldFrom(Expr\YieldFrom $node) { return $this->pPrefixOp('Expr_YieldFrom', 'yield from ', $node->expr); } protected function pExpr_Print(Expr\Print_ $node) { return $this->pPrefixOp('Expr_Print', 'print ', $node->expr); } // Casts protected function pExpr_Cast_Int(Cast\Int_ $node) { return $this->pPrefixOp('Expr_Cast_Int', '(int) ', $node->expr); } protected function pExpr_Cast_Double(Cast\Double $node) { return $this->pPrefixOp('Expr_Cast_Double', '(double) ', $node->expr); } protected function pExpr_Cast_String(Cast\String_ $node) { return $this->pPrefixOp('Expr_Cast_String', '(string) ', $node->expr); } protected function pExpr_Cast_Array(Cast\Array_ $node) { return $this->pPrefixOp('Expr_Cast_Array', '(array) ', $node->expr); } protected function pExpr_Cast_Object(Cast\Object_ $node) { return $this->pPrefixOp('Expr_Cast_Object', '(object) ', $node->expr); } protected function pExpr_Cast_Bool(Cast\Bool_ $node) { return $this->pPrefixOp('Expr_Cast_Bool', '(bool) ', $node->expr); } protected function pExpr_Cast_Unset(Cast\Unset_ $node) { return $this->pPrefixOp('Expr_Cast_Unset', '(unset) ', $node->expr); } // Function calls and similar constructs protected function pExpr_FuncCall(Expr\FuncCall $node) { return $this->pCallLhs($node->name) . '(' . $this->pMaybeMultiline($node->args) . ')'; } protected function pExpr_MethodCall(Expr\MethodCall $node) { return $this->pDereferenceLhs($node->var) . '->' . $this->pObjectProperty($node->name) . '(' . $this->pMaybeMultiline($node->args) . ')'; } protected function pExpr_StaticCall(Expr\StaticCall $node) { return $this->pDereferenceLhs($node->class) . '::' . ($node->name instanceof Expr ? ($node->name instanceof Expr\Variable ? $this->p($node->name) : '{' . $this->p($node->name) . '}') : $node->name) . '(' . $this->pMaybeMultiline($node->args) . ')'; } protected function pExpr_Empty(Expr\Empty_ $node) { return 'empty(' . $this->p($node->expr) . ')'; } protected function pExpr_Isset(Expr\Isset_ $node) { return 'isset(' . $this->pCommaSeparated($node->vars) . ')'; } protected function pExpr_Eval(Expr\Eval_ $node) { return 'eval(' . $this->p($node->expr) . ')'; } protected function pExpr_Include(Expr\Include_ $node) { static $map = array( Expr\Include_::TYPE_INCLUDE => 'include', Expr\Include_::TYPE_INCLUDE_ONCE => 'include_once', Expr\Include_::TYPE_REQUIRE => 'require', Expr\Include_::TYPE_REQUIRE_ONCE => 'require_once', ); return $map[$node->type] . ' ' . $this->p($node->expr); } protected function pExpr_List(Expr\List_ $node) { return 'list(' . $this->pCommaSeparated($node->items) . ')'; } // Other protected function pExpr_Error(Expr\Error $node) { throw new \LogicException('Cannot pretty-print AST with Error nodes'); } protected function pExpr_Variable(Expr\Variable $node) { if ($node->name instanceof Expr) { return '${' . $this->p($node->name) . '}'; } else { return '$' . $node->name; } } protected function pExpr_Array(Expr\Array_ $node) { $syntax = $node->getAttribute('kind', $this->options['shortArraySyntax'] ? Expr\Array_::KIND_SHORT : Expr\Array_::KIND_LONG); if ($syntax === Expr\Array_::KIND_SHORT) { return '[' . $this->pMaybeMultiline($node->items, true) . ']'; } else { return 'array(' . $this->pMaybeMultiline($node->items, true) . ')'; } } protected function pExpr_ArrayItem(Expr\ArrayItem $node) { return (null !== $node->key ? $this->p($node->key) . ' => ' : '') . ($node->byRef ? '&' : '') . $this->p($node->value); } protected function pExpr_ArrayDimFetch(Expr\ArrayDimFetch $node) { return $this->pDereferenceLhs($node->var) . '[' . (null !== $node->dim ? $this->p($node->dim) : '') . ']'; } protected function pExpr_ConstFetch(Expr\ConstFetch $node) { return $this->p($node->name); } protected function pExpr_ClassConstFetch(Expr\ClassConstFetch $node) { return $this->p($node->class) . '::' . (is_string($node->name) ? $node->name : $this->p($node->name)); } protected function pExpr_PropertyFetch(Expr\PropertyFetch $node) { return $this->pDereferenceLhs($node->var) . '->' . $this->pObjectProperty($node->name); } protected function pExpr_StaticPropertyFetch(Expr\StaticPropertyFetch $node) { return $this->pDereferenceLhs($node->class) . '::$' . $this->pObjectProperty($node->name); } protected function pExpr_ShellExec(Expr\ShellExec $node) { return '`' . $this->pEncapsList($node->parts, '`') . '`'; } protected function pExpr_Closure(Expr\Closure $node) { return ($node->static ? 'static ' : '') . 'function ' . ($node->byRef ? '&' : '') . '(' . $this->pCommaSeparated($node->params) . ')' . (!empty($node->uses) ? ' use(' . $this->pCommaSeparated($node->uses) . ')': '') . (null !== $node->returnType ? ' : ' . $this->pType($node->returnType) : '') . ' {' . $this->pStmts($node->stmts) . "\n" . '}'; } protected function pExpr_ClosureUse(Expr\ClosureUse $node) { return ($node->byRef ? '&' : '') . '$' . $node->var; } protected function pExpr_New(Expr\New_ $node) { if ($node->class instanceof Stmt\Class_) { $args = $node->args ? '(' . $this->pMaybeMultiline($node->args) . ')' : ''; return 'new ' . $this->pClassCommon($node->class, $args); } return 'new ' . $this->p($node->class) . '(' . $this->pMaybeMultiline($node->args) . ')'; } protected function pExpr_Clone(Expr\Clone_ $node) { return 'clone ' . $this->p($node->expr); } protected function pExpr_Ternary(Expr\Ternary $node) { // a bit of cheating: we treat the ternary as a binary op where the ?...: part is the operator. // this is okay because the part between ? and : never needs parentheses. return $this->pInfixOp('Expr_Ternary', $node->cond, ' ?' . (null !== $node->if ? ' ' . $this->p($node->if) . ' ' : '') . ': ', $node->else ); } protected function pExpr_Exit(Expr\Exit_ $node) { $kind = $node->getAttribute('kind', Expr\Exit_::KIND_DIE); return ($kind === Expr\Exit_::KIND_EXIT ? 'exit' : 'die') . (null !== $node->expr ? '(' . $this->p($node->expr) . ')' : ''); } protected function pExpr_Yield(Expr\Yield_ $node) { if ($node->value === null) { return 'yield'; } else { // this is a bit ugly, but currently there is no way to detect whether the parentheses are necessary return '(yield ' . ($node->key !== null ? $this->p($node->key) . ' => ' : '') . $this->p($node->value) . ')'; } } // Declarations protected function pStmt_Namespace(Stmt\Namespace_ $node) { if ($this->canUseSemicolonNamespaces) { return 'namespace ' . $this->p($node->name) . ';' . "\n" . $this->pStmts($node->stmts, false); } else { return 'namespace' . (null !== $node->name ? ' ' . $this->p($node->name) : '') . ' {' . $this->pStmts($node->stmts) . "\n" . '}'; } } protected function pStmt_Use(Stmt\Use_ $node) { return 'use ' . $this->pUseType($node->type) . $this->pCommaSeparated($node->uses) . ';'; } protected function pStmt_GroupUse(Stmt\GroupUse $node) { return 'use ' . $this->pUseType($node->type) . $this->pName($node->prefix) . '\{' . $this->pCommaSeparated($node->uses) . '};'; } protected function pStmt_UseUse(Stmt\UseUse $node) { return $this->pUseType($node->type) . $this->p($node->name) . ($node->name->getLast() !== $node->alias ? ' as ' . $node->alias : ''); } protected function pUseType($type) { return $type === Stmt\Use_::TYPE_FUNCTION ? 'function ' : ($type === Stmt\Use_::TYPE_CONSTANT ? 'const ' : ''); } protected function pStmt_Interface(Stmt\Interface_ $node) { return 'interface ' . $node->name . (!empty($node->extends) ? ' extends ' . $this->pCommaSeparated($node->extends) : '') . "\n" . '{' . $this->pStmts($node->stmts) . "\n" . '}'; } protected function pStmt_Class(Stmt\Class_ $node) { return $this->pClassCommon($node, ' ' . $node->name); } protected function pStmt_Trait(Stmt\Trait_ $node) { return 'trait ' . $node->name . "\n" . '{' . $this->pStmts($node->stmts) . "\n" . '}'; } protected function pStmt_TraitUse(Stmt\TraitUse $node) { return 'use ' . $this->pCommaSeparated($node->traits) . (empty($node->adaptations) ? ';' : ' {' . $this->pStmts($node->adaptations) . "\n" . '}'); } protected function pStmt_TraitUseAdaptation_Precedence(Stmt\TraitUseAdaptation\Precedence $node) { return $this->p($node->trait) . '::' . $node->method . ' insteadof ' . $this->pCommaSeparated($node->insteadof) . ';'; } protected function pStmt_TraitUseAdaptation_Alias(Stmt\TraitUseAdaptation\Alias $node) { return (null !== $node->trait ? $this->p($node->trait) . '::' : '') . $node->method . ' as' . (null !== $node->newModifier ? ' ' . rtrim($this->pModifiers($node->newModifier), ' ') : '') . (null !== $node->newName ? ' ' . $node->newName : '') . ';'; } protected function pStmt_Property(Stmt\Property $node) { return (0 === $node->flags ? 'var ' : $this->pModifiers($node->flags)) . $this->pCommaSeparated($node->props) . ';'; } protected function pStmt_PropertyProperty(Stmt\PropertyProperty $node) { return '$' . $node->name . (null !== $node->default ? ' = ' . $this->p($node->default) : ''); } protected function pStmt_ClassMethod(Stmt\ClassMethod $node) { return $this->pModifiers($node->flags) . 'function ' . ($node->byRef ? '&' : '') . $node->name . '(' . $this->pCommaSeparated($node->params) . ')' . (null !== $node->returnType ? ' : ' . $this->pType($node->returnType) : '') . (null !== $node->stmts ? "\n" . '{' . $this->pStmts($node->stmts) . "\n" . '}' : ';'); } protected function pStmt_ClassConst(Stmt\ClassConst $node) { return $this->pModifiers($node->flags) . 'const ' . $this->pCommaSeparated($node->consts) . ';'; } protected function pStmt_Function(Stmt\Function_ $node) { return 'function ' . ($node->byRef ? '&' : '') . $node->name . '(' . $this->pCommaSeparated($node->params) . ')' . (null !== $node->returnType ? ' : ' . $this->pType($node->returnType) : '') . "\n" . '{' . $this->pStmts($node->stmts) . "\n" . '}'; } protected function pStmt_Const(Stmt\Const_ $node) { return 'const ' . $this->pCommaSeparated($node->consts) . ';'; } protected function pStmt_Declare(Stmt\Declare_ $node) { return 'declare (' . $this->pCommaSeparated($node->declares) . ')' . (null !== $node->stmts ? ' {' . $this->pStmts($node->stmts) . "\n" . '}' : ';'); } protected function pStmt_DeclareDeclare(Stmt\DeclareDeclare $node) { return $node->key . '=' . $this->p($node->value); } // Control flow protected function pStmt_If(Stmt\If_ $node) { return 'if (' . $this->p($node->cond) . ') {' . $this->pStmts($node->stmts) . "\n" . '}' . $this->pImplode($node->elseifs) . (null !== $node->else ? $this->p($node->else) : ''); } protected function pStmt_ElseIf(Stmt\ElseIf_ $node) { return ' elseif (' . $this->p($node->cond) . ') {' . $this->pStmts($node->stmts) . "\n" . '}'; } protected function pStmt_Else(Stmt\Else_ $node) { return ' else {' . $this->pStmts($node->stmts) . "\n" . '}'; } protected function pStmt_For(Stmt\For_ $node) { return 'for (' . $this->pCommaSeparated($node->init) . ';' . (!empty($node->cond) ? ' ' : '') . $this->pCommaSeparated($node->cond) . ';' . (!empty($node->loop) ? ' ' : '') . $this->pCommaSeparated($node->loop) . ') {' . $this->pStmts($node->stmts) . "\n" . '}'; } protected function pStmt_Foreach(Stmt\Foreach_ $node) { return 'foreach (' . $this->p($node->expr) . ' as ' . (null !== $node->keyVar ? $this->p($node->keyVar) . ' => ' : '') . ($node->byRef ? '&' : '') . $this->p($node->valueVar) . ') {' . $this->pStmts($node->stmts) . "\n" . '}'; } protected function pStmt_While(Stmt\While_ $node) { return 'while (' . $this->p($node->cond) . ') {' . $this->pStmts($node->stmts) . "\n" . '}'; } protected function pStmt_Do(Stmt\Do_ $node) { return 'do {' . $this->pStmts($node->stmts) . "\n" . '} while (' . $this->p($node->cond) . ');'; } protected function pStmt_Switch(Stmt\Switch_ $node) { return 'switch (' . $this->p($node->cond) . ') {' . $this->pStmts($node->cases) . "\n" . '}'; } protected function pStmt_Case(Stmt\Case_ $node) { return (null !== $node->cond ? 'case ' . $this->p($node->cond) : 'default') . ':' . $this->pStmts($node->stmts); } protected function pStmt_TryCatch(Stmt\TryCatch $node) { return 'try {' . $this->pStmts($node->stmts) . "\n" . '}' . $this->pImplode($node->catches) . ($node->finally !== null ? $this->p($node->finally) : ''); } protected function pStmt_Catch(Stmt\Catch_ $node) { return ' catch (' . $this->pImplode($node->types, '|') . ' $' . $node->var . ') {' . $this->pStmts($node->stmts) . "\n" . '}'; } protected function pStmt_Finally(Stmt\Finally_ $node) { return ' finally {' . $this->pStmts($node->stmts) . "\n" . '}'; } protected function pStmt_Break(Stmt\Break_ $node) { return 'break' . ($node->num !== null ? ' ' . $this->p($node->num) : '') . ';'; } protected function pStmt_Continue(Stmt\Continue_ $node) { return 'continue' . ($node->num !== null ? ' ' . $this->p($node->num) : '') . ';'; } protected function pStmt_Return(Stmt\Return_ $node) { return 'return' . (null !== $node->expr ? ' ' . $this->p($node->expr) : '') . ';'; } protected function pStmt_Throw(Stmt\Throw_ $node) { return 'throw ' . $this->p($node->expr) . ';'; } protected function pStmt_Label(Stmt\Label $node) { return $node->name . ':'; } protected function pStmt_Goto(Stmt\Goto_ $node) { return 'goto ' . $node->name . ';'; } // Other protected function pStmt_Echo(Stmt\Echo_ $node) { return 'echo ' . $this->pCommaSeparated($node->exprs) . ';'; } protected function pStmt_Static(Stmt\Static_ $node) { return 'static ' . $this->pCommaSeparated($node->vars) . ';'; } protected function pStmt_Global(Stmt\Global_ $node) { return 'global ' . $this->pCommaSeparated($node->vars) . ';'; } protected function pStmt_StaticVar(Stmt\StaticVar $node) { return '$' . $node->name . (null !== $node->default ? ' = ' . $this->p($node->default) : ''); } protected function pStmt_Unset(Stmt\Unset_ $node) { return 'unset(' . $this->pCommaSeparated($node->vars) . ');'; } protected function pStmt_InlineHTML(Stmt\InlineHTML $node) { $newline = $node->getAttribute('hasLeadingNewline', true) ? "\n" : ''; return '?>' . $this->pNoIndent($newline . $node->value) . 'remaining; } protected function pStmt_Nop(Stmt\Nop $node) { return ''; } // Helpers protected function pType($node) { return is_string($node) ? $node : $this->p($node); } protected function pClassCommon(Stmt\Class_ $node, $afterClassToken) { return $this->pModifiers($node->flags) . 'class' . $afterClassToken . (null !== $node->extends ? ' extends ' . $this->p($node->extends) : '') . (!empty($node->implements) ? ' implements ' . $this->pCommaSeparated($node->implements) : '') . "\n" . '{' . $this->pStmts($node->stmts) . "\n" . '}'; } protected function pObjectProperty($node) { if ($node instanceof Expr) { return '{' . $this->p($node) . '}'; } else { return $node; } } protected function pModifiers($modifiers) { return ($modifiers & Stmt\Class_::MODIFIER_PUBLIC ? 'public ' : '') . ($modifiers & Stmt\Class_::MODIFIER_PROTECTED ? 'protected ' : '') . ($modifiers & Stmt\Class_::MODIFIER_PRIVATE ? 'private ' : '') . ($modifiers & Stmt\Class_::MODIFIER_STATIC ? 'static ' : '') . ($modifiers & Stmt\Class_::MODIFIER_ABSTRACT ? 'abstract ' : '') . ($modifiers & Stmt\Class_::MODIFIER_FINAL ? 'final ' : ''); } protected function pEncapsList(array $encapsList, $quote) { $return = ''; foreach ($encapsList as $element) { if ($element instanceof Scalar\EncapsedStringPart) { $return .= $this->escapeString($element->value, $quote); } else { $return .= '{' . $this->p($element) . '}'; } } return $return; } protected function escapeString($string, $quote) { if (null === $quote) { // For doc strings, don't escape newlines $escaped = addcslashes($string, "\t\f\v$\\"); } else { $escaped = addcslashes($string, "\n\r\t\f\v$" . $quote . "\\"); } // Escape other control characters return preg_replace_callback('/([\0-\10\16-\37])(?=([0-7]?))/', function ($matches) { $oct = decoct(ord($matches[1])); if ($matches[2] !== '') { // If there is a trailing digit, use the full three character form return '\\' . str_pad($oct, 3, '0', STR_PAD_LEFT); } return '\\' . $oct; }, $escaped); } protected function containsEndLabel($string, $label, $atStart = true, $atEnd = true) { $start = $atStart ? '(?:^|[\r\n])' : '[\r\n]'; $end = $atEnd ? '(?:$|[;\r\n])' : '[;\r\n]'; return false !== strpos($string, $label) && preg_match('/' . $start . $label . $end . '/', $string); } protected function encapsedContainsEndLabel(array $parts, $label) { foreach ($parts as $i => $part) { $atStart = $i === 0; $atEnd = $i === count($parts) - 1; if ($part instanceof Scalar\EncapsedStringPart && $this->containsEndLabel($part->value, $label, $atStart, $atEnd) ) { return true; } } return false; } protected function pDereferenceLhs(Node $node) { if ($node instanceof Expr\Variable || $node instanceof Name || $node instanceof Expr\ArrayDimFetch || $node instanceof Expr\PropertyFetch || $node instanceof Expr\StaticPropertyFetch || $node instanceof Expr\FuncCall || $node instanceof Expr\MethodCall || $node instanceof Expr\StaticCall || $node instanceof Expr\Array_ || $node instanceof Scalar\String_ || $node instanceof Expr\ConstFetch || $node instanceof Expr\ClassConstFetch ) { return $this->p($node); } else { return '(' . $this->p($node) . ')'; } } protected function pCallLhs(Node $node) { if ($node instanceof Name || $node instanceof Expr\Variable || $node instanceof Expr\ArrayDimFetch || $node instanceof Expr\FuncCall || $node instanceof Expr\MethodCall || $node instanceof Expr\StaticCall || $node instanceof Expr\Array_ ) { return $this->p($node); } else { return '(' . $this->p($node) . ')'; } } private function hasNodeWithComments(array $nodes) { foreach ($nodes as $node) { if ($node && $node->getAttribute('comments')) { return true; } } return false; } private function pMaybeMultiline(array $nodes, $trailingComma = false) { if (!$this->hasNodeWithComments($nodes)) { return $this->pCommaSeparated($nodes); } else { return $this->pCommaSeparatedMultiline($nodes, $trailingComma) . "\n"; } } } PHP-Parser-3.1.4/lib/PhpParser/PrettyPrinterAbstract.php000066400000000000000000000313231323244626500231130ustar00rootroot00000000000000 array( 0, 1), 'Expr_BitwiseNot' => array( 10, 1), 'Expr_PreInc' => array( 10, 1), 'Expr_PreDec' => array( 10, 1), 'Expr_PostInc' => array( 10, -1), 'Expr_PostDec' => array( 10, -1), 'Expr_UnaryPlus' => array( 10, 1), 'Expr_UnaryMinus' => array( 10, 1), 'Expr_Cast_Int' => array( 10, 1), 'Expr_Cast_Double' => array( 10, 1), 'Expr_Cast_String' => array( 10, 1), 'Expr_Cast_Array' => array( 10, 1), 'Expr_Cast_Object' => array( 10, 1), 'Expr_Cast_Bool' => array( 10, 1), 'Expr_Cast_Unset' => array( 10, 1), 'Expr_ErrorSuppress' => array( 10, 1), 'Expr_Instanceof' => array( 20, 0), 'Expr_BooleanNot' => array( 30, 1), 'Expr_BinaryOp_Mul' => array( 40, -1), 'Expr_BinaryOp_Div' => array( 40, -1), 'Expr_BinaryOp_Mod' => array( 40, -1), 'Expr_BinaryOp_Plus' => array( 50, -1), 'Expr_BinaryOp_Minus' => array( 50, -1), 'Expr_BinaryOp_Concat' => array( 50, -1), 'Expr_BinaryOp_ShiftLeft' => array( 60, -1), 'Expr_BinaryOp_ShiftRight' => array( 60, -1), 'Expr_BinaryOp_Smaller' => array( 70, 0), 'Expr_BinaryOp_SmallerOrEqual' => array( 70, 0), 'Expr_BinaryOp_Greater' => array( 70, 0), 'Expr_BinaryOp_GreaterOrEqual' => array( 70, 0), 'Expr_BinaryOp_Equal' => array( 80, 0), 'Expr_BinaryOp_NotEqual' => array( 80, 0), 'Expr_BinaryOp_Identical' => array( 80, 0), 'Expr_BinaryOp_NotIdentical' => array( 80, 0), 'Expr_BinaryOp_Spaceship' => array( 80, 0), 'Expr_BinaryOp_BitwiseAnd' => array( 90, -1), 'Expr_BinaryOp_BitwiseXor' => array(100, -1), 'Expr_BinaryOp_BitwiseOr' => array(110, -1), 'Expr_BinaryOp_BooleanAnd' => array(120, -1), 'Expr_BinaryOp_BooleanOr' => array(130, -1), 'Expr_BinaryOp_Coalesce' => array(140, 1), 'Expr_Ternary' => array(150, -1), // parser uses %left for assignments, but they really behave as %right 'Expr_Assign' => array(160, 1), 'Expr_AssignRef' => array(160, 1), 'Expr_AssignOp_Plus' => array(160, 1), 'Expr_AssignOp_Minus' => array(160, 1), 'Expr_AssignOp_Mul' => array(160, 1), 'Expr_AssignOp_Div' => array(160, 1), 'Expr_AssignOp_Concat' => array(160, 1), 'Expr_AssignOp_Mod' => array(160, 1), 'Expr_AssignOp_BitwiseAnd' => array(160, 1), 'Expr_AssignOp_BitwiseOr' => array(160, 1), 'Expr_AssignOp_BitwiseXor' => array(160, 1), 'Expr_AssignOp_ShiftLeft' => array(160, 1), 'Expr_AssignOp_ShiftRight' => array(160, 1), 'Expr_AssignOp_Pow' => array(160, 1), 'Expr_YieldFrom' => array(165, 1), 'Expr_Print' => array(168, 1), 'Expr_BinaryOp_LogicalAnd' => array(170, -1), 'Expr_BinaryOp_LogicalXor' => array(180, -1), 'Expr_BinaryOp_LogicalOr' => array(190, -1), 'Expr_Include' => array(200, -1), ); protected $noIndentToken; protected $docStringEndToken; protected $canUseSemicolonNamespaces; protected $options; /** * Creates a pretty printer instance using the given options. * * Supported options: * * bool $shortArraySyntax = false: Whether to use [] instead of array() as the default array * syntax, if the node does not specify a format. * * @param array $options Dictionary of formatting options */ public function __construct(array $options = []) { $this->noIndentToken = '_NO_INDENT_' . mt_rand(); $this->docStringEndToken = '_DOC_STRING_END_' . mt_rand(); $defaultOptions = ['shortArraySyntax' => false]; $this->options = $options + $defaultOptions; } /** * Pretty prints an array of statements. * * @param Node[] $stmts Array of statements * * @return string Pretty printed statements */ public function prettyPrint(array $stmts) { $this->preprocessNodes($stmts); return ltrim($this->handleMagicTokens($this->pStmts($stmts, false))); } /** * Pretty prints an expression. * * @param Expr $node Expression node * * @return string Pretty printed node */ public function prettyPrintExpr(Expr $node) { return $this->handleMagicTokens($this->p($node)); } /** * Pretty prints a file of statements (includes the opening prettyPrint($stmts); if ($stmts[0] instanceof Stmt\InlineHTML) { $p = preg_replace('/^<\?php\s+\?>\n?/', '', $p); } if ($stmts[count($stmts) - 1] instanceof Stmt\InlineHTML) { $p = preg_replace('/<\?php$/', '', rtrim($p)); } return $p; } /** * Preprocesses the top-level nodes to initialize pretty printer state. * * @param Node[] $nodes Array of nodes */ protected function preprocessNodes(array $nodes) { /* We can use semicolon-namespaces unless there is a global namespace declaration */ $this->canUseSemicolonNamespaces = true; foreach ($nodes as $node) { if ($node instanceof Stmt\Namespace_ && null === $node->name) { $this->canUseSemicolonNamespaces = false; } } } protected function handleMagicTokens($str) { // Drop no-indent tokens $str = str_replace($this->noIndentToken, '', $str); // Replace doc-string-end tokens with nothing or a newline $str = str_replace($this->docStringEndToken . ";\n", ";\n", $str); $str = str_replace($this->docStringEndToken, "\n", $str); return $str; } /** * Pretty prints an array of nodes (statements) and indents them optionally. * * @param Node[] $nodes Array of nodes * @param bool $indent Whether to indent the printed nodes * * @return string Pretty printed statements */ protected function pStmts(array $nodes, $indent = true) { $result = ''; foreach ($nodes as $node) { $comments = $node->getAttribute('comments', array()); if ($comments) { $result .= "\n" . $this->pComments($comments); if ($node instanceof Stmt\Nop) { continue; } } $result .= "\n" . $this->p($node) . ($node instanceof Expr ? ';' : ''); } if ($indent) { return preg_replace('~\n(?!$|' . $this->noIndentToken . ')~', "\n ", $result); } else { return $result; } } /** * Pretty prints a node. * * @param Node $node Node to be pretty printed * * @return string Pretty printed node */ protected function p(Node $node) { return $this->{'p' . $node->getType()}($node); } protected function pInfixOp($type, Node $leftNode, $operatorString, Node $rightNode) { list($precedence, $associativity) = $this->precedenceMap[$type]; return $this->pPrec($leftNode, $precedence, $associativity, -1) . $operatorString . $this->pPrec($rightNode, $precedence, $associativity, 1); } protected function pPrefixOp($type, $operatorString, Node $node) { list($precedence, $associativity) = $this->precedenceMap[$type]; return $operatorString . $this->pPrec($node, $precedence, $associativity, 1); } protected function pPostfixOp($type, Node $node, $operatorString) { list($precedence, $associativity) = $this->precedenceMap[$type]; return $this->pPrec($node, $precedence, $associativity, -1) . $operatorString; } /** * Prints an expression node with the least amount of parentheses necessary to preserve the meaning. * * @param Node $node Node to pretty print * @param int $parentPrecedence Precedence of the parent operator * @param int $parentAssociativity Associativity of parent operator * (-1 is left, 0 is nonassoc, 1 is right) * @param int $childPosition Position of the node relative to the operator * (-1 is left, 1 is right) * * @return string The pretty printed node */ protected function pPrec(Node $node, $parentPrecedence, $parentAssociativity, $childPosition) { $type = $node->getType(); if (isset($this->precedenceMap[$type])) { $childPrecedence = $this->precedenceMap[$type][0]; if ($childPrecedence > $parentPrecedence || ($parentPrecedence == $childPrecedence && $parentAssociativity != $childPosition) ) { return '(' . $this->p($node) . ')'; } } return $this->p($node); } /** * Pretty prints an array of nodes and implodes the printed values. * * @param Node[] $nodes Array of Nodes to be printed * @param string $glue Character to implode with * * @return string Imploded pretty printed nodes */ protected function pImplode(array $nodes, $glue = '') { $pNodes = array(); foreach ($nodes as $node) { if (null === $node) { $pNodes[] = ''; } else { $pNodes[] = $this->p($node); } } return implode($glue, $pNodes); } /** * Pretty prints an array of nodes and implodes the printed values with commas. * * @param Node[] $nodes Array of Nodes to be printed * * @return string Comma separated pretty printed nodes */ protected function pCommaSeparated(array $nodes) { return $this->pImplode($nodes, ', '); } /** * Pretty prints a comma-separated list of nodes in multiline style, including comments. * * The result includes a leading newline and one level of indentation (same as pStmts). * * @param Node[] $nodes Array of Nodes to be printed * @param bool $trailingComma Whether to use a trailing comma * * @return string Comma separated pretty printed nodes in multiline style */ protected function pCommaSeparatedMultiline(array $nodes, $trailingComma) { $result = ''; $lastIdx = count($nodes) - 1; foreach ($nodes as $idx => $node) { if ($node !== null) { $comments = $node->getAttribute('comments', array()); if ($comments) { $result .= "\n" . $this->pComments($comments); } $result .= "\n" . $this->p($node); } else { $result .= "\n"; } if ($trailingComma || $idx !== $lastIdx) { $result .= ','; } } return preg_replace('~\n(?!$|' . $this->noIndentToken . ')~', "\n ", $result); } /** * Signals the pretty printer that a string shall not be indented. * * @param string $string Not to be indented string * * @return string String marked with $this->noIndentToken's. */ protected function pNoIndent($string) { return str_replace("\n", "\n" . $this->noIndentToken, $string); } /** * Prints reformatted text of the passed comments. * * @param Comment[] $comments List of comments * * @return string Reformatted text of comments */ protected function pComments(array $comments) { $formattedComments = []; foreach ($comments as $comment) { $formattedComments[] = $comment->getReformattedText(); } return implode("\n", $formattedComments); } } PHP-Parser-3.1.4/lib/PhpParser/Serializer.php000066400000000000000000000004331323244626500207030ustar00rootroot00000000000000writer = new XMLWriter; $this->writer->openMemory(); $this->writer->setIndent(true); } public function serialize(array $nodes) { $this->writer->flush(); $this->writer->startDocument('1.0', 'UTF-8'); $this->writer->startElement('AST'); $this->writer->writeAttribute('xmlns:node', 'http://nikic.github.com/PHPParser/XML/node'); $this->writer->writeAttribute('xmlns:subNode', 'http://nikic.github.com/PHPParser/XML/subNode'); $this->writer->writeAttribute('xmlns:attribute', 'http://nikic.github.com/PHPParser/XML/attribute'); $this->writer->writeAttribute('xmlns:scalar', 'http://nikic.github.com/PHPParser/XML/scalar'); $this->_serialize($nodes); $this->writer->endElement(); return $this->writer->outputMemory(); } protected function _serialize($node) { if ($node instanceof Node) { $this->writer->startElement('node:' . $node->getType()); foreach ($node->getAttributes() as $name => $value) { $this->writer->startElement('attribute:' . $name); $this->_serialize($value); $this->writer->endElement(); } foreach ($node as $name => $subNode) { $this->writer->startElement('subNode:' . $name); $this->_serialize($subNode); $this->writer->endElement(); } $this->writer->endElement(); } elseif ($node instanceof Comment) { $this->writer->startElement('comment'); $this->writer->writeAttribute('isDocComment', $node instanceof Comment\Doc ? 'true' : 'false'); $this->writer->writeAttribute('line', (string) $node->getLine()); $this->writer->text($node->getText()); $this->writer->endElement(); } elseif (is_array($node)) { $this->writer->startElement('scalar:array'); foreach ($node as $subNode) { $this->_serialize($subNode); } $this->writer->endElement(); } elseif (is_string($node)) { $this->writer->writeElement('scalar:string', $node); } elseif (is_int($node)) { $this->writer->writeElement('scalar:int', (string) $node); } elseif (is_float($node)) { // TODO Higher precision conversion? $this->writer->writeElement('scalar:float', (string) $node); } elseif (true === $node) { $this->writer->writeElement('scalar:true'); } elseif (false === $node) { $this->writer->writeElement('scalar:false'); } elseif (null === $node) { $this->writer->writeElement('scalar:null'); } else { throw new \InvalidArgumentException('Unexpected node type'); } } } PHP-Parser-3.1.4/lib/PhpParser/Unserializer.php000066400000000000000000000004431323244626500212470ustar00rootroot00000000000000reader = new XMLReader; } public function unserialize($string) { $this->reader->XML($string); $this->reader->read(); if ('AST' !== $this->reader->name) { throw new DomainException('AST root element not found'); } return $this->read($this->reader->depth); } protected function read($depthLimit, $throw = true, &$nodeFound = null) { $nodeFound = true; while ($this->reader->read() && $depthLimit < $this->reader->depth) { if (XMLReader::ELEMENT !== $this->reader->nodeType) { continue; } if ('node' === $this->reader->prefix) { return $this->readNode(); } elseif ('scalar' === $this->reader->prefix) { return $this->readScalar(); } elseif ('comment' === $this->reader->name) { return $this->readComment(); } else { throw new DomainException(sprintf('Unexpected node of type "%s"', $this->reader->name)); } } $nodeFound = false; if ($throw) { throw new DomainException('Expected node or scalar'); } } protected function readNode() { $className = $this->getClassNameFromType($this->reader->localName); // create the node without calling it's constructor $node = unserialize( sprintf( "O:%d:\"%s\":1:{s:13:\"\0*\0attributes\";a:0:{}}", strlen($className), $className ) ); $depthLimit = $this->reader->depth; while ($this->reader->read() && $depthLimit < $this->reader->depth) { if (XMLReader::ELEMENT !== $this->reader->nodeType) { continue; } $type = $this->reader->prefix; if ('subNode' !== $type && 'attribute' !== $type) { throw new DomainException( sprintf('Expected sub node or attribute, got node of type "%s"', $this->reader->name) ); } $name = $this->reader->localName; $value = $this->read($this->reader->depth); if ('subNode' === $type) { $node->$name = $value; } else { $node->setAttribute($name, $value); } } return $node; } protected function readScalar() { switch ($name = $this->reader->localName) { case 'array': $depth = $this->reader->depth; $array = array(); while (true) { $node = $this->read($depth, false, $nodeFound); if (!$nodeFound) { break; } $array[] = $node; } return $array; case 'string': return $this->reader->readString(); case 'int': return $this->parseInt($this->reader->readString()); case 'float': $text = $this->reader->readString(); if (false === $float = filter_var($text, FILTER_VALIDATE_FLOAT)) { throw new DomainException(sprintf('"%s" is not a valid float', $text)); } return $float; case 'true': case 'false': case 'null': if (!$this->reader->isEmptyElement) { throw new DomainException(sprintf('"%s" scalar must be empty', $name)); } return constant($name); default: throw new DomainException(sprintf('Unknown scalar type "%s"', $name)); } } private function parseInt($text) { if (false === $int = filter_var($text, FILTER_VALIDATE_INT)) { throw new DomainException(sprintf('"%s" is not a valid integer', $text)); } return $int; } protected function readComment() { $className = $this->reader->getAttribute('isDocComment') === 'true' ? 'PhpParser\Comment\Doc' : 'PhpParser\Comment' ; return new $className( $this->reader->readString(), $this->parseInt($this->reader->getAttribute('line')) ); } protected function getClassNameFromType($type) { $className = 'PhpParser\\Node\\' . strtr($type, '_', '\\'); if (!class_exists($className)) { $className .= '_'; } if (!class_exists($className)) { throw new DomainException(sprintf('Unknown node type "%s"', $type)); } return $className; } } PHP-Parser-3.1.4/lib/bootstrap.php000066400000000000000000000002131323244626500166770ustar00rootroot00000000000000 ./test/ ./lib/PhpParser/ PHP-Parser-3.1.4/test/000077500000000000000000000000001323244626500143665ustar00rootroot00000000000000PHP-Parser-3.1.4/test/PhpParser/000077500000000000000000000000001323244626500162725ustar00rootroot00000000000000PHP-Parser-3.1.4/test/PhpParser/AutoloaderTest.php000066400000000000000000000007651323244626500217520ustar00rootroot00000000000000assertTrue(class_exists('PhpParser\NodeVisitorAbstract')); $this->assertFalse(class_exists('PHPParser_NodeVisitor_NameResolver')); $this->assertFalse(class_exists('PhpParser\FooBar')); $this->assertFalse(class_exists('PHPParser_FooBar')); } } PHP-Parser-3.1.4/test/PhpParser/Builder/000077500000000000000000000000001323244626500176605ustar00rootroot00000000000000PHP-Parser-3.1.4/test/PhpParser/Builder/ClassTest.php000066400000000000000000000105361323244626500223030ustar00rootroot00000000000000createClassBuilder('SomeLogger') ->extend('BaseLogger') ->implement('Namespaced\Logger', new Name('SomeInterface')) ->implement('\Fully\Qualified', 'namespace\NamespaceRelative') ->getNode() ; $this->assertEquals( new Stmt\Class_('SomeLogger', array( 'extends' => new Name('BaseLogger'), 'implements' => array( new Name('Namespaced\Logger'), new Name('SomeInterface'), new Name\FullyQualified('Fully\Qualified'), new Name\Relative('NamespaceRelative'), ), )), $node ); } public function testAbstract() { $node = $this->createClassBuilder('Test') ->makeAbstract() ->getNode() ; $this->assertEquals( new Stmt\Class_('Test', array( 'flags' => Stmt\Class_::MODIFIER_ABSTRACT )), $node ); } public function testFinal() { $node = $this->createClassBuilder('Test') ->makeFinal() ->getNode() ; $this->assertEquals( new Stmt\Class_('Test', array( 'flags' => Stmt\Class_::MODIFIER_FINAL )), $node ); } public function testStatementOrder() { $method = new Stmt\ClassMethod('testMethod'); $property = new Stmt\Property( Stmt\Class_::MODIFIER_PUBLIC, array(new Stmt\PropertyProperty('testProperty')) ); $const = new Stmt\ClassConst(array( new Node\Const_('TEST_CONST', new Node\Scalar\String_('ABC')) )); $use = new Stmt\TraitUse(array(new Name('SomeTrait'))); $node = $this->createClassBuilder('Test') ->addStmt($method) ->addStmt($property) ->addStmts(array($const, $use)) ->getNode() ; $this->assertEquals( new Stmt\Class_('Test', array( 'stmts' => array($use, $const, $property, $method) )), $node ); } public function testDocComment() { $docComment = <<<'DOC' /** * Test */ DOC; $class = $this->createClassBuilder('Test') ->setDocComment($docComment) ->getNode(); $this->assertEquals( new Stmt\Class_('Test', array(), array( 'comments' => array( new Comment\Doc($docComment) ) )), $class ); $class = $this->createClassBuilder('Test') ->setDocComment(new Comment\Doc($docComment)) ->getNode(); $this->assertEquals( new Stmt\Class_('Test', array(), array( 'comments' => array( new Comment\Doc($docComment) ) )), $class ); } /** * @expectedException \LogicException * @expectedExceptionMessage Unexpected node of type "Stmt_Echo" */ public function testInvalidStmtError() { $this->createClassBuilder('Test') ->addStmt(new Stmt\Echo_(array())) ; } /** * @expectedException \LogicException * @expectedExceptionMessage Doc comment must be a string or an instance of PhpParser\Comment\Doc */ public function testInvalidDocComment() { $this->createClassBuilder('Test') ->setDocComment(new Comment('Test')); } /** * @expectedException \LogicException * @expectedExceptionMessage Name cannot be empty */ public function testEmptyName() { $this->createClassBuilder('Test') ->extend(''); } /** * @expectedException \LogicException * @expectedExceptionMessage Name must be a string or an instance of PhpParser\Node\Name */ public function testInvalidName() { $this->createClassBuilder('Test') ->extend(array('Foo')); } } PHP-Parser-3.1.4/test/PhpParser/Builder/FunctionTest.php000066400000000000000000000054321323244626500230220ustar00rootroot00000000000000createFunctionBuilder('test') ->makeReturnByRef() ->getNode() ; $this->assertEquals( new Stmt\Function_('test', array( 'byRef' => true )), $node ); } public function testParams() { $param1 = new Node\Param('test1'); $param2 = new Node\Param('test2'); $param3 = new Node\Param('test3'); $node = $this->createFunctionBuilder('test') ->addParam($param1) ->addParams(array($param2, $param3)) ->getNode() ; $this->assertEquals( new Stmt\Function_('test', array( 'params' => array($param1, $param2, $param3) )), $node ); } public function testStmts() { $stmt1 = new Print_(new String_('test1')); $stmt2 = new Print_(new String_('test2')); $stmt3 = new Print_(new String_('test3')); $node = $this->createFunctionBuilder('test') ->addStmt($stmt1) ->addStmts(array($stmt2, $stmt3)) ->getNode() ; $this->assertEquals( new Stmt\Function_('test', array( 'stmts' => array($stmt1, $stmt2, $stmt3) )), $node ); } public function testDocComment() { $node = $this->createFunctionBuilder('test') ->setDocComment('/** Test */') ->getNode(); $this->assertEquals(new Stmt\Function_('test', array(), array( 'comments' => array(new Comment\Doc('/** Test */')) )), $node); } public function testReturnType() { $node = $this->createFunctionBuilder('test') ->setReturnType('void') ->getNode(); $this->assertEquals(new Stmt\Function_('test', array( 'returnType' => 'void' ), array()), $node); } /** * @expectedException \LogicException * @expectedExceptionMessage void type cannot be nullable */ public function testInvalidNullableVoidType() { $this->createFunctionBuilder('test')->setReturnType('?void'); } /** * @expectedException \LogicException * @expectedExceptionMessage Expected parameter node, got "Name" */ public function testInvalidParamError() { $this->createFunctionBuilder('test') ->addParam(new Node\Name('foo')) ; } } PHP-Parser-3.1.4/test/PhpParser/Builder/InterfaceTest.php000066400000000000000000000062121323244626500231320ustar00rootroot00000000000000builder = new Interface_('Contract'); } private function dump($node) { $pp = new \PhpParser\PrettyPrinter\Standard; return $pp->prettyPrint(array($node)); } public function testEmpty() { $contract = $this->builder->getNode(); $this->assertInstanceOf('PhpParser\Node\Stmt\Interface_', $contract); $this->assertSame('Contract', $contract->name); } public function testExtending() { $contract = $this->builder->extend('Space\Root1', 'Root2')->getNode(); $this->assertEquals( new Stmt\Interface_('Contract', array( 'extends' => array( new Node\Name('Space\Root1'), new Node\Name('Root2') ), )), $contract ); } public function testAddMethod() { $method = new Stmt\ClassMethod('doSomething'); $contract = $this->builder->addStmt($method)->getNode(); $this->assertSame(array($method), $contract->stmts); } public function testAddConst() { $const = new Stmt\ClassConst(array( new Node\Const_('SPEED_OF_LIGHT', new DNumber(299792458.0)) )); $contract = $this->builder->addStmt($const)->getNode(); $this->assertSame(299792458.0, $contract->stmts[0]->consts[0]->value->value); } public function testOrder() { $const = new Stmt\ClassConst(array( new Node\Const_('SPEED_OF_LIGHT', new DNumber(299792458)) )); $method = new Stmt\ClassMethod('doSomething'); $contract = $this->builder ->addStmt($method) ->addStmt($const) ->getNode() ; $this->assertInstanceOf('PhpParser\Node\Stmt\ClassConst', $contract->stmts[0]); $this->assertInstanceOf('PhpParser\Node\Stmt\ClassMethod', $contract->stmts[1]); } public function testDocComment() { $node = $this->builder ->setDocComment('/** Test */') ->getNode(); $this->assertEquals(new Stmt\Interface_('Contract', array(), array( 'comments' => array(new Comment\Doc('/** Test */')) )), $node); } /** * @expectedException \LogicException * @expectedExceptionMessage Unexpected node of type "Stmt_PropertyProperty" */ public function testInvalidStmtError() { $this->builder->addStmt(new Stmt\PropertyProperty('invalid')); } public function testFullFunctional() { $const = new Stmt\ClassConst(array( new Node\Const_('SPEED_OF_LIGHT', new DNumber(299792458)) )); $method = new Stmt\ClassMethod('doSomething'); $contract = $this->builder ->addStmt($method) ->addStmt($const) ->getNode() ; eval($this->dump($contract)); $this->assertTrue(interface_exists('Contract', false)); } } PHP-Parser-3.1.4/test/PhpParser/Builder/MethodTest.php000066400000000000000000000105661323244626500224610ustar00rootroot00000000000000createMethodBuilder('test') ->makePublic() ->makeAbstract() ->makeStatic() ->getNode() ; $this->assertEquals( new Stmt\ClassMethod('test', array( 'flags' => Stmt\Class_::MODIFIER_PUBLIC | Stmt\Class_::MODIFIER_ABSTRACT | Stmt\Class_::MODIFIER_STATIC, 'stmts' => null, )), $node ); $node = $this->createMethodBuilder('test') ->makeProtected() ->makeFinal() ->getNode() ; $this->assertEquals( new Stmt\ClassMethod('test', array( 'flags' => Stmt\Class_::MODIFIER_PROTECTED | Stmt\Class_::MODIFIER_FINAL )), $node ); $node = $this->createMethodBuilder('test') ->makePrivate() ->getNode() ; $this->assertEquals( new Stmt\ClassMethod('test', array( 'type' => Stmt\Class_::MODIFIER_PRIVATE )), $node ); } public function testReturnByRef() { $node = $this->createMethodBuilder('test') ->makeReturnByRef() ->getNode() ; $this->assertEquals( new Stmt\ClassMethod('test', array( 'byRef' => true )), $node ); } public function testParams() { $param1 = new Node\Param('test1'); $param2 = new Node\Param('test2'); $param3 = new Node\Param('test3'); $node = $this->createMethodBuilder('test') ->addParam($param1) ->addParams(array($param2, $param3)) ->getNode() ; $this->assertEquals( new Stmt\ClassMethod('test', array( 'params' => array($param1, $param2, $param3) )), $node ); } public function testStmts() { $stmt1 = new Print_(new String_('test1')); $stmt2 = new Print_(new String_('test2')); $stmt3 = new Print_(new String_('test3')); $node = $this->createMethodBuilder('test') ->addStmt($stmt1) ->addStmts(array($stmt2, $stmt3)) ->getNode() ; $this->assertEquals( new Stmt\ClassMethod('test', array( 'stmts' => array($stmt1, $stmt2, $stmt3) )), $node ); } public function testDocComment() { $node = $this->createMethodBuilder('test') ->setDocComment('/** Test */') ->getNode(); $this->assertEquals(new Stmt\ClassMethod('test', array(), array( 'comments' => array(new Comment\Doc('/** Test */')) )), $node); } public function testReturnType() { $node = $this->createMethodBuilder('test') ->setReturnType('bool') ->getNode(); $this->assertEquals(new Stmt\ClassMethod('test', array( 'returnType' => 'bool' ), array()), $node); } /** * @expectedException \LogicException * @expectedExceptionMessage Cannot add statements to an abstract method */ public function testAddStmtToAbstractMethodError() { $this->createMethodBuilder('test') ->makeAbstract() ->addStmt(new Print_(new String_('test'))) ; } /** * @expectedException \LogicException * @expectedExceptionMessage Cannot make method with statements abstract */ public function testMakeMethodWithStmtsAbstractError() { $this->createMethodBuilder('test') ->addStmt(new Print_(new String_('test'))) ->makeAbstract() ; } /** * @expectedException \LogicException * @expectedExceptionMessage Expected parameter node, got "Name" */ public function testInvalidParamError() { $this->createMethodBuilder('test') ->addParam(new Node\Name('foo')) ; } } PHP-Parser-3.1.4/test/PhpParser/Builder/NamespaceTest.php000066400000000000000000000025561323244626500231350ustar00rootroot00000000000000 array($docComment)) ); $node = $this->createNamespaceBuilder('Name\Space') ->addStmt($stmt1) ->addStmts(array($stmt2, $stmt3)) ->setDocComment($docComment) ->getNode() ; $this->assertEquals($expected, $node); $node = $this->createNamespaceBuilder(new Node\Name(array('Name', 'Space'))) ->setDocComment($docComment) ->addStmts(array($stmt1, $stmt2)) ->addStmt($stmt3) ->getNode() ; $this->assertEquals($expected, $node); $node = $this->createNamespaceBuilder(null)->getNode(); $this->assertNull($node->name); $this->assertEmpty($node->stmts); } } PHP-Parser-3.1.4/test/PhpParser/Builder/ParamTest.php000066400000000000000000000121541323244626500222740ustar00rootroot00000000000000createParamBuilder('test') ->setDefault($value) ->getNode() ; $this->assertEquals($expectedValueNode, $node->default); } public function provideTestDefaultValues() { return array( array( null, new Expr\ConstFetch(new Node\Name('null')) ), array( true, new Expr\ConstFetch(new Node\Name('true')) ), array( false, new Expr\ConstFetch(new Node\Name('false')) ), array( 31415, new Scalar\LNumber(31415) ), array( 3.1415, new Scalar\DNumber(3.1415) ), array( 'Hallo World', new Scalar\String_('Hallo World') ), array( array(1, 2, 3), new Expr\Array_(array( new Expr\ArrayItem(new Scalar\LNumber(1)), new Expr\ArrayItem(new Scalar\LNumber(2)), new Expr\ArrayItem(new Scalar\LNumber(3)), )) ), array( array('foo' => 'bar', 'bar' => 'foo'), new Expr\Array_(array( new Expr\ArrayItem( new Scalar\String_('bar'), new Scalar\String_('foo') ), new Expr\ArrayItem( new Scalar\String_('foo'), new Scalar\String_('bar') ), )) ), array( new Scalar\MagicConst\Dir, new Scalar\MagicConst\Dir ) ); } /** * @dataProvider provideTestTypeHints */ public function testTypeHints($typeHint, $expectedType) { $node = $this->createParamBuilder('test') ->setTypeHint($typeHint) ->getNode() ; $type = $node->type; /* Manually implement comparison to avoid __toString stupidity */ if ($expectedType instanceof Node\NullableType) { $this->assertInstanceOf(get_class($expectedType), $type); $expectedType = $expectedType->type; $type = $type->type; } if ($expectedType instanceof Node\Name) { $this->assertInstanceOf(get_class($expectedType), $type); $this->assertEquals($expectedType, $type); } else { $this->assertSame($expectedType, $type); } } public function provideTestTypeHints() { return array( array('array', 'array'), array('callable', 'callable'), array('bool', 'bool'), array('int', 'int'), array('float', 'float'), array('string', 'string'), array('iterable', 'iterable'), array('object', 'object'), array('Array', 'array'), array('CALLABLE', 'callable'), array('Some\Class', new Node\Name('Some\Class')), array('\Foo', new Node\Name\FullyQualified('Foo')), array('self', new Node\Name('self')), array('?array', new Node\NullableType('array')), array('?Some\Class', new Node\NullableType(new Node\Name('Some\Class'))), array(new Node\Name('Some\Class'), new Node\Name('Some\Class')), array(new Node\NullableType('int'), new Node\NullableType('int')), array( new Node\NullableType(new Node\Name('Some\Class')), new Node\NullableType(new Node\Name('Some\Class')) ), ); } /** * @expectedException \LogicException * @expectedExceptionMessage Parameter type cannot be void */ public function testVoidTypeError() { $this->createParamBuilder('test')->setTypeHint('void'); } /** * @expectedException \LogicException * @expectedExceptionMessage Type must be a string, or an instance of Name or NullableType */ public function testInvalidTypeError() { $this->createParamBuilder('test')->setTypeHint(new \stdClass); } public function testByRef() { $node = $this->createParamBuilder('test') ->makeByRef() ->getNode() ; $this->assertEquals( new Node\Param('test', null, null, true), $node ); } public function testVariadic() { $node = $this->createParamBuilder('test') ->makeVariadic() ->getNode() ; $this->assertEquals( new Node\Param('test', null, null, false, true), $node ); } } PHP-Parser-3.1.4/test/PhpParser/Builder/PropertyTest.php000066400000000000000000000075661323244626500230730ustar00rootroot00000000000000createPropertyBuilder('test') ->makePrivate() ->makeStatic() ->getNode() ; $this->assertEquals( new Stmt\Property( Stmt\Class_::MODIFIER_PRIVATE | Stmt\Class_::MODIFIER_STATIC, array( new Stmt\PropertyProperty('test') ) ), $node ); $node = $this->createPropertyBuilder('test') ->makeProtected() ->getNode() ; $this->assertEquals( new Stmt\Property( Stmt\Class_::MODIFIER_PROTECTED, array( new Stmt\PropertyProperty('test') ) ), $node ); $node = $this->createPropertyBuilder('test') ->makePublic() ->getNode() ; $this->assertEquals( new Stmt\Property( Stmt\Class_::MODIFIER_PUBLIC, array( new Stmt\PropertyProperty('test') ) ), $node ); } public function testDocComment() { $node = $this->createPropertyBuilder('test') ->setDocComment('/** Test */') ->getNode(); $this->assertEquals(new Stmt\Property( Stmt\Class_::MODIFIER_PUBLIC, array( new Stmt\PropertyProperty('test') ), array( 'comments' => array(new Comment\Doc('/** Test */')) ) ), $node); } /** * @dataProvider provideTestDefaultValues */ public function testDefaultValues($value, $expectedValueNode) { $node = $this->createPropertyBuilder('test') ->setDefault($value) ->getNode() ; $this->assertEquals($expectedValueNode, $node->props[0]->default); } public function provideTestDefaultValues() { return array( array( null, new Expr\ConstFetch(new Name('null')) ), array( true, new Expr\ConstFetch(new Name('true')) ), array( false, new Expr\ConstFetch(new Name('false')) ), array( 31415, new Scalar\LNumber(31415) ), array( 3.1415, new Scalar\DNumber(3.1415) ), array( 'Hallo World', new Scalar\String_('Hallo World') ), array( array(1, 2, 3), new Expr\Array_(array( new Expr\ArrayItem(new Scalar\LNumber(1)), new Expr\ArrayItem(new Scalar\LNumber(2)), new Expr\ArrayItem(new Scalar\LNumber(3)), )) ), array( array('foo' => 'bar', 'bar' => 'foo'), new Expr\Array_(array( new Expr\ArrayItem( new Scalar\String_('bar'), new Scalar\String_('foo') ), new Expr\ArrayItem( new Scalar\String_('foo'), new Scalar\String_('bar') ), )) ), array( new Scalar\MagicConst\Dir, new Scalar\MagicConst\Dir ) ); } } PHP-Parser-3.1.4/test/PhpParser/Builder/TraitTest.php000066400000000000000000000026441323244626500223220ustar00rootroot00000000000000createTraitBuilder('TestTrait') ->setDocComment('/** Nice trait */') ->addStmt($method1) ->addStmts([$method2, $method3]) ->addStmt($prop) ->addStmt($use) ->getNode(); $this->assertEquals(new Stmt\Trait_('TestTrait', [ 'stmts' => [$use, $prop, $method1, $method2, $method3] ], [ 'comments' => [ new Comment\Doc('/** Nice trait */') ] ]), $trait); } /** * @expectedException \LogicException * @expectedExceptionMessage Unexpected node of type "Stmt_Echo" */ public function testInvalidStmtError() { $this->createTraitBuilder('Test') ->addStmt(new Stmt\Echo_(array())) ; } } PHP-Parser-3.1.4/test/PhpParser/Builder/UseTest.php000066400000000000000000000022331323244626500217650ustar00rootroot00000000000000createUseBuilder('Foo\Bar')->getNode(); $this->assertEquals(new Stmt\Use_(array( new Stmt\UseUse(new Name('Foo\Bar'), 'Bar') )), $node); $node = $this->createUseBuilder(new Name('Foo\Bar'))->as('XYZ')->getNode(); $this->assertEquals(new Stmt\Use_(array( new Stmt\UseUse(new Name('Foo\Bar'), 'XYZ') )), $node); $node = $this->createUseBuilder('foo\bar', Stmt\Use_::TYPE_FUNCTION)->as('foo')->getNode(); $this->assertEquals(new Stmt\Use_(array( new Stmt\UseUse(new Name('foo\bar'), 'foo') ), Stmt\Use_::TYPE_FUNCTION), $node); } public function testNonExistingMethod() { $this->setExpectedException('LogicException', 'Method "foo" does not exist'); $builder = $this->createUseBuilder('Test'); $builder->foo(); } } PHP-Parser-3.1.4/test/PhpParser/BuilderFactoryTest.php000066400000000000000000000067751323244626500226000ustar00rootroot00000000000000assertInstanceOf($className, $factory->$methodName('test')); } public function provideTestFactory() { return array( array('namespace', 'PhpParser\Builder\Namespace_'), array('class', 'PhpParser\Builder\Class_'), array('interface', 'PhpParser\Builder\Interface_'), array('trait', 'PhpParser\Builder\Trait_'), array('method', 'PhpParser\Builder\Method'), array('function', 'PhpParser\Builder\Function_'), array('property', 'PhpParser\Builder\Property'), array('param', 'PhpParser\Builder\Param'), array('use', 'PhpParser\Builder\Use_'), ); } public function testNonExistingMethod() { $this->setExpectedException('LogicException', 'Method "foo" does not exist'); $factory = new BuilderFactory(); $factory->foo(); } public function testIntegration() { $factory = new BuilderFactory; $node = $factory->namespace('Name\Space') ->addStmt($factory->use('Foo\Bar\SomeOtherClass')) ->addStmt($factory->use('Foo\Bar')->as('A')) ->addStmt($factory ->class('SomeClass') ->extend('SomeOtherClass') ->implement('A\Few', '\Interfaces') ->makeAbstract() ->addStmt($factory->method('firstMethod')) ->addStmt($factory->method('someMethod') ->makePublic() ->makeAbstract() ->addParam($factory->param('someParam')->setTypeHint('SomeClass')) ->setDocComment('/** * This method does something. * * @param SomeClass And takes a parameter */')) ->addStmt($factory->method('anotherMethod') ->makeProtected() ->addParam($factory->param('someParam')->setDefault('test')) ->addStmt(new Expr\Print_(new Expr\Variable('someParam')))) ->addStmt($factory->property('someProperty')->makeProtected()) ->addStmt($factory->property('anotherProperty') ->makePrivate() ->setDefault(array(1, 2, 3)))) ->getNode() ; $expected = <<<'EOC' prettyPrintFile($stmts); $this->assertEquals( str_replace("\r\n", "\n", $expected), str_replace("\r\n", "\n", $generated) ); } } PHP-Parser-3.1.4/test/PhpParser/CodeParsingTest.php000066400000000000000000000043021323244626500220400ustar00rootroot00000000000000 array( 'startLine', 'endLine', 'startFilePos', 'endFilePos', 'comments' ))); $parser5 = new Parser\Php5($lexer); $parser7 = new Parser\Php7($lexer); $dumpPositions = isset($modes['positions']); $output5 = $this->getParseOutput($parser5, $code, $dumpPositions); $output7 = $this->getParseOutput($parser7, $code, $dumpPositions); if (isset($modes['php5'])) { $this->assertSame($expected, $output5, $name); $this->assertNotSame($expected, $output7, $name); } else if (isset($modes['php7'])) { $this->assertNotSame($expected, $output5, $name); $this->assertSame($expected, $output7, $name); } else { $this->assertSame($expected, $output5, $name); $this->assertSame($expected, $output7, $name); } } private function getParseOutput(Parser $parser, $code, $dumpPositions) { $errors = new ErrorHandler\Collecting; $stmts = $parser->parse($code, $errors); $output = ''; foreach ($errors->getErrors() as $error) { $output .= $this->formatErrorMessage($error, $code) . "\n"; } if (null !== $stmts) { $dumper = new NodeDumper(['dumpComments' => true, 'dumpPositions' => $dumpPositions]); $output .= $dumper->dump($stmts, $code); } return canonicalize($output); } public function provideTestParse() { return $this->getTests(__DIR__ . '/../code/parser', 'test'); } private function formatErrorMessage(Error $e, $code) { if ($e->hasColumnInfo()) { return $e->getMessageWithColumnInfo($code); } else { return $e->getMessage(); } } } PHP-Parser-3.1.4/test/PhpParser/CodeTestAbstract.php000066400000000000000000000041731323244626500222060ustar00rootroot00000000000000getPathname(); $fileContents = file_get_contents($fileName); $fileContents = canonicalize($fileContents); // evaluate @@{expr}@@ expressions $fileContents = preg_replace_callback( '/@@\{(.*?)\}@@/', function($matches) { return eval('return ' . $matches[1] . ';'); }, $fileContents ); // parse sections $parts = preg_split("/\n-----(?:\n|$)/", $fileContents); // first part is the name $name = array_shift($parts) . ' (' . $fileName . ')'; $shortName = ltrim(str_replace($directory, '', $fileName), '/\\'); // multiple sections possible with always two forming a pair $chunks = array_chunk($parts, 2); foreach ($chunks as $i => $chunk) { $dataSetName = $shortName . (count($chunks) > 1 ? '#' . $i : ''); list($expected, $mode) = $this->extractMode($chunk[1]); $tests[$dataSetName] = array($name, $chunk[0], $expected, $mode); } } return $tests; } private function extractMode($expected) { $firstNewLine = strpos($expected, "\n"); if (false === $firstNewLine) { $firstNewLine = strlen($expected); } $firstLine = substr($expected, 0, $firstNewLine); if (0 !== strpos($firstLine, '!!')) { return [$expected, null]; } $expected = (string) substr($expected, $firstNewLine + 1); return [$expected, substr($firstLine, 2)]; } } PHP-Parser-3.1.4/test/PhpParser/CommentTest.php000066400000000000000000000033171323244626500212510ustar00rootroot00000000000000assertSame('/* Some comment */', $comment->getText()); $this->assertSame('/* Some comment */', (string) $comment); $this->assertSame(1, $comment->getLine()); $this->assertSame(10, $comment->getFilePos()); } /** * @dataProvider provideTestReformatting */ public function testReformatting($commentText, $reformattedText) { $comment = new Comment($commentText); $this->assertSame($reformattedText, $comment->getReformattedText()); } public function provideTestReformatting() { return array( array('// Some text' . "\n", '// Some text'), array('/* Some text */', '/* Some text */'), array( '/** * Some text. * Some more text. */', '/** * Some text. * Some more text. */' ), array( '/* Some text. Some more text. */', '/* Some text. Some more text. */' ), array( '/* Some text. More text. Even more text. */', '/* Some text. More text. Even more text. */' ), array( '/* Some text. More text. Indented text. */', '/* Some text. More text. Indented text. */', ), // invalid comment -> no reformatting array( 'hallo world', 'hallo world', ), ); } }PHP-Parser-3.1.4/test/PhpParser/ErrorHandler/000077500000000000000000000000001323244626500206615ustar00rootroot00000000000000PHP-Parser-3.1.4/test/PhpParser/ErrorHandler/CollectingTest.php000066400000000000000000000013241323244626500243150ustar00rootroot00000000000000assertFalse($errorHandler->hasErrors()); $this->assertEmpty($errorHandler->getErrors()); $errorHandler->handleError($e1 = new Error('Test 1')); $errorHandler->handleError($e2 = new Error('Test 2')); $this->assertTrue($errorHandler->hasErrors()); $this->assertSame([$e1, $e2], $errorHandler->getErrors()); $errorHandler->clearErrors(); $this->assertFalse($errorHandler->hasErrors()); $this->assertEmpty($errorHandler->getErrors()); } }PHP-Parser-3.1.4/test/PhpParser/ErrorHandler/ThrowingTest.php000066400000000000000000000005501323244626500240330ustar00rootroot00000000000000handleError(new Error('Test')); } }PHP-Parser-3.1.4/test/PhpParser/ErrorTest.php000066400000000000000000000071131323244626500207360ustar00rootroot00000000000000 10, 'endLine' => 11, ); $error = new Error('Some error', $attributes); $this->assertSame('Some error', $error->getRawMessage()); $this->assertSame($attributes, $error->getAttributes()); $this->assertSame(10, $error->getStartLine()); $this->assertSame(11, $error->getEndLine()); $this->assertSame('Some error on line 10', $error->getMessage()); return $error; } /** * @depends testConstruct */ public function testSetMessageAndLine(Error $error) { $error->setRawMessage('Some other error'); $this->assertSame('Some other error', $error->getRawMessage()); $error->setStartLine(15); $this->assertSame(15, $error->getStartLine()); $this->assertSame('Some other error on line 15', $error->getMessage()); } public function testUnknownLine() { $error = new Error('Some error'); $this->assertSame(-1, $error->getStartLine()); $this->assertSame(-1, $error->getEndLine()); $this->assertSame('Some error on unknown line', $error->getMessage()); } /** @dataProvider provideTestColumnInfo */ public function testColumnInfo($code, $startPos, $endPos, $startColumn, $endColumn) { $error = new Error('Some error', array( 'startFilePos' => $startPos, 'endFilePos' => $endPos, )); $this->assertSame(true, $error->hasColumnInfo()); $this->assertSame($startColumn, $error->getStartColumn($code)); $this->assertSame($endColumn, $error->getEndColumn($code)); } public function provideTestColumnInfo() { return array( // Error at "bar" array("assertSame(false, $error->hasColumnInfo()); try { $error->getStartColumn(''); $this->fail('Expected RuntimeException'); } catch (\RuntimeException $e) { $this->assertSame('Error does not have column information', $e->getMessage()); } try { $error->getEndColumn(''); $this->fail('Expected RuntimeException'); } catch (\RuntimeException $e) { $this->assertSame('Error does not have column information', $e->getMessage()); } } /** * @expectedException \RuntimeException * @expectedExceptionMessage Invalid position information */ public function testInvalidPosInfo() { $error = new Error('Some error', array( 'startFilePos' => 10, 'endFilePos' => 11, )); $error->getStartColumn('code'); } } PHP-Parser-3.1.4/test/PhpParser/Lexer/000077500000000000000000000000001323244626500173515ustar00rootroot00000000000000PHP-Parser-3.1.4/test/PhpParser/Lexer/EmulativeTest.php000066400000000000000000000107471323244626500226660ustar00rootroot00000000000000getLexer(); $lexer->startLexing('assertSame($expectedToken, $lexer->getNextToken()); $this->assertSame(0, $lexer->getNextToken()); } /** * @dataProvider provideTestReplaceKeywords */ public function testNoReplaceKeywordsAfterObjectOperator($keyword) { $lexer = $this->getLexer(); $lexer->startLexing('' . $keyword); $this->assertSame(Tokens::T_OBJECT_OPERATOR, $lexer->getNextToken()); $this->assertSame(Tokens::T_STRING, $lexer->getNextToken()); $this->assertSame(0, $lexer->getNextToken()); } public function provideTestReplaceKeywords() { return array( // PHP 5.5 array('finally', Tokens::T_FINALLY), array('yield', Tokens::T_YIELD), // PHP 5.4 array('callable', Tokens::T_CALLABLE), array('insteadof', Tokens::T_INSTEADOF), array('trait', Tokens::T_TRAIT), array('__TRAIT__', Tokens::T_TRAIT_C), // PHP 5.3 array('__DIR__', Tokens::T_DIR), array('goto', Tokens::T_GOTO), array('namespace', Tokens::T_NAMESPACE), array('__NAMESPACE__', Tokens::T_NS_C), ); } /** * @dataProvider provideTestLexNewFeatures */ public function testLexNewFeatures($code, array $expectedTokens) { $lexer = $this->getLexer(); $lexer->startLexing('assertSame($expectedTokenType, $lexer->getNextToken($text)); $this->assertSame($expectedTokenText, $text); } $this->assertSame(0, $lexer->getNextToken()); } /** * @dataProvider provideTestLexNewFeatures */ public function testLeaveStuffAloneInStrings($code) { $stringifiedToken = '"' . addcslashes($code, '"\\') . '"'; $lexer = $this->getLexer(); $lexer->startLexing('assertSame(Tokens::T_CONSTANT_ENCAPSED_STRING, $lexer->getNextToken($text)); $this->assertSame($stringifiedToken, $text); $this->assertSame(0, $lexer->getNextToken()); } public function provideTestLexNewFeatures() { return array( array('yield from', array( array(Tokens::T_YIELD_FROM, 'yield from'), )), array("yield\r\nfrom", array( array(Tokens::T_YIELD_FROM, "yield\r\nfrom"), )), array('...', array( array(Tokens::T_ELLIPSIS, '...'), )), array('**', array( array(Tokens::T_POW, '**'), )), array('**=', array( array(Tokens::T_POW_EQUAL, '**='), )), array('??', array( array(Tokens::T_COALESCE, '??'), )), array('<=>', array( array(Tokens::T_SPACESHIP, '<=>'), )), array('0b1010110', array( array(Tokens::T_LNUMBER, '0b1010110'), )), array('0b1011010101001010110101010010101011010101010101101011001110111100', array( array(Tokens::T_DNUMBER, '0b1011010101001010110101010010101011010101010101101011001110111100'), )), array('\\', array( array(Tokens::T_NS_SEPARATOR, '\\'), )), array("<<<'NOWDOC'\nNOWDOC;\n", array( array(Tokens::T_START_HEREDOC, "<<<'NOWDOC'\n"), array(Tokens::T_END_HEREDOC, 'NOWDOC'), array(ord(';'), ';'), )), array("<<<'NOWDOC'\nFoobar\nNOWDOC;\n", array( array(Tokens::T_START_HEREDOC, "<<<'NOWDOC'\n"), array(Tokens::T_ENCAPSED_AND_WHITESPACE, "Foobar\n"), array(Tokens::T_END_HEREDOC, 'NOWDOC'), array(ord(';'), ';'), )), ); } } PHP-Parser-3.1.4/test/PhpParser/LexerTest.php000066400000000000000000000232341323244626500207260ustar00rootroot00000000000000markTestSkipped('HHVM does not throw warnings from token_get_all()'); } $errorHandler = new ErrorHandler\Collecting(); $lexer = $this->getLexer(['usedAttributes' => [ 'comments', 'startLine', 'endLine', 'startFilePos', 'endFilePos' ]]); $lexer->startLexing($code, $errorHandler); $errors = $errorHandler->getErrors(); $this->assertSame(count($messages), count($errors)); for ($i = 0; $i < count($messages); $i++) { $this->assertSame($messages[$i], $errors[$i]->getMessageWithColumnInfo($code)); } } public function provideTestError() { return array( array("getLexer($options); $lexer->startLexing($code); while ($id = $lexer->getNextToken($value, $startAttributes, $endAttributes)) { $token = array_shift($tokens); $this->assertSame($token[0], $id); $this->assertSame($token[1], $value); $this->assertEquals($token[2], $startAttributes); $this->assertEquals($token[3], $endAttributes); } } public function provideTestLex() { return array( // tests conversion of closing PHP tag and drop of whitespace and opening tags array( 'plaintext', array(), array( array( Tokens::T_STRING, 'tokens', array('startLine' => 1), array('endLine' => 1) ), array( ord(';'), '?>', array('startLine' => 1), array('endLine' => 1) ), array( Tokens::T_INLINE_HTML, 'plaintext', array('startLine' => 1, 'hasLeadingNewline' => false), array('endLine' => 1) ), ) ), // tests line numbers array( ' 2), array('endLine' => 2) ), array( Tokens::T_STRING, 'token', array('startLine' => 2), array('endLine' => 2) ), array( ord('$'), '$', array( 'startLine' => 3, 'comments' => array( new Comment\Doc('/** doc' . "\n" . 'comment */', 2, 14), ) ), array('endLine' => 3) ), ) ), // tests comment extraction array( ' 2, 'comments' => array( new Comment('/* comment */', 1, 6), new Comment('// comment' . "\n", 1, 20), new Comment\Doc('/** docComment 1 */', 2, 31), new Comment\Doc('/** docComment 2 */', 2, 50), ), ), array('endLine' => 2) ), ) ), // tests differing start and end line array( ' 1), array('endLine' => 2) ), ) ), // tests exact file offsets array( ' array('startFilePos', 'endFilePos')), array( array( Tokens::T_CONSTANT_ENCAPSED_STRING, '"a"', array('startFilePos' => 6), array('endFilePos' => 8) ), array( ord(';'), ';', array('startFilePos' => 9), array('endFilePos' => 9) ), array( Tokens::T_CONSTANT_ENCAPSED_STRING, '"b"', array('startFilePos' => 18), array('endFilePos' => 20) ), array( ord(';'), ';', array('startFilePos' => 21), array('endFilePos' => 21) ), ) ), // tests token offsets array( ' array('startTokenPos', 'endTokenPos')), array( array( Tokens::T_CONSTANT_ENCAPSED_STRING, '"a"', array('startTokenPos' => 1), array('endTokenPos' => 1) ), array( ord(';'), ';', array('startTokenPos' => 2), array('endTokenPos' => 2) ), array( Tokens::T_CONSTANT_ENCAPSED_STRING, '"b"', array('startTokenPos' => 5), array('endTokenPos' => 5) ), array( ord(';'), ';', array('startTokenPos' => 6), array('endTokenPos' => 6) ), ) ), // tests all attributes being disabled array( ' array()), array( array( Tokens::T_VARIABLE, '$bar', array(), array() ), array( ord(';'), ';', array(), array() ) ) ), // tests no tokens array( '', array(), array() ), ); } /** * @dataProvider provideTestHaltCompiler */ public function testHandleHaltCompiler($code, $remaining) { $lexer = $this->getLexer(); $lexer->startLexing($code); while (Tokens::T_HALT_COMPILER !== $lexer->getNextToken()); $this->assertSame($remaining, $lexer->handleHaltCompiler()); $this->assertSame(0, $lexer->getNextToken()); } public function provideTestHaltCompiler() { return array( array('Remaining Text', 'Remaining Text'), //array('getLexer(); $lexer->startLexing('getNextToken()); $lexer->handleHaltCompiler(); } public function testGetTokens() { $code = 'getLexer(); $lexer->startLexing($code); $this->assertSame($expectedTokens, $lexer->getTokens()); } } PHP-Parser-3.1.4/test/PhpParser/Node/000077500000000000000000000000001323244626500171575ustar00rootroot00000000000000PHP-Parser-3.1.4/test/PhpParser/Node/NameTest.php000066400000000000000000000110621323244626500214100ustar00rootroot00000000000000assertSame(array('foo', 'bar'), $name->parts); $name = new Name('foo\bar'); $this->assertSame(array('foo', 'bar'), $name->parts); $name = new Name($name); $this->assertSame(array('foo', 'bar'), $name->parts); } public function testGet() { $name = new Name('foo'); $this->assertSame('foo', $name->getFirst()); $this->assertSame('foo', $name->getLast()); $name = new Name('foo\bar'); $this->assertSame('foo', $name->getFirst()); $this->assertSame('bar', $name->getLast()); } public function testToString() { $name = new Name('foo\bar'); $this->assertSame('foo\bar', (string) $name); $this->assertSame('foo\bar', $name->toString()); } public function testSlice() { $name = new Name('foo\bar\baz'); $this->assertEquals(new Name('foo\bar\baz'), $name->slice(0)); $this->assertEquals(new Name('bar\baz'), $name->slice(1)); $this->assertNull($name->slice(3)); $this->assertEquals(new Name('foo\bar\baz'), $name->slice(-3)); $this->assertEquals(new Name('bar\baz'), $name->slice(-2)); $this->assertEquals(new Name('foo\bar'), $name->slice(0, -1)); $this->assertNull($name->slice(0, -3)); $this->assertEquals(new Name('bar'), $name->slice(1, -1)); $this->assertNull($name->slice(1, -2)); $this->assertEquals(new Name('bar'), $name->slice(-2, 1)); $this->assertEquals(new Name('bar'), $name->slice(-2, -1)); $this->assertNull($name->slice(-2, -2)); } /** * @expectedException \OutOfBoundsException * @expectedExceptionMessage Offset 4 is out of bounds */ public function testSliceOffsetTooLarge() { (new Name('foo\bar\baz'))->slice(4); } /** * @expectedException \OutOfBoundsException * @expectedExceptionMessage Offset -4 is out of bounds */ public function testSliceOffsetTooSmall() { (new Name('foo\bar\baz'))->slice(-4); } /** * @expectedException \OutOfBoundsException * @expectedExceptionMessage Length 4 is out of bounds */ public function testSliceLengthTooLarge() { (new Name('foo\bar\baz'))->slice(0, 4); } /** * @expectedException \OutOfBoundsException * @expectedExceptionMessage Length -4 is out of bounds */ public function testSliceLengthTooSmall() { (new Name('foo\bar\baz'))->slice(0, -4); } public function testConcat() { $this->assertEquals(new Name('foo\bar\baz'), Name::concat('foo', 'bar\baz')); $this->assertEquals( new Name\FullyQualified('foo\bar'), Name\FullyQualified::concat(['foo'], new Name('bar')) ); $attributes = ['foo' => 'bar']; $this->assertEquals( new Name\Relative('foo\bar\baz', $attributes), Name\Relative::concat(new Name\FullyQualified('foo\bar'), 'baz', $attributes) ); $this->assertEquals(new Name('foo'), Name::concat(null, 'foo')); $this->assertEquals(new Name('foo'), Name::concat('foo', null)); $this->assertNull(Name::concat(null, null)); } public function testIs() { $name = new Name('foo'); $this->assertTrue ($name->isUnqualified()); $this->assertFalse($name->isQualified()); $this->assertFalse($name->isFullyQualified()); $this->assertFalse($name->isRelative()); $name = new Name('foo\bar'); $this->assertFalse($name->isUnqualified()); $this->assertTrue ($name->isQualified()); $this->assertFalse($name->isFullyQualified()); $this->assertFalse($name->isRelative()); $name = new Name\FullyQualified('foo'); $this->assertFalse($name->isUnqualified()); $this->assertFalse($name->isQualified()); $this->assertTrue ($name->isFullyQualified()); $this->assertFalse($name->isRelative()); $name = new Name\Relative('foo'); $this->assertFalse($name->isUnqualified()); $this->assertFalse($name->isQualified()); $this->assertFalse($name->isFullyQualified()); $this->assertTrue ($name->isRelative()); } /** * @expectedException \InvalidArgumentException * @expectedExceptionMessage Expected string, array of parts or Name instance */ public function testInvalidArg() { Name::concat('foo', new \stdClass); } }PHP-Parser-3.1.4/test/PhpParser/Node/Scalar/000077500000000000000000000000001323244626500203645ustar00rootroot00000000000000PHP-Parser-3.1.4/test/PhpParser/Node/Scalar/MagicConstTest.php000066400000000000000000000014551323244626500237710ustar00rootroot00000000000000assertSame($name, $magicConst->getName()); } public function provideTestGetName() { return array( array(new MagicConst\Class_, '__CLASS__'), array(new MagicConst\Dir, '__DIR__'), array(new MagicConst\File, '__FILE__'), array(new MagicConst\Function_, '__FUNCTION__'), array(new MagicConst\Line, '__LINE__'), array(new MagicConst\Method, '__METHOD__'), array(new MagicConst\Namespace_, '__NAMESPACE__'), array(new MagicConst\Trait_, '__TRAIT__'), ); } }PHP-Parser-3.1.4/test/PhpParser/Node/Scalar/StringTest.php000066400000000000000000000035451323244626500232120ustar00rootroot00000000000000assertSame( $expected, String_::parseEscapeSequences($string, $quote) ); } /** * @dataProvider provideTestParse */ public function testCreate($expected, $string) { $this->assertSame( $expected, String_::parse($string) ); } public function provideTestParseEscapeSequences() { return array( array('"', '\\"', '"'), array('\\"', '\\"', '`'), array('\\"\\`', '\\"\\`', null), array("\\\$\n\r\t\f\v", '\\\\\$\n\r\t\f\v', null), array("\x1B", '\e', null), array(chr(255), '\xFF', null), array(chr(255), '\377', null), array(chr(0), '\400', null), array("\0", '\0', null), array('\xFF', '\\\\xFF', null), ); } public function provideTestParse() { $tests = array( array('A', '\'A\''), array('A', 'b\'A\''), array('A', '"A"'), array('A', 'b"A"'), array('\\', '\'\\\\\''), array('\'', '\'\\\'\''), ); foreach ($this->provideTestParseEscapeSequences() as $i => $test) { // skip second and third tests, they aren't for double quotes if ($i != 1 && $i != 2) { $tests[] = array($test[0], '"' . $test[1] . '"'); } } return $tests; } } PHP-Parser-3.1.4/test/PhpParser/Node/Stmt/000077500000000000000000000000001323244626500201065ustar00rootroot00000000000000PHP-Parser-3.1.4/test/PhpParser/Node/Stmt/ClassConstTest.php000066400000000000000000000015571323244626500235430ustar00rootroot00000000000000assertTrue($node->{'is' . $modifier}()); } public function testNoModifiers() { $node = new ClassConst(array(), 0); $this->assertTrue($node->isPublic()); $this->assertFalse($node->isProtected()); $this->assertFalse($node->isPrivate()); $this->assertFalse($node->isStatic()); } public function provideModifiers() { return array( array('public'), array('protected'), array('private'), ); } }PHP-Parser-3.1.4/test/PhpParser/Node/Stmt/ClassMethodTest.php000066400000000000000000000033271323244626500236720ustar00rootroot00000000000000 constant('PhpParser\Node\Stmt\Class_::MODIFIER_' . strtoupper($modifier)) )); $this->assertTrue($node->{'is' . $modifier}()); } public function testNoModifiers() { $node = new ClassMethod('foo', array('type' => 0)); $this->assertTrue($node->isPublic()); $this->assertFalse($node->isProtected()); $this->assertFalse($node->isPrivate()); $this->assertFalse($node->isAbstract()); $this->assertFalse($node->isFinal()); $this->assertFalse($node->isStatic()); } public function provideModifiers() { return array( array('public'), array('protected'), array('private'), array('abstract'), array('final'), array('static'), ); } /** * Checks that implicit public modifier detection for method is working * * @dataProvider implicitPublicModifiers * * @param integer $modifier Node type modifier */ public function testImplicitPublic($modifier) { $node = new ClassMethod('foo', array( 'type' => constant('PhpParser\Node\Stmt\Class_::MODIFIER_' . strtoupper($modifier)) )); $this->assertTrue($node->isPublic(), 'Node should be implicitly public'); } public function implicitPublicModifiers() { return array( array('abstract'), array('final'), array('static'), ); } } PHP-Parser-3.1.4/test/PhpParser/Node/Stmt/ClassTest.php000066400000000000000000000040521323244626500225250ustar00rootroot00000000000000 Class_::MODIFIER_ABSTRACT)); $this->assertTrue($class->isAbstract()); $class = new Class_('Foo'); $this->assertFalse($class->isAbstract()); } public function testIsFinal() { $class = new Class_('Foo', array('type' => Class_::MODIFIER_FINAL)); $this->assertTrue($class->isFinal()); $class = new Class_('Foo'); $this->assertFalse($class->isFinal()); } public function testGetMethods() { $methods = array( new ClassMethod('foo'), new ClassMethod('bar'), new ClassMethod('fooBar'), ); $class = new Class_('Foo', array( 'stmts' => array( new TraitUse(array()), $methods[0], new ClassConst(array()), $methods[1], new Property(0, array()), $methods[2], ) )); $this->assertSame($methods, $class->getMethods()); } public function testGetMethod() { $methodConstruct = new ClassMethod('__CONSTRUCT'); $methodTest = new ClassMethod('test'); $class = new Class_('Foo', array( 'stmts' => array( new ClassConst(array()), $methodConstruct, new Property(0, array()), $methodTest, ) )); $this->assertSame($methodConstruct, $class->getMethod('__construct')); $this->assertSame($methodTest, $class->getMethod('test')); $this->assertNull($class->getMethod('nonExisting')); } public function testDeprecatedTypeNode() { $class = new Class_('Foo', array('type' => Class_::MODIFIER_ABSTRACT)); $this->assertTrue($class->isAbstract()); $this->assertSame(Class_::MODIFIER_ABSTRACT, $class->flags); $this->assertSame(Class_::MODIFIER_ABSTRACT, $class->type); } } PHP-Parser-3.1.4/test/PhpParser/Node/Stmt/InterfaceTest.php000066400000000000000000000014471323244626500233650ustar00rootroot00000000000000 array( new Node\Stmt\ClassConst(array(new Node\Const_('C1', new Node\Scalar\String_('C1')))), $methods[0], new Node\Stmt\ClassConst(array(new Node\Const_('C2', new Node\Scalar\String_('C2')))), $methods[1], new Node\Stmt\ClassConst(array(new Node\Const_('C3', new Node\Scalar\String_('C3')))), ) )); $this->assertSame($methods, $interface->getMethods()); } } PHP-Parser-3.1.4/test/PhpParser/Node/Stmt/PropertyTest.php000066400000000000000000000022771323244626500233130ustar00rootroot00000000000000assertTrue($node->{'is' . $modifier}()); } public function testNoModifiers() { $node = new Property(0, array()); $this->assertTrue($node->isPublic()); $this->assertFalse($node->isProtected()); $this->assertFalse($node->isPrivate()); $this->assertFalse($node->isStatic()); } public function testStaticImplicitlyPublic() { $node = new Property(Class_::MODIFIER_STATIC, array()); $this->assertTrue($node->isPublic()); $this->assertFalse($node->isProtected()); $this->assertFalse($node->isPrivate()); $this->assertTrue($node->isStatic()); } public function provideModifiers() { return array( array('public'), array('protected'), array('private'), array('static'), ); } } PHP-Parser-3.1.4/test/PhpParser/NodeAbstractTest.php000066400000000000000000000204171323244626500222200ustar00rootroot00000000000000subNode1 = $subNode1; $this->subNode2 = $subNode2; } public function getSubNodeNames() { return array('subNode1', 'subNode2'); } // This method is only overwritten because the node is located in an unusual namespace public function getType() { return 'Dummy'; } } class NodeAbstractTest extends \PHPUnit_Framework_TestCase { public function provideNodes() { $attributes = array( 'startLine' => 10, 'comments' => array( new Comment('// Comment' . "\n"), new Comment\Doc('/** doc comment */'), ), ); $node = new DummyNode('value1', 'value2', $attributes); $node->notSubNode = 'value3'; return array( array($attributes, $node), ); } /** * @dataProvider provideNodes */ public function testConstruct(array $attributes, Node $node) { $this->assertSame('Dummy', $node->getType()); $this->assertSame(array('subNode1', 'subNode2'), $node->getSubNodeNames()); $this->assertSame(10, $node->getLine()); $this->assertSame('/** doc comment */', $node->getDocComment()->getText()); $this->assertSame('value1', $node->subNode1); $this->assertSame('value2', $node->subNode2); $this->assertTrue(isset($node->subNode1)); $this->assertTrue(isset($node->subNode2)); $this->assertFalse(isset($node->subNode3)); $this->assertSame($attributes, $node->getAttributes()); return $node; } /** * @dataProvider provideNodes */ public function testGetDocComment(array $attributes, Node $node) { $this->assertSame('/** doc comment */', $node->getDocComment()->getText()); array_pop($node->getAttribute('comments')); // remove doc comment $this->assertNull($node->getDocComment()); array_pop($node->getAttribute('comments')); // remove comment $this->assertNull($node->getDocComment()); } public function testSetDocComment() { $node = new DummyNode(null, null, []); // Add doc comment to node without comments $docComment = new Comment\Doc('/** doc */'); $node->setDocComment($docComment); $this->assertSame($docComment, $node->getDocComment()); // Replace it $docComment = new Comment\Doc('/** doc 2 */'); $node->setDocComment($docComment); $this->assertSame($docComment, $node->getDocComment()); // Add docmment to node with other comments $c1 = new Comment('/* foo */'); $c2 = new Comment('/* bar */'); $docComment = new Comment\Doc('/** baz */'); $node->setAttribute('comments', [$c1, $c2]); $node->setDocComment($docComment); $this->assertSame([$c1, $c2, $docComment], $node->getAttribute('comments')); } /** * @dataProvider provideNodes */ public function testChange(array $attributes, Node $node) { // change of line $node->setLine(15); $this->assertSame(15, $node->getLine()); // direct modification $node->subNode = 'newValue'; $this->assertSame('newValue', $node->subNode); // indirect modification $subNode =& $node->subNode; $subNode = 'newNewValue'; $this->assertSame('newNewValue', $node->subNode); // removal unset($node->subNode); $this->assertFalse(isset($node->subNode)); } /** * @dataProvider provideNodes */ public function testIteration(array $attributes, Node $node) { // Iteration is simple object iteration over properties, // not over subnodes $i = 0; foreach ($node as $key => $value) { if ($i === 0) { $this->assertSame('subNode1', $key); $this->assertSame('value1', $value); } else if ($i === 1) { $this->assertSame('subNode2', $key); $this->assertSame('value2', $value); } else if ($i === 2) { $this->assertSame('notSubNode', $key); $this->assertSame('value3', $value); } else { throw new \Exception; } $i++; } $this->assertSame(3, $i); } public function testAttributes() { /** @var $node Node */ $node = $this->getMockForAbstractClass('PhpParser\NodeAbstract'); $this->assertEmpty($node->getAttributes()); $node->setAttribute('key', 'value'); $this->assertTrue($node->hasAttribute('key')); $this->assertSame('value', $node->getAttribute('key')); $this->assertFalse($node->hasAttribute('doesNotExist')); $this->assertNull($node->getAttribute('doesNotExist')); $this->assertSame('default', $node->getAttribute('doesNotExist', 'default')); $node->setAttribute('null', null); $this->assertTrue($node->hasAttribute('null')); $this->assertNull($node->getAttribute('null')); $this->assertNull($node->getAttribute('null', 'default')); $this->assertSame( array( 'key' => 'value', 'null' => null, ), $node->getAttributes() ); } public function testJsonSerialization() { $code = <<<'PHP' parse(canonicalize($code)); $json = json_encode($stmts, JSON_PRETTY_PRINT); $this->assertEquals(canonicalize($expected), canonicalize($json)); } } PHP-Parser-3.1.4/test/PhpParser/NodeDumperTest.php000066400000000000000000000045421323244626500217120ustar00rootroot00000000000000assertSame($this->canonicalize($dump), $this->canonicalize($dumper->dump($node))); } public function provideTestDump() { return array( array( array(), 'array( )' ), array( array('Foo', 'Bar', 'Key' => 'FooBar'), 'array( 0: Foo 1: Bar Key: FooBar )' ), array( new Node\Name(array('Hallo', 'World')), 'Name( parts: array( 0: Hallo 1: World ) )' ), array( new Node\Expr\Array_(array( new Node\Expr\ArrayItem(new Node\Scalar\String_('Foo')) )), 'Expr_Array( items: array( 0: Expr_ArrayItem( key: null value: Scalar_String( value: Foo ) byRef: false ) ) )' ), ); } public function testDumpWithPositions() { $parser = (new ParserFactory)->create( ParserFactory::ONLY_PHP7, new Lexer(['usedAttributes' => ['startLine', 'endLine', 'startFilePos', 'endFilePos']]) ); $dumper = new NodeDumper(['dumpPositions' => true]); $code = "parse($code); $dump = $dumper->dump($stmts, $code); $this->assertSame($this->canonicalize($expected), $this->canonicalize($dump)); } /** * @expectedException \InvalidArgumentException * @expectedExceptionMessage Can only dump nodes and arrays. */ public function testError() { $dumper = new NodeDumper; $dumper->dump(new \stdClass); } } PHP-Parser-3.1.4/test/PhpParser/NodeTraverserTest.php000066400000000000000000000272021323244626500224310ustar00rootroot00000000000000getMockBuilder('PhpParser\NodeVisitor')->getMock(); $visitor->expects($this->at(0))->method('beforeTraverse')->with($stmts); $visitor->expects($this->at(1))->method('enterNode')->with($echoNode); $visitor->expects($this->at(2))->method('enterNode')->with($str1Node); $visitor->expects($this->at(3))->method('leaveNode')->with($str1Node); $visitor->expects($this->at(4))->method('enterNode')->with($str2Node); $visitor->expects($this->at(5))->method('leaveNode')->with($str2Node); $visitor->expects($this->at(6))->method('leaveNode')->with($echoNode); $visitor->expects($this->at(7))->method('afterTraverse')->with($stmts); $traverser = new NodeTraverser; $traverser->addVisitor($visitor); $this->assertEquals($stmts, $traverser->traverse($stmts)); } public function testModifying() { $str1Node = new String_('Foo'); $str2Node = new String_('Bar'); $printNode = new Expr\Print_($str1Node); // first visitor changes the node, second verifies the change $visitor1 = $this->getMockBuilder('PhpParser\NodeVisitor')->getMock(); $visitor2 = $this->getMockBuilder('PhpParser\NodeVisitor')->getMock(); // replace empty statements with string1 node $visitor1->expects($this->at(0))->method('beforeTraverse')->with(array()) ->will($this->returnValue(array($str1Node))); $visitor2->expects($this->at(0))->method('beforeTraverse')->with(array($str1Node)); // replace string1 node with print node $visitor1->expects($this->at(1))->method('enterNode')->with($str1Node) ->will($this->returnValue($printNode)); $visitor2->expects($this->at(1))->method('enterNode')->with($printNode); // replace string1 node with string2 node $visitor1->expects($this->at(2))->method('enterNode')->with($str1Node) ->will($this->returnValue($str2Node)); $visitor2->expects($this->at(2))->method('enterNode')->with($str2Node); // replace string2 node with string1 node again $visitor1->expects($this->at(3))->method('leaveNode')->with($str2Node) ->will($this->returnValue($str1Node)); $visitor2->expects($this->at(3))->method('leaveNode')->with($str1Node); // replace print node with string1 node again $visitor1->expects($this->at(4))->method('leaveNode')->with($printNode) ->will($this->returnValue($str1Node)); $visitor2->expects($this->at(4))->method('leaveNode')->with($str1Node); // replace string1 node with empty statements again $visitor1->expects($this->at(5))->method('afterTraverse')->with(array($str1Node)) ->will($this->returnValue(array())); $visitor2->expects($this->at(5))->method('afterTraverse')->with(array()); $traverser = new NodeTraverser; $traverser->addVisitor($visitor1); $traverser->addVisitor($visitor2); // as all operations are reversed we end where we start $this->assertEquals(array(), $traverser->traverse(array())); } public function testRemove() { $str1Node = new String_('Foo'); $str2Node = new String_('Bar'); $visitor = $this->getMockBuilder('PhpParser\NodeVisitor')->getMock(); // remove the string1 node, leave the string2 node $visitor->expects($this->at(2))->method('leaveNode')->with($str1Node) ->will($this->returnValue(false)); $traverser = new NodeTraverser; $traverser->addVisitor($visitor); $this->assertEquals(array($str2Node), $traverser->traverse(array($str1Node, $str2Node))); } public function testMerge() { $strStart = new String_('Start'); $strMiddle = new String_('End'); $strEnd = new String_('Middle'); $strR1 = new String_('Replacement 1'); $strR2 = new String_('Replacement 2'); $visitor = $this->getMockBuilder('PhpParser\NodeVisitor')->getMock(); // replace strMiddle with strR1 and strR2 by merge $visitor->expects($this->at(4))->method('leaveNode')->with($strMiddle) ->will($this->returnValue(array($strR1, $strR2))); $traverser = new NodeTraverser; $traverser->addVisitor($visitor); $this->assertEquals( array($strStart, $strR1, $strR2, $strEnd), $traverser->traverse(array($strStart, $strMiddle, $strEnd)) ); } public function testDeepArray() { $strNode = new String_('Foo'); $stmts = array(array(array($strNode))); $visitor = $this->getMockBuilder('PhpParser\NodeVisitor')->getMock(); $visitor->expects($this->at(1))->method('enterNode')->with($strNode); $traverser = new NodeTraverser; $traverser->addVisitor($visitor); $this->assertEquals($stmts, $traverser->traverse($stmts)); } public function testDontTraverseChildren() { $strNode = new String_('str'); $printNode = new Expr\Print_($strNode); $varNode = new Expr\Variable('foo'); $mulNode = new Expr\BinaryOp\Mul($varNode, $varNode); $negNode = new Expr\UnaryMinus($mulNode); $stmts = array($printNode, $negNode); $visitor1 = $this->getMockBuilder('PhpParser\NodeVisitor')->getMock(); $visitor2 = $this->getMockBuilder('PhpParser\NodeVisitor')->getMock(); $visitor1->expects($this->at(1))->method('enterNode')->with($printNode) ->will($this->returnValue(NodeTraverser::DONT_TRAVERSE_CHILDREN)); $visitor2->expects($this->at(1))->method('enterNode')->with($printNode); $visitor1->expects($this->at(2))->method('leaveNode')->with($printNode); $visitor2->expects($this->at(2))->method('leaveNode')->with($printNode); $visitor1->expects($this->at(3))->method('enterNode')->with($negNode); $visitor2->expects($this->at(3))->method('enterNode')->with($negNode); $visitor1->expects($this->at(4))->method('enterNode')->with($mulNode); $visitor2->expects($this->at(4))->method('enterNode')->with($mulNode) ->will($this->returnValue(NodeTraverser::DONT_TRAVERSE_CHILDREN)); $visitor1->expects($this->at(5))->method('leaveNode')->with($mulNode); $visitor2->expects($this->at(5))->method('leaveNode')->with($mulNode); $visitor1->expects($this->at(6))->method('leaveNode')->with($negNode); $visitor2->expects($this->at(6))->method('leaveNode')->with($negNode); $traverser = new NodeTraverser; $traverser->addVisitor($visitor1); $traverser->addVisitor($visitor2); $this->assertEquals($stmts, $traverser->traverse($stmts)); } public function testStopTraversal() { $varNode1 = new Expr\Variable('a'); $varNode2 = new Expr\Variable('b'); $varNode3 = new Expr\Variable('c'); $mulNode = new Expr\BinaryOp\Mul($varNode1, $varNode2); $printNode = new Expr\Print_($varNode3); $stmts = [$mulNode, $printNode]; // From enterNode() with array parent $visitor = $this->getMockBuilder('PhpParser\NodeVisitor')->getMock(); $visitor->expects($this->at(1))->method('enterNode')->with($mulNode) ->will($this->returnValue(NodeTraverser::STOP_TRAVERSAL)); $visitor->expects($this->at(2))->method('afterTraverse'); $traverser = new NodeTraverser; $traverser->addVisitor($visitor); $this->assertEquals($stmts, $traverser->traverse($stmts)); // From enterNode with Node parent $visitor = $this->getMockBuilder('PhpParser\NodeVisitor')->getMock(); $visitor->expects($this->at(2))->method('enterNode')->with($varNode1) ->will($this->returnValue(NodeTraverser::STOP_TRAVERSAL)); $visitor->expects($this->at(3))->method('afterTraverse'); $traverser = new NodeTraverser; $traverser->addVisitor($visitor); $this->assertEquals($stmts, $traverser->traverse($stmts)); // From leaveNode with Node parent $visitor = $this->getMockBuilder('PhpParser\NodeVisitor')->getMock(); $visitor->expects($this->at(3))->method('leaveNode')->with($varNode1) ->will($this->returnValue(NodeTraverser::STOP_TRAVERSAL)); $visitor->expects($this->at(4))->method('afterTraverse'); $traverser = new NodeTraverser; $traverser->addVisitor($visitor); $this->assertEquals($stmts, $traverser->traverse($stmts)); // From leaveNode with array parent $visitor = $this->getMockBuilder('PhpParser\NodeVisitor')->getMock(); $visitor->expects($this->at(6))->method('leaveNode')->with($mulNode) ->will($this->returnValue(NodeTraverser::STOP_TRAVERSAL)); $visitor->expects($this->at(7))->method('afterTraverse'); $traverser = new NodeTraverser; $traverser->addVisitor($visitor); $this->assertEquals($stmts, $traverser->traverse($stmts)); // Check that pending array modifications are still carried out $visitor = $this->getMockBuilder('PhpParser\NodeVisitor')->getMock(); $visitor->expects($this->at(6))->method('leaveNode')->with($mulNode) ->will($this->returnValue(NodeTraverser::REMOVE_NODE)); $visitor->expects($this->at(7))->method('enterNode')->with($printNode) ->will($this->returnValue(NodeTraverser::STOP_TRAVERSAL)); $visitor->expects($this->at(8))->method('afterTraverse'); $traverser = new NodeTraverser; $traverser->addVisitor($visitor); $this->assertEquals([$printNode], $traverser->traverse($stmts)); } public function testRemovingVisitor() { $visitor1 = $this->getMockBuilder('PhpParser\NodeVisitor')->getMock(); $visitor2 = $this->getMockBuilder('PhpParser\NodeVisitor')->getMock(); $visitor3 = $this->getMockBuilder('PhpParser\NodeVisitor')->getMock(); $traverser = new NodeTraverser; $traverser->addVisitor($visitor1); $traverser->addVisitor($visitor2); $traverser->addVisitor($visitor3); $preExpected = array($visitor1, $visitor2, $visitor3); $this->assertAttributeSame($preExpected, 'visitors', $traverser, 'The appropriate visitors have not been added'); $traverser->removeVisitor($visitor2); $postExpected = array(0 => $visitor1, 2 => $visitor3); $this->assertAttributeSame($postExpected, 'visitors', $traverser, 'The appropriate visitors are not present after removal'); } public function testNoCloneNodes() { $stmts = array(new Node\Stmt\Echo_(array(new String_('Foo'), new String_('Bar')))); $traverser = new NodeTraverser; $this->assertSame($stmts, $traverser->traverse($stmts)); } /** * @expectedException \LogicException * @expectedExceptionMessage leaveNode() may only return an array if the parent structure is an array */ public function testReplaceByArrayOnlyAllowedIfParentIsArray() { $stmts = array(new Node\Expr\UnaryMinus(new Node\Scalar\LNumber(42))); $visitor = $this->getMockBuilder('PhpParser\NodeVisitor')->getMock(); $visitor->method('leaveNode')->willReturn(array(new Node\Scalar\DNumber(42.0))); $traverser = new NodeTraverser(); $traverser->addVisitor($visitor); $traverser->traverse($stmts); } } PHP-Parser-3.1.4/test/PhpParser/NodeVisitor/000077500000000000000000000000001323244626500205375ustar00rootroot00000000000000PHP-Parser-3.1.4/test/PhpParser/NodeVisitor/NameResolverTest.php000066400000000000000000000275111323244626500245200ustar00rootroot00000000000000addVisitor(new NameResolver); $stmts = $parser->parse($code); $stmts = $traverser->traverse($stmts); $this->assertSame( $this->canonicalize($expectedCode), $prettyPrinter->prettyPrint($stmts) ); } /** * @covers PhpParser\NodeVisitor\NameResolver */ public function testResolveLocations() { $code = <<<'EOC' addVisitor(new NameResolver); $stmts = $parser->parse($code); $stmts = $traverser->traverse($stmts); $this->assertSame( $this->canonicalize($expectedCode), $prettyPrinter->prettyPrint($stmts) ); } public function testNoResolveSpecialName() { $stmts = array(new Node\Expr\New_(new Name('self'))); $traverser = new PhpParser\NodeTraverser; $traverser->addVisitor(new NameResolver); $this->assertEquals($stmts, $traverser->traverse($stmts)); } public function testAddDeclarationNamespacedName() { $nsStmts = array( new Stmt\Class_('A'), new Stmt\Interface_('B'), new Stmt\Function_('C'), new Stmt\Const_(array( new Node\Const_('D', new Node\Scalar\LNumber(42)) )), new Stmt\Trait_('E'), new Expr\New_(new Stmt\Class_(null)), ); $traverser = new PhpParser\NodeTraverser; $traverser->addVisitor(new NameResolver); $stmts = $traverser->traverse([new Stmt\Namespace_(new Name('NS'), $nsStmts)]); $this->assertSame('NS\\A', (string) $stmts[0]->stmts[0]->namespacedName); $this->assertSame('NS\\B', (string) $stmts[0]->stmts[1]->namespacedName); $this->assertSame('NS\\C', (string) $stmts[0]->stmts[2]->namespacedName); $this->assertSame('NS\\D', (string) $stmts[0]->stmts[3]->consts[0]->namespacedName); $this->assertSame('NS\\E', (string) $stmts[0]->stmts[4]->namespacedName); $this->assertObjectNotHasAttribute('namespacedName', $stmts[0]->stmts[5]->class); $stmts = $traverser->traverse([new Stmt\Namespace_(null, $nsStmts)]); $this->assertSame('A', (string) $stmts[0]->stmts[0]->namespacedName); $this->assertSame('B', (string) $stmts[0]->stmts[1]->namespacedName); $this->assertSame('C', (string) $stmts[0]->stmts[2]->namespacedName); $this->assertSame('D', (string) $stmts[0]->stmts[3]->consts[0]->namespacedName); $this->assertSame('E', (string) $stmts[0]->stmts[4]->namespacedName); $this->assertObjectNotHasAttribute('namespacedName', $stmts[0]->stmts[5]->class); } public function testAddRuntimeResolvedNamespacedName() { $stmts = array( new Stmt\Namespace_(new Name('NS'), array( new Expr\FuncCall(new Name('foo')), new Expr\ConstFetch(new Name('FOO')), )), new Stmt\Namespace_(null, array( new Expr\FuncCall(new Name('foo')), new Expr\ConstFetch(new Name('FOO')), )), ); $traverser = new PhpParser\NodeTraverser; $traverser->addVisitor(new NameResolver); $stmts = $traverser->traverse($stmts); $this->assertSame('NS\\foo', (string) $stmts[0]->stmts[0]->name->getAttribute('namespacedName')); $this->assertSame('NS\\FOO', (string) $stmts[0]->stmts[1]->name->getAttribute('namespacedName')); $this->assertFalse($stmts[1]->stmts[0]->name->hasAttribute('namespacedName')); $this->assertFalse($stmts[1]->stmts[1]->name->hasAttribute('namespacedName')); } /** * @dataProvider provideTestError */ public function testError(Node $stmt, $errorMsg) { $this->setExpectedException('PhpParser\Error', $errorMsg); $traverser = new PhpParser\NodeTraverser; $traverser->addVisitor(new NameResolver); $traverser->traverse(array($stmt)); } public function provideTestError() { return array( array( new Stmt\Use_(array( new Stmt\UseUse(new Name('A\B'), 'B', 0, array('startLine' => 1)), new Stmt\UseUse(new Name('C\D'), 'B', 0, array('startLine' => 2)), ), Stmt\Use_::TYPE_NORMAL), 'Cannot use C\D as B because the name is already in use on line 2' ), array( new Stmt\Use_(array( new Stmt\UseUse(new Name('a\b'), 'b', 0, array('startLine' => 1)), new Stmt\UseUse(new Name('c\d'), 'B', 0, array('startLine' => 2)), ), Stmt\Use_::TYPE_FUNCTION), 'Cannot use function c\d as B because the name is already in use on line 2' ), array( new Stmt\Use_(array( new Stmt\UseUse(new Name('A\B'), 'B', 0, array('startLine' => 1)), new Stmt\UseUse(new Name('C\D'), 'B', 0, array('startLine' => 2)), ), Stmt\Use_::TYPE_CONSTANT), 'Cannot use const C\D as B because the name is already in use on line 2' ), array( new Expr\New_(new Name\FullyQualified('self', array('startLine' => 3))), "'\\self' is an invalid class name on line 3" ), array( new Expr\New_(new Name\Relative('self', array('startLine' => 3))), "'\\self' is an invalid class name on line 3" ), array( new Expr\New_(new Name\FullyQualified('PARENT', array('startLine' => 3))), "'\\PARENT' is an invalid class name on line 3" ), array( new Expr\New_(new Name\Relative('STATIC', array('startLine' => 3))), "'\\STATIC' is an invalid class name on line 3" ), ); } public function testClassNameIsCaseInsensitive() { $source = <<<'EOC' parse($source); $traverser = new PhpParser\NodeTraverser; $traverser->addVisitor(new NameResolver); $stmts = $traverser->traverse($stmts); $stmt = $stmts[0]; $this->assertSame(array('Bar', 'Baz'), $stmt->stmts[1]->expr->class->parts); } public function testSpecialClassNamesAreCaseInsensitive() { $source = <<<'EOC' parse($source); $traverser = new PhpParser\NodeTraverser; $traverser->addVisitor(new NameResolver); $stmts = $traverser->traverse($stmts); $classStmt = $stmts[0]; $methodStmt = $classStmt->stmts[0]->stmts[0]; $this->assertSame('SELF', (string)$methodStmt->stmts[0]->class); $this->assertSame('PARENT', (string)$methodStmt->stmts[1]->class); $this->assertSame('STATIC', (string)$methodStmt->stmts[2]->class); } public function testAddOriginalNames() { $traverser = new PhpParser\NodeTraverser; $traverser->addVisitor(new NameResolver(null, ['preserveOriginalNames' => true])); $n1 = new Name('Bar'); $n2 = new Name('bar'); $origStmts = [ new Stmt\Namespace_(new Name('Foo'), [ new Expr\ClassConstFetch($n1, 'FOO'), new Expr\FuncCall($n2), ]) ]; $stmts = $traverser->traverse($origStmts); $this->assertSame($n1, $stmts[0]->stmts[0]->class->getAttribute('originalName')); $this->assertSame($n2, $stmts[0]->stmts[1]->name->getAttribute('originalName')); } } PHP-Parser-3.1.4/test/PhpParser/Parser/000077500000000000000000000000001323244626500175265ustar00rootroot00000000000000PHP-Parser-3.1.4/test/PhpParser/Parser/MultipleTest.php000066400000000000000000000057041323244626500227000ustar00rootroot00000000000000 []]); return new Multiple([new Php7($lexer), new Php5($lexer)]); } private function getPrefer5() { $lexer = new Lexer(['usedAttributes' => []]); return new Multiple([new Php5($lexer), new Php7($lexer)]); } /** @dataProvider provideTestParse */ public function testParse($code, Multiple $parser, $expected) { $this->assertEquals($expected, $parser->parse($code)); } public function provideTestParse() { return [ [ // PHP 7 only code 'getPrefer5(), [ new Stmt\Class_('Test', ['stmts' => [ new Stmt\ClassMethod('function') ]]), ] ], [ // PHP 5 only code 'b;', $this->getPrefer7(), [ new Stmt\Global_([ new Expr\Variable(new Expr\PropertyFetch(new Expr\Variable('a'), 'b')) ]) ] ], [ // Different meaning (PHP 5) 'getPrefer5(), [ new Expr\Variable( new Expr\ArrayDimFetch(new Expr\Variable('a'), LNumber::fromString('0')) ) ] ], [ // Different meaning (PHP 7) 'getPrefer7(), [ new Expr\ArrayDimFetch( new Expr\Variable(new Expr\Variable('a')), LNumber::fromString('0') ) ] ], ]; } public function testThrownError() { $this->setExpectedException('PhpParser\Error', 'FAIL A'); $parserA = $this->getMockBuilder('PhpParser\Parser')->getMock(); $parserA->expects($this->at(0)) ->method('parse')->will($this->throwException(new Error('FAIL A'))); $parserB = $this->getMockBuilder('PhpParser\Parser')->getMock(); $parserB->expects($this->at(0)) ->method('parse')->will($this->throwException(new Error('FAIL B'))); $parser = new Multiple([$parserA, $parserB]); $parser->parse('dummy'); } }PHP-Parser-3.1.4/test/PhpParser/Parser/Php5Test.php000066400000000000000000000004001323244626500217050ustar00rootroot00000000000000assertInstanceOf($expected, (new ParserFactory)->create($kind, $lexer)); } public function provideTestCreate() { $lexer = new Lexer(); return [ [ ParserFactory::PREFER_PHP7, $lexer, 'PhpParser\Parser\Multiple' ], [ ParserFactory::PREFER_PHP5, null, 'PhpParser\Parser\Multiple' ], [ ParserFactory::ONLY_PHP7, null, 'PhpParser\Parser\Php7' ], [ ParserFactory::ONLY_PHP5, $lexer, 'PhpParser\Parser\Php5' ] ]; } }PHP-Parser-3.1.4/test/PhpParser/ParserTest.php000066400000000000000000000162201323244626500211000ustar00rootroot00000000000000getParser(new Lexer()); $parser->parse('getParser(new Lexer()); $parser->parse('getParser(new Lexer()); $parser->parse(' array( 'comments', 'startLine', 'endLine', 'startTokenPos', 'endTokenPos', ) )); $code = <<<'EOC' getParser($lexer); $stmts = $parser->parse($code); /** @var \PhpParser\Node\Stmt\Function_ $fn */ $fn = $stmts[0]; $this->assertInstanceOf('PhpParser\Node\Stmt\Function_', $fn); $this->assertEquals(array( 'comments' => array( new Comment\Doc('/** Doc comment */', 2, 6), ), 'startLine' => 3, 'endLine' => 7, 'startTokenPos' => 3, 'endTokenPos' => 21, ), $fn->getAttributes()); $param = $fn->params[0]; $this->assertInstanceOf('PhpParser\Node\Param', $param); $this->assertEquals(array( 'startLine' => 3, 'endLine' => 3, 'startTokenPos' => 7, 'endTokenPos' => 7, ), $param->getAttributes()); /** @var \PhpParser\Node\Stmt\Echo_ $echo */ $echo = $fn->stmts[0]; $this->assertInstanceOf('PhpParser\Node\Stmt\Echo_', $echo); $this->assertEquals(array( 'comments' => array( new Comment("// Line\n", 4, 49), new Comment("// Comments\n", 5, 61), ), 'startLine' => 6, 'endLine' => 6, 'startTokenPos' => 16, 'endTokenPos' => 19, ), $echo->getAttributes()); /** @var \PhpParser\Node\Expr\Variable $var */ $var = $echo->exprs[0]; $this->assertInstanceOf('PhpParser\Node\Expr\Variable', $var); $this->assertEquals(array( 'startLine' => 6, 'endLine' => 6, 'startTokenPos' => 18, 'endTokenPos' => 18, ), $var->getAttributes()); } /** * @expectedException \RangeException * @expectedExceptionMessage The lexer returned an invalid token (id=999, value=foobar) */ public function testInvalidToken() { $lexer = new InvalidTokenLexer; $parser = $this->getParser($lexer); $parser->parse('dummy'); } /** * @dataProvider provideTestExtraAttributes */ public function testExtraAttributes($code, $expectedAttributes) { $parser = $this->getParser(new Lexer); $stmts = $parser->parse("getAttributes(); foreach ($expectedAttributes as $name => $value) { $this->assertSame($value, $attributes[$name]); } } public function provideTestExtraAttributes() { return array( array('0', ['kind' => Scalar\LNumber::KIND_DEC]), array('9', ['kind' => Scalar\LNumber::KIND_DEC]), array('07', ['kind' => Scalar\LNumber::KIND_OCT]), array('0xf', ['kind' => Scalar\LNumber::KIND_HEX]), array('0XF', ['kind' => Scalar\LNumber::KIND_HEX]), array('0b1', ['kind' => Scalar\LNumber::KIND_BIN]), array('0B1', ['kind' => Scalar\LNumber::KIND_BIN]), array('[]', ['kind' => Expr\Array_::KIND_SHORT]), array('array()', ['kind' => Expr\Array_::KIND_LONG]), array("'foo'", ['kind' => String_::KIND_SINGLE_QUOTED]), array("b'foo'", ['kind' => String_::KIND_SINGLE_QUOTED]), array("B'foo'", ['kind' => String_::KIND_SINGLE_QUOTED]), array('"foo"', ['kind' => String_::KIND_DOUBLE_QUOTED]), array('b"foo"', ['kind' => String_::KIND_DOUBLE_QUOTED]), array('B"foo"', ['kind' => String_::KIND_DOUBLE_QUOTED]), array('"foo$bar"', ['kind' => String_::KIND_DOUBLE_QUOTED]), array('b"foo$bar"', ['kind' => String_::KIND_DOUBLE_QUOTED]), array('B"foo$bar"', ['kind' => String_::KIND_DOUBLE_QUOTED]), array("<<<'STR'\nSTR\n", ['kind' => String_::KIND_NOWDOC, 'docLabel' => 'STR']), array("<< String_::KIND_HEREDOC, 'docLabel' => 'STR']), array("<<<\"STR\"\nSTR\n", ['kind' => String_::KIND_HEREDOC, 'docLabel' => 'STR']), array("b<<<'STR'\nSTR\n", ['kind' => String_::KIND_NOWDOC, 'docLabel' => 'STR']), array("B<<<'STR'\nSTR\n", ['kind' => String_::KIND_NOWDOC, 'docLabel' => 'STR']), array("<<< \t 'STR'\nSTR\n", ['kind' => String_::KIND_NOWDOC, 'docLabel' => 'STR']), // HHVM doesn't support this due to a lexer bug // (https://github.com/facebook/hhvm/issues/6970) // array("<<<'\xff'\n\xff\n", ['kind' => String_::KIND_NOWDOC, 'docLabel' => "\xff"]), array("<<<\"STR\"\n\$a\nSTR\n", ['kind' => String_::KIND_HEREDOC, 'docLabel' => 'STR']), array("b<<<\"STR\"\n\$a\nSTR\n", ['kind' => String_::KIND_HEREDOC, 'docLabel' => 'STR']), array("B<<<\"STR\"\n\$a\nSTR\n", ['kind' => String_::KIND_HEREDOC, 'docLabel' => 'STR']), array("<<< \t \"STR\"\n\$a\nSTR\n", ['kind' => String_::KIND_HEREDOC, 'docLabel' => 'STR']), array("die", ['kind' => Expr\Exit_::KIND_DIE]), array("die('done')", ['kind' => Expr\Exit_::KIND_DIE]), array("exit", ['kind' => Expr\Exit_::KIND_EXIT]), array("exit(1)", ['kind' => Expr\Exit_::KIND_EXIT]), array("?>Foo", ['hasLeadingNewline' => false]), array("?>\nFoo", ['hasLeadingNewline' => true]), array("namespace Foo;", ['kind' => Node\Stmt\Namespace_::KIND_SEMICOLON]), array("namespace Foo {}", ['kind' => Node\Stmt\Namespace_::KIND_BRACED]), array("namespace {}", ['kind' => Node\Stmt\Namespace_::KIND_BRACED]), ); } } class InvalidTokenLexer extends Lexer { public function getNextToken(&$value = null, &$startAttributes = null, &$endAttributes = null) { $value = 'foobar'; return 999; } } PHP-Parser-3.1.4/test/PhpParser/PrettyPrinterTest.php000066400000000000000000000213141323244626500224770ustar00rootroot00000000000000parseModeLine($modeLine); $prettyPrinter = new Standard($options); try { $output5 = canonicalize($prettyPrinter->$method($parser5->parse($code))); } catch (Error $e) { $output5 = null; if ('php7' !== $version) { throw $e; } } try { $output7 = canonicalize($prettyPrinter->$method($parser7->parse($code))); } catch (Error $e) { $output7 = null; if ('php5' !== $version) { throw $e; } } if ('php5' === $version) { $this->assertSame($expected, $output5, $name); $this->assertNotSame($expected, $output7, $name); } else if ('php7' === $version) { $this->assertSame($expected, $output7, $name); $this->assertNotSame($expected, $output5, $name); } else { $this->assertSame($expected, $output5, $name); $this->assertSame($expected, $output7, $name); } } /** * @dataProvider provideTestPrettyPrint * @covers PhpParser\PrettyPrinter\Standard */ public function testPrettyPrint($name, $code, $expected, $mode) { $this->doTestPrettyPrintMethod('prettyPrint', $name, $code, $expected, $mode); } /** * @dataProvider provideTestPrettyPrintFile * @covers PhpParser\PrettyPrinter\Standard */ public function testPrettyPrintFile($name, $code, $expected, $mode) { $this->doTestPrettyPrintMethod('prettyPrintFile', $name, $code, $expected, $mode); } public function provideTestPrettyPrint() { return $this->getTests(__DIR__ . '/../code/prettyPrinter', 'test'); } public function provideTestPrettyPrintFile() { return $this->getTests(__DIR__ . '/../code/prettyPrinter', 'file-test'); } public function testPrettyPrintExpr() { $prettyPrinter = new Standard; $expr = new Expr\BinaryOp\Mul( new Expr\BinaryOp\Plus(new Expr\Variable('a'), new Expr\Variable('b')), new Expr\Variable('c') ); $this->assertEquals('($a + $b) * $c', $prettyPrinter->prettyPrintExpr($expr)); $expr = new Expr\Closure(array( 'stmts' => array(new Stmt\Return_(new String_("a\nb"))) )); $this->assertEquals("function () {\n return 'a\nb';\n}", $prettyPrinter->prettyPrintExpr($expr)); } public function testCommentBeforeInlineHTML() { $prettyPrinter = new PrettyPrinter\Standard; $comment = new Comment\Doc("/**\n * This is a comment\n */"); $stmts = [new Stmt\InlineHTML('Hello World!', ['comments' => [$comment]])]; $expected = "\nHello World!"; $this->assertSame($expected, $prettyPrinter->prettyPrintFile($stmts)); } private function parseModeLine($modeLine) { $parts = explode(' ', $modeLine, 2); $version = isset($parts[0]) ? $parts[0] : 'both'; $options = isset($parts[1]) ? json_decode($parts[1], true) : []; return [$version, $options]; } public function testArraySyntaxDefault() { $prettyPrinter = new Standard(['shortArraySyntax' => true]); $expr = new Expr\Array_([ new Expr\ArrayItem(new String_('val'), new String_('key')) ]); $expected = "['key' => 'val']"; $this->assertSame($expected, $prettyPrinter->prettyPrintExpr($expr)); } /** * @dataProvider provideTestKindAttributes */ public function testKindAttributes($node, $expected) { $prttyPrinter = new PrettyPrinter\Standard; $result = $prttyPrinter->prettyPrintExpr($node); $this->assertSame($expected, $result); } public function provideTestKindAttributes() { $nowdoc = ['kind' => String_::KIND_NOWDOC, 'docLabel' => 'STR']; $heredoc = ['kind' => String_::KIND_HEREDOC, 'docLabel' => 'STR']; return [ // Defaults to single quoted [new String_('foo'), "'foo'"], // Explicit single/double quoted [new String_('foo', ['kind' => String_::KIND_SINGLE_QUOTED]), "'foo'"], [new String_('foo', ['kind' => String_::KIND_DOUBLE_QUOTED]), '"foo"'], // Fallback from doc string if no label [new String_('foo', ['kind' => String_::KIND_NOWDOC]), "'foo'"], [new String_('foo', ['kind' => String_::KIND_HEREDOC]), '"foo"'], // Fallback if string contains label [new String_("A\nB\nC", ['kind' => String_::KIND_NOWDOC, 'docLabel' => 'A']), "'A\nB\nC'"], [new String_("A\nB\nC", ['kind' => String_::KIND_NOWDOC, 'docLabel' => 'B']), "'A\nB\nC'"], [new String_("A\nB\nC", ['kind' => String_::KIND_NOWDOC, 'docLabel' => 'C']), "'A\nB\nC'"], [new String_("STR;", ['kind' => String_::KIND_NOWDOC, 'docLabel' => 'STR']), "'STR;'"], // Doc string if label not contained (or not in ending position) [new String_("foo", $nowdoc), "<<<'STR'\nfoo\nSTR\n"], [new String_("foo", $heredoc), "<<prettyPrintExpr($node); $this->assertSame($expected, $result); } public function provideTestUnnaturalLiterals() { return [ [new LNumber(-1), '-1'], [new LNumber(-PHP_INT_MAX - 1), '(-' . PHP_INT_MAX . '-1)'], [new LNumber(-1, ['kind' => LNumber::KIND_BIN]), '-0b1'], [new LNumber(-1, ['kind' => LNumber::KIND_OCT]), '-01'], [new LNumber(-1, ['kind' => LNumber::KIND_HEX]), '-0x1'], [new DNumber(\INF), '\INF'], [new DNumber(-\INF), '-\INF'], [new DNumber(-\NAN), '\NAN'], ]; } /** * @expectedException \LogicException * @expectedExceptionMessage Cannot pretty-print AST with Error nodes */ public function testPrettyPrintWithError() { $stmts = [new Expr\PropertyFetch(new Expr\Variable('a'), new Expr\Error())]; $prettyPrinter = new PrettyPrinter\Standard; $prettyPrinter->prettyPrint($stmts); } /** * @expectedException \LogicException * @expectedExceptionMessage Cannot pretty-print AST with Error nodes */ public function testPrettyPrintWithErrorInClassConstFetch() { $stmts = [new Expr\ClassConstFetch(new Name('Foo'), new Expr\Error())]; $prettyPrinter = new PrettyPrinter\Standard; $prettyPrinter->prettyPrint($stmts); } } PHP-Parser-3.1.4/test/PhpParser/Serializer/000077500000000000000000000000001323244626500204035ustar00rootroot00000000000000PHP-Parser-3.1.4/test/PhpParser/Serializer/XMLTest.php000066400000000000000000000110661323244626500224200ustar00rootroot00000000000000 */ public function testSerialize() { $code = << 4 // comment /** doc comment */ 6 functionName 4 4 a 4 4 10 0 4 4 b 4 4 1 5 5 5 5 1 Foo XML; $parser = new PhpParser\Parser\Php7(new PhpParser\Lexer); $serializer = new XML; $code = str_replace("\r\n", "\n", $code); $stmts = $parser->parse($code); $this->assertXmlStringEqualsXmlString($xml, $serializer->serialize($stmts)); } /** * @expectedException \InvalidArgumentException * @expectedExceptionMessage Unexpected node type */ public function testError() { $serializer = new XML; $serializer->serialize(array(new \stdClass)); } } PHP-Parser-3.1.4/test/PhpParser/Unserializer/000077500000000000000000000000001323244626500207465ustar00rootroot00000000000000PHP-Parser-3.1.4/test/PhpParser/Unserializer/XMLTest.php000066400000000000000000000111311323244626500227540ustar00rootroot00000000000000 1 // comment /** doc comment */ Test XML; $unserializer = new XML; $this->assertEquals( new Scalar\String_('Test', array( 'startLine' => 1, 'comments' => array( new Comment('// comment' . "\n", 2), new Comment\Doc('/** doc comment */', 3), ), )), $unserializer->unserialize($xml) ); } public function testEmptyNode() { $xml = << XML; $unserializer = new XML; $this->assertEquals( new Scalar\MagicConst\Class_, $unserializer->unserialize($xml) ); } public function testScalars() { $xml = << test 1 1 1.5 XML; $result = array( array(), array(), 'test', '', '', 1, 1, 1.5, true, false, null ); $unserializer = new XML; $this->assertEquals($result, $unserializer->unserialize($xml)); } /** * @expectedException \DomainException * @expectedExceptionMessage AST root element not found */ public function testWrongRootElementError() { $xml = << XML; $unserializer = new XML; $unserializer->unserialize($xml); } /** * @dataProvider provideTestErrors */ public function testErrors($xml, $errorMsg) { $this->setExpectedException('DomainException', $errorMsg); $xml = << $xml XML; $unserializer = new XML; $unserializer->unserialize($xml); } public function provideTestErrors() { return array( array('test', '"true" scalar must be empty'), array('test', '"false" scalar must be empty'), array('test', '"null" scalar must be empty'), array('bar', 'Unknown scalar type "foo"'), array('x', '"x" is not a valid int'), array('x', '"x" is not a valid float'), array('', 'Expected node or scalar'), array('test', 'Unexpected node of type "foo:bar"'), array( 'test', 'Expected sub node or attribute, got node of type "foo:bar"' ), array( '', 'Expected node or scalar' ), array( '', 'Unknown node type "Foo"' ), ); } } PHP-Parser-3.1.4/test/bootstrap.php000066400000000000000000000006761323244626500171250ustar00rootroot00000000000000 ----- array( 0: Stmt_Nop( comments: array( 0: /** doc */ 1: /* foobar */ 2: // foo 3: // bar ) ) ) ----- ; ----- !!positions Syntax error, unexpected ';', expecting T_STRING or T_VARIABLE or '{' or '$' from 3:1 to 3:1 array( 0: Expr_PropertyFetch[2:1 - 2:6]( var: Expr_Variable[2:1 - 2:4]( name: foo ) name: Expr_Error[3:1 - 2:6]( ) ) ) ----- } ----- !!positions Syntax error, unexpected '}', expecting T_STRING or T_VARIABLE or '{' or '$' from 4:1 to 4:1 array( 0: Stmt_Function[2:1 - 4:1]( byRef: false name: foo params: array( ) returnType: null stmts: array( 0: Expr_PropertyFetch[3:5 - 3:10]( var: Expr_Variable[3:5 - 3:8]( name: bar ) name: Expr_Error[4:1 - 3:10]( ) ) ) ) ) ----- 'd', 'e' => &$f); // short array syntax []; [1, 2, 3]; ['a' => 'b']; ----- array( 0: Expr_Array( items: array( ) ) 1: Expr_Array( items: array( 0: Expr_ArrayItem( key: null value: Scalar_String( value: a ) byRef: false ) ) ) 2: Expr_Array( items: array( 0: Expr_ArrayItem( key: null value: Scalar_String( value: a ) byRef: false ) ) ) 3: Expr_Array( items: array( 0: Expr_ArrayItem( key: null value: Scalar_String( value: a ) byRef: false ) 1: Expr_ArrayItem( key: null value: Scalar_String( value: b ) byRef: false ) ) ) 4: Expr_Array( items: array( 0: Expr_ArrayItem( key: null value: Scalar_String( value: a ) byRef: false ) 1: Expr_ArrayItem( key: null value: Expr_Variable( name: b ) byRef: true ) 2: Expr_ArrayItem( key: Scalar_String( value: c ) value: Scalar_String( value: d ) byRef: false ) 3: Expr_ArrayItem( key: Scalar_String( value: e ) value: Expr_Variable( name: f ) byRef: true ) ) ) 5: Expr_Array( items: array( ) comments: array( 0: // short array syntax ) ) 6: Expr_Array( items: array( 0: Expr_ArrayItem( key: null value: Scalar_LNumber( value: 1 ) byRef: false ) 1: Expr_ArrayItem( key: null value: Scalar_LNumber( value: 2 ) byRef: false ) 2: Expr_ArrayItem( key: null value: Scalar_LNumber( value: 3 ) byRef: false ) ) ) 7: Expr_Array( items: array( 0: Expr_ArrayItem( key: Scalar_String( value: a ) value: Scalar_String( value: b ) byRef: false ) ) ) )PHP-Parser-3.1.4/test/code/parser/expr/arrayDestructuring.test000066400000000000000000000075361323244626500243670ustar00rootroot00000000000000Array destructuring ----- $b, 'b' => $a] = $baz; ----- !!php7 array( 0: Expr_Assign( var: Expr_Array( items: array( 0: Expr_ArrayItem( key: null value: Expr_Variable( name: a ) byRef: false ) 1: Expr_ArrayItem( key: null value: Expr_Variable( name: b ) byRef: false ) ) ) expr: Expr_Array( items: array( 0: Expr_ArrayItem( key: null value: Expr_Variable( name: c ) byRef: false ) 1: Expr_ArrayItem( key: null value: Expr_Variable( name: d ) byRef: false ) ) ) ) 1: Expr_Assign( var: Expr_Array( items: array( 0: null 1: Expr_ArrayItem( key: null value: Expr_Variable( name: a ) byRef: false ) 2: null 3: null 4: Expr_ArrayItem( key: null value: Expr_Variable( name: b ) byRef: false ) 5: null ) ) expr: Expr_Variable( name: foo ) ) 2: Expr_Assign( var: Expr_Array( items: array( 0: null 1: Expr_ArrayItem( key: null value: Expr_Array( items: array( 0: Expr_ArrayItem( key: null value: Expr_Array( items: array( 0: Expr_ArrayItem( key: null value: Expr_Variable( name: a ) byRef: false ) ) ) byRef: false ) ) ) byRef: false ) 2: Expr_ArrayItem( key: null value: Expr_Variable( name: b ) byRef: false ) ) ) expr: Expr_Variable( name: bar ) ) 3: Expr_Assign( var: Expr_Array( items: array( 0: Expr_ArrayItem( key: Scalar_String( value: a ) value: Expr_Variable( name: b ) byRef: false ) 1: Expr_ArrayItem( key: Scalar_String( value: b ) value: Expr_Variable( name: a ) byRef: false ) ) ) expr: Expr_Variable( name: baz ) ) )PHP-Parser-3.1.4/test/code/parser/expr/assign.test000066400000000000000000000140761323244626500217470ustar00rootroot00000000000000Assignments ----- >= $b; $a **= $b; // chained assign $a = $b *= $c **= $d; // by ref assign $a =& $b; // list() assign list($a) = $b; list($a, , $b) = $c; list($a, list(, $c), $d) = $e; // inc/dec ++$a; $a++; --$a; $a--; ----- array( 0: Expr_Assign( var: Expr_Variable( name: a comments: array( 0: // simple assign ) ) expr: Expr_Variable( name: b ) comments: array( 0: // simple assign ) ) 1: Expr_AssignOp_BitwiseAnd( var: Expr_Variable( name: a comments: array( 0: // combined assign ) ) expr: Expr_Variable( name: b ) comments: array( 0: // combined assign ) ) 2: Expr_AssignOp_BitwiseOr( var: Expr_Variable( name: a ) expr: Expr_Variable( name: b ) ) 3: Expr_AssignOp_BitwiseXor( var: Expr_Variable( name: a ) expr: Expr_Variable( name: b ) ) 4: Expr_AssignOp_Concat( var: Expr_Variable( name: a ) expr: Expr_Variable( name: b ) ) 5: Expr_AssignOp_Div( var: Expr_Variable( name: a ) expr: Expr_Variable( name: b ) ) 6: Expr_AssignOp_Minus( var: Expr_Variable( name: a ) expr: Expr_Variable( name: b ) ) 7: Expr_AssignOp_Mod( var: Expr_Variable( name: a ) expr: Expr_Variable( name: b ) ) 8: Expr_AssignOp_Mul( var: Expr_Variable( name: a ) expr: Expr_Variable( name: b ) ) 9: Expr_AssignOp_Plus( var: Expr_Variable( name: a ) expr: Expr_Variable( name: b ) ) 10: Expr_AssignOp_ShiftLeft( var: Expr_Variable( name: a ) expr: Expr_Variable( name: b ) ) 11: Expr_AssignOp_ShiftRight( var: Expr_Variable( name: a ) expr: Expr_Variable( name: b ) ) 12: Expr_AssignOp_Pow( var: Expr_Variable( name: a ) expr: Expr_Variable( name: b ) ) 13: Expr_Assign( var: Expr_Variable( name: a comments: array( 0: // chained assign ) ) expr: Expr_AssignOp_Mul( var: Expr_Variable( name: b ) expr: Expr_AssignOp_Pow( var: Expr_Variable( name: c ) expr: Expr_Variable( name: d ) ) ) comments: array( 0: // chained assign ) ) 14: Expr_AssignRef( var: Expr_Variable( name: a comments: array( 0: // by ref assign ) ) expr: Expr_Variable( name: b ) comments: array( 0: // by ref assign ) ) 15: Expr_Assign( var: Expr_List( items: array( 0: Expr_ArrayItem( key: null value: Expr_Variable( name: a ) byRef: false ) ) comments: array( 0: // list() assign ) ) expr: Expr_Variable( name: b ) comments: array( 0: // list() assign ) ) 16: Expr_Assign( var: Expr_List( items: array( 0: Expr_ArrayItem( key: null value: Expr_Variable( name: a ) byRef: false ) 1: null 2: Expr_ArrayItem( key: null value: Expr_Variable( name: b ) byRef: false ) ) ) expr: Expr_Variable( name: c ) ) 17: Expr_Assign( var: Expr_List( items: array( 0: Expr_ArrayItem( key: null value: Expr_Variable( name: a ) byRef: false ) 1: Expr_ArrayItem( key: null value: Expr_List( items: array( 0: null 1: Expr_ArrayItem( key: null value: Expr_Variable( name: c ) byRef: false ) ) ) byRef: false ) 2: Expr_ArrayItem( key: null value: Expr_Variable( name: d ) byRef: false ) ) ) expr: Expr_Variable( name: e ) ) 18: Expr_PreInc( var: Expr_Variable( name: a ) comments: array( 0: // inc/dec ) ) 19: Expr_PostInc( var: Expr_Variable( name: a ) ) 20: Expr_PreDec( var: Expr_Variable( name: a ) ) 21: Expr_PostDec( var: Expr_Variable( name: a ) ) )PHP-Parser-3.1.4/test/code/parser/expr/assignNewByRef.test000066400000000000000000000011261323244626500233410ustar00rootroot00000000000000Assigning new by reference (PHP 5 only) ----- $b; $a >= $b; $a == $b; $a === $b; $a != $b; $a !== $b; $a <=> $b; $a instanceof B; $a instanceof $b; ----- array( 0: Expr_BinaryOp_Smaller( left: Expr_Variable( name: a ) right: Expr_Variable( name: b ) ) 1: Expr_BinaryOp_SmallerOrEqual( left: Expr_Variable( name: a ) right: Expr_Variable( name: b ) ) 2: Expr_BinaryOp_Greater( left: Expr_Variable( name: a ) right: Expr_Variable( name: b ) ) 3: Expr_BinaryOp_GreaterOrEqual( left: Expr_Variable( name: a ) right: Expr_Variable( name: b ) ) 4: Expr_BinaryOp_Equal( left: Expr_Variable( name: a ) right: Expr_Variable( name: b ) ) 5: Expr_BinaryOp_Identical( left: Expr_Variable( name: a ) right: Expr_Variable( name: b ) ) 6: Expr_BinaryOp_NotEqual( left: Expr_Variable( name: a ) right: Expr_Variable( name: b ) ) 7: Expr_BinaryOp_NotIdentical( left: Expr_Variable( name: a ) right: Expr_Variable( name: b ) ) 8: Expr_BinaryOp_Spaceship( left: Expr_Variable( name: a ) right: Expr_Variable( name: b ) ) 9: Expr_Instanceof( expr: Expr_Variable( name: a ) class: Name( parts: array( 0: B ) ) ) 10: Expr_Instanceof( expr: Expr_Variable( name: a ) class: Expr_Variable( name: b ) ) ) PHP-Parser-3.1.4/test/code/parser/expr/constant_expr.test000066400000000000000000000400141323244626500233410ustar00rootroot00000000000000Expressions in static scalar context ----- 0; const T_20 = 1 >= 0; const T_21 = 1 === 1; const T_22 = 1 !== 1; const T_23 = 0 != "0"; const T_24 = 1 == "1"; const T_25 = 1 + 2 * 3; const T_26 = "1" + 2 + "3"; const T_27 = 2 ** 3; const T_28 = [1, 2, 3][1]; const T_29 = 12 - 13; const T_30 = 12 ^ 13; const T_31 = 12 & 13; const T_32 = 12 | 13; const T_33 = 12 % 3; const T_34 = 100 >> 4; const T_35 = !false; ----- array( 0: Stmt_Const( consts: array( 0: Const( name: T_1 value: Expr_BinaryOp_ShiftLeft( left: Scalar_LNumber( value: 1 ) right: Scalar_LNumber( value: 1 ) ) ) ) ) 1: Stmt_Const( consts: array( 0: Const( name: T_2 value: Expr_BinaryOp_Div( left: Scalar_LNumber( value: 1 ) right: Scalar_LNumber( value: 2 ) ) ) ) ) 2: Stmt_Const( consts: array( 0: Const( name: T_3 value: Expr_BinaryOp_Plus( left: Scalar_DNumber( value: 1.5 ) right: Scalar_DNumber( value: 1.5 ) ) ) ) ) 3: Stmt_Const( consts: array( 0: Const( name: T_4 value: Expr_BinaryOp_Concat( left: Scalar_String( value: foo ) right: Scalar_String( value: bar ) ) ) ) ) 4: Stmt_Const( consts: array( 0: Const( name: T_5 value: Expr_BinaryOp_Mul( left: Expr_BinaryOp_Plus( left: Scalar_DNumber( value: 1.5 ) right: Scalar_DNumber( value: 1.5 ) ) right: Scalar_LNumber( value: 2 ) ) ) ) ) 5: Stmt_Const( consts: array( 0: Const( name: T_6 value: Expr_BinaryOp_Concat( left: Expr_BinaryOp_Concat( left: Expr_BinaryOp_Concat( left: Scalar_String( value: foo ) right: Scalar_LNumber( value: 2 ) ) right: Scalar_LNumber( value: 3 ) ) right: Scalar_DNumber( value: 4 ) ) ) ) ) 6: Stmt_Const( consts: array( 0: Const( name: T_7 value: Scalar_MagicConst_Line( ) ) ) ) 7: Stmt_Const( consts: array( 0: Const( name: T_8 value: Scalar_String( value: This is a test string ) ) ) ) 8: Stmt_Const( consts: array( 0: Const( name: T_9 value: Expr_BitwiseNot( expr: Expr_UnaryMinus( expr: Scalar_LNumber( value: 1 ) ) ) ) ) ) 9: Stmt_Const( consts: array( 0: Const( name: T_10 value: Expr_BinaryOp_Plus( left: Expr_Ternary( cond: Expr_UnaryMinus( expr: Scalar_LNumber( value: 1 ) ) if: null else: Scalar_LNumber( value: 1 ) ) right: Expr_Ternary( cond: Scalar_LNumber( value: 0 ) if: Scalar_LNumber( value: 2 ) else: Scalar_LNumber( value: 3 ) ) ) ) ) ) 10: Stmt_Const( consts: array( 0: Const( name: T_11 value: Expr_BinaryOp_BooleanAnd( left: Scalar_LNumber( value: 1 ) right: Scalar_LNumber( value: 0 ) ) ) ) ) 11: Stmt_Const( consts: array( 0: Const( name: T_12 value: Expr_BinaryOp_LogicalAnd( left: Scalar_LNumber( value: 1 ) right: Scalar_LNumber( value: 1 ) ) ) ) ) 12: Stmt_Const( consts: array( 0: Const( name: T_13 value: Expr_BinaryOp_BooleanOr( left: Scalar_LNumber( value: 0 ) right: Scalar_LNumber( value: 0 ) ) ) ) ) 13: Stmt_Const( consts: array( 0: Const( name: T_14 value: Expr_BinaryOp_LogicalOr( left: Scalar_LNumber( value: 1 ) right: Scalar_LNumber( value: 0 ) ) ) ) ) 14: Stmt_Const( consts: array( 0: Const( name: T_15 value: Expr_BinaryOp_LogicalXor( left: Scalar_LNumber( value: 1 ) right: Scalar_LNumber( value: 1 ) ) ) ) ) 15: Stmt_Const( consts: array( 0: Const( name: T_16 value: Expr_BinaryOp_LogicalXor( left: Scalar_LNumber( value: 1 ) right: Scalar_LNumber( value: 0 ) ) ) ) ) 16: Stmt_Const( consts: array( 0: Const( name: T_17 value: Expr_BinaryOp_Smaller( left: Scalar_LNumber( value: 1 ) right: Scalar_LNumber( value: 0 ) ) ) ) ) 17: Stmt_Const( consts: array( 0: Const( name: T_18 value: Expr_BinaryOp_SmallerOrEqual( left: Scalar_LNumber( value: 0 ) right: Scalar_LNumber( value: 0 ) ) ) ) ) 18: Stmt_Const( consts: array( 0: Const( name: T_19 value: Expr_BinaryOp_Greater( left: Scalar_LNumber( value: 1 ) right: Scalar_LNumber( value: 0 ) ) ) ) ) 19: Stmt_Const( consts: array( 0: Const( name: T_20 value: Expr_BinaryOp_GreaterOrEqual( left: Scalar_LNumber( value: 1 ) right: Scalar_LNumber( value: 0 ) ) ) ) ) 20: Stmt_Const( consts: array( 0: Const( name: T_21 value: Expr_BinaryOp_Identical( left: Scalar_LNumber( value: 1 ) right: Scalar_LNumber( value: 1 ) ) ) ) ) 21: Stmt_Const( consts: array( 0: Const( name: T_22 value: Expr_BinaryOp_NotIdentical( left: Scalar_LNumber( value: 1 ) right: Scalar_LNumber( value: 1 ) ) ) ) ) 22: Stmt_Const( consts: array( 0: Const( name: T_23 value: Expr_BinaryOp_NotEqual( left: Scalar_LNumber( value: 0 ) right: Scalar_String( value: 0 ) ) ) ) ) 23: Stmt_Const( consts: array( 0: Const( name: T_24 value: Expr_BinaryOp_Equal( left: Scalar_LNumber( value: 1 ) right: Scalar_String( value: 1 ) ) ) ) ) 24: Stmt_Const( consts: array( 0: Const( name: T_25 value: Expr_BinaryOp_Plus( left: Scalar_LNumber( value: 1 ) right: Expr_BinaryOp_Mul( left: Scalar_LNumber( value: 2 ) right: Scalar_LNumber( value: 3 ) ) ) ) ) ) 25: Stmt_Const( consts: array( 0: Const( name: T_26 value: Expr_BinaryOp_Plus( left: Expr_BinaryOp_Plus( left: Scalar_String( value: 1 ) right: Scalar_LNumber( value: 2 ) ) right: Scalar_String( value: 3 ) ) ) ) ) 26: Stmt_Const( consts: array( 0: Const( name: T_27 value: Expr_BinaryOp_Pow( left: Scalar_LNumber( value: 2 ) right: Scalar_LNumber( value: 3 ) ) ) ) ) 27: Stmt_Const( consts: array( 0: Const( name: T_28 value: Expr_ArrayDimFetch( var: Expr_Array( items: array( 0: Expr_ArrayItem( key: null value: Scalar_LNumber( value: 1 ) byRef: false ) 1: Expr_ArrayItem( key: null value: Scalar_LNumber( value: 2 ) byRef: false ) 2: Expr_ArrayItem( key: null value: Scalar_LNumber( value: 3 ) byRef: false ) ) ) dim: Scalar_LNumber( value: 1 ) ) ) ) ) 28: Stmt_Const( consts: array( 0: Const( name: T_29 value: Expr_BinaryOp_Minus( left: Scalar_LNumber( value: 12 ) right: Scalar_LNumber( value: 13 ) ) ) ) ) 29: Stmt_Const( consts: array( 0: Const( name: T_30 value: Expr_BinaryOp_BitwiseXor( left: Scalar_LNumber( value: 12 ) right: Scalar_LNumber( value: 13 ) ) ) ) ) 30: Stmt_Const( consts: array( 0: Const( name: T_31 value: Expr_BinaryOp_BitwiseAnd( left: Scalar_LNumber( value: 12 ) right: Scalar_LNumber( value: 13 ) ) ) ) ) 31: Stmt_Const( consts: array( 0: Const( name: T_32 value: Expr_BinaryOp_BitwiseOr( left: Scalar_LNumber( value: 12 ) right: Scalar_LNumber( value: 13 ) ) ) ) ) 32: Stmt_Const( consts: array( 0: Const( name: T_33 value: Expr_BinaryOp_Mod( left: Scalar_LNumber( value: 12 ) right: Scalar_LNumber( value: 3 ) ) ) ) ) 33: Stmt_Const( consts: array( 0: Const( name: T_34 value: Expr_BinaryOp_ShiftRight( left: Scalar_LNumber( value: 100 ) right: Scalar_LNumber( value: 4 ) ) ) ) ) 34: Stmt_Const( consts: array( 0: Const( name: T_35 value: Expr_BooleanNot( expr: Expr_ConstFetch( name: Name( parts: array( 0: false ) ) ) ) ) ) ) )PHP-Parser-3.1.4/test/code/parser/expr/errorSuppress.test000066400000000000000000000002151323244626500233470ustar00rootroot00000000000000Error suppression ----- b['c'](); // array dereferencing a()['b']; ----- array( 0: Expr_FuncCall( name: Name( parts: array( 0: a ) comments: array( 0: // function name variations ) ) args: array( ) comments: array( 0: // function name variations ) ) 1: Expr_FuncCall( name: Expr_Variable( name: a ) args: array( ) ) 2: Expr_FuncCall( name: Expr_Variable( name: Scalar_String( value: a ) ) args: array( ) ) 3: Expr_FuncCall( name: Expr_Variable( name: Expr_Variable( name: a ) ) args: array( ) ) 4: Expr_FuncCall( name: Expr_Variable( name: Expr_Variable( name: Expr_Variable( name: a ) ) ) args: array( ) ) 5: Expr_FuncCall( name: Expr_ArrayDimFetch( var: Expr_Variable( name: a ) dim: Scalar_String( value: b ) ) args: array( ) ) 6: Expr_FuncCall( name: Expr_ArrayDimFetch( var: Expr_Variable( name: a ) dim: Scalar_String( value: b ) ) args: array( ) ) 7: Expr_FuncCall( name: Expr_ArrayDimFetch( var: Expr_PropertyFetch( var: Expr_Variable( name: a ) name: b ) dim: Scalar_String( value: c ) ) args: array( ) ) 8: Expr_ArrayDimFetch( var: Expr_FuncCall( name: Name( parts: array( 0: a ) comments: array( 0: // array dereferencing ) ) args: array( ) comments: array( 0: // array dereferencing ) ) dim: Scalar_String( value: b ) comments: array( 0: // array dereferencing ) ) )PHP-Parser-3.1.4/test/code/parser/expr/fetchAndCall/newDeref.test000066400000000000000000000024371323244626500245300ustar00rootroot00000000000000New expression dereferencing ----- b; (new A)->b(); (new A)['b']; (new A)['b']['c']; ----- array( 0: Expr_PropertyFetch( var: Expr_New( class: Name( parts: array( 0: A ) ) args: array( ) ) name: b ) 1: Expr_MethodCall( var: Expr_New( class: Name( parts: array( 0: A ) ) args: array( ) ) name: b args: array( ) ) 2: Expr_ArrayDimFetch( var: Expr_New( class: Name( parts: array( 0: A ) ) args: array( ) ) dim: Scalar_String( value: b ) ) 3: Expr_ArrayDimFetch( var: Expr_ArrayDimFetch( var: Expr_New( class: Name( parts: array( 0: A ) ) args: array( ) ) dim: Scalar_String( value: b ) ) dim: Scalar_String( value: c ) ) )PHP-Parser-3.1.4/test/code/parser/expr/fetchAndCall/objectAccess.test000066400000000000000000000054171323244626500253620ustar00rootroot00000000000000Object access ----- b; $a->b['c']; $a->b{'c'}; // method call variations $a->b(); $a->{'b'}(); $a->$b(); $a->$b['c'](); // array dereferencing $a->b()['c']; $a->b(){'c'}; // invalid PHP: drop Support? ----- !!php5 array( 0: Expr_PropertyFetch( var: Expr_Variable( name: a comments: array( 0: // property fetch variations ) ) name: b comments: array( 0: // property fetch variations ) ) 1: Expr_ArrayDimFetch( var: Expr_PropertyFetch( var: Expr_Variable( name: a ) name: b ) dim: Scalar_String( value: c ) ) 2: Expr_ArrayDimFetch( var: Expr_PropertyFetch( var: Expr_Variable( name: a ) name: b ) dim: Scalar_String( value: c ) ) 3: Expr_MethodCall( var: Expr_Variable( name: a comments: array( 0: // method call variations ) ) name: b args: array( ) comments: array( 0: // method call variations ) ) 4: Expr_MethodCall( var: Expr_Variable( name: a ) name: Scalar_String( value: b ) args: array( ) ) 5: Expr_MethodCall( var: Expr_Variable( name: a ) name: Expr_Variable( name: b ) args: array( ) ) 6: Expr_MethodCall( var: Expr_Variable( name: a ) name: Expr_ArrayDimFetch( var: Expr_Variable( name: b ) dim: Scalar_String( value: c ) ) args: array( ) ) 7: Expr_ArrayDimFetch( var: Expr_MethodCall( var: Expr_Variable( name: a comments: array( 0: // array dereferencing ) ) name: b args: array( ) comments: array( 0: // array dereferencing ) ) dim: Scalar_String( value: c ) comments: array( 0: // array dereferencing ) ) 8: Expr_ArrayDimFetch( var: Expr_MethodCall( var: Expr_Variable( name: a ) name: b args: array( ) ) dim: Scalar_String( value: c ) ) 9: Stmt_Nop( comments: array( 0: // invalid PHP: drop Support? ) ) )PHP-Parser-3.1.4/test/code/parser/expr/fetchAndCall/simpleArrayAccess.test000066400000000000000000000021131323244626500263720ustar00rootroot00000000000000Simple array access ----- $b) = ['a' => 'b']; list('a' => list($b => $c), 'd' => $e) = $x; ----- !!php7 array( 0: Expr_Assign( var: Expr_List( items: array( 0: Expr_ArrayItem( key: Scalar_String( value: a ) value: Expr_Variable( name: b ) byRef: false ) ) ) expr: Expr_Array( items: array( 0: Expr_ArrayItem( key: Scalar_String( value: a ) value: Scalar_String( value: b ) byRef: false ) ) ) ) 1: Expr_Assign( var: Expr_List( items: array( 0: Expr_ArrayItem( key: Scalar_String( value: a ) value: Expr_List( items: array( 0: Expr_ArrayItem( key: Expr_Variable( name: b ) value: Expr_Variable( name: c ) byRef: false ) ) ) byRef: false ) 1: Expr_ArrayItem( key: Scalar_String( value: d ) value: Expr_Variable( name: e ) byRef: false ) ) ) expr: Expr_Variable( name: x ) ) )PHP-Parser-3.1.4/test/code/parser/expr/logic.test000066400000000000000000000061611323244626500215540ustar00rootroot00000000000000Logical operators ----- > $b; $a ** $b; // associativity $a * $b * $c; $a * ($b * $c); // precedence $a + $b * $c; ($a + $b) * $c; // pow is special $a ** $b ** $c; ($a ** $b) ** $c; ----- array( 0: Expr_BitwiseNot( expr: Expr_Variable( name: a ) comments: array( 0: // unary ops ) ) 1: Expr_UnaryPlus( expr: Expr_Variable( name: a ) ) 2: Expr_UnaryMinus( expr: Expr_Variable( name: a ) ) 3: Expr_BinaryOp_BitwiseAnd( left: Expr_Variable( name: a comments: array( 0: // binary ops ) ) right: Expr_Variable( name: b ) comments: array( 0: // binary ops ) ) 4: Expr_BinaryOp_BitwiseOr( left: Expr_Variable( name: a ) right: Expr_Variable( name: b ) ) 5: Expr_BinaryOp_BitwiseXor( left: Expr_Variable( name: a ) right: Expr_Variable( name: b ) ) 6: Expr_BinaryOp_Concat( left: Expr_Variable( name: a ) right: Expr_Variable( name: b ) ) 7: Expr_BinaryOp_Div( left: Expr_Variable( name: a ) right: Expr_Variable( name: b ) ) 8: Expr_BinaryOp_Minus( left: Expr_Variable( name: a ) right: Expr_Variable( name: b ) ) 9: Expr_BinaryOp_Mod( left: Expr_Variable( name: a ) right: Expr_Variable( name: b ) ) 10: Expr_BinaryOp_Mul( left: Expr_Variable( name: a ) right: Expr_Variable( name: b ) ) 11: Expr_BinaryOp_Plus( left: Expr_Variable( name: a ) right: Expr_Variable( name: b ) ) 12: Expr_BinaryOp_ShiftLeft( left: Expr_Variable( name: a ) right: Expr_Variable( name: b ) ) 13: Expr_BinaryOp_ShiftRight( left: Expr_Variable( name: a ) right: Expr_Variable( name: b ) ) 14: Expr_BinaryOp_Pow( left: Expr_Variable( name: a ) right: Expr_Variable( name: b ) ) 15: Expr_BinaryOp_Mul( left: Expr_BinaryOp_Mul( left: Expr_Variable( name: a comments: array( 0: // associativity ) ) right: Expr_Variable( name: b ) comments: array( 0: // associativity ) ) right: Expr_Variable( name: c ) comments: array( 0: // associativity ) ) 16: Expr_BinaryOp_Mul( left: Expr_Variable( name: a ) right: Expr_BinaryOp_Mul( left: Expr_Variable( name: b ) right: Expr_Variable( name: c ) ) ) 17: Expr_BinaryOp_Plus( left: Expr_Variable( name: a comments: array( 0: // precedence ) ) right: Expr_BinaryOp_Mul( left: Expr_Variable( name: b ) right: Expr_Variable( name: c ) ) comments: array( 0: // precedence ) ) 18: Expr_BinaryOp_Mul( left: Expr_BinaryOp_Plus( left: Expr_Variable( name: a ) right: Expr_Variable( name: b ) ) right: Expr_Variable( name: c ) ) 19: Expr_BinaryOp_Pow( left: Expr_Variable( name: a comments: array( 0: // pow is special ) ) right: Expr_BinaryOp_Pow( left: Expr_Variable( name: b ) right: Expr_Variable( name: c ) ) comments: array( 0: // pow is special ) ) 20: Expr_BinaryOp_Pow( left: Expr_BinaryOp_Pow( left: Expr_Variable( name: a ) right: Expr_Variable( name: b ) ) right: Expr_Variable( name: c ) ) )PHP-Parser-3.1.4/test/code/parser/expr/new.test000066400000000000000000000052641323244626500212530ustar00rootroot00000000000000New ----- b(); new $a->b->c(); new $a->b['c'](); new $a->b{'c'}(); // test regression introduces by new dereferencing syntax (new A); ----- array( 0: Expr_New( class: Name( parts: array( 0: A ) ) args: array( ) ) 1: Expr_New( class: Name( parts: array( 0: A ) ) args: array( 0: Arg( value: Expr_Variable( name: b ) byRef: false unpack: false ) ) ) 2: Expr_New( class: Expr_Variable( name: a ) args: array( ) comments: array( 0: // class name variations ) ) 3: Expr_New( class: Expr_ArrayDimFetch( var: Expr_Variable( name: a ) dim: Scalar_String( value: b ) ) args: array( ) ) 4: Expr_New( class: Expr_StaticPropertyFetch( class: Name( parts: array( 0: A ) ) name: b ) args: array( ) ) 5: Expr_New( class: Expr_PropertyFetch( var: Expr_Variable( name: a ) name: b ) args: array( ) comments: array( 0: // DNCR object access ) ) 6: Expr_New( class: Expr_PropertyFetch( var: Expr_PropertyFetch( var: Expr_Variable( name: a ) name: b ) name: c ) args: array( ) ) 7: Expr_New( class: Expr_ArrayDimFetch( var: Expr_PropertyFetch( var: Expr_Variable( name: a ) name: b ) dim: Scalar_String( value: c ) ) args: array( ) ) 8: Expr_New( class: Expr_ArrayDimFetch( var: Expr_PropertyFetch( var: Expr_Variable( name: a ) name: b ) dim: Scalar_String( value: c ) ) args: array( ) ) 9: Expr_New( class: Name( parts: array( 0: A ) ) args: array( ) ) )PHP-Parser-3.1.4/test/code/parser/expr/newWithoutClass.test000066400000000000000000000004261323244626500236200ustar00rootroot00000000000000New without a class ----- bar; ----- !!php7 Syntax error, unexpected T_OBJECT_OPERATOR, expecting ';' from 2:13 to 2:14 array( 0: Stmt_Global( vars: array( 0: Expr_Variable( name: Expr_Variable( name: foo ) ) ) ) 1: Expr_ConstFetch( name: Name( parts: array( 0: bar ) ) ) )PHP-Parser-3.1.4/test/code/parser/expr/uvs/indirectCall.test000066400000000000000000000340671323244626500236770ustar00rootroot00000000000000UVS indirect calls ----- 'b']->a); isset("str"->a); ----- !!php7 array( 0: Expr_Isset( vars: array( 0: Expr_ArrayDimFetch( var: Expr_BinaryOp_Plus( left: Expr_Array( items: array( 0: Expr_ArrayItem( key: null value: Scalar_LNumber( value: 0 ) byRef: false ) 1: Expr_ArrayItem( key: null value: Scalar_LNumber( value: 1 ) byRef: false ) ) ) right: Expr_Array( items: array( ) ) ) dim: Scalar_LNumber( value: 0 ) ) ) ) 1: Expr_Isset( vars: array( 0: Expr_PropertyFetch( var: Expr_Array( items: array( 0: Expr_ArrayItem( key: Scalar_String( value: a ) value: Scalar_String( value: b ) byRef: false ) ) ) name: a ) ) ) 2: Expr_Isset( vars: array( 0: Expr_PropertyFetch( var: Scalar_String( value: str ) name: a ) ) ) ) PHP-Parser-3.1.4/test/code/parser/expr/uvs/misc.test000066400000000000000000000047171323244626500222340ustar00rootroot00000000000000Uniform variable syntax in PHP 7 (misc) ----- length(); (clone $obj)->b[0](1); [0, 1][0] = 1; ----- !!php7 array( 0: Expr_ArrayDimFetch( var: Expr_ClassConstFetch( class: Name( parts: array( 0: A ) ) name: A ) dim: Scalar_LNumber( value: 0 ) ) 1: Expr_ArrayDimFetch( var: Expr_ArrayDimFetch( var: Expr_ArrayDimFetch( var: Expr_ClassConstFetch( class: Name( parts: array( 0: A ) ) name: A ) dim: Scalar_LNumber( value: 0 ) ) dim: Scalar_LNumber( value: 1 ) ) dim: Scalar_LNumber( value: 2 ) ) 2: Expr_MethodCall( var: Scalar_String( value: string ) name: length args: array( ) ) 3: Expr_FuncCall( name: Expr_ArrayDimFetch( var: Expr_PropertyFetch( var: Expr_Clone( expr: Expr_Variable( name: obj ) ) name: b ) dim: Scalar_LNumber( value: 0 ) ) args: array( 0: Arg( value: Scalar_LNumber( value: 1 ) byRef: false unpack: false ) ) ) 4: Expr_Assign( var: Expr_ArrayDimFetch( var: Expr_Array( items: array( 0: Expr_ArrayItem( key: null value: Scalar_LNumber( value: 0 ) byRef: false ) 1: Expr_ArrayItem( key: null value: Scalar_LNumber( value: 1 ) byRef: false ) ) ) dim: Scalar_LNumber( value: 0 ) ) expr: Scalar_LNumber( value: 1 ) ) ) PHP-Parser-3.1.4/test/code/parser/expr/uvs/new.test000066400000000000000000000036541323244626500220710ustar00rootroot00000000000000UVS new expressions ----- className; new Test::$className; new $test::$className; new $weird[0]->foo::$className; ----- !!php7 array( 0: Expr_New( class: Expr_Variable( name: className ) args: array( ) ) 1: Expr_New( class: Expr_ArrayDimFetch( var: Expr_Variable( name: array ) dim: Scalar_String( value: className ) ) args: array( ) ) 2: Expr_New( class: Expr_ArrayDimFetch( var: Expr_Variable( name: array ) dim: Scalar_String( value: className ) ) args: array( ) ) 3: Expr_New( class: Expr_PropertyFetch( var: Expr_Variable( name: obj ) name: className ) args: array( ) ) 4: Expr_New( class: Expr_StaticPropertyFetch( class: Name( parts: array( 0: Test ) ) name: className ) args: array( ) ) 5: Expr_New( class: Expr_StaticPropertyFetch( class: Expr_Variable( name: test ) name: className ) args: array( ) ) 6: Expr_New( class: Expr_StaticPropertyFetch( class: Expr_PropertyFetch( var: Expr_ArrayDimFetch( var: Expr_Variable( name: weird ) dim: Scalar_LNumber( value: 0 ) ) name: foo ) name: className ) args: array( ) ) ) PHP-Parser-3.1.4/test/code/parser/expr/uvs/staticProperty.test000066400000000000000000000033311323244626500243240ustar00rootroot00000000000000UVS static access ----- c test EOS; b<<B"; "$A[B]"; "$A[0]"; "$A[1234]"; "$A[9223372036854775808]"; "$A[000]"; "$A[0x0]"; "$A[0b0]"; "$A[$B]"; "{$A}"; "{$A['B']}"; "${A}"; "${A['B']}"; "${$A}"; "\{$A}"; "\{ $A }"; "\\{$A}"; "\\{ $A }"; "{$$A}[B]"; "$$A[B]"; "A $B C"; b"$A"; B"$A"; ----- array( 0: Scalar_Encapsed( parts: array( 0: Expr_Variable( name: A ) ) ) 1: Scalar_Encapsed( parts: array( 0: Expr_PropertyFetch( var: Expr_Variable( name: A ) name: B ) ) ) 2: Scalar_Encapsed( parts: array( 0: Expr_ArrayDimFetch( var: Expr_Variable( name: A ) dim: Scalar_String( value: B ) ) ) ) 3: Scalar_Encapsed( parts: array( 0: Expr_ArrayDimFetch( var: Expr_Variable( name: A ) dim: Scalar_LNumber( value: 0 ) ) ) ) 4: Scalar_Encapsed( parts: array( 0: Expr_ArrayDimFetch( var: Expr_Variable( name: A ) dim: Scalar_LNumber( value: 1234 ) ) ) ) 5: Scalar_Encapsed( parts: array( 0: Expr_ArrayDimFetch( var: Expr_Variable( name: A ) dim: Scalar_String( value: 9223372036854775808 ) ) ) ) 6: Scalar_Encapsed( parts: array( 0: Expr_ArrayDimFetch( var: Expr_Variable( name: A ) dim: Scalar_String( value: 000 ) ) ) ) 7: Scalar_Encapsed( parts: array( 0: Expr_ArrayDimFetch( var: Expr_Variable( name: A ) dim: Scalar_String( value: 0x0 ) ) ) ) 8: Scalar_Encapsed( parts: array( 0: Expr_ArrayDimFetch( var: Expr_Variable( name: A ) dim: Scalar_String( value: 0b0 ) ) ) ) 9: Scalar_Encapsed( parts: array( 0: Expr_ArrayDimFetch( var: Expr_Variable( name: A ) dim: Expr_Variable( name: B ) ) ) ) 10: Scalar_Encapsed( parts: array( 0: Expr_Variable( name: A ) ) ) 11: Scalar_Encapsed( parts: array( 0: Expr_ArrayDimFetch( var: Expr_Variable( name: A ) dim: Scalar_String( value: B ) ) ) ) 12: Scalar_Encapsed( parts: array( 0: Expr_Variable( name: A ) ) ) 13: Scalar_Encapsed( parts: array( 0: Expr_ArrayDimFetch( var: Expr_Variable( name: A ) dim: Scalar_String( value: B ) ) ) ) 14: Scalar_Encapsed( parts: array( 0: Expr_Variable( name: Expr_Variable( name: A ) ) ) ) 15: Scalar_Encapsed( parts: array( 0: Scalar_EncapsedStringPart( value: \{ ) 1: Expr_Variable( name: A ) 2: Scalar_EncapsedStringPart( value: } ) ) ) 16: Scalar_Encapsed( parts: array( 0: Scalar_EncapsedStringPart( value: \{ ) 1: Expr_Variable( name: A ) 2: Scalar_EncapsedStringPart( value: } ) ) ) 17: Scalar_Encapsed( parts: array( 0: Scalar_EncapsedStringPart( value: \ ) 1: Expr_Variable( name: A ) ) ) 18: Scalar_Encapsed( parts: array( 0: Scalar_EncapsedStringPart( value: \{ ) 1: Expr_Variable( name: A ) 2: Scalar_EncapsedStringPart( value: } ) ) ) 19: Scalar_Encapsed( parts: array( 0: Expr_Variable( name: Expr_Variable( name: A ) ) 1: Scalar_EncapsedStringPart( value: [B] ) ) ) 20: Scalar_Encapsed( parts: array( 0: Scalar_EncapsedStringPart( value: $ ) 1: Expr_ArrayDimFetch( var: Expr_Variable( name: A ) dim: Scalar_String( value: B ) ) ) ) 21: Scalar_Encapsed( parts: array( 0: Scalar_EncapsedStringPart( value: A ) 1: Expr_Variable( name: B ) 2: Scalar_EncapsedStringPart( value: C ) ) ) 22: Scalar_Encapsed( parts: array( 0: Expr_Variable( name: A ) ) ) 23: Scalar_Encapsed( parts: array( 0: Expr_Variable( name: A ) ) ) )PHP-Parser-3.1.4/test/code/parser/scalar/float.test000066400000000000000000000025331323244626500220520ustar00rootroot00000000000000Different float syntaxes ----- float overflows // (all are actually the same number, just in different representations) 18446744073709551615; 0xFFFFFFFFFFFFFFFF; 01777777777777777777777; 0177777777777777777777787; 0b1111111111111111111111111111111111111111111111111111111111111111; ----- array( 0: Scalar_DNumber( value: 0 ) 1: Scalar_DNumber( value: 0 ) 2: Scalar_DNumber( value: 0 ) 3: Scalar_DNumber( value: 0 ) 4: Scalar_DNumber( value: 0 ) 5: Scalar_DNumber( value: 0 ) 6: Scalar_DNumber( value: 0 ) 7: Scalar_DNumber( value: 302000000000 ) 8: Scalar_DNumber( value: 3.002E+102 ) 9: Scalar_DNumber( value: INF ) 10: Scalar_DNumber( value: 1.844674407371E+19 comments: array( 0: // various integer -> float overflows 1: // (all are actually the same number, just in different representations) ) ) 11: Scalar_DNumber( value: 1.844674407371E+19 ) 12: Scalar_DNumber( value: 1.844674407371E+19 ) 13: Scalar_DNumber( value: 1.844674407371E+19 ) 14: Scalar_DNumber( value: 1.844674407371E+19 ) )PHP-Parser-3.1.4/test/code/parser/scalar/int.test000066400000000000000000000011551323244626500215360ustar00rootroot00000000000000Different integer syntaxes ----- array(); $t->public(); Test::list(); Test::protected(); $t->class; $t->private; Test::TRAIT; Test::FINAL; class Foo { use TraitA, TraitB { TraitA::catch insteadof namespace\TraitB; TraitA::list as foreach; TraitB::throw as protected public; TraitB::self as protected; exit as die; \TraitC::exit as bye; namespace\TraitC::exit as byebye; TraitA:: // /** doc comment */ # catch /* comment */ // comment # comment insteadof TraitB; } } ----- array( 0: Stmt_Class( flags: 0 name: Test extends: null implements: array( ) stmts: array( 0: Stmt_ClassMethod( flags: 0 byRef: false name: array params: array( ) returnType: null stmts: array( ) ) 1: Stmt_ClassMethod( flags: 0 byRef: false name: public params: array( ) returnType: null stmts: array( ) ) 2: Stmt_ClassMethod( flags: MODIFIER_STATIC (8) byRef: false name: list params: array( ) returnType: null stmts: array( ) ) 3: Stmt_ClassMethod( flags: MODIFIER_STATIC (8) byRef: false name: protected params: array( ) returnType: null stmts: array( ) ) 4: Stmt_Property( flags: MODIFIER_PUBLIC (1) props: array( 0: Stmt_PropertyProperty( name: class default: null ) ) ) 5: Stmt_Property( flags: MODIFIER_PUBLIC (1) props: array( 0: Stmt_PropertyProperty( name: private default: null ) ) ) 6: Stmt_ClassConst( flags: 0 consts: array( 0: Const( name: TRAIT value: Scalar_LNumber( value: 3 ) ) 1: Const( name: FINAL value: Scalar_LNumber( value: 4 ) ) ) ) 7: Stmt_ClassConst( flags: 0 consts: array( 0: Const( name: __CLASS__ value: Scalar_LNumber( value: 1 ) ) 1: Const( name: __TRAIT__ value: Scalar_LNumber( value: 2 ) ) 2: Const( name: __FUNCTION__ value: Scalar_LNumber( value: 3 ) ) 3: Const( name: __METHOD__ value: Scalar_LNumber( value: 4 ) ) 4: Const( name: __LINE__ value: Scalar_LNumber( value: 5 ) ) 5: Const( name: __FILE__ value: Scalar_LNumber( value: 6 ) ) 6: Const( name: __DIR__ value: Scalar_LNumber( value: 7 ) ) 7: Const( name: __NAMESPACE__ value: Scalar_LNumber( value: 8 ) ) ) ) ) ) 1: Expr_Assign( var: Expr_Variable( name: t ) expr: Expr_New( class: Name( parts: array( 0: Test ) ) args: array( ) ) ) 2: Expr_MethodCall( var: Expr_Variable( name: t ) name: array args: array( ) ) 3: Expr_MethodCall( var: Expr_Variable( name: t ) name: public args: array( ) ) 4: Expr_StaticCall( class: Name( parts: array( 0: Test ) ) name: list args: array( ) ) 5: Expr_StaticCall( class: Name( parts: array( 0: Test ) ) name: protected args: array( ) ) 6: Expr_PropertyFetch( var: Expr_Variable( name: t ) name: class ) 7: Expr_PropertyFetch( var: Expr_Variable( name: t ) name: private ) 8: Expr_ClassConstFetch( class: Name( parts: array( 0: Test ) ) name: TRAIT ) 9: Expr_ClassConstFetch( class: Name( parts: array( 0: Test ) ) name: FINAL ) 10: Stmt_Class( flags: 0 name: Foo extends: null implements: array( ) stmts: array( 0: Stmt_TraitUse( traits: array( 0: Name( parts: array( 0: TraitA ) ) 1: Name( parts: array( 0: TraitB ) ) ) adaptations: array( 0: Stmt_TraitUseAdaptation_Precedence( trait: Name( parts: array( 0: TraitA ) ) method: catch insteadof: array( 0: Name_Relative( parts: array( 0: TraitB ) ) ) ) 1: Stmt_TraitUseAdaptation_Alias( trait: Name( parts: array( 0: TraitA ) ) method: list newModifier: null newName: foreach ) 2: Stmt_TraitUseAdaptation_Alias( trait: Name( parts: array( 0: TraitB ) ) method: throw newModifier: MODIFIER_PROTECTED (2) newName: public ) 3: Stmt_TraitUseAdaptation_Alias( trait: Name( parts: array( 0: TraitB ) ) method: self newModifier: MODIFIER_PROTECTED (2) newName: null ) 4: Stmt_TraitUseAdaptation_Alias( trait: null method: exit newModifier: null newName: die ) 5: Stmt_TraitUseAdaptation_Alias( trait: Name_FullyQualified( parts: array( 0: TraitC ) ) method: exit newModifier: null newName: bye ) 6: Stmt_TraitUseAdaptation_Alias( trait: Name_Relative( parts: array( 0: TraitC ) ) method: exit newModifier: null newName: byebye ) 7: Stmt_TraitUseAdaptation_Precedence( trait: Name( parts: array( 0: TraitA ) ) method: catch insteadof: array( 0: Name( parts: array( 0: TraitB ) ) ) ) ) ) ) ) )PHP-Parser-3.1.4/test/code/parser/stmt/000077500000000000000000000000001323244626500175635ustar00rootroot00000000000000PHP-Parser-3.1.4/test/code/parser/stmt/blocklessStatement.test000066400000000000000000000037541323244626500243430ustar00rootroot00000000000000Blockless statements for if/for/etc ----- 'baz'] ) {} ----- array( 0: Stmt_Function( byRef: false name: a params: array( 0: Param( type: null byRef: false variadic: false name: b default: Expr_ConstFetch( name: Name( parts: array( 0: null ) ) ) ) 1: Param( type: null byRef: false variadic: false name: c default: Scalar_String( value: foo ) ) 2: Param( type: null byRef: false variadic: false name: d default: Expr_ClassConstFetch( class: Name( parts: array( 0: A ) ) name: B ) ) 3: Param( type: null byRef: false variadic: false name: f default: Expr_UnaryPlus( expr: Scalar_LNumber( value: 1 ) ) ) 4: Param( type: null byRef: false variadic: false name: g default: Expr_UnaryMinus( expr: Scalar_DNumber( value: 1 ) ) ) 5: Param( type: null byRef: false variadic: false name: h default: Expr_Array( items: array( ) ) ) 6: Param( type: null byRef: false variadic: false name: i default: Expr_Array( items: array( ) ) ) 7: Param( type: null byRef: false variadic: false name: j default: Expr_Array( items: array( 0: Expr_ArrayItem( key: null value: Scalar_String( value: foo ) byRef: false ) ) ) ) 8: Param( type: null byRef: false variadic: false name: k default: Expr_Array( items: array( 0: Expr_ArrayItem( key: null value: Scalar_String( value: foo ) byRef: false ) 1: Expr_ArrayItem( key: Scalar_String( value: bar ) value: Scalar_String( value: baz ) byRef: false ) ) ) ) ) returnType: null stmts: array( ) ) ) PHP-Parser-3.1.4/test/code/parser/stmt/function/nullableTypes.test000066400000000000000000000017351323244626500251420ustar00rootroot00000000000000Nullable types ----- $value; // expressions $data = yield; $data = (yield $value); $data = (yield $key => $value); // yield in language constructs with their own parentheses if (yield $foo); elseif (yield $foo); if (yield $foo): elseif (yield $foo): endif; while (yield $foo); do {} while (yield $foo); switch (yield $foo) {} die(yield $foo); // yield in function calls func(yield $foo); $foo->func(yield $foo); new Foo(yield $foo); yield from $foo; yield from $foo and yield from $bar; yield from $foo + $bar; } ----- array( 0: Stmt_Function( byRef: false name: gen params: array( ) returnType: null stmts: array( 0: Expr_Yield( key: null value: null comments: array( 0: // statements ) ) 1: Expr_Yield( key: null value: Expr_Variable( name: value ) ) 2: Expr_Yield( key: Expr_Variable( name: key ) value: Expr_Variable( name: value ) ) 3: Expr_Assign( var: Expr_Variable( name: data comments: array( 0: // expressions ) ) expr: Expr_Yield( key: null value: null ) comments: array( 0: // expressions ) ) 4: Expr_Assign( var: Expr_Variable( name: data ) expr: Expr_Yield( key: null value: Expr_Variable( name: value ) ) ) 5: Expr_Assign( var: Expr_Variable( name: data ) expr: Expr_Yield( key: Expr_Variable( name: key ) value: Expr_Variable( name: value ) ) ) 6: Stmt_If( cond: Expr_Yield( key: null value: Expr_Variable( name: foo ) ) stmts: array( ) elseifs: array( 0: Stmt_ElseIf( cond: Expr_Yield( key: null value: Expr_Variable( name: foo ) ) stmts: array( ) ) ) else: null comments: array( 0: // yield in language constructs with their own parentheses ) ) 7: Stmt_If( cond: Expr_Yield( key: null value: Expr_Variable( name: foo ) ) stmts: array( ) elseifs: array( 0: Stmt_ElseIf( cond: Expr_Yield( key: null value: Expr_Variable( name: foo ) ) stmts: array( ) ) ) else: null ) 8: Stmt_While( cond: Expr_Yield( key: null value: Expr_Variable( name: foo ) ) stmts: array( ) ) 9: Stmt_Do( cond: Expr_Yield( key: null value: Expr_Variable( name: foo ) ) stmts: array( ) ) 10: Stmt_Switch( cond: Expr_Yield( key: null value: Expr_Variable( name: foo ) ) cases: array( ) ) 11: Expr_Exit( expr: Expr_Yield( key: null value: Expr_Variable( name: foo ) ) ) 12: Expr_FuncCall( name: Name( parts: array( 0: func ) comments: array( 0: // yield in function calls ) ) args: array( 0: Arg( value: Expr_Yield( key: null value: Expr_Variable( name: foo ) ) byRef: false unpack: false ) ) comments: array( 0: // yield in function calls ) ) 13: Expr_MethodCall( var: Expr_Variable( name: foo ) name: func args: array( 0: Arg( value: Expr_Yield( key: null value: Expr_Variable( name: foo ) ) byRef: false unpack: false ) ) ) 14: Expr_New( class: Name( parts: array( 0: Foo ) ) args: array( 0: Arg( value: Expr_Yield( key: null value: Expr_Variable( name: foo ) ) byRef: false unpack: false ) ) ) 15: Expr_YieldFrom( expr: Expr_Variable( name: foo ) ) 16: Expr_BinaryOp_LogicalAnd( left: Expr_YieldFrom( expr: Expr_Variable( name: foo ) ) right: Expr_YieldFrom( expr: Expr_Variable( name: bar ) ) ) 17: Expr_YieldFrom( expr: Expr_BinaryOp_Plus( left: Expr_Variable( name: foo ) right: Expr_Variable( name: bar ) ) ) ) ) )PHP-Parser-3.1.4/test/code/parser/stmt/generator/yieldPrecedence.test000066400000000000000000000175041323244626500255450ustar00rootroot00000000000000Yield operator precedence ----- "a" . "b"; yield "k" => "a" or die; var_dump([yield "k" => "a" . "b"]); yield yield "k1" => yield "k2" => "a" . "b"; yield yield "k1" => (yield "k2") => "a" . "b"; var_dump([yield "k1" => yield "k2" => "a" . "b"]); var_dump([yield "k1" => (yield "k2") => "a" . "b"]); } ----- !!php7 array( 0: Stmt_Function( byRef: false name: gen params: array( ) returnType: null stmts: array( 0: Expr_Yield( key: null value: Expr_BinaryOp_Concat( left: Scalar_String( value: a ) right: Scalar_String( value: b ) ) ) 1: Expr_BinaryOp_LogicalOr( left: Expr_Yield( key: null value: Scalar_String( value: a ) ) right: Expr_Exit( expr: null ) ) 2: Expr_Yield( key: Scalar_String( value: k ) value: Expr_BinaryOp_Concat( left: Scalar_String( value: a ) right: Scalar_String( value: b ) ) ) 3: Expr_BinaryOp_LogicalOr( left: Expr_Yield( key: Scalar_String( value: k ) value: Scalar_String( value: a ) ) right: Expr_Exit( expr: null ) ) 4: Expr_FuncCall( name: Name( parts: array( 0: var_dump ) ) args: array( 0: Arg( value: Expr_Array( items: array( 0: Expr_ArrayItem( key: null value: Expr_Yield( key: Scalar_String( value: k ) value: Expr_BinaryOp_Concat( left: Scalar_String( value: a ) right: Scalar_String( value: b ) ) ) byRef: false ) ) ) byRef: false unpack: false ) ) ) 5: Expr_Yield( key: null value: Expr_Yield( key: Scalar_String( value: k1 ) value: Expr_Yield( key: Scalar_String( value: k2 ) value: Expr_BinaryOp_Concat( left: Scalar_String( value: a ) right: Scalar_String( value: b ) ) ) ) ) 6: Expr_Yield( key: Expr_Yield( key: Scalar_String( value: k1 ) value: Expr_Yield( key: null value: Scalar_String( value: k2 ) ) ) value: Expr_BinaryOp_Concat( left: Scalar_String( value: a ) right: Scalar_String( value: b ) ) ) 7: Expr_FuncCall( name: Name( parts: array( 0: var_dump ) ) args: array( 0: Arg( value: Expr_Array( items: array( 0: Expr_ArrayItem( key: null value: Expr_Yield( key: Scalar_String( value: k1 ) value: Expr_Yield( key: Scalar_String( value: k2 ) value: Expr_BinaryOp_Concat( left: Scalar_String( value: a ) right: Scalar_String( value: b ) ) ) ) byRef: false ) ) ) byRef: false unpack: false ) ) ) 8: Expr_FuncCall( name: Name( parts: array( 0: var_dump ) ) args: array( 0: Arg( value: Expr_Array( items: array( 0: Expr_ArrayItem( key: Expr_Yield( key: Scalar_String( value: k1 ) value: Expr_Yield( key: null value: Scalar_String( value: k2 ) ) ) value: Expr_BinaryOp_Concat( left: Scalar_String( value: a ) right: Scalar_String( value: b ) ) byRef: false ) ) ) byRef: false unpack: false ) ) ) ) ) ) PHP-Parser-3.1.4/test/code/parser/stmt/generator/yieldUnaryPrecedence.test000066400000000000000000000020231323244626500265520ustar00rootroot00000000000000Yield with unary operator argument ----- Hallo World! ----- array( 0: Expr_Variable( name: a ) 1: Stmt_HaltCompiler( remaining: Hallo World! ) ) ----- #!/usr/bin/env php ----- array( 0: Stmt_InlineHTML( value: #!/usr/bin/env php ) 1: Stmt_Echo( exprs: array( 0: Scalar_String( value: foobar ) ) ) 2: Stmt_InlineHTML( value: #!/usr/bin/env php ) ) PHP-Parser-3.1.4/test/code/parser/stmt/if.test000066400000000000000000000034761323244626500210740ustar00rootroot00000000000000If/Elseif/Else ----- B $c) {} foreach ($a as $b => &$c) {} foreach ($a as list($a, $b)) {} foreach ($a as $a => list($b, , $c)) {} // foreach on expression foreach (array() as $b) {} // alternative syntax foreach ($a as $b): endforeach; ----- array( 0: Stmt_Foreach( expr: Expr_Variable( name: a ) keyVar: null byRef: false valueVar: Expr_Variable( name: b ) stmts: array( ) comments: array( 0: // foreach on variable ) ) 1: Stmt_Foreach( expr: Expr_Variable( name: a ) keyVar: null byRef: true valueVar: Expr_Variable( name: b ) stmts: array( ) ) 2: Stmt_Foreach( expr: Expr_Variable( name: a ) keyVar: Expr_Variable( name: b ) byRef: false valueVar: Expr_Variable( name: c ) stmts: array( ) ) 3: Stmt_Foreach( expr: Expr_Variable( name: a ) keyVar: Expr_Variable( name: b ) byRef: true valueVar: Expr_Variable( name: c ) stmts: array( ) ) 4: Stmt_Foreach( expr: Expr_Variable( name: a ) keyVar: null byRef: false valueVar: Expr_List( items: array( 0: Expr_ArrayItem( key: null value: Expr_Variable( name: a ) byRef: false ) 1: Expr_ArrayItem( key: null value: Expr_Variable( name: b ) byRef: false ) ) ) stmts: array( ) ) 5: Stmt_Foreach( expr: Expr_Variable( name: a ) keyVar: Expr_Variable( name: a ) byRef: false valueVar: Expr_List( items: array( 0: Expr_ArrayItem( key: null value: Expr_Variable( name: b ) byRef: false ) 1: null 2: Expr_ArrayItem( key: null value: Expr_Variable( name: c ) byRef: false ) ) ) stmts: array( ) ) 6: Stmt_Foreach( expr: Expr_Array( items: array( ) ) keyVar: null byRef: false valueVar: Expr_Variable( name: b ) stmts: array( ) comments: array( 0: // foreach on expression ) ) 7: Stmt_Foreach( expr: Expr_Variable( name: a ) keyVar: null byRef: false valueVar: Expr_Variable( name: b ) stmts: array( ) comments: array( 0: // alternative syntax ) ) )PHP-Parser-3.1.4/test/code/parser/stmt/loop/while.test000066400000000000000000000004631323244626500225500ustar00rootroot00000000000000While loop ----- Hi! ----- array( 0: Stmt_Declare( declares: array( 0: Stmt_DeclareDeclare( key: A value: Scalar_String( value: B ) ) ) stmts: null ) 1: Stmt_Namespace( name: Name( parts: array( 0: B ) ) stmts: array( ) ) 2: Stmt_HaltCompiler( remaining: Hi! ) ) ----- a = $a; } }; ----- new class { }; new class extends A implements B, C { }; new class($a) extends A { private $a; public function __construct($a) { $this->a = $a; } }; PHP-Parser-3.1.4/test/code/prettyPrinter/expr/arrayDestructuring.test000066400000000000000000000003661323244626500257600ustar00rootroot00000000000000Array destructuring ----- $b, 'b' => $a] = $baz; ----- !!php7 [$a, $b] = [$c, $d]; [, $a, , , $b, ] = $foo; [, [[$a]], $b] = $bar; ['a' => $b, 'b' => $a] = $baz;PHP-Parser-3.1.4/test/code/prettyPrinter/expr/call.test000066400000000000000000000001601323244626500227620ustar00rootroot00000000000000Calls ----- d} STR; call( <<d} STR; call(<<> $b; $a < $b; $a <= $b; $a > $b; $a >= $b; $a == $b; $a != $b; $a <> $b; $a === $b; $a !== $b; $a <=> $b; $a & $b; $a ^ $b; $a | $b; $a && $b; $a || $b; $a ? $b : $c; $a ?: $c; $a ?? $c; $a = $b; $a **= $b; $a *= $b; $a /= $b; $a %= $b; $a += $b; $a -= $b; $a .= $b; $a <<= $b; $a >>= $b; $a &= $b; $a ^= $b; $a |= $b; $a =& $b; $a and $b; $a xor $b; $a or $b; $a instanceof Foo; $a instanceof $b; ----- $a ** $b; ++$a; --$a; $a++; $a--; @$a; ~$a; -$a; +$a; (int) $a; (int) $a; (double) $a; (double) $a; (double) $a; (string) $a; (string) $a; (array) $a; (object) $a; (bool) $a; (bool) $a; (unset) $a; $a * $b; $a / $b; $a % $b; $a + $b; $a - $b; $a . $b; $a << $b; $a >> $b; $a < $b; $a <= $b; $a > $b; $a >= $b; $a == $b; $a != $b; $a != $b; $a === $b; $a !== $b; $a <=> $b; $a & $b; $a ^ $b; $a | $b; $a && $b; $a || $b; $a ? $b : $c; $a ?: $c; $a ?? $c; $a = $b; $a **= $b; $a *= $b; $a /= $b; $a %= $b; $a += $b; $a -= $b; $a .= $b; $a <<= $b; $a >>= $b; $a &= $b; $a ^= $b; $a |= $b; $a =& $b; $a and $b; $a xor $b; $a or $b; $a instanceof Foo; $a instanceof $b; PHP-Parser-3.1.4/test/code/prettyPrinter/expr/parentheses.test000066400000000000000000000034721323244626500244010ustar00rootroot00000000000000Pretty printer generates least-parentheses output ----- 0) > (1 < 0); ++$a + $b; $a + $b++; $a ** $b ** $c; ($a ** $b) ** $c; -1 ** 2; yield from $a and yield from $b; yield from ($a and yield from $b); print ($a and print $b); -(-$a); +(+$a); -(--$a); +(++$a); // The following will currently add unnecessary parentheses, because the pretty printer is not aware that assignment // and incdec only work on variables. !$a = $b; ++$a ** $b; $a ** $b++; ----- echo 'abc' . 'cde' . 'fgh'; echo 'abc' . ('cde' . 'fgh'); echo 'abc' . 1 + 2 . 'fgh'; echo 'abc' . (1 + 2) . 'fgh'; echo 1 * 2 + 3 / 4 % 5 . 6; echo 1 * (2 + 3) / (4 % (5 . 6)); $a = $b = $c = $d = $f && true; ($a = $b = $c = $d = $f) && true; $a = $b = $c = $d = $f and true; $a = $b = $c = $d = ($f and true); $a ? $b : $c ? $d : $e ? $f : $g; $a ? $b : ($c ? $d : ($e ? $f : $g)); $a ? $b ? $c : $d : $f; $a ?? $b ?? $c; ($a ?? $b) ?? $c; $a ?? ($b ? $c : $d); $a || ($b ?? $c); (1 > 0) > (1 < 0); ++$a + $b; $a + $b++; $a ** $b ** $c; ($a ** $b) ** $c; -1 ** 2; yield from $a and yield from $b; yield from ($a and yield from $b); print ($a and print $b); -(-$a); +(+$a); -(--$a); +(++$a); // The following will currently add unnecessary parentheses, because the pretty printer is not aware that assignment // and incdec only work on variables. !($a = $b); (++$a) ** $b; $a ** ($b++); PHP-Parser-3.1.4/test/code/prettyPrinter/expr/shortArraySyntax.test000066400000000000000000000002011323244626500254100ustar00rootroot00000000000000Short array syntax ----- 'b', 'c' => 'd']; ----- []; array(1, 2, 3); ['a' => 'b', 'c' => 'd'];PHP-Parser-3.1.4/test/code/prettyPrinter/expr/stringEscaping.test000066400000000000000000000007471323244626500250420ustar00rootroot00000000000000Escape sequences in double-quoted strings ----- b)(); (A::$b)(); ----- !!php7 (function () { })(); array('a', 'b')()(); A::$b::$c; $A::$b[$c](); $A::{$b[$c]}(); A::${$b}[$c](); ($a->b)(); (A::$b)(); PHP-Parser-3.1.4/test/code/prettyPrinter/expr/variables.test000066400000000000000000000014551323244626500240270ustar00rootroot00000000000000Variables ----- b; $a->b(); $a->b($c); $a->$b(); $a->{$b}(); $a->$b[$c](); $$a->b; $a[$b]; $a[$b](); $$a[$b]; $a::B; $a::$b; $a::b(); $a::b($c); $a::$b(); $a::$b[$c]; $a::$b[$c]($d); $a::{$b[$c]}($d); $a::{$b->c}(); A::$$b[$c](); a(); $a(); $a()[$b]; $a->b()[$c]; $a::$b()[$c]; (new A)->b; (new A())->b(); (new $$a)[$b]; (new $a->b)->c; global $a, $$a, $$a[$b], $$a->b; ----- !!php5 $a; ${$a}; ${$a}; $a->b; $a->b(); $a->b($c); $a->{$b}(); $a->{$b}(); $a->{$b[$c]}(); ${$a}->b; $a[$b]; $a[$b](); ${$a[$b]}; $a::B; $a::$b; $a::b(); $a::b($c); $a::$b(); $a::$b[$c]; $a::{$b[$c]}($d); $a::{$b[$c]}($d); $a::{$b->c}(); A::${$b[$c]}(); a(); $a(); $a()[$b]; $a->b()[$c]; $a::$b()[$c]; (new A())->b; (new A())->b(); (new ${$a}())[$b]; (new $a->b())->c; global $a, ${$a}, ${$a[$b]}, ${$a->b}; PHP-Parser-3.1.4/test/code/prettyPrinter/expr/yield.test000066400000000000000000000012701323244626500231600ustar00rootroot00000000000000Yield ----- $b; $a = yield; $a = (yield $b); $a = (yield $b => $c); } // TODO Get rid of parens for cases 2 and 3 ----- function gen() { yield; (yield $a); (yield $a => $b); $a = yield; $a = (yield $b); $a = (yield $b => $c); } // TODO Get rid of parens for cases 2 and 3 ----- $c; yield from $a; $a = yield from $b; } // TODO Get rid of parens for last case ----- !!php7 function gen() { $a = (yield $b); $a = (yield $b => $c); yield from $a; $a = (yield from $b); } // TODO Get rid of parens for last casePHP-Parser-3.1.4/test/code/prettyPrinter/inlineHTMLandPHPtest.file-test000066400000000000000000000006611323244626500257120ustar00rootroot00000000000000File containing both inline HTML and PHP ----- HTML HTML ----- HTML ----- HTML HTML ----- HTML HTML ----- HTML HTML HTML ----- HTML HTML HTML ----- HTMLHTML ----- HTMLHTMLPHP-Parser-3.1.4/test/code/prettyPrinter/onlyInlineHTML.file-test000066400000000000000000000002261323244626500246160ustar00rootroot00000000000000File containing only inline HTML ----- Hallo World Foo Bar Bar Foo World Hallo ----- Hallo World Foo Bar Bar Foo World Hallo ----- Test ----- TestPHP-Parser-3.1.4/test/code/prettyPrinter/onlyPHP.file-test000066400000000000000000000002141323244626500233370ustar00rootroot00000000000000File containing only PHP ----- a = 'bar'; echo 'test'; } protected function baz() {} public function foo() {} abstract static function bar() {} } trait Bar { function test() { } } ----- class Foo extends Bar implements ABC, \DEF, namespace\GHI { var $a = 'foo'; private $b = 'bar'; static $c = 'baz'; function test() { $this->a = 'bar'; echo 'test'; } protected function baz() { } public function foo() { } static abstract function bar() { } } trait Bar { function test() { } }PHP-Parser-3.1.4/test/code/prettyPrinter/stmt/class_const.test000066400000000000000000000004671323244626500244050ustar00rootroot00000000000000Class constants ----- $val) { } foreach ($arr as $key => &$val) { } ----- foreach ($arr as $val) { } foreach ($arr as &$val) { } foreach ($arr as $key => $val) { } foreach ($arr as $key => &$val) { }PHP-Parser-3.1.4/test/code/prettyPrinter/stmt/function_signatures.test000066400000000000000000000016031323244626500261540ustar00rootroot00000000000000Function signatures ----- parse($code); $parseTime += microtime(true) - $startTime; $startTime = microtime(true); $code = 'prettyPrint($stmts); $ppTime += microtime(true) - $startTime; try { $startTime = microtime(true); $ppStmts = $parser->parse($code); $reparseTime += microtime(true) - $startTime; $startTime = microtime(true); $same = $nodeDumper->dump($stmts) == $nodeDumper->dump($ppStmts); $compareTime += microtime(true) - $startTime; if (!$same) { echo $file, ":\n Result of initial parse and parse after pretty print differ\n"; if ($verbose) { echo "Pretty printer output:\n=====\n$code\n=====\n\n"; } ++$compareFail; } } catch (PhpParser\Error $e) { echo $file, ":\n Parse of pretty print failed with message: {$e->getMessage()}\n"; if ($verbose) { echo "Pretty printer output:\n=====\n$code\n=====\n\n"; } ++$ppFail; } } catch (PhpParser\Error $e) { echo $file, ":\n Parse failed with message: {$e->getMessage()}\n"; ++$parseFail; } } if (0 === $parseFail && 0 === $ppFail && 0 === $compareFail) { $exit = 0; echo "\n\n", 'All tests passed.', "\n"; } else { $exit = 1; echo "\n\n", '==========', "\n\n", 'There were: ', "\n"; if (0 !== $parseFail) { echo ' ', $parseFail, ' parse failures.', "\n"; } if (0 !== $ppFail) { echo ' ', $ppFail, ' pretty print failures.', "\n"; } if (0 !== $compareFail) { echo ' ', $compareFail, ' compare failures.', "\n"; } } echo "\n", 'Tested files: ', $count, "\n", "\n", 'Reading files took: ', $readTime, "\n", 'Parsing took: ', $parseTime, "\n", 'Pretty printing took: ', $ppTime, "\n", 'Reparsing took: ', $reparseTime, "\n", 'Comparing took: ', $compareTime, "\n", "\n", 'Total time: ', microtime(true) - $totalStartTime, "\n", 'Maximum memory usage: ', memory_get_peak_usage(true), "\n"; exit($exit);