mirror of
https://github.com/nikic/PHP-Parser.git
synced 2025-07-14 19:06:36 +02:00
Compare commits
2 Commits
Author | SHA1 | Date | |
---|---|---|---|
c4bbc8e236 | |||
f78af2c9c8 |
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,4 +0,0 @@
|
|||||||
vendor/
|
|
||||||
composer.lock
|
|
||||||
grammar/kmyacc.exe
|
|
||||||
grammar/y.output
|
|
10
.travis.yml
10
.travis.yml
@ -1,20 +1,14 @@
|
|||||||
language: php
|
language: php
|
||||||
|
|
||||||
sudo: false
|
|
||||||
|
|
||||||
php:
|
php:
|
||||||
|
- 5.3
|
||||||
- 5.4
|
- 5.4
|
||||||
- 5.5
|
- 5.5
|
||||||
- 5.6
|
- 5.6
|
||||||
- 7.0
|
- 7.0
|
||||||
- nightly
|
|
||||||
- hhvm
|
- hhvm
|
||||||
|
|
||||||
install: composer install --prefer-source
|
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
allow_failures:
|
allow_failures:
|
||||||
- php: nightly
|
- php: 7.0
|
||||||
fast_finish: true
|
fast_finish: true
|
||||||
|
|
||||||
script: vendor/bin/phpunit
|
|
70
CHANGELOG.md
70
CHANGELOG.md
@ -1,77 +1,16 @@
|
|||||||
Version 2.0.1-dev
|
Version 1.4.2-dev
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
Nothing yet.
|
Nothing yet.
|
||||||
|
|
||||||
Version 2.0.0 (2015-12-04)
|
Version 1.4.1 (2015-09-19)
|
||||||
--------------------------
|
--------------------------
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
* String parts of encapsed strings are now represented using `Scalar\EncapsStringPart` nodes.
|
|
||||||
Previously raw strings were used. This affects the `parts` child of `Scalar\Encaps` and
|
|
||||||
`Expr\ShellExec`. The change has been done to allow assignment of attributes to encapsed string
|
|
||||||
parts.
|
|
||||||
|
|
||||||
Version 2.0.0-beta1 (2015-10-21)
|
|
||||||
--------------------------------
|
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
* Fixed issue with too many newlines being stripped at the end of heredoc/nowdoc strings in some
|
* Fixed issue with too many newlines being stripped at the end of heredoc/nowdoc strings in some
|
||||||
cases. (#227)
|
cases. (#227)
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
* Update group use support to be in line with recent PHP 7.0 builds.
|
|
||||||
* Renamed `php-parse.php` to `php-parse` and registered it as a composer bin.
|
|
||||||
* Use composer PSR-4 autoloader instead of custom autoloader.
|
|
||||||
* Specify phpunit as a dev dependency.
|
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
* Added `shortArraySyntax` option to pretty printer, to print all arrays using short syntax.
|
|
||||||
|
|
||||||
Version 2.0.0-alpha1 (2015-07-14)
|
|
||||||
---------------------------------
|
|
||||||
|
|
||||||
A more detailed description of backwards incompatible changes can be found in the
|
|
||||||
[upgrading guide](UPGRADE-2.0.md).
|
|
||||||
|
|
||||||
### Removed
|
|
||||||
|
|
||||||
* Removed support for running on PHP 5.4. It is however still possible to parse PHP 5.2 and PHP 5.3
|
|
||||||
code while running on a newer version.
|
|
||||||
* Removed legacy class name aliases. This includes the old non-namespaced class names and the old
|
|
||||||
names for classes that were renamed for PHP 7 compatibility.
|
|
||||||
* Removed support for legacy node format. All nodes must have a `getSubNodeNames()` method now.
|
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
* Added support for remaining PHP 7 features that were not present in 1.x:
|
|
||||||
* Group use declarations. These are represented using `Stmt\GroupUse` nodes. Furthermore a `type`
|
|
||||||
attribute was added to `Stmt\UseUse` to handle mixed group use declarations.
|
|
||||||
* Uniform variable syntax.
|
|
||||||
* Generalized yield operator.
|
|
||||||
* Scalar type declarations. These are presented using `'bool'`, `'int'`, `'float'` and `'string'`
|
|
||||||
as the type. The PHP 5 parser also accepts these, however they'll be `Name` instances there.
|
|
||||||
* Unicode escape sequences.
|
|
||||||
* Added `PhpParser\ParserFactory` class, which should be used to create parser instances.
|
|
||||||
* Added `Name::concat()` which concatenates two names.
|
|
||||||
* Added `Name->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)`.
|
|
||||||
|
|
||||||
Version 1.4.0 (2015-07-14)
|
Version 1.4.0 (2015-07-14)
|
||||||
--------------------------
|
--------------------------
|
||||||
|
|
||||||
@ -309,5 +248,6 @@ Version 1.0.0-beta1 (2014-03-27)
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
**This changelog only includes changes from the 1.0 and 2.0 series. For older changes see the
|
**This changelog only includes changes from the 1.0 series. For older changes see the [0.9 series changelog][1].**
|
||||||
[0.9 series changelog][https://github.com/nikic/PHP-Parser/blob/0.9/CHANGELOG.md].**
|
|
||||||
|
[1]: https://github.com/nikic/PHP-Parser/blob/0.9/CHANGELOG.md
|
||||||
|
26
README.md
26
README.md
@ -1,13 +1,12 @@
|
|||||||
PHP Parser
|
PHP Parser
|
||||||
==========
|
==========
|
||||||
|
|
||||||
This is a PHP 5.2 to PHP 7.0 parser written in PHP. Its purpose is to simplify static code analysis and
|
This is a PHP 5.2 to PHP 5.6 parser written in PHP. Its purpose is to simplify static code analysis and
|
||||||
manipulation.
|
manipulation.
|
||||||
|
|
||||||
|
[**Documentation for version 1.x**][doc_1_x] (stable; for running on PHP >= 5.3).
|
||||||
|
|
||||||
[**Documentation for version 2.x**][doc_master] (stable; for running on PHP >= 5.4; for parsing PHP 5.2 to PHP 7.0).
|
[Documentation for version 0.9.x][doc_0_9] (unsupported; for running on PHP 5.2).
|
||||||
|
|
||||||
[Documentation for version 1.x][doc_1_x] (stable; for running on PHP >= 5.3; for parsing PHP 5.2 to PHP 5.6).
|
|
||||||
|
|
||||||
In a Nutshell
|
In a Nutshell
|
||||||
-------------
|
-------------
|
||||||
@ -71,25 +70,18 @@ programming errors or security issues).
|
|||||||
Additionally, you can convert a syntax tree back to PHP code. This allows you to do code preprocessing
|
Additionally, you can convert a syntax tree back to PHP code. This allows you to do code preprocessing
|
||||||
(like automatedly porting code to older PHP versions).
|
(like automatedly porting code to older PHP versions).
|
||||||
|
|
||||||
Installation
|
|
||||||
------------
|
|
||||||
|
|
||||||
The preferred installation method is [composer](https://getcomposer.org):
|
|
||||||
|
|
||||||
php composer.phar require nikic/php-parser
|
|
||||||
|
|
||||||
Documentation
|
Documentation
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
1. [Introduction](doc/0_Introduction.markdown)
|
1. [Introduction](doc/0_Introduction.markdown)
|
||||||
2. [Usage of basic components](doc/2_Usage_of_basic_components.markdown)
|
2. [Installation](doc/1_Installation.markdown)
|
||||||
3. [Other node tree representations](doc/3_Other_node_tree_representations.markdown)
|
3. [Usage of basic components](doc/2_Usage_of_basic_components.markdown)
|
||||||
4. [Code generation](doc/4_Code_generation.markdown)
|
4. [Other node tree representations](doc/3_Other_node_tree_representations.markdown)
|
||||||
|
5. [Code generation](doc/4_Code_generation.markdown)
|
||||||
|
|
||||||
Component documentation:
|
Component documentation:
|
||||||
|
|
||||||
1. [Error](doc/component/Error.markdown)
|
1. [Lexer](doc/component/Lexer.markdown)
|
||||||
2. [Lexer](doc/component/Lexer.markdown)
|
|
||||||
|
|
||||||
|
[doc_0_9]: https://github.com/nikic/PHP-Parser/tree/0.9/doc
|
||||||
[doc_1_x]: https://github.com/nikic/PHP-Parser/tree/1.x/doc
|
[doc_1_x]: https://github.com/nikic/PHP-Parser/tree/1.x/doc
|
||||||
[doc_master]: https://github.com/nikic/PHP-Parser/tree/master/doc
|
|
||||||
|
@ -1,74 +0,0 @@
|
|||||||
Upgrading 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`.
|
|
15
bin/php-parse → bin/php-parse.php
Normal file → Executable file
15
bin/php-parse → bin/php-parse.php
Normal file → Executable file
@ -1,12 +1,7 @@
|
|||||||
#!/usr/bin/env php
|
#!/usr/bin/env php
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
foreach ([__DIR__ . '/../../../autoload.php', __DIR__ . '/../vendor/autoload.php'] as $file) {
|
require __DIR__ . '/../lib/bootstrap.php';
|
||||||
if (file_exists($file)) {
|
|
||||||
require $file;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ini_set('xdebug.max_nesting_level', 3000);
|
ini_set('xdebug.max_nesting_level', 3000);
|
||||||
|
|
||||||
@ -29,7 +24,7 @@ if (empty($files)) {
|
|||||||
$lexer = new PhpParser\Lexer\Emulative(array('usedAttributes' => array(
|
$lexer = new PhpParser\Lexer\Emulative(array('usedAttributes' => array(
|
||||||
'startLine', 'endLine', 'startFilePos', 'endFilePos'
|
'startLine', 'endLine', 'startFilePos', 'endFilePos'
|
||||||
)));
|
)));
|
||||||
$parser = (new PhpParser\ParserFactory)->create(PhpParser\ParserFactory::PREFER_PHP7, $lexer);
|
$parser = new PhpParser\Parser($lexer);
|
||||||
$dumper = new PhpParser\NodeDumper;
|
$dumper = new PhpParser\NodeDumper;
|
||||||
$prettyPrinter = new PhpParser\PrettyPrinter\Standard;
|
$prettyPrinter = new PhpParser\PrettyPrinter\Standard;
|
||||||
$serializer = new PhpParser\Serializer\XML;
|
$serializer = new PhpParser\Serializer\XML;
|
||||||
@ -89,8 +84,8 @@ foreach ($files as $file) {
|
|||||||
function showHelp($error) {
|
function showHelp($error) {
|
||||||
die($error . "\n\n" .
|
die($error . "\n\n" .
|
||||||
<<<OUTPUT
|
<<<OUTPUT
|
||||||
Usage: php-parse [operations] file1.php [file2.php ...]
|
Usage: php php-parse.php [operations] file1.php [file2.php ...]
|
||||||
or: php-parse [operations] "<?php code"
|
or: php php-parse.php [operations] "<?php code"
|
||||||
Turn PHP source code into an abstract syntax tree.
|
Turn PHP source code into an abstract syntax tree.
|
||||||
|
|
||||||
Operations is a list of the following options (--dump by default):
|
Operations is a list of the following options (--dump by default):
|
||||||
@ -103,7 +98,7 @@ Operations is a list of the following options (--dump by default):
|
|||||||
-c, --with-column-info Show column-numbers for errors (if available)
|
-c, --with-column-info Show column-numbers for errors (if available)
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
php-parse -d -p -N -d file.php
|
php php-parse.php -d -p -N -d file.php
|
||||||
|
|
||||||
Dumps nodes, pretty prints them, then resolves names and dumps them again.
|
Dumps nodes, pretty prints them, then resolves names and dumps them again.
|
||||||
|
|
@ -10,21 +10,15 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=5.4",
|
"php": ">=5.3",
|
||||||
"ext-tokenizer": "*"
|
"ext-tokenizer": "*"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
|
||||||
"phpunit/phpunit": "~4.0"
|
|
||||||
},
|
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"files": ["lib/bootstrap.php"]
|
||||||
"PhpParser\\": "lib/PhpParser"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"bin": ["bin/php-parse"],
|
|
||||||
"extra": {
|
"extra": {
|
||||||
"branch-alias": {
|
"branch-alias": {
|
||||||
"dev-master": "2.0-dev"
|
"dev-master": "1.4-dev"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
Introduction
|
Introduction
|
||||||
============
|
============
|
||||||
|
|
||||||
This project is a PHP 5.2 to PHP 7.0 parser **written in PHP itself**.
|
This project is a PHP 5.2 to PHP 5.6 parser **written in PHP itself**.
|
||||||
|
|
||||||
What is this for?
|
What is this for?
|
||||||
-----------------
|
-----------------
|
||||||
@ -26,12 +26,13 @@ programmatic PHP code analysis are incidentally PHP developers, not C developers
|
|||||||
What can it parse?
|
What can it parse?
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
The parser supports parsing PHP 5.2-5.6 and PHP 7.
|
The parser uses a PHP 5.6 compliant grammar, which is backwards compatible with all PHP version from PHP 5.2
|
||||||
|
upwards (and maybe older).
|
||||||
|
|
||||||
As the parser is based on the tokens returned by `token_get_all` (which is only able to lex the PHP
|
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 new tokens from 5.5, 5.6 and 7.0 is
|
version it runs on), additionally a wrapper for emulating new tokens from 5.3, 5.4, 5.5 and 5.6 is provided.
|
||||||
provided. This allows to parse PHP 7.0 source code running on PHP 5.4, for example. This emulation
|
This allows to parse PHP 5.6 source code running on PHP 5.3, for example. This emulation is very hacky and not
|
||||||
is somewhat hacky and not perfect, but it should work well on any sane code.
|
perfect, but it should work well on any sane code.
|
||||||
|
|
||||||
What output does it produce?
|
What output does it produce?
|
||||||
----------------------------
|
----------------------------
|
||||||
|
31
doc/1_Installation.markdown
Normal file
31
doc/1_Installation.markdown
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
Installation
|
||||||
|
============
|
||||||
|
|
||||||
|
There are multiple ways to include the PHP parser into your project:
|
||||||
|
|
||||||
|
Installing via Composer
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
Run the following command inside your project:
|
||||||
|
|
||||||
|
php composer.phar require nikic/php-parser
|
||||||
|
|
||||||
|
If you haven't installed [Composer][1] yet, you can do so using:
|
||||||
|
|
||||||
|
curl -s http://getcomposer.org/installer | php
|
||||||
|
|
||||||
|
Installing as a Git Submodule
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Run the following command to install the parser into the `vendor/PHP-Parser` folder:
|
||||||
|
|
||||||
|
git submodule add git://github.com/nikic/PHP-Parser.git vendor/PHP-Parser
|
||||||
|
|
||||||
|
Installing from the Zip- or Tarball
|
||||||
|
-----------------------------------
|
||||||
|
|
||||||
|
Download the latest version from [the download page][2], unpack it and move the files somewhere into your project.
|
||||||
|
|
||||||
|
|
||||||
|
[1]: https://getcomposer.org/
|
||||||
|
[2]: https://github.com/nikic/PHP-Parser/tags
|
@ -6,15 +6,20 @@ This document explains how to use the parser, the pretty printer and the node tr
|
|||||||
Bootstrapping
|
Bootstrapping
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
To bootstrap the library, include the autoloader generated by composer:
|
The library needs to register a class autoloader. You can either use the `vendor/autoload.php` file generated by
|
||||||
|
Composer or by including the bundled `lib/bootstrap.php` file:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
|
<?php
|
||||||
|
require 'path/to/PHP-Parser/lib/bootstrap.php';
|
||||||
|
// Or, if you're using Composer:
|
||||||
require 'path/to/vendor/autoload.php';
|
require 'path/to/vendor/autoload.php';
|
||||||
```
|
```
|
||||||
|
|
||||||
Additionally you may want to set the `xdebug.max_nesting_level` ini option to a higher value:
|
Additionally you may want to set the `xdebug.max_nesting_level` ini option to a higher value:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
|
<?php
|
||||||
ini_set('xdebug.max_nesting_level', 3000);
|
ini_set('xdebug.max_nesting_level', 3000);
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -23,41 +28,33 @@ This ensures that there will be no errors when traversing highly nested node tre
|
|||||||
Parsing
|
Parsing
|
||||||
-------
|
-------
|
||||||
|
|
||||||
In order to parse code, you first have to create a parser instance:
|
In order to parse some source code you first have to create a `PhpParser\Parser` object, which
|
||||||
|
needs to be passed a `PhpParser\Lexer` instance:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
use PhpParser\ParserFactory;
|
<?php
|
||||||
$parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7);
|
|
||||||
|
$parser = new PhpParser\Parser(new PhpParser\Lexer);
|
||||||
|
// or
|
||||||
|
$parser = new PhpParser\Parser(new PhpParser\Lexer\Emulative);
|
||||||
```
|
```
|
||||||
|
|
||||||
The factory accepts a kind argument, that determines how different PHP versions are treated:
|
Use of the emulative lexer is required if you want to parse PHP code from newer versions than the one
|
||||||
|
you're running on. For example it will allow you to parse PHP 5.6 code while running on PHP 5.3.
|
||||||
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 `<?php` tag) to the `parse` method in order to
|
Subsequently you can pass PHP code (including the opening `<?php` tag) to the `parse` method in order to
|
||||||
create a syntax tree. If a syntax error is encountered, an `PhpParser\Error` exception will be thrown:
|
create a syntax tree. If a syntax error is encountered, an `PhpParser\Error` exception will be thrown:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
use PhpParser\Error;
|
<?php
|
||||||
use PhpParser\ParserFactory;
|
|
||||||
|
|
||||||
$code = '<?php // some code';
|
$code = '<?php // some code';
|
||||||
$parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7);
|
|
||||||
|
$parser = new PhpParser\Parser(new PhpParser\Lexer\Emulative);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$stmts = $parser->parse($code);
|
$stmts = $parser->parse($code);
|
||||||
// $stmts is an array of statement nodes
|
// $stmts is an array of statement nodes
|
||||||
} catch (Error $e) {
|
} catch (PhpParser\Error $e) {
|
||||||
echo 'Parse Error: ', $e->getMessage();
|
echo 'Parse Error: ', $e->getMessage();
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@ -140,14 +137,11 @@ information the formatting is done using a specified scheme. Currently there is
|
|||||||
namely `PhpParser\PrettyPrinter\Standard`.
|
namely `PhpParser\PrettyPrinter\Standard`.
|
||||||
|
|
||||||
```php
|
```php
|
||||||
use PhpParser\Error;
|
<?php
|
||||||
use PhpParser\ParserFactory;
|
|
||||||
use PhpParser\PrettyPrinter;
|
|
||||||
|
|
||||||
$code = "<?php echo 'Hi ', hi\\getTarget();";
|
$code = "<?php echo 'Hi ', hi\\getTarget();";
|
||||||
|
|
||||||
$parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7);
|
$parser = new PhpParser\Parser(new PhpParser\Lexer);
|
||||||
$prettyPrinter = new PrettyPrinter\Standard;
|
$prettyPrinter = new PhpParser\PrettyPrinter\Standard;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// parse
|
// parse
|
||||||
@ -164,7 +158,7 @@ try {
|
|||||||
$code = $prettyPrinter->prettyPrint($stmts);
|
$code = $prettyPrinter->prettyPrint($stmts);
|
||||||
|
|
||||||
echo $code;
|
echo $code;
|
||||||
} catch (Error $e) {
|
} catch (PhpParser\Error $e) {
|
||||||
echo 'Parse Error: ', $e->getMessage();
|
echo 'Parse Error: ', $e->getMessage();
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@ -194,13 +188,11 @@ For this purpose the parser provides a component for traversing and visiting the
|
|||||||
structure of a program using this `PhpParser\NodeTraverser` looks like this:
|
structure of a program using this `PhpParser\NodeTraverser` looks like this:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
use PhpParser\NodeTraverser;
|
<?php
|
||||||
use PhpParser\ParserFactory;
|
|
||||||
use PhpParser\PrettyPrinter;
|
|
||||||
|
|
||||||
$parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7);
|
$parser = new PhpParser\Parser(new PhpParser\Lexer\Emulative);
|
||||||
$traverser = new NodeTraverser;
|
$traverser = new PhpParser\NodeTraverser;
|
||||||
$prettyPrinter = new PrettyPrinter\Standard;
|
$prettyPrinter = new PhpParser\PrettyPrinter\Standard;
|
||||||
|
|
||||||
// add your visitor
|
// add your visitor
|
||||||
$traverser->addVisitor(new MyNodeVisitor);
|
$traverser->addVisitor(new MyNodeVisitor);
|
||||||
@ -226,10 +218,10 @@ try {
|
|||||||
The corresponding node visitor might look like this:
|
The corresponding node visitor might look like this:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
|
<?php
|
||||||
use PhpParser\Node;
|
use PhpParser\Node;
|
||||||
use PhpParser\NodeVisitorAbstract;
|
|
||||||
|
|
||||||
class MyNodeVisitor extends NodeVisitorAbstract
|
class MyNodeVisitor extends PhpParser\NodeVisitorAbstract
|
||||||
{
|
{
|
||||||
public function leaveNode(Node $node) {
|
public function leaveNode(Node $node) {
|
||||||
if ($node instanceof Node\Scalar\String_) {
|
if ($node instanceof Node\Scalar\String_) {
|
||||||
@ -244,12 +236,10 @@ 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
|
All visitors must implement the `PhpParser\NodeVisitor` interface, which defines the following four
|
||||||
methods:
|
methods:
|
||||||
|
|
||||||
```php
|
|
||||||
public function beforeTraverse(array $nodes);
|
public function beforeTraverse(array $nodes);
|
||||||
public function enterNode(\PhpParser\Node $node);
|
public function enterNode(PhpParser\Node $node);
|
||||||
public function leaveNode(\PhpParser\Node $node);
|
public function leaveNode(PhpParser\Node $node);
|
||||||
public function afterTraverse(array $nodes);
|
public function afterTraverse(array $nodes);
|
||||||
```
|
|
||||||
|
|
||||||
The `beforeTraverse()` method is called once before the traversal begins and is passed the nodes the
|
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
|
traverser was called with. This method can be used for resetting values before traversation or
|
||||||
@ -309,24 +299,20 @@ assume that no dynamic features are used.
|
|||||||
We start off with the following base code:
|
We start off with the following base code:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
use PhpParser\ParserFactory;
|
<?php
|
||||||
use PhpParser\PrettyPrinter;
|
|
||||||
use PhpParser\NodeTraverser;
|
|
||||||
use PhpParser\NodeVisitor\NameResolver;
|
|
||||||
|
|
||||||
$inDir = '/some/path';
|
$inDir = '/some/path';
|
||||||
$outDir = '/some/other/path';
|
$outDir = '/some/other/path';
|
||||||
|
|
||||||
$parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7);
|
$parser = new PhpParser\Parser(new PhpParser\Lexer\Emulative);
|
||||||
$traverser = new NodeTraverser;
|
$traverser = new PhpParser\NodeTraverser;
|
||||||
$prettyPrinter = new PrettyPrinter\Standard;
|
$prettyPrinter = new PhpParser\PrettyPrinter\Standard;
|
||||||
|
|
||||||
$traverser->addVisitor(new NameResolver); // we will need resolved names
|
$traverser->addVisitor(new PhpParser\NodeVisitor\NameResolver); // we will need resolved names
|
||||||
$traverser->addVisitor(new NamespaceConverter); // our own node visitor
|
$traverser->addVisitor(new NodeVisitor\NamespaceConverter); // our own node visitor
|
||||||
|
|
||||||
// iterate over all .php files in the directory
|
// iterate over all .php files in the directory
|
||||||
$files = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($inDir));
|
$files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($inDir));
|
||||||
$files = new \RegexIterator($files, '/\.php$/');
|
$files = new RegexIterator($files, '/\.php$/');
|
||||||
|
|
||||||
foreach ($files as $file) {
|
foreach ($files as $file) {
|
||||||
try {
|
try {
|
||||||
@ -357,9 +343,9 @@ Now lets start with the main code, the `NodeVisitor\NamespaceConverter`. One thi
|
|||||||
is convert `A\\B` style names to `A_B` style ones.
|
is convert `A\\B` style names to `A_B` style ones.
|
||||||
|
|
||||||
```php
|
```php
|
||||||
|
<?php
|
||||||
use PhpParser\Node;
|
use PhpParser\Node;
|
||||||
|
class NodeVisitor_NamespaceConverter extends PhpParser\NodeVisitorAbstract
|
||||||
class NamespaceConverter extends \PhpParser\NodeVisitorAbstract
|
|
||||||
{
|
{
|
||||||
public function leaveNode(Node $node) {
|
public function leaveNode(Node $node) {
|
||||||
if ($node instanceof Node\Name) {
|
if ($node instanceof Node\Name) {
|
||||||
@ -380,10 +366,10 @@ only the shortname (i.e. the last part of the name), but they need to contain th
|
|||||||
the namespace prefix:
|
the namespace prefix:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
|
<?php
|
||||||
use PhpParser\Node;
|
use PhpParser\Node;
|
||||||
use PhpParser\Node\Stmt;
|
use PhpParser\Node\Stmt;
|
||||||
|
class NodeVisitor_NamespaceConverter extends PhpParser\NodeVisitorAbstract
|
||||||
class NodeVisitor_NamespaceConverter extends \PhpParser\NodeVisitorAbstract
|
|
||||||
{
|
{
|
||||||
public function leaveNode(Node $node) {
|
public function leaveNode(Node $node) {
|
||||||
if ($node instanceof Node\Name) {
|
if ($node instanceof Node\Name) {
|
||||||
@ -406,10 +392,10 @@ There is not much more to it than converting the namespaced name to string with
|
|||||||
The last thing we need to do is remove the `namespace` and `use` statements:
|
The last thing we need to do is remove the `namespace` and `use` statements:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
|
<?php
|
||||||
use PhpParser\Node;
|
use PhpParser\Node;
|
||||||
use PhpParser\Node\Stmt;
|
use PhpParser\Node\Stmt;
|
||||||
|
class NodeVisitor_NamespaceConverter extends PhpParser\NodeVisitorAbstract
|
||||||
class NodeVisitor_NamespaceConverter extends \PhpParser\NodeVisitorAbstract
|
|
||||||
{
|
{
|
||||||
public function leaveNode(Node $node) {
|
public function leaveNode(Node $node) {
|
||||||
if ($node instanceof Node\Name) {
|
if ($node instanceof Node\Name) {
|
||||||
|
@ -17,6 +17,7 @@ Furthermore it is possible to dump nodes into a human readable format using the
|
|||||||
`PhpParser\NodeDumper`. This can be used for debugging.
|
`PhpParser\NodeDumper`. This can be used for debugging.
|
||||||
|
|
||||||
```php
|
```php
|
||||||
|
<?php
|
||||||
$code = <<<'CODE'
|
$code = <<<'CODE'
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
@ -27,7 +28,7 @@ function printLine($msg) {
|
|||||||
printLine('Hello World!!!');
|
printLine('Hello World!!!');
|
||||||
CODE;
|
CODE;
|
||||||
|
|
||||||
$parser = (new PhpParser\ParserFactory)->create(PhpParser\ParserFactory::PREFER_PHP7);
|
$parser = new PhpParser\Parser(new PhpParser\Lexer);
|
||||||
$nodeDumper = new PhpParser\NodeDumper;
|
$nodeDumper = new PhpParser\NodeDumper;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -105,7 +106,7 @@ function printLine($msg) {
|
|||||||
printLine('Hello World!!!');
|
printLine('Hello World!!!');
|
||||||
CODE;
|
CODE;
|
||||||
|
|
||||||
$parser = (new PhpParser\ParserFactory)->create(PhpParser\ParserFactory::PREFER_PHP7);
|
$parser = new PhpParser\Parser(new PhpParser\Lexer);
|
||||||
$serializer = new PhpParser\Serializer\XML;
|
$serializer = new PhpParser\Serializer\XML;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -14,11 +14,8 @@ the following syntactic elements:
|
|||||||
Here is an example:
|
Here is an example:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
use PhpParser\BuilderFactory;
|
<?php
|
||||||
use PhpParser\PrettyPrinter;
|
$factory = new PhpParser\BuilderFactory;
|
||||||
use PhpParser\Node;
|
|
||||||
|
|
||||||
$factory = new BuilderFactory;
|
|
||||||
$node = $factory->namespace('Name\Space')
|
$node = $factory->namespace('Name\Space')
|
||||||
->addStmt($factory->use('Some\Other\Thingy')->as('SomeOtherClass'))
|
->addStmt($factory->use('Some\Other\Thingy')->as('SomeOtherClass'))
|
||||||
->addStmt($factory->class('SomeClass')
|
->addStmt($factory->class('SomeClass')
|
||||||
@ -41,7 +38,7 @@ $node = $factory->namespace('Name\Space')
|
|||||||
->makeProtected() // ->makePublic() [default], ->makePrivate()
|
->makeProtected() // ->makePublic() [default], ->makePrivate()
|
||||||
->addParam($factory->param('someParam')->setDefault('test'))
|
->addParam($factory->param('someParam')->setDefault('test'))
|
||||||
// it is possible to add manually created nodes
|
// it is possible to add manually created nodes
|
||||||
->addStmt(new Node\Expr\Print_(new Node\Expr\Variable('someParam')))
|
->addStmt(new PhpParser\Node\Expr\Print_(new PhpParser\Node\Expr\Variable('someParam')))
|
||||||
)
|
)
|
||||||
|
|
||||||
// properties will be correctly reordered above the methods
|
// properties will be correctly reordered above the methods
|
||||||
@ -53,7 +50,7 @@ $node = $factory->namespace('Name\Space')
|
|||||||
;
|
;
|
||||||
|
|
||||||
$stmts = array($node);
|
$stmts = array($node);
|
||||||
$prettyPrinter = new PrettyPrinter\Standard();
|
$prettyPrinter = new PhpParser\PrettyPrinter\Standard();
|
||||||
echo $prettyPrinter->prettyPrintFile($stmts);
|
echo $prettyPrinter->prettyPrintFile($stmts);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ position attributes in the lexer need to be enabled:
|
|||||||
$lexer = new PhpParser\Lexer(array(
|
$lexer = new PhpParser\Lexer(array(
|
||||||
'usedAttributes' => array('comments', 'startLine', 'endLine', 'startFilePos', 'endFilePos'),
|
'usedAttributes' => array('comments', 'startLine', 'endLine', 'startFilePos', 'endFilePos'),
|
||||||
));
|
));
|
||||||
$parser = (new PhpParser\ParserFactory)->create(PhpParser\ParserFactory::PREFER_PHP7, $lexer);
|
$parser = new PhpParser\Parser($lexer);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$stmts = $parser->parse($code);
|
$stmts = $parser->parse($code);
|
||||||
@ -58,7 +58,7 @@ or `null` if recovery fails.
|
|||||||
A usage example:
|
A usage example:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
$parser = (new PhpParser\ParserFactory)->create(PhpParser\ParserFactory::PREFER_PHP7, null, array(
|
$parser = new PhpParser\Parser(new PhpParser\Lexer, array(
|
||||||
'throwOnError' => false,
|
'throwOnError' => false,
|
||||||
));
|
));
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ $lexer = new PhpParser\Lexer(array(
|
|||||||
'comments', 'startLine', 'endLine', 'startTokenPos', 'endTokenPos'
|
'comments', 'startLine', 'endLine', 'startTokenPos', 'endTokenPos'
|
||||||
)
|
)
|
||||||
));
|
));
|
||||||
$parser = (new PhpParser\ParserFactory)->create(PhpParser\ParserFactory::PREFER_PHP7, $lexer);
|
$parser = new PhpParser\Parser($lexer);
|
||||||
|
|
||||||
$visitor = new MyNodeVisitor();
|
$visitor = new MyNodeVisitor();
|
||||||
$traverser = new PhpParser\NodeTraverser();
|
$traverser = new PhpParser\NodeTraverser();
|
||||||
@ -127,17 +127,14 @@ information about the formatting of integers (like decimal vs. hexadecimal) or s
|
|||||||
escape sequences). This can be remedied by storing the original value in an attribute:
|
escape sequences). This can be remedied by storing the original value in an attribute:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
use PhpParser\Lexer;
|
class KeepOriginalValueLexer extends PHPParser\Lexer // or PHPParser\Lexer\Emulative
|
||||||
use PhpParser\Parser\Tokens;
|
|
||||||
|
|
||||||
class KeepOriginalValueLexer extends Lexer // or Lexer\Emulative
|
|
||||||
{
|
{
|
||||||
public function getNextToken(&$value = null, &$startAttributes = null, &$endAttributes = null) {
|
public function getNextToken(&$value = null, &$startAttributes = null, &$endAttributes = null) {
|
||||||
$tokenId = parent::getNextToken($value, $startAttributes, $endAttributes);
|
$tokenId = parent::getNextToken($value, $startAttributes, $endAttributes);
|
||||||
|
|
||||||
if ($tokenId == Tokens::T_CONSTANT_ENCAPSED_STRING // non-interpolated string
|
if ($tokenId == PHPParser\Parser::T_CONSTANT_ENCAPSED_STRING // non-interpolated string
|
||||||
|| $tokenId == Tokens::T_LNUMBER // integer
|
|| $tokenId == PHPParser\Parser::T_LNUMBER // integer
|
||||||
|| $tokenId == Tokens::T_DNUMBER // floating point number
|
|| $tokenId == PHPParser\Parser::T_DNUMBER // floating point number
|
||||||
) {
|
) {
|
||||||
// could also use $startAttributes, doesn't really matter here
|
// could also use $startAttributes, doesn't really matter here
|
||||||
$endAttributes['originalValue'] = $value;
|
$endAttributes['originalValue'] = $value;
|
||||||
|
@ -1,23 +1,22 @@
|
|||||||
What do all those files mean?
|
What do all those files mean?
|
||||||
=============================
|
=============================
|
||||||
|
|
||||||
* `php5.y`: PHP 5 grammar written in a pseudo language
|
* `zend_language_parser.phpy`: PHP grammer written in a pseudo language
|
||||||
* `php7.y`: PHP 7 grammar written in a pseudo language
|
* `analyze.php`: Analyzes the `.phpy`-grammer and outputs some info about it
|
||||||
* `tokens.y`: Tokens definition shared between PHP 5 and PHP 7 grammars
|
* `rebuildParser.php`: Preprocesses the `.phpy`-grammar and builds the parser using `kmyacc`
|
||||||
* `parser.template`: A `kmyacc` parser prototype file for PHP
|
* `kmyacc.php.parser`: A `kmyacc` parser prototype file for PHP
|
||||||
* `tokens.template`: A `kmyacc` prototype file for the `Tokens` class
|
|
||||||
* `analyze.php`: Analyzes the grammer and outputs some info about it
|
|
||||||
* `rebuildParser.php`: Preprocesses the grammar and builds the parser using `kmyacc`
|
|
||||||
|
|
||||||
.phpy pseudo language
|
.phpy pseudo language
|
||||||
=====================
|
=====================
|
||||||
|
|
||||||
The `.y` file is a normal grammer in `kmyacc` (`yacc`) style, with some transformations
|
The `.phpy` file is a normal grammer in `kmyacc` (`yacc`) style, with some transformations
|
||||||
applied to it:
|
applied to it:
|
||||||
|
|
||||||
* Nodes are created using the syntax `Name[..., ...]`. This is transformed into
|
* Nodes are created using the syntax `Name[..., ...]`. This is transformed into
|
||||||
`new Name(..., ..., attributes())`
|
`new Name(..., ..., attributes())`
|
||||||
* Some function-like constructs are resolved (see `rebuildParser.php` for a list)
|
* Some function-like constructs are resolved (see `rebuildParser.php` for a list)
|
||||||
|
* Associative arrays are written as `[key: value, ...]`, which is transformed to
|
||||||
|
`array('key' => value, ...)`
|
||||||
|
|
||||||
Building the parser
|
Building the parser
|
||||||
===================
|
===================
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
const GRAMMAR_FILE = './php5.y';
|
const GRAMMAR_FILE = './zend_language_parser.phpy';
|
||||||
|
|
||||||
const LIB = '(?(DEFINE)
|
const LIB = '(?(DEFINE)
|
||||||
(?<singleQuotedString>\'[^\\\\\']*+(?:\\\\.[^\\\\\']*+)*+\')
|
(?<singleQuotedString>\'[^\\\\\']*+(?:\\\\.[^\\\\\']*+)*+\')
|
||||||
|
@ -5,23 +5,16 @@ $meta #
|
|||||||
#semval(%n) $this->stackPos-(%l-%n)
|
#semval(%n) $this->stackPos-(%l-%n)
|
||||||
#semval(%n,%t) $this->stackPos-(%l-%n)
|
#semval(%n,%t) $this->stackPos-(%l-%n)
|
||||||
|
|
||||||
namespace PhpParser\Parser;
|
namespace PhpParser;
|
||||||
|
|
||||||
use PhpParser\Error;
|
|
||||||
use PhpParser\Node;
|
|
||||||
use PhpParser\Node\Expr;
|
|
||||||
use PhpParser\Node\Name;
|
|
||||||
use PhpParser\Node\Scalar;
|
|
||||||
use PhpParser\Node\Stmt;
|
|
||||||
#include;
|
#include;
|
||||||
|
|
||||||
/* This is an automatically GENERATED file, which should not be manually edited.
|
/* This is an automatically GENERATED file, which should not be manually edited.
|
||||||
* Instead edit one of the following:
|
* Instead edit one of the following:
|
||||||
* * the grammar files grammar/php5.y or grammar/php7.y
|
* * the grammar file grammar/zend_language_parser.phpy
|
||||||
* * the skeleton file grammar/parser.template
|
* * the skeleton file grammar/kymacc.php.parser
|
||||||
* * the preprocessing script grammar/rebuildParsers.php
|
* * the preprocessing script grammar/rebuildParser.php
|
||||||
*/
|
*/
|
||||||
class #(-p) extends \PhpParser\ParserAbstract
|
class Parser extends ParserAbstract
|
||||||
{
|
{
|
||||||
protected $tokenToSymbolMapSize = #(YYMAXLEX);
|
protected $tokenToSymbolMapSize = #(YYMAXLEX);
|
||||||
protected $actionTableSize = #(YYLAST);
|
protected $actionTableSize = #(YYLAST);
|
||||||
@ -35,6 +28,10 @@ class #(-p) extends \PhpParser\ParserAbstract
|
|||||||
protected $YY2TBLSTATE = #(YY2TBLSTATE);
|
protected $YY2TBLSTATE = #(YY2TBLSTATE);
|
||||||
protected $YYNLSTATES = #(YYNLSTATES);
|
protected $YYNLSTATES = #(YYNLSTATES);
|
||||||
|
|
||||||
|
#tokenval
|
||||||
|
const %s = %n;
|
||||||
|
#endtokenval
|
||||||
|
|
||||||
protected $symbolToName = array(
|
protected $symbolToName = array(
|
||||||
#listvar terminals
|
#listvar terminals
|
||||||
);
|
);
|
813
grammar/php7.y
813
grammar/php7.y
@ -1,813 +0,0 @@
|
|||||||
%pure_parser
|
|
||||||
%expect 2
|
|
||||||
|
|
||||||
%tokens
|
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
||||||
start:
|
|
||||||
top_statement_list { $$ = $this->handleNamespaces($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
top_statement_list:
|
|
||||||
top_statement_list top_statement { pushNormalizing($1, $2); }
|
|
||||||
| /* empty */ { init(); }
|
|
||||||
;
|
|
||||||
|
|
||||||
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
|
|
||||||
;
|
|
||||||
|
|
||||||
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]; }
|
|
||||||
| T_NAMESPACE namespace_name '{' top_statement_list '}' { $$ = Stmt\Namespace_[$2, $4]; }
|
|
||||||
| T_NAMESPACE '{' top_statement_list '}' { $$ = Stmt\Namespace_[null, $3]; }
|
|
||||||
| 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[Name[$3], $6, $2]; }
|
|
||||||
| T_USE use_type T_NS_SEPARATOR namespace_name_parts T_NS_SEPARATOR '{' unprefixed_use_declarations '}'
|
|
||||||
{ $$ = Stmt\GroupUse[Name[$4], $7, $2]; }
|
|
||||||
| T_USE namespace_name_parts T_NS_SEPARATOR '{' inline_use_declarations '}'
|
|
||||||
{ $$ = Stmt\GroupUse[Name[$2], $5, Stmt\Use_::TYPE_UNKNOWN]; }
|
|
||||||
| T_USE T_NS_SEPARATOR namespace_name_parts T_NS_SEPARATOR '{' inline_use_declarations '}'
|
|
||||||
{ $$ = Stmt\GroupUse[Name[$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]; }
|
|
||||||
| namespace_name T_AS T_STRING { $$ = Stmt\UseUse[$1, $3, Stmt\Use_::TYPE_UNKNOWN]; }
|
|
||||||
;
|
|
||||||
|
|
||||||
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 '=' expr { $$ = Node\Const_[$1, $3]; }
|
|
||||||
;
|
|
||||||
|
|
||||||
class_const_list:
|
|
||||||
class_const_list ',' class_const { push($1, $3); }
|
|
||||||
| class_const { init($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
class_const:
|
|
||||||
identifier '=' expr { $$ = Node\Const_[$1, $3]; }
|
|
||||||
;
|
|
||||||
|
|
||||||
inner_statement_list:
|
|
||||||
inner_statement_list inner_statement { pushNormalizing($1, $2); }
|
|
||||||
| /* empty */ { init(); }
|
|
||||||
;
|
|
||||||
|
|
||||||
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()); }
|
|
||||||
;
|
|
||||||
|
|
||||||
statement:
|
|
||||||
'{' inner_statement_list '}' { $$ = $2; }
|
|
||||||
| 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 ';' { $$ = Stmt\Break_[$2]; }
|
|
||||||
| T_CONTINUE optional_expr ';' { $$ = Stmt\Continue_[$2]; }
|
|
||||||
| T_RETURN optional_expr ';' { $$ = Stmt\Return_[$2]; }
|
|
||||||
| 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]; }
|
|
||||||
| ';' { $$ = array(); /* means: no statement */ }
|
|
||||||
| T_TRY '{' inner_statement_list '}' catches optional_finally
|
|
||||||
{ $$ = Stmt\TryCatch[$3, $5, $6]; }
|
|
||||||
| T_THROW expr ';' { $$ = Stmt\Throw_[$2]; }
|
|
||||||
| T_GOTO T_STRING ';' { $$ = Stmt\Goto_[$2]; }
|
|
||||||
| T_STRING ':' { $$ = Stmt\Label[$1]; }
|
|
||||||
| error { $$ = array(); /* means: no statement */ }
|
|
||||||
;
|
|
||||||
|
|
||||||
catches:
|
|
||||||
/* empty */ { init(); }
|
|
||||||
| catches catch { push($1, $2); }
|
|
||||||
;
|
|
||||||
|
|
||||||
catch:
|
|
||||||
T_CATCH '(' name T_VARIABLE ')' '{' inner_statement_list '}'
|
|
||||||
{ $$ = Stmt\Catch_[$3, parseVar($4), $7]; }
|
|
||||||
;
|
|
||||||
|
|
||||||
optional_finally:
|
|
||||||
/* empty */ { $$ = null; }
|
|
||||||
| T_FINALLY '{' inner_statement_list '}' { $$ = $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]]; }
|
|
||||||
| T_INTERFACE T_STRING interface_extends_list '{' class_statement_list '}'
|
|
||||||
{ $$ = Stmt\Interface_[$2, ['extends' => $3, 'stmts' => $5]]; }
|
|
||||||
| T_TRAIT T_STRING '{' class_statement_list '}'
|
|
||||||
{ $$ = Stmt\Trait_[$2, $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 name { $$ = $2; }
|
|
||||||
;
|
|
||||||
|
|
||||||
interface_extends_list:
|
|
||||||
/* empty */ { $$ = array(); }
|
|
||||||
| T_EXTENDS name_list { $$ = $2; }
|
|
||||||
;
|
|
||||||
|
|
||||||
implements_list:
|
|
||||||
/* empty */ { $$ = array(); }
|
|
||||||
| T_IMPLEMENTS name_list { $$ = $2; }
|
|
||||||
;
|
|
||||||
|
|
||||||
name_list:
|
|
||||||
name { init($1); }
|
|
||||||
| name_list ',' 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:
|
|
||||||
statement { $$ = toArray($1); }
|
|
||||||
| ':' 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 '=' 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); }
|
|
||||||
;
|
|
||||||
|
|
||||||
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]; }
|
|
||||||
| optional_param_type optional_ref optional_ellipsis T_VARIABLE '=' expr
|
|
||||||
{ $$ = Node\Param[parseVar($4), $6, $1, $2, $3]; }
|
|
||||||
;
|
|
||||||
|
|
||||||
type:
|
|
||||||
name { $$ = $this->handleScalarTypes($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; }
|
|
||||||
;
|
|
||||||
|
|
||||||
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:
|
|
||||||
simple_variable { $$ = Expr\Variable[$1]; }
|
|
||||||
;
|
|
||||||
|
|
||||||
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 '=' 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]; }
|
|
||||||
| T_CONST class_const_list ';' { $$ = Stmt\ClassConst[$2]; }
|
|
||||||
| 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]]; }
|
|
||||||
| T_USE 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 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 { Stmt\Class_::verifyModifier($1, $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 '=' expr { $$ = 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]; }
|
|
||||||
| '(' 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 { $$ = Expr\Exit_ [$2]; }
|
|
||||||
| '@' 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); }
|
|
||||||
|
|
||||||
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]; }
|
|
||||||
| 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; }
|
|
||||||
;
|
|
||||||
|
|
||||||
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]; }
|
|
||||||
;
|
|
||||||
|
|
||||||
dereferencable_scalar:
|
|
||||||
T_ARRAY '(' array_pair_list ')' { $$ = Expr\Array_[$3]; }
|
|
||||||
| '[' array_pair_list ']' { $$ = Expr\Array_[$2]; }
|
|
||||||
| T_CONSTANT_ENCAPSED_STRING { $$ = Scalar\String_[Scalar\String_::parse($1)]; }
|
|
||||||
;
|
|
||||||
|
|
||||||
scalar:
|
|
||||||
T_LNUMBER { $$ = Scalar\LNumber[Scalar\LNumber::parse($1)]; }
|
|
||||||
| 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
|
|
||||||
{ $$ = Scalar\String_[Scalar\String_::parseDocString($1, $2)]; }
|
|
||||||
| T_START_HEREDOC T_END_HEREDOC
|
|
||||||
{ $$ = Scalar\String_['']; }
|
|
||||||
| '"' encaps_list '"'
|
|
||||||
{ parseEncapsed($2, '"', true); $$ = Scalar\Encapsed[$2]; }
|
|
||||||
| T_START_HEREDOC encaps_list T_END_HEREDOC
|
|
||||||
{ parseEncapsedDoc($2, true); $$ = Scalar\Encapsed[$2]; }
|
|
||||||
;
|
|
||||||
|
|
||||||
optional_comma:
|
|
||||||
/* empty */
|
|
||||||
| ','
|
|
||||||
;
|
|
||||||
|
|
||||||
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]; }
|
|
||||||
;
|
|
||||||
|
|
||||||
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]; }
|
|
||||||
;
|
|
||||||
|
|
||||||
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 { $$ = $1; }
|
|
||||||
| list_expr { $$ = $1; }
|
|
||||||
| /* 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_var:
|
|
||||||
T_VARIABLE { $$ = Expr\Variable[parseVar($1)]; }
|
|
||||||
| T_VARIABLE '[' encaps_var_offset ']' { $$ = Expr\ArrayDimFetch[Expr\Variable[parseVar($1)], $3]; }
|
|
||||||
| T_VARIABLE T_OBJECT_OPERATOR T_STRING { $$ = Expr\PropertyFetch[Expr\Variable[parseVar($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 { $$ = Scalar\String_[$1]; }
|
|
||||||
| T_VARIABLE { $$ = Expr\Variable[parseVar($1)]; }
|
|
||||||
;
|
|
||||||
|
|
||||||
%%
|
|
@ -1,17 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
$grammarFileToName = [
|
$grammarFile = __DIR__ . '/zend_language_parser.phpy';
|
||||||
__DIR__ . '/php5.y' => 'Php5',
|
$skeletonFile = __DIR__ . '/kmyacc.php.parser';
|
||||||
__DIR__ . '/php7.y' => 'Php7',
|
|
||||||
];
|
|
||||||
|
|
||||||
$tokensFile = __DIR__ . '/tokens.y';
|
|
||||||
$tokensTemplate = __DIR__ . '/tokens.template';
|
|
||||||
$skeletonFile = __DIR__ . '/parser.template';
|
|
||||||
$tmpGrammarFile = __DIR__ . '/tmp_parser.phpy';
|
$tmpGrammarFile = __DIR__ . '/tmp_parser.phpy';
|
||||||
$tmpResultFile = __DIR__ . '/tmp_parser.php';
|
$tmpResultFile = __DIR__ . '/tmp_parser.php';
|
||||||
$resultDir = __DIR__ . '/../lib/PhpParser/Parser';
|
$parserResultFile = __DIR__ . '/../lib/PhpParser/Parser.php';
|
||||||
$tokensResultsFile = $resultDir . '/Tokens.php';
|
|
||||||
|
|
||||||
// check for kmyacc.exe binary in this directory, otherwise fall back to global name
|
// check for kmyacc.exe binary in this directory, otherwise fall back to global name
|
||||||
$kmyacc = __DIR__ . '/kmyacc.exe';
|
$kmyacc = __DIR__ . '/kmyacc.exe';
|
||||||
@ -42,42 +35,33 @@ const ARGS = '\((?<args>[^()]*+(?:\((?&args)\)[^()]*+)*+)\)';
|
|||||||
/// Main script ///
|
/// Main script ///
|
||||||
///////////////////
|
///////////////////
|
||||||
|
|
||||||
$tokens = file_get_contents($tokensFile);
|
echo 'Building temporary preproprocessed grammar file.', "\n";
|
||||||
|
|
||||||
foreach ($grammarFileToName as $grammarFile => $name) {
|
|
||||||
echo "Building temporary $name grammar file.\n";
|
|
||||||
|
|
||||||
$grammarCode = file_get_contents($grammarFile);
|
$grammarCode = file_get_contents($grammarFile);
|
||||||
$grammarCode = str_replace('%tokens', $tokens, $grammarCode);
|
|
||||||
|
|
||||||
$grammarCode = resolveNodes($grammarCode);
|
$grammarCode = resolveNodes($grammarCode);
|
||||||
$grammarCode = resolveMacros($grammarCode);
|
$grammarCode = resolveMacros($grammarCode);
|
||||||
|
$grammarCode = resolveArrays($grammarCode);
|
||||||
$grammarCode = resolveStackAccess($grammarCode);
|
$grammarCode = resolveStackAccess($grammarCode);
|
||||||
|
|
||||||
file_put_contents($tmpGrammarFile, $grammarCode);
|
file_put_contents($tmpGrammarFile, $grammarCode);
|
||||||
|
|
||||||
$additionalArgs = $optionDebug ? '-t -v' : '';
|
$additionalArgs = $optionDebug ? '-t -v' : '';
|
||||||
|
|
||||||
echo "Building $name parser.\n";
|
echo "Building parser.\n";
|
||||||
$output = trim(shell_exec("$kmyacc $additionalArgs -l -m $skeletonFile -p $name $tmpGrammarFile 2>&1"));
|
$output = trim(shell_exec("$kmyacc $additionalArgs -l -m $skeletonFile $tmpGrammarFile 2>&1"));
|
||||||
echo "Output: \"$output\"\n";
|
echo "Output: \"$output\"\n";
|
||||||
|
|
||||||
$resultCode = file_get_contents($tmpResultFile);
|
$resultCode = file_get_contents($tmpResultFile);
|
||||||
$resultCode = removeTrailingWhitespace($resultCode);
|
$resultCode = removeTrailingWhitespace($resultCode);
|
||||||
|
|
||||||
ensureDirExists($resultDir);
|
ensureDirExists(dirname($parserResultFile));
|
||||||
file_put_contents("$resultDir/$name.php", $resultCode);
|
file_put_contents($parserResultFile, $resultCode);
|
||||||
unlink($tmpResultFile);
|
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) {
|
if (!$optionKeepTmpGrammar) {
|
||||||
unlink($tmpGrammarFile);
|
unlink($tmpGrammarFile);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////
|
///////////////////////////////
|
||||||
/// Preprocessing functions ///
|
/// Preprocessing functions ///
|
||||||
@ -137,8 +121,7 @@ function resolveMacros($code) {
|
|||||||
if ('pushNormalizing' == $name) {
|
if ('pushNormalizing' == $name) {
|
||||||
assertArgs(2, $args, $name);
|
assertArgs(2, $args, $name);
|
||||||
|
|
||||||
return 'if (is_array(' . $args[1] . ')) { $$ = array_merge(' . $args[0] . ', ' . $args[1] . '); }'
|
return 'if (is_array(' . $args[1] . ')) { $$ = array_merge(' . $args[0] . ', ' . $args[1] . '); } else { ' . $args[0] . '[] = ' . $args[1] . '; $$ = ' . $args[0] . '; }';
|
||||||
. ' else { ' . $args[0] . '[] = ' . $args[1] . '; $$ = ' . $args[0] . '; }';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('toArray' == $name) {
|
if ('toArray' == $name) {
|
||||||
@ -154,19 +137,15 @@ function resolveMacros($code) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ('parseEncapsed' == $name) {
|
if ('parseEncapsed' == $name) {
|
||||||
assertArgs(3, $args, $name);
|
assertArgs(2, $args, $name);
|
||||||
|
|
||||||
return 'foreach (' . $args[0] . ' as $s) { if ($s instanceof Node\Scalar\EncapsedStringPart) {'
|
return 'foreach (' . $args[0] . ' as &$s) { if (is_string($s)) { $s = Node\Scalar\String_::parseEscapeSequences($s, ' . $args[1] . '); } }';
|
||||||
. ' $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, ' . $args[1] . ', ' . $args[2] . '); } }';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('parseEncapsedDoc' == $name) {
|
if ('parseEncapsedDoc' == $name) {
|
||||||
assertArgs(2, $args, $name);
|
assertArgs(1, $args, $name);
|
||||||
|
|
||||||
return 'foreach (' . $args[0] . ' as $s) { if ($s instanceof Node\Scalar\EncapsedStringPart) {'
|
return 'foreach (' . $args[0] . ' as &$s) { if (is_string($s)) { $s = Node\Scalar\String_::parseEscapeSequences($s, null); } } $s = preg_replace(\'~(\r\n|\n|\r)\z~\', \'\', $s); if (\'\' === $s) array_pop(' . $args[0] . ');';
|
||||||
. ' $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] . ');';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $matches[0];
|
return $matches[0];
|
||||||
@ -181,6 +160,37 @@ function assertArgs($num, $args, $name) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function resolveArrays($code) {
|
||||||
|
return preg_replace_callback(
|
||||||
|
'~' . PARAMS . '~',
|
||||||
|
function ($matches) {
|
||||||
|
$elements = magicSplit(
|
||||||
|
'(?:' . PARAMS . '|' . ARGS . ')(*SKIP)(*FAIL)|,',
|
||||||
|
$matches['params']
|
||||||
|
);
|
||||||
|
|
||||||
|
// don't convert [] to array, it might have different meaning
|
||||||
|
if (empty($elements)) {
|
||||||
|
return $matches[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
$elementCodes = array();
|
||||||
|
foreach ($elements as $element) {
|
||||||
|
// convert only arrays where all elements have keys
|
||||||
|
if (false === strpos($element, ':')) {
|
||||||
|
return $matches[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
list($key, $value) = explode(':', $element, 2);
|
||||||
|
$elementCodes[] = "'" . $key . "' =>" . $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'array(' . implode(', ', $elementCodes) . ')';
|
||||||
|
},
|
||||||
|
$code
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function resolveStackAccess($code) {
|
function resolveStackAccess($code) {
|
||||||
$code = preg_replace('/\$\d+/', '$this->semStack[$0]', $code);
|
$code = preg_replace('/\$\d+/', '$this->semStack[$0]', $code);
|
||||||
$code = preg_replace('/#(\d+)/', '$$1', $code);
|
$code = preg_replace('/#(\d+)/', '$$1', $code);
|
||||||
@ -214,9 +224,5 @@ function magicSplit($regex, $string) {
|
|||||||
$piece = trim($piece);
|
$piece = trim($piece);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($pieces === ['']) {
|
return array_filter($pieces);
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $pieces;
|
|
||||||
}
|
}
|
@ -1,17 +0,0 @@
|
|||||||
<?php
|
|
||||||
$meta #
|
|
||||||
#semval($) $this->semValue
|
|
||||||
#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
|
|
||||||
}
|
|
113
grammar/tokens.y
113
grammar/tokens.y
@ -1,113 +0,0 @@
|
|||||||
/* 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
|
|
@ -1,7 +1,122 @@
|
|||||||
%pure_parser
|
%pure_parser
|
||||||
%expect 6
|
%expect 2
|
||||||
|
|
||||||
%tokens
|
%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_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
|
||||||
|
|
||||||
|
%{
|
||||||
|
use PhpParser\Node\Expr;
|
||||||
|
use PhpParser\Node\Name;
|
||||||
|
use PhpParser\Node\Scalar;
|
||||||
|
use PhpParser\Node\Stmt;
|
||||||
|
%}
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
@ -14,25 +129,6 @@ top_statement_list:
|
|||||||
| /* empty */ { init(); }
|
| /* empty */ { init(); }
|
||||||
;
|
;
|
||||||
|
|
||||||
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
|
|
||||||
;
|
|
||||||
|
|
||||||
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:
|
namespace_name_parts:
|
||||||
T_STRING { init($1); }
|
T_STRING { init($1); }
|
||||||
| namespace_name_parts T_NS_SEPARATOR T_STRING { push($1, $3); }
|
| namespace_name_parts T_NS_SEPARATOR T_STRING { push($1, $3); }
|
||||||
@ -52,57 +148,21 @@ top_statement:
|
|||||||
| T_NAMESPACE namespace_name '{' top_statement_list '}' { $$ = Stmt\Namespace_[$2, $4]; }
|
| T_NAMESPACE namespace_name '{' top_statement_list '}' { $$ = Stmt\Namespace_[$2, $4]; }
|
||||||
| T_NAMESPACE '{' top_statement_list '}' { $$ = Stmt\Namespace_[null, $3]; }
|
| T_NAMESPACE '{' top_statement_list '}' { $$ = Stmt\Namespace_[null, $3]; }
|
||||||
| T_USE use_declarations ';' { $$ = Stmt\Use_[$2, Stmt\Use_::TYPE_NORMAL]; }
|
| T_USE use_declarations ';' { $$ = Stmt\Use_[$2, Stmt\Use_::TYPE_NORMAL]; }
|
||||||
| T_USE use_type use_declarations ';' { $$ = Stmt\Use_[$3, $2]; }
|
| T_USE T_FUNCTION use_declarations ';' { $$ = Stmt\Use_[$3, Stmt\Use_::TYPE_FUNCTION]; }
|
||||||
| group_use_declaration ';' { $$ = $1; }
|
| T_USE T_CONST use_declarations ';' { $$ = Stmt\Use_[$3, Stmt\Use_::TYPE_CONSTANT]; }
|
||||||
| T_CONST constant_declaration_list ';' { $$ = Stmt\Const_[$2]; }
|
| 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[Name[$3], $6, $2]; }
|
|
||||||
| T_USE use_type T_NS_SEPARATOR namespace_name_parts T_NS_SEPARATOR '{' unprefixed_use_declarations '}'
|
|
||||||
{ $$ = Stmt\GroupUse[Name[$4], $7, $2]; }
|
|
||||||
| T_USE namespace_name_parts T_NS_SEPARATOR '{' inline_use_declarations '}'
|
|
||||||
{ $$ = Stmt\GroupUse[Name[$2], $5, Stmt\Use_::TYPE_UNKNOWN]; }
|
|
||||||
| T_USE T_NS_SEPARATOR namespace_name_parts T_NS_SEPARATOR '{' inline_use_declarations '}'
|
|
||||||
{ $$ = Stmt\GroupUse[Name[$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_declarations ',' use_declaration { push($1, $3); }
|
use_declarations ',' use_declaration { push($1, $3); }
|
||||||
| use_declaration { init($1); }
|
| 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]; }
|
|
||||||
| namespace_name T_AS T_STRING { $$ = Stmt\UseUse[$1, $3, Stmt\Use_::TYPE_UNKNOWN]; }
|
|
||||||
;
|
|
||||||
|
|
||||||
use_declaration:
|
use_declaration:
|
||||||
unprefixed_use_declaration { $$ = $1; }
|
namespace_name { $$ = Stmt\UseUse[$1, null]; }
|
||||||
| T_NS_SEPARATOR unprefixed_use_declaration { $$ = $2; }
|
| namespace_name T_AS T_STRING { $$ = Stmt\UseUse[$1, $3]; }
|
||||||
;
|
| T_NS_SEPARATOR namespace_name { $$ = Stmt\UseUse[$2, null]; }
|
||||||
|
| T_NS_SEPARATOR namespace_name T_AS T_STRING { $$ = Stmt\UseUse[$2, $4]; }
|
||||||
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:
|
||||||
@ -114,15 +174,6 @@ constant_declaration:
|
|||||||
T_STRING '=' static_scalar { $$ = Node\Const_[$1, $3]; }
|
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:
|
inner_statement_list:
|
||||||
inner_statement_list inner_statement { pushNormalizing($1, $2); }
|
inner_statement_list inner_statement { pushNormalizing($1, $2); }
|
||||||
| /* empty */ { init(); }
|
| /* empty */ { init(); }
|
||||||
@ -139,13 +190,13 @@ inner_statement:
|
|||||||
statement:
|
statement:
|
||||||
'{' inner_statement_list '}' { $$ = $2; }
|
'{' inner_statement_list '}' { $$ = $2; }
|
||||||
| T_IF parentheses_expr statement elseif_list else_single
|
| T_IF parentheses_expr statement elseif_list else_single
|
||||||
{ $$ = Stmt\If_[$2, ['stmts' => toArray($3), 'elseifs' => $4, 'else' => $5]]; }
|
{ $$ = 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 ';'
|
| T_IF parentheses_expr ':' inner_statement_list new_elseif_list new_else_single T_ENDIF ';'
|
||||||
{ $$ = Stmt\If_[$2, ['stmts' => $4, 'elseifs' => $5, 'else' => $6]]; }
|
{ $$ = Stmt\If_[$2, [stmts: $4, elseifs: $5, else: $6]]; }
|
||||||
| T_WHILE parentheses_expr while_statement { $$ = Stmt\While_[$2, $3]; }
|
| T_WHILE parentheses_expr while_statement { $$ = Stmt\While_[$2, $3]; }
|
||||||
| T_DO statement T_WHILE parentheses_expr ';' { $$ = Stmt\Do_ [$4, toArray($2)]; }
|
| T_DO statement T_WHILE parentheses_expr ';' { $$ = Stmt\Do_ [$4, toArray($2)]; }
|
||||||
| T_FOR '(' for_expr ';' for_expr ';' for_expr ')' for_statement
|
| T_FOR '(' for_expr ';' for_expr ';' for_expr ')' for_statement
|
||||||
{ $$ = Stmt\For_[['init' => $3, 'cond' => $5, 'loop' => $7, 'stmts' => $9]]; }
|
{ $$ = Stmt\For_[[init: $3, cond: $5, loop: $7, stmts: $9]]; }
|
||||||
| T_SWITCH parentheses_expr switch_case_list { $$ = Stmt\Switch_[$2, $3]; }
|
| T_SWITCH parentheses_expr switch_case_list { $$ = Stmt\Switch_[$2, $3]; }
|
||||||
| T_BREAK ';' { $$ = Stmt\Break_[null]; }
|
| T_BREAK ';' { $$ = Stmt\Break_[null]; }
|
||||||
| T_BREAK expr ';' { $$ = Stmt\Break_[$2]; }
|
| T_BREAK expr ';' { $$ = Stmt\Break_[$2]; }
|
||||||
@ -161,9 +212,9 @@ statement:
|
|||||||
| expr ';' { $$ = $1; }
|
| expr ';' { $$ = $1; }
|
||||||
| T_UNSET '(' variables_list ')' ';' { $$ = Stmt\Unset_[$3]; }
|
| T_UNSET '(' variables_list ')' ';' { $$ = Stmt\Unset_[$3]; }
|
||||||
| T_FOREACH '(' expr T_AS foreach_variable ')' foreach_statement
|
| T_FOREACH '(' expr T_AS foreach_variable ')' foreach_statement
|
||||||
{ $$ = Stmt\Foreach_[$3, $5[0], ['keyVar' => null, 'byRef' => $5[1], 'stmts' => $7]]; }
|
{ $$ = 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
|
| 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]]; }
|
{ $$ = Stmt\Foreach_[$3, $7[0], [keyVar: $5, byRef: $7[1], stmts: $9]]; }
|
||||||
| T_DECLARE '(' declare_list ')' declare_statement { $$ = Stmt\Declare_[$3, $5]; }
|
| T_DECLARE '(' declare_list ')' declare_statement { $$ = Stmt\Declare_[$3, $5]; }
|
||||||
| ';' { $$ = array(); /* means: no statement */ }
|
| ';' { $$ = array(); /* means: no statement */ }
|
||||||
| T_TRY '{' inner_statement_list '}' catches optional_finally
|
| T_TRY '{' inner_statement_list '}' catches optional_finally
|
||||||
@ -206,14 +257,14 @@ optional_ellipsis:
|
|||||||
|
|
||||||
function_declaration_statement:
|
function_declaration_statement:
|
||||||
T_FUNCTION optional_ref T_STRING '(' parameter_list ')' optional_return_type '{' inner_statement_list '}'
|
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]]; }
|
{ $$ = Stmt\Function_[$3, [byRef: $2, params: $5, returnType: $7, stmts: $9]]; }
|
||||||
;
|
;
|
||||||
|
|
||||||
class_declaration_statement:
|
class_declaration_statement:
|
||||||
class_entry_type T_STRING extends_from implements_list '{' class_statement_list '}'
|
class_entry_type T_STRING extends_from implements_list '{' class_statement_list '}'
|
||||||
{ $$ = Stmt\Class_[$2, ['type' => $1, 'extends' => $3, 'implements' => $4, 'stmts' => $6]]; }
|
{ $$ = Stmt\Class_[$2, [type: $1, extends: $3, implements: $4, stmts: $6]]; }
|
||||||
| T_INTERFACE T_STRING interface_extends_list '{' class_statement_list '}'
|
| T_INTERFACE T_STRING interface_extends_list '{' class_statement_list '}'
|
||||||
{ $$ = Stmt\Interface_[$2, ['extends' => $3, 'stmts' => $5]]; }
|
{ $$ = Stmt\Interface_[$2, [extends: $3, stmts: $5]]; }
|
||||||
| T_TRAIT T_STRING '{' class_statement_list '}'
|
| T_TRAIT T_STRING '{' class_statement_list '}'
|
||||||
{ $$ = Stmt\Trait_[$2, $4]; }
|
{ $$ = Stmt\Trait_[$2, $4]; }
|
||||||
;
|
;
|
||||||
@ -407,9 +458,9 @@ class_statement_list:
|
|||||||
|
|
||||||
class_statement:
|
class_statement:
|
||||||
variable_modifiers property_declaration_list ';' { $$ = Stmt\Property[$1, $2]; }
|
variable_modifiers property_declaration_list ';' { $$ = Stmt\Property[$1, $2]; }
|
||||||
| T_CONST class_const_list ';' { $$ = Stmt\ClassConst[$2]; }
|
| T_CONST constant_declaration_list ';' { $$ = Stmt\ClassConst[$2]; }
|
||||||
| method_modifiers T_FUNCTION optional_ref identifier '(' parameter_list ')' optional_return_type method_body
|
| method_modifiers T_FUNCTION optional_ref T_STRING '(' parameter_list ')' optional_return_type method_body
|
||||||
{ $$ = Stmt\ClassMethod[$4, ['type' => $1, 'byRef' => $3, 'params' => $6, 'returnType' => $8, 'stmts' => $9]]; }
|
{ $$ = Stmt\ClassMethod[$4, [type: $1, byRef: $3, params: $6, returnType: $8, stmts: $9]]; }
|
||||||
| T_USE name_list trait_adaptations { $$ = Stmt\TraitUse[$2, $3]; }
|
| T_USE name_list trait_adaptations { $$ = Stmt\TraitUse[$2, $3]; }
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -426,22 +477,20 @@ trait_adaptation_list:
|
|||||||
trait_adaptation:
|
trait_adaptation:
|
||||||
trait_method_reference_fully_qualified T_INSTEADOF name_list ';'
|
trait_method_reference_fully_qualified T_INSTEADOF name_list ';'
|
||||||
{ $$ = Stmt\TraitUseAdaptation\Precedence[$1[0], $1[1], $3]; }
|
{ $$ = Stmt\TraitUseAdaptation\Precedence[$1[0], $1[1], $3]; }
|
||||||
| trait_method_reference T_AS member_modifier identifier ';'
|
| trait_method_reference T_AS member_modifier T_STRING ';'
|
||||||
{ $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], $3, $4]; }
|
{ $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], $3, $4]; }
|
||||||
| trait_method_reference T_AS member_modifier ';'
|
| trait_method_reference T_AS member_modifier ';'
|
||||||
{ $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], $3, null]; }
|
{ $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], $3, null]; }
|
||||||
| trait_method_reference T_AS T_STRING ';'
|
| trait_method_reference T_AS T_STRING ';'
|
||||||
{ $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], null, $3]; }
|
{ $$ = 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:
|
trait_method_reference_fully_qualified:
|
||||||
name T_PAAMAYIM_NEKUDOTAYIM identifier { $$ = array($1, $3); }
|
name T_PAAMAYIM_NEKUDOTAYIM T_STRING { $$ = array($1, $3); }
|
||||||
;
|
;
|
||||||
trait_method_reference:
|
trait_method_reference:
|
||||||
trait_method_reference_fully_qualified { $$ = $1; }
|
trait_method_reference_fully_qualified { $$ = $1; }
|
||||||
| identifier { $$ = array(null, $1); }
|
| T_STRING { $$ = array(null, $1); }
|
||||||
;
|
;
|
||||||
|
|
||||||
method_body:
|
method_body:
|
||||||
@ -579,10 +628,10 @@ expr:
|
|||||||
| T_YIELD_FROM expr { $$ = Expr\YieldFrom[$2]; }
|
| T_YIELD_FROM expr { $$ = Expr\YieldFrom[$2]; }
|
||||||
| T_FUNCTION optional_ref '(' parameter_list ')' lexical_vars optional_return_type
|
| T_FUNCTION optional_ref '(' parameter_list ')' lexical_vars optional_return_type
|
||||||
'{' inner_statement_list '}'
|
'{' inner_statement_list '}'
|
||||||
{ $$ = Expr\Closure[['static' => false, 'byRef' => $2, 'params' => $4, 'uses' => $6, 'returnType' => $7, 'stmts' => $9]]; }
|
{ $$ = 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
|
| T_STATIC T_FUNCTION optional_ref '(' parameter_list ')' lexical_vars optional_return_type
|
||||||
'{' inner_statement_list '}'
|
'{' inner_statement_list '}'
|
||||||
{ $$ = Expr\Closure[['static' => true, 'byRef' => $3, 'params' => $5, 'uses' => $7, 'returnType' => $8, 'stmts' => $10]]; }
|
{ $$ = Expr\Closure[[static: true, byRef: $3, params: $5, uses: $7, returnType: $8, stmts: $10]]; }
|
||||||
;
|
;
|
||||||
|
|
||||||
parentheses_expr:
|
parentheses_expr:
|
||||||
@ -603,7 +652,7 @@ array_expr:
|
|||||||
scalar_dereference:
|
scalar_dereference:
|
||||||
array_expr '[' dim_offset ']' { $$ = Expr\ArrayDimFetch[$1, $3]; }
|
array_expr '[' dim_offset ']' { $$ = Expr\ArrayDimFetch[$1, $3]; }
|
||||||
| T_CONSTANT_ENCAPSED_STRING '[' dim_offset ']'
|
| T_CONSTANT_ENCAPSED_STRING '[' dim_offset ']'
|
||||||
{ $$ = Expr\ArrayDimFetch[Scalar\String_[Scalar\String_::parse($1, false)], $3]; }
|
{ $$ = Expr\ArrayDimFetch[Scalar\String_[Scalar\String_::parse($1)], $3]; }
|
||||||
| constant '[' dim_offset ']' { $$ = Expr\ArrayDimFetch[$1, $3]; }
|
| constant '[' dim_offset ']' { $$ = Expr\ArrayDimFetch[$1, $3]; }
|
||||||
| scalar_dereference '[' dim_offset ']' { $$ = Expr\ArrayDimFetch[$1, $3]; }
|
| scalar_dereference '[' dim_offset ']' { $$ = Expr\ArrayDimFetch[$1, $3]; }
|
||||||
/* alternative array syntax missing intentionally */
|
/* alternative array syntax missing intentionally */
|
||||||
@ -611,7 +660,7 @@ scalar_dereference:
|
|||||||
|
|
||||||
anonymous_class:
|
anonymous_class:
|
||||||
T_CLASS ctor_arguments extends_from implements_list '{' class_statement_list '}'
|
T_CLASS ctor_arguments extends_from implements_list '{' class_statement_list '}'
|
||||||
{ $$ = array(Stmt\Class_[null, ['type' => 0, 'extends' => $3, 'implements' => $4, 'stmts' => $6]], $2); }
|
{ $$ = array(Stmt\Class_[null, [type: 0, extends: $3, implements: $4, stmts: $6]], $2); }
|
||||||
|
|
||||||
new_expr:
|
new_expr:
|
||||||
T_NEW class_name_reference ctor_arguments { $$ = Expr\New_[$2, $3]; }
|
T_NEW class_name_reference ctor_arguments { $$ = Expr\New_[$2, $3]; }
|
||||||
@ -635,7 +684,7 @@ lexical_var:
|
|||||||
|
|
||||||
function_call:
|
function_call:
|
||||||
name argument_list { $$ = Expr\FuncCall[$1, $2]; }
|
name argument_list { $$ = Expr\FuncCall[$1, $2]; }
|
||||||
| class_name_or_var T_PAAMAYIM_NEKUDOTAYIM identifier argument_list
|
| class_name_or_var T_PAAMAYIM_NEKUDOTAYIM T_STRING argument_list
|
||||||
{ $$ = Expr\StaticCall[$1, $3, $4]; }
|
{ $$ = Expr\StaticCall[$1, $3, $4]; }
|
||||||
| class_name_or_var T_PAAMAYIM_NEKUDOTAYIM '{' expr '}' argument_list
|
| class_name_or_var T_PAAMAYIM_NEKUDOTAYIM '{' expr '}' argument_list
|
||||||
{ $$ = Expr\StaticCall[$1, $4, $6]; }
|
{ $$ = Expr\StaticCall[$1, $4, $6]; }
|
||||||
@ -703,9 +752,8 @@ exit_expr:
|
|||||||
|
|
||||||
backticks_expr:
|
backticks_expr:
|
||||||
/* empty */ { $$ = array(); }
|
/* empty */ { $$ = array(); }
|
||||||
| T_ENCAPSED_AND_WHITESPACE
|
| T_ENCAPSED_AND_WHITESPACE { $$ = array(Scalar\String_::parseEscapeSequences($1, '`')); }
|
||||||
{ $$ = array(Scalar\EncapsedStringPart[Scalar\String_::parseEscapeSequences($1, '`', false)]); }
|
| encaps_list { parseEncapsed($1, '`'); $$ = $1; }
|
||||||
| encaps_list { parseEncapsed($1, '`', false); $$ = $1; }
|
|
||||||
;
|
;
|
||||||
|
|
||||||
ctor_arguments:
|
ctor_arguments:
|
||||||
@ -716,7 +764,7 @@ ctor_arguments:
|
|||||||
common_scalar:
|
common_scalar:
|
||||||
T_LNUMBER { $$ = Scalar\LNumber[Scalar\LNumber::parse($1)]; }
|
T_LNUMBER { $$ = Scalar\LNumber[Scalar\LNumber::parse($1)]; }
|
||||||
| T_DNUMBER { $$ = Scalar\DNumber[Scalar\DNumber::parse($1)]; }
|
| T_DNUMBER { $$ = Scalar\DNumber[Scalar\DNumber::parse($1)]; }
|
||||||
| T_CONSTANT_ENCAPSED_STRING { $$ = Scalar\String_[Scalar\String_::parse($1, false)]; }
|
| T_CONSTANT_ENCAPSED_STRING { $$ = Scalar\String_[Scalar\String_::parse($1)]; }
|
||||||
| T_LINE { $$ = Scalar\MagicConst\Line[]; }
|
| T_LINE { $$ = Scalar\MagicConst\Line[]; }
|
||||||
| T_FILE { $$ = Scalar\MagicConst\File[]; }
|
| T_FILE { $$ = Scalar\MagicConst\File[]; }
|
||||||
| T_DIR { $$ = Scalar\MagicConst\Dir[]; }
|
| T_DIR { $$ = Scalar\MagicConst\Dir[]; }
|
||||||
@ -726,14 +774,14 @@ common_scalar:
|
|||||||
| T_FUNC_C { $$ = Scalar\MagicConst\Function_[]; }
|
| T_FUNC_C { $$ = Scalar\MagicConst\Function_[]; }
|
||||||
| T_NS_C { $$ = Scalar\MagicConst\Namespace_[]; }
|
| T_NS_C { $$ = Scalar\MagicConst\Namespace_[]; }
|
||||||
| T_START_HEREDOC T_ENCAPSED_AND_WHITESPACE T_END_HEREDOC
|
| T_START_HEREDOC T_ENCAPSED_AND_WHITESPACE T_END_HEREDOC
|
||||||
{ $$ = Scalar\String_[Scalar\String_::parseDocString($1, $2, false)]; }
|
{ $$ = Scalar\String_[Scalar\String_::parseDocString($1, $2)]; }
|
||||||
| T_START_HEREDOC T_END_HEREDOC
|
| T_START_HEREDOC T_END_HEREDOC
|
||||||
{ $$ = Scalar\String_['']; }
|
{ $$ = Scalar\String_['']; }
|
||||||
;
|
;
|
||||||
|
|
||||||
static_scalar:
|
static_scalar:
|
||||||
common_scalar { $$ = $1; }
|
common_scalar { $$ = $1; }
|
||||||
| class_name T_PAAMAYIM_NEKUDOTAYIM identifier { $$ = Expr\ClassConstFetch[$1, $3]; }
|
| class_name T_PAAMAYIM_NEKUDOTAYIM class_const_name { $$ = Expr\ClassConstFetch[$1, $3]; }
|
||||||
| name { $$ = Expr\ConstFetch[$1]; }
|
| name { $$ = Expr\ConstFetch[$1]; }
|
||||||
| T_ARRAY '(' static_array_pair_list ')' { $$ = Expr\Array_[$3]; }
|
| T_ARRAY '(' static_array_pair_list ')' { $$ = Expr\Array_[$3]; }
|
||||||
| '[' static_array_pair_list ']' { $$ = Expr\Array_[$2]; }
|
| '[' static_array_pair_list ']' { $$ = Expr\Array_[$2]; }
|
||||||
@ -778,7 +826,7 @@ static_operation:
|
|||||||
|
|
||||||
constant:
|
constant:
|
||||||
name { $$ = Expr\ConstFetch[$1]; }
|
name { $$ = Expr\ConstFetch[$1]; }
|
||||||
| class_name_or_var T_PAAMAYIM_NEKUDOTAYIM identifier
|
| class_name_or_var T_PAAMAYIM_NEKUDOTAYIM class_const_name
|
||||||
{ $$ = Expr\ClassConstFetch[$1, $3]; }
|
{ $$ = Expr\ClassConstFetch[$1, $3]; }
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -786,9 +834,14 @@ scalar:
|
|||||||
common_scalar { $$ = $1; }
|
common_scalar { $$ = $1; }
|
||||||
| constant { $$ = $1; }
|
| constant { $$ = $1; }
|
||||||
| '"' encaps_list '"'
|
| '"' encaps_list '"'
|
||||||
{ parseEncapsed($2, '"', false); $$ = Scalar\Encapsed[$2]; }
|
{ parseEncapsed($2, '"'); $$ = Scalar\Encapsed[$2]; }
|
||||||
| T_START_HEREDOC encaps_list T_END_HEREDOC
|
| T_START_HEREDOC encaps_list T_END_HEREDOC
|
||||||
{ parseEncapsedDoc($2, false); $$ = Scalar\Encapsed[$2]; }
|
{ parseEncapsedDoc($2); $$ = Scalar\Encapsed[$2]; }
|
||||||
|
;
|
||||||
|
|
||||||
|
class_const_name:
|
||||||
|
T_STRING { $$ = $1; }
|
||||||
|
| T_CLASS { $$ = 'class'; }
|
||||||
;
|
;
|
||||||
|
|
||||||
static_array_pair_list:
|
static_array_pair_list:
|
||||||
@ -916,13 +969,9 @@ array_pair:
|
|||||||
|
|
||||||
encaps_list:
|
encaps_list:
|
||||||
encaps_list encaps_var { push($1, $2); }
|
encaps_list encaps_var { push($1, $2); }
|
||||||
| encaps_list encaps_string_part { push($1, $2); }
|
| encaps_list T_ENCAPSED_AND_WHITESPACE { push($1, $2); }
|
||||||
| encaps_var { init($1); }
|
| encaps_var { init($1); }
|
||||||
| encaps_string_part encaps_var { init($1, $2); }
|
| T_ENCAPSED_AND_WHITESPACE encaps_var { init($1, $2); }
|
||||||
;
|
|
||||||
|
|
||||||
encaps_string_part:
|
|
||||||
T_ENCAPSED_AND_WHITESPACE { $$ = Scalar\EncapsedStringPart[$1]; }
|
|
||||||
;
|
;
|
||||||
|
|
||||||
encaps_var:
|
encaps_var:
|
@ -10,6 +10,9 @@ class Autoloader
|
|||||||
/** @var bool Whether the autoloader has been registered. */
|
/** @var bool Whether the autoloader has been registered. */
|
||||||
private static $registered = false;
|
private static $registered = false;
|
||||||
|
|
||||||
|
/** @var bool Whether we're running on PHP 7. */
|
||||||
|
private static $runningOnPhp7;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers PhpParser\Autoloader as an SPL autoloader.
|
* Registers PhpParser\Autoloader as an SPL autoloader.
|
||||||
*
|
*
|
||||||
@ -22,6 +25,7 @@ class Autoloader
|
|||||||
|
|
||||||
spl_autoload_register(array(__CLASS__, 'autoload'), true, $prepend);
|
spl_autoload_register(array(__CLASS__, 'autoload'), true, $prepend);
|
||||||
self::$registered = true;
|
self::$registered = true;
|
||||||
|
self::$runningOnPhp7 = version_compare(PHP_VERSION, '7.0-dev', '>=');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -31,10 +35,241 @@ class Autoloader
|
|||||||
*/
|
*/
|
||||||
static public function autoload($class) {
|
static public function autoload($class) {
|
||||||
if (0 === strpos($class, 'PhpParser\\')) {
|
if (0 === strpos($class, 'PhpParser\\')) {
|
||||||
|
if (isset(self::$php7AliasesOldToNew[$class])) {
|
||||||
|
if (self::$runningOnPhp7) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load the new class, alias will be registered afterwards
|
||||||
|
$class = self::$php7AliasesOldToNew[$class];
|
||||||
|
}
|
||||||
|
|
||||||
$fileName = dirname(__DIR__) . '/' . strtr($class, '\\', '/') . '.php';
|
$fileName = dirname(__DIR__) . '/' . strtr($class, '\\', '/') . '.php';
|
||||||
if (file_exists($fileName)) {
|
if (file_exists($fileName)) {
|
||||||
require $fileName;
|
require $fileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isset(self::$php7AliasesNewToOld[$class])) {
|
||||||
|
// New class name was used, register alias for old one, otherwise
|
||||||
|
// it won't be usable in "instanceof" and other non-autoloading places.
|
||||||
|
if (!self::$runningOnPhp7) {
|
||||||
|
class_alias($class, self::$php7AliasesNewToOld[$class]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (0 === strpos($class, 'PHPParser_')) {
|
||||||
|
if (isset(self::$nonNamespacedAliases[$class])) {
|
||||||
|
// Register all aliases at once to avoid dependency issues
|
||||||
|
self::registerNonNamespacedAliases();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static function registerNonNamespacedAliases() {
|
||||||
|
foreach (self::$nonNamespacedAliases as $old => $new) {
|
||||||
|
class_alias($new, $old);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static $php7AliasesOldToNew = array(
|
||||||
|
'PhpParser\Node\Expr\Cast\Bool' => 'PhpParser\Node\Expr\Cast\Bool_',
|
||||||
|
'PhpParser\Node\Expr\Cast\Int' => 'PhpParser\Node\Expr\Cast\Int_',
|
||||||
|
'PhpParser\Node\Expr\Cast\Object' => 'PhpParser\Node\Expr\Cast\Object_',
|
||||||
|
'PhpParser\Node\Expr\Cast\String' => 'PhpParser\Node\Expr\Cast\String_',
|
||||||
|
'PhpParser\Node\Scalar\String' => 'PhpParser\Node\Scalar\String_',
|
||||||
|
);
|
||||||
|
|
||||||
|
private static $php7AliasesNewToOld = array(
|
||||||
|
'PhpParser\Node\Expr\Cast\Bool_' => 'PhpParser\Node\Expr\Cast\Bool',
|
||||||
|
'PhpParser\Node\Expr\Cast\Int_' => 'PhpParser\Node\Expr\Cast\Int',
|
||||||
|
'PhpParser\Node\Expr\Cast\Object_' => 'PhpParser\Node\Expr\Cast\Object',
|
||||||
|
'PhpParser\Node\Expr\Cast\String_' => 'PhpParser\Node\Expr\Cast\String',
|
||||||
|
'PhpParser\Node\Scalar\String_' => 'PhpParser\Node\Scalar\String',
|
||||||
|
);
|
||||||
|
|
||||||
|
private static $nonNamespacedAliases = array(
|
||||||
|
'PHPParser_Builder' => 'PhpParser\Builder',
|
||||||
|
'PHPParser_BuilderAbstract' => 'PhpParser\BuilderAbstract',
|
||||||
|
'PHPParser_BuilderFactory' => 'PhpParser\BuilderFactory',
|
||||||
|
'PHPParser_Comment' => 'PhpParser\Comment',
|
||||||
|
'PHPParser_Comment_Doc' => 'PhpParser\Comment\Doc',
|
||||||
|
'PHPParser_Error' => 'PhpParser\Error',
|
||||||
|
'PHPParser_Lexer' => 'PhpParser\Lexer',
|
||||||
|
'PHPParser_Lexer_Emulative' => 'PhpParser\Lexer\Emulative',
|
||||||
|
'PHPParser_Node' => 'PhpParser\Node',
|
||||||
|
'PHPParser_NodeAbstract' => 'PhpParser\NodeAbstract',
|
||||||
|
'PHPParser_NodeDumper' => 'PhpParser\NodeDumper',
|
||||||
|
'PHPParser_NodeTraverser' => 'PhpParser\NodeTraverser',
|
||||||
|
'PHPParser_NodeTraverserInterface' => 'PhpParser\NodeTraverserInterface',
|
||||||
|
'PHPParser_NodeVisitor' => 'PhpParser\NodeVisitor',
|
||||||
|
'PHPParser_NodeVisitor_NameResolver' => 'PhpParser\NodeVisitor\NameResolver',
|
||||||
|
'PHPParser_NodeVisitorAbstract' => 'PhpParser\NodeVisitorAbstract',
|
||||||
|
'PHPParser_Parser' => 'PhpParser\Parser',
|
||||||
|
'PHPParser_PrettyPrinterAbstract' => 'PhpParser\PrettyPrinterAbstract',
|
||||||
|
'PHPParser_PrettyPrinter_Default' => 'PhpParser\PrettyPrinter\Standard',
|
||||||
|
'PHPParser_PrettyPrinter_Zend' => 'PhpParser\PrettyPrinter\Standard',
|
||||||
|
'PHPParser_Serializer' => 'PhpParser\Serializer',
|
||||||
|
'PHPParser_Serializer_XML' => 'PhpParser\Serializer\XML',
|
||||||
|
'PHPParser_Unserializer' => 'PhpParser\Unserializer',
|
||||||
|
'PHPParser_Unserializer_XML' => 'PhpParser\Unserializer\XML',
|
||||||
|
|
||||||
|
'PHPParser_Builder_Class' => 'PhpParser\Builder\Class_',
|
||||||
|
'PHPParser_Builder_Function' => 'PhpParser\Builder\Function_',
|
||||||
|
'PHPParser_Builder_Interface' => 'PhpParser\Builder\Interface_',
|
||||||
|
'PHPParser_Builder_Method' => 'PhpParser\Builder\Method',
|
||||||
|
'PHPParser_Builder_Param' => 'PhpParser\Builder\Param',
|
||||||
|
'PHPParser_Builder_Property' => 'PhpParser\Builder\Property',
|
||||||
|
|
||||||
|
'PHPParser_Node_Arg' => 'PhpParser\Node\Arg',
|
||||||
|
'PHPParser_Node_Const' => 'PhpParser\Node\Const_',
|
||||||
|
'PHPParser_Node_Expr' => 'PhpParser\Node\Expr',
|
||||||
|
'PHPParser_Node_Name' => 'PhpParser\Node\Name',
|
||||||
|
'PHPParser_Node_Name_FullyQualified' => 'PhpParser\Node\Name\FullyQualified',
|
||||||
|
'PHPParser_Node_Name_Relative' => 'PhpParser\Node\Name\Relative',
|
||||||
|
'PHPParser_Node_Param' => 'PhpParser\Node\Param',
|
||||||
|
'PHPParser_Node_Scalar' => 'PhpParser\Node\Scalar',
|
||||||
|
'PHPParser_Node_Stmt' => 'PhpParser\Node\Stmt',
|
||||||
|
|
||||||
|
'PHPParser_Node_Stmt_Break' => 'PhpParser\Node\Stmt\Break_',
|
||||||
|
'PHPParser_Node_Stmt_Case' => 'PhpParser\Node\Stmt\Case_',
|
||||||
|
'PHPParser_Node_Stmt_Catch' => 'PhpParser\Node\Stmt\Catch_',
|
||||||
|
'PHPParser_Node_Stmt_Class' => 'PhpParser\Node\Stmt\Class_',
|
||||||
|
'PHPParser_Node_Stmt_ClassConst' => 'PhpParser\Node\Stmt\ClassConst',
|
||||||
|
'PHPParser_Node_Stmt_ClassMethod' => 'PhpParser\Node\Stmt\ClassMethod',
|
||||||
|
'PHPParser_Node_Stmt_Const' => 'PhpParser\Node\Stmt\Const_',
|
||||||
|
'PHPParser_Node_Stmt_Continue' => 'PhpParser\Node\Stmt\Continue_',
|
||||||
|
'PHPParser_Node_Stmt_Declare' => 'PhpParser\Node\Stmt\Declare_',
|
||||||
|
'PHPParser_Node_Stmt_DeclareDeclare' => 'PhpParser\Node\Stmt\DeclareDeclare',
|
||||||
|
'PHPParser_Node_Stmt_Do' => 'PhpParser\Node\Stmt\Do_',
|
||||||
|
'PHPParser_Node_Stmt_Echo' => 'PhpParser\Node\Stmt\Echo_',
|
||||||
|
'PHPParser_Node_Stmt_Else' => 'PhpParser\Node\Stmt\Else_',
|
||||||
|
'PHPParser_Node_Stmt_ElseIf' => 'PhpParser\Node\Stmt\ElseIf_',
|
||||||
|
'PHPParser_Node_Stmt_For' => 'PhpParser\Node\Stmt\For_',
|
||||||
|
'PHPParser_Node_Stmt_Foreach' => 'PhpParser\Node\Stmt\Foreach_',
|
||||||
|
'PHPParser_Node_Stmt_Function' => 'PhpParser\Node\Stmt\Function_',
|
||||||
|
'PHPParser_Node_Stmt_Global' => 'PhpParser\Node\Stmt\Global_',
|
||||||
|
'PHPParser_Node_Stmt_Goto' => 'PhpParser\Node\Stmt\Goto_',
|
||||||
|
'PHPParser_Node_Stmt_HaltCompiler' => 'PhpParser\Node\Stmt\HaltCompiler',
|
||||||
|
'PHPParser_Node_Stmt_If' => 'PhpParser\Node\Stmt\If_',
|
||||||
|
'PHPParser_Node_Stmt_InlineHTML' => 'PhpParser\Node\Stmt\InlineHTML',
|
||||||
|
'PHPParser_Node_Stmt_Interface' => 'PhpParser\Node\Stmt\Interface_',
|
||||||
|
'PHPParser_Node_Stmt_Label' => 'PhpParser\Node\Stmt\Label',
|
||||||
|
'PHPParser_Node_Stmt_Namespace' => 'PhpParser\Node\Stmt\Namespace_',
|
||||||
|
'PHPParser_Node_Stmt_Property' => 'PhpParser\Node\Stmt\Property',
|
||||||
|
'PHPParser_Node_Stmt_PropertyProperty' => 'PhpParser\Node\Stmt\PropertyProperty',
|
||||||
|
'PHPParser_Node_Stmt_Return' => 'PhpParser\Node\Stmt\Return_',
|
||||||
|
'PHPParser_Node_Stmt_Static' => 'PhpParser\Node\Stmt\Static_',
|
||||||
|
'PHPParser_Node_Stmt_StaticVar' => 'PhpParser\Node\Stmt\StaticVar',
|
||||||
|
'PHPParser_Node_Stmt_Switch' => 'PhpParser\Node\Stmt\Switch_',
|
||||||
|
'PHPParser_Node_Stmt_Throw' => 'PhpParser\Node\Stmt\Throw_',
|
||||||
|
'PHPParser_Node_Stmt_Trait' => 'PhpParser\Node\Stmt\Trait_',
|
||||||
|
'PHPParser_Node_Stmt_TraitUse' => 'PhpParser\Node\Stmt\TraitUse',
|
||||||
|
'PHPParser_Node_Stmt_TraitUseAdaptation' => 'PhpParser\Node\Stmt\TraitUseAdaptation',
|
||||||
|
'PHPParser_Node_Stmt_TraitUseAdaptation_Alias' => 'PhpParser\Node\Stmt\TraitUseAdaptation\Alias',
|
||||||
|
'PHPParser_Node_Stmt_TraitUseAdaptation_Precedence' => 'PhpParser\Node\Stmt\TraitUseAdaptation\Precedence',
|
||||||
|
'PHPParser_Node_Stmt_TryCatch' => 'PhpParser\Node\Stmt\TryCatch',
|
||||||
|
'PHPParser_Node_Stmt_Unset' => 'PhpParser\Node\Stmt\Unset_',
|
||||||
|
'PHPParser_Node_Stmt_UseUse' => 'PhpParser\Node\Stmt\UseUse',
|
||||||
|
'PHPParser_Node_Stmt_Use' => 'PhpParser\Node\Stmt\Use_',
|
||||||
|
'PHPParser_Node_Stmt_While' => 'PhpParser\Node\Stmt\While_',
|
||||||
|
|
||||||
|
'PHPParser_Node_Expr_AssignBitwiseAnd' => 'PhpParser\Node\Expr\AssignOp\BitwiseAnd',
|
||||||
|
'PHPParser_Node_Expr_AssignBitwiseOr' => 'PhpParser\Node\Expr\AssignOp\BitwiseOr',
|
||||||
|
'PHPParser_Node_Expr_AssignBitwiseXor' => 'PhpParser\Node\Expr\AssignOp\BitwiseXor',
|
||||||
|
'PHPParser_Node_Expr_AssignConcat' => 'PhpParser\Node\Expr\AssignOp\Concat',
|
||||||
|
'PHPParser_Node_Expr_AssignDiv' => 'PhpParser\Node\Expr\AssignOp\Div',
|
||||||
|
'PHPParser_Node_Expr_AssignMinus' => 'PhpParser\Node\Expr\AssignOp\Minus',
|
||||||
|
'PHPParser_Node_Expr_AssignMod' => 'PhpParser\Node\Expr\AssignOp\Mod',
|
||||||
|
'PHPParser_Node_Expr_AssignMul' => 'PhpParser\Node\Expr\AssignOp\Mul',
|
||||||
|
'PHPParser_Node_Expr_AssignPlus' => 'PhpParser\Node\Expr\AssignOp\Plus',
|
||||||
|
'PHPParser_Node_Expr_AssignShiftLeft' => 'PhpParser\Node\Expr\AssignOp\ShiftLeft',
|
||||||
|
'PHPParser_Node_Expr_AssignShiftRight' => 'PhpParser\Node\Expr\AssignOp\ShiftRight',
|
||||||
|
|
||||||
|
'PHPParser_Node_Expr_Cast' => 'PhpParser\Node\Expr\Cast',
|
||||||
|
'PHPParser_Node_Expr_Cast_Array' => 'PhpParser\Node\Expr\Cast\Array_',
|
||||||
|
'PHPParser_Node_Expr_Cast_Bool' => 'PhpParser\Node\Expr\Cast\Bool_',
|
||||||
|
'PHPParser_Node_Expr_Cast_Double' => 'PhpParser\Node\Expr\Cast\Double',
|
||||||
|
'PHPParser_Node_Expr_Cast_Int' => 'PhpParser\Node\Expr\Cast\Int_',
|
||||||
|
'PHPParser_Node_Expr_Cast_Object' => 'PhpParser\Node\Expr\Cast\Object_',
|
||||||
|
'PHPParser_Node_Expr_Cast_String' => 'PhpParser\Node\Expr\Cast\String_',
|
||||||
|
'PHPParser_Node_Expr_Cast_Unset' => 'PhpParser\Node\Expr\Cast\Unset_',
|
||||||
|
|
||||||
|
'PHPParser_Node_Expr_BitwiseAnd' => 'PhpParser\Node\Expr\BinaryOp\BitwiseAnd',
|
||||||
|
'PHPParser_Node_Expr_BitwiseOr' => 'PhpParser\Node\Expr\BinaryOp\BitwiseOr',
|
||||||
|
'PHPParser_Node_Expr_BitwiseXor' => 'PhpParser\Node\Expr\BinaryOp\BitwiseXor',
|
||||||
|
'PHPParser_Node_Expr_BooleanAnd' => 'PhpParser\Node\Expr\BinaryOp\BooleanAnd',
|
||||||
|
'PHPParser_Node_Expr_BooleanOr' => 'PhpParser\Node\Expr\BinaryOp\BooleanOr',
|
||||||
|
'PHPParser_Node_Expr_Concat' => 'PhpParser\Node\Expr\BinaryOp\Concat',
|
||||||
|
'PHPParser_Node_Expr_Div' => 'PhpParser\Node\Expr\BinaryOp\Div',
|
||||||
|
'PHPParser_Node_Expr_Equal' => 'PhpParser\Node\Expr\BinaryOp\Equal',
|
||||||
|
'PHPParser_Node_Expr_Greater' => 'PhpParser\Node\Expr\BinaryOp\Greater',
|
||||||
|
'PHPParser_Node_Expr_GreaterOrEqual' => 'PhpParser\Node\Expr\BinaryOp\GreaterOrEqual',
|
||||||
|
'PHPParser_Node_Expr_Identical' => 'PhpParser\Node\Expr\BinaryOp\Identical',
|
||||||
|
'PHPParser_Node_Expr_LogicalAnd' => 'PhpParser\Node\Expr\BinaryOp\LogicalAnd',
|
||||||
|
'PHPParser_Node_Expr_LogicalOr' => 'PhpParser\Node\Expr\BinaryOp\LogicalOr',
|
||||||
|
'PHPParser_Node_Expr_LogicalXor' => 'PhpParser\Node\Expr\BinaryOp\LogicalXor',
|
||||||
|
'PHPParser_Node_Expr_Minus' => 'PhpParser\Node\Expr\BinaryOp\Minus',
|
||||||
|
'PHPParser_Node_Expr_Mod' => 'PhpParser\Node\Expr\BinaryOp\Mod',
|
||||||
|
'PHPParser_Node_Expr_Mul' => 'PhpParser\Node\Expr\BinaryOp\Mul',
|
||||||
|
'PHPParser_Node_Expr_NotEqual' => 'PhpParser\Node\Expr\BinaryOp\NotEqual',
|
||||||
|
'PHPParser_Node_Expr_NotIdentical' => 'PhpParser\Node\Expr\BinaryOp\NotIdentical',
|
||||||
|
'PHPParser_Node_Expr_Plus' => 'PhpParser\Node\Expr\BinaryOp\Plus',
|
||||||
|
'PHPParser_Node_Expr_ShiftLeft' => 'PhpParser\Node\Expr\BinaryOp\ShiftLeft',
|
||||||
|
'PHPParser_Node_Expr_ShiftRight' => 'PhpParser\Node\Expr\BinaryOp\ShiftRight',
|
||||||
|
'PHPParser_Node_Expr_Smaller' => 'PhpParser\Node\Expr\BinaryOp\Smaller',
|
||||||
|
'PHPParser_Node_Expr_SmallerOrEqual' => 'PhpParser\Node\Expr\BinaryOp\SmallerOrEqual',
|
||||||
|
|
||||||
|
'PHPParser_Node_Expr_Array' => 'PhpParser\Node\Expr\Array_',
|
||||||
|
'PHPParser_Node_Expr_ArrayDimFetch' => 'PhpParser\Node\Expr\ArrayDimFetch',
|
||||||
|
'PHPParser_Node_Expr_ArrayItem' => 'PhpParser\Node\Expr\ArrayItem',
|
||||||
|
'PHPParser_Node_Expr_Assign' => 'PhpParser\Node\Expr\Assign',
|
||||||
|
'PHPParser_Node_Expr_AssignRef' => 'PhpParser\Node\Expr\AssignRef',
|
||||||
|
'PHPParser_Node_Expr_BitwiseNot' => 'PhpParser\Node\Expr\BitwiseNot',
|
||||||
|
'PHPParser_Node_Expr_BooleanNot' => 'PhpParser\Node\Expr\BooleanNot',
|
||||||
|
'PHPParser_Node_Expr_ClassConstFetch' => 'PhpParser\Node\Expr\ClassConstFetch',
|
||||||
|
'PHPParser_Node_Expr_Clone' => 'PhpParser\Node\Expr\Clone_',
|
||||||
|
'PHPParser_Node_Expr_Closure' => 'PhpParser\Node\Expr\Closure',
|
||||||
|
'PHPParser_Node_Expr_ClosureUse' => 'PhpParser\Node\Expr\ClosureUse',
|
||||||
|
'PHPParser_Node_Expr_ConstFetch' => 'PhpParser\Node\Expr\ConstFetch',
|
||||||
|
'PHPParser_Node_Expr_Empty' => 'PhpParser\Node\Expr\Empty_',
|
||||||
|
'PHPParser_Node_Expr_ErrorSuppress' => 'PhpParser\Node\Expr\ErrorSuppress',
|
||||||
|
'PHPParser_Node_Expr_Eval' => 'PhpParser\Node\Expr\Eval_',
|
||||||
|
'PHPParser_Node_Expr_Exit' => 'PhpParser\Node\Expr\Exit_',
|
||||||
|
'PHPParser_Node_Expr_FuncCall' => 'PhpParser\Node\Expr\FuncCall',
|
||||||
|
'PHPParser_Node_Expr_Include' => 'PhpParser\Node\Expr\Include_',
|
||||||
|
'PHPParser_Node_Expr_Instanceof' => 'PhpParser\Node\Expr\Instanceof_',
|
||||||
|
'PHPParser_Node_Expr_Isset' => 'PhpParser\Node\Expr\Isset_',
|
||||||
|
'PHPParser_Node_Expr_List' => 'PhpParser\Node\Expr\List_',
|
||||||
|
'PHPParser_Node_Expr_MethodCall' => 'PhpParser\Node\Expr\MethodCall',
|
||||||
|
'PHPParser_Node_Expr_New' => 'PhpParser\Node\Expr\New_',
|
||||||
|
'PHPParser_Node_Expr_PostDec' => 'PhpParser\Node\Expr\PostDec',
|
||||||
|
'PHPParser_Node_Expr_PostInc' => 'PhpParser\Node\Expr\PostInc',
|
||||||
|
'PHPParser_Node_Expr_PreDec' => 'PhpParser\Node\Expr\PreDec',
|
||||||
|
'PHPParser_Node_Expr_PreInc' => 'PhpParser\Node\Expr\PreInc',
|
||||||
|
'PHPParser_Node_Expr_Print' => 'PhpParser\Node\Expr\Print_',
|
||||||
|
'PHPParser_Node_Expr_PropertyFetch' => 'PhpParser\Node\Expr\PropertyFetch',
|
||||||
|
'PHPParser_Node_Expr_ShellExec' => 'PhpParser\Node\Expr\ShellExec',
|
||||||
|
'PHPParser_Node_Expr_StaticCall' => 'PhpParser\Node\Expr\StaticCall',
|
||||||
|
'PHPParser_Node_Expr_StaticPropertyFetch' => 'PhpParser\Node\Expr\StaticPropertyFetch',
|
||||||
|
'PHPParser_Node_Expr_Ternary' => 'PhpParser\Node\Expr\Ternary',
|
||||||
|
'PHPParser_Node_Expr_UnaryMinus' => 'PhpParser\Node\Expr\UnaryMinus',
|
||||||
|
'PHPParser_Node_Expr_UnaryPlus' => 'PhpParser\Node\Expr\UnaryPlus',
|
||||||
|
'PHPParser_Node_Expr_Variable' => 'PhpParser\Node\Expr\Variable',
|
||||||
|
'PHPParser_Node_Expr_Yield' => 'PhpParser\Node\Expr\Yield_',
|
||||||
|
|
||||||
|
'PHPParser_Node_Scalar_ClassConst' => 'PhpParser\Node\Scalar\MagicConst\Class_',
|
||||||
|
'PHPParser_Node_Scalar_DirConst' => 'PhpParser\Node\Scalar\MagicConst\Dir',
|
||||||
|
'PHPParser_Node_Scalar_FileConst' => 'PhpParser\Node\Scalar\MagicConst\File',
|
||||||
|
'PHPParser_Node_Scalar_FuncConst' => 'PhpParser\Node\Scalar\MagicConst\Function_',
|
||||||
|
'PHPParser_Node_Scalar_LineConst' => 'PhpParser\Node\Scalar\MagicConst\Line',
|
||||||
|
'PHPParser_Node_Scalar_MethodConst' => 'PhpParser\Node\Scalar\MagicConst\Method',
|
||||||
|
'PHPParser_Node_Scalar_NSConst' => 'PhpParser\Node\Scalar\MagicConst\Namespace_',
|
||||||
|
'PHPParser_Node_Scalar_TraitConst' => 'PhpParser\Node\Scalar\MagicConst\Trait_',
|
||||||
|
|
||||||
|
'PHPParser_Node_Scalar_DNumber' => 'PhpParser\Node\Scalar\DNumber',
|
||||||
|
'PHPParser_Node_Scalar_Encapsed' => 'PhpParser\Node\Scalar\Encapsed',
|
||||||
|
'PHPParser_Node_Scalar_LNumber' => 'PhpParser\Node\Scalar\LNumber',
|
||||||
|
'PHPParser_Node_Scalar_String' => 'PhpParser\Node\Scalar\String_',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class_alias('PhpParser\Autoloader', 'PHPParser_Autoloader');
|
||||||
|
@ -2,8 +2,6 @@
|
|||||||
|
|
||||||
namespace PhpParser;
|
namespace PhpParser;
|
||||||
|
|
||||||
use PhpParser\Parser\Tokens;
|
|
||||||
|
|
||||||
class Lexer
|
class Lexer
|
||||||
{
|
{
|
||||||
protected $code;
|
protected $code;
|
||||||
@ -67,21 +65,14 @@ class Lexer
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected function resetErrors() {
|
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_get_last() to defined state by forcing an undefined variable error
|
||||||
set_error_handler(function() { return false; }, 0);
|
set_error_handler(function() { return false; }, 0);
|
||||||
@$undefinedVariable;
|
@$undefinedVariable;
|
||||||
restore_error_handler();
|
restore_error_handler();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
protected function handleErrors() {
|
protected function handleErrors() {
|
||||||
$error = error_get_last();
|
$error = error_get_last();
|
||||||
if (null === $error) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (preg_match(
|
if (preg_match(
|
||||||
'~^Unterminated comment starting line ([0-9]+)$~',
|
'~^Unterminated comment starting line ([0-9]+)$~',
|
||||||
@ -263,18 +254,18 @@ class Lexer
|
|||||||
for ($i = 256; $i < 1000; ++$i) {
|
for ($i = 256; $i < 1000; ++$i) {
|
||||||
if (T_DOUBLE_COLON === $i) {
|
if (T_DOUBLE_COLON === $i) {
|
||||||
// T_DOUBLE_COLON is equivalent to T_PAAMAYIM_NEKUDOTAYIM
|
// T_DOUBLE_COLON is equivalent to T_PAAMAYIM_NEKUDOTAYIM
|
||||||
$tokenMap[$i] = Tokens::T_PAAMAYIM_NEKUDOTAYIM;
|
$tokenMap[$i] = Parser::T_PAAMAYIM_NEKUDOTAYIM;
|
||||||
} elseif(T_OPEN_TAG_WITH_ECHO === $i) {
|
} elseif(T_OPEN_TAG_WITH_ECHO === $i) {
|
||||||
// T_OPEN_TAG_WITH_ECHO with dropped T_OPEN_TAG results in T_ECHO
|
// T_OPEN_TAG_WITH_ECHO with dropped T_OPEN_TAG results in T_ECHO
|
||||||
$tokenMap[$i] = Tokens::T_ECHO;
|
$tokenMap[$i] = Parser::T_ECHO;
|
||||||
} elseif(T_CLOSE_TAG === $i) {
|
} elseif(T_CLOSE_TAG === $i) {
|
||||||
// T_CLOSE_TAG is equivalent to ';'
|
// T_CLOSE_TAG is equivalent to ';'
|
||||||
$tokenMap[$i] = ord(';');
|
$tokenMap[$i] = ord(';');
|
||||||
} elseif ('UNKNOWN' !== $name = token_name($i)) {
|
} elseif ('UNKNOWN' !== $name = token_name($i)) {
|
||||||
if ('T_HASHBANG' === $name) {
|
if ('T_HASHBANG' === $name) {
|
||||||
// HHVM uses a special token for #! hashbang lines
|
// HHVM uses a special token for #! hashbang lines
|
||||||
$tokenMap[$i] = Tokens::T_INLINE_HTML;
|
$tokenMap[$i] = Parser::T_INLINE_HTML;
|
||||||
} else if (defined($name = 'PhpParser\Parser\Tokens::' . $name)) {
|
} else if (defined($name = 'PhpParser\Parser::' . $name)) {
|
||||||
// Other tokens can be mapped directly
|
// Other tokens can be mapped directly
|
||||||
$tokenMap[$i] = constant($name);
|
$tokenMap[$i] = constant($name);
|
||||||
}
|
}
|
||||||
@ -283,11 +274,11 @@ class Lexer
|
|||||||
|
|
||||||
// HHVM uses a special token for numbers that overflow to double
|
// HHVM uses a special token for numbers that overflow to double
|
||||||
if (defined('T_ONUMBER')) {
|
if (defined('T_ONUMBER')) {
|
||||||
$tokenMap[T_ONUMBER] = Tokens::T_DNUMBER;
|
$tokenMap[T_ONUMBER] = Parser::T_DNUMBER;
|
||||||
}
|
}
|
||||||
// HHVM also has a separate token for the __COMPILER_HALT_OFFSET__ constant
|
// HHVM also has a separate token for the __COMPILER_HALT_OFFSET__ constant
|
||||||
if (defined('T_COMPILER_HALT_OFFSET')) {
|
if (defined('T_COMPILER_HALT_OFFSET')) {
|
||||||
$tokenMap[T_COMPILER_HALT_OFFSET] = Tokens::T_STRING;
|
$tokenMap[T_COMPILER_HALT_OFFSET] = Parser::T_STRING;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $tokenMap;
|
return $tokenMap;
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace PhpParser\Lexer;
|
namespace PhpParser\Lexer;
|
||||||
|
|
||||||
use PhpParser\Parser\Tokens;
|
use PhpParser\Parser;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ATTENTION: This code is WRITE-ONLY. Do not try to read it.
|
* ATTENTION: This code is WRITE-ONLY. Do not try to read it.
|
||||||
@ -22,14 +22,21 @@ class Emulative extends \PhpParser\Lexer
|
|||||||
const PHP_7_0 = '7.0.0dev';
|
const PHP_7_0 = '7.0.0dev';
|
||||||
const PHP_5_6 = '5.6.0rc1';
|
const PHP_5_6 = '5.6.0rc1';
|
||||||
const PHP_5_5 = '5.5.0beta1';
|
const PHP_5_5 = '5.5.0beta1';
|
||||||
|
const PHP_5_4 = '5.4.0beta1';
|
||||||
|
|
||||||
public function __construct(array $options = array()) {
|
public function __construct(array $options = array()) {
|
||||||
parent::__construct($options);
|
parent::__construct($options);
|
||||||
|
|
||||||
$newKeywordsPerVersion = array(
|
$newKeywordsPerVersion = array(
|
||||||
self::PHP_5_5 => array(
|
self::PHP_5_5 => array(
|
||||||
'finally' => Tokens::T_FINALLY,
|
'finally' => Parser::T_FINALLY,
|
||||||
'yield' => Tokens::T_YIELD,
|
'yield' => Parser::T_YIELD,
|
||||||
|
),
|
||||||
|
self::PHP_5_4 => array(
|
||||||
|
'callable' => Parser::T_CALLABLE,
|
||||||
|
'insteadof' => Parser::T_INSTEADOF,
|
||||||
|
'trait' => Parser::T_TRAIT,
|
||||||
|
'__trait__' => Parser::T_TRAIT_C,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -45,16 +52,16 @@ class Emulative extends \PhpParser\Lexer
|
|||||||
if (version_compare(PHP_VERSION, self::PHP_7_0, '>=')) {
|
if (version_compare(PHP_VERSION, self::PHP_7_0, '>=')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$this->tokenMap[self::T_COALESCE] = Tokens::T_COALESCE;
|
$this->tokenMap[self::T_COALESCE] = Parser::T_COALESCE;
|
||||||
$this->tokenMap[self::T_SPACESHIP] = Tokens::T_SPACESHIP;
|
$this->tokenMap[self::T_SPACESHIP] = Parser::T_SPACESHIP;
|
||||||
$this->tokenMap[self::T_YIELD_FROM] = Tokens::T_YIELD_FROM;
|
$this->tokenMap[self::T_YIELD_FROM] = Parser::T_YIELD_FROM;
|
||||||
|
|
||||||
if (version_compare(PHP_VERSION, self::PHP_5_6, '>=')) {
|
if (version_compare(PHP_VERSION, self::PHP_5_6, '>=')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$this->tokenMap[self::T_ELLIPSIS] = Tokens::T_ELLIPSIS;
|
$this->tokenMap[self::T_ELLIPSIS] = Parser::T_ELLIPSIS;
|
||||||
$this->tokenMap[self::T_POW] = Tokens::T_POW;
|
$this->tokenMap[self::T_POW] = Parser::T_POW;
|
||||||
$this->tokenMap[self::T_POW_EQUAL] = Tokens::T_POW_EQUAL;
|
$this->tokenMap[self::T_POW_EQUAL] = Parser::T_POW_EQUAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function startLexing($code) {
|
public function startLexing($code) {
|
||||||
@ -99,9 +106,14 @@ class Emulative extends \PhpParser\Lexer
|
|||||||
$code = preg_replace('((?<!/)\*\*=)', '~__EMU__POWEQUAL__~', $code);
|
$code = preg_replace('((?<!/)\*\*=)', '~__EMU__POWEQUAL__~', $code);
|
||||||
$code = preg_replace('((?<!/)\*\*(?!/))', '~__EMU__POW__~', $code);
|
$code = preg_replace('((?<!/)\*\*(?!/))', '~__EMU__POW__~', $code);
|
||||||
|
|
||||||
|
if (version_compare(PHP_VERSION, self::PHP_5_4, '>=')) {
|
||||||
return $code;
|
return $code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// binary notation (0b010101101001...)
|
||||||
|
return preg_replace('(\b0b[01]+\b)', '~__EMU__BINARY__$0__~', $code);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Replaces the ~__EMU__...~ sequences with real tokens or their original
|
* Replaces the ~__EMU__...~ sequences with real tokens or their original
|
||||||
* value.
|
* value.
|
||||||
@ -118,7 +130,14 @@ class Emulative extends \PhpParser\Lexer
|
|||||||
&& T_STRING === $this->tokens[$i + 1][0]
|
&& T_STRING === $this->tokens[$i + 1][0]
|
||||||
&& preg_match('(^__EMU__([A-Z]++)__(?:([A-Za-z0-9]++)__)?$)', $this->tokens[$i + 1][1], $matches)
|
&& preg_match('(^__EMU__([A-Z]++)__(?:([A-Za-z0-9]++)__)?$)', $this->tokens[$i + 1][1], $matches)
|
||||||
) {
|
) {
|
||||||
if ('ELLIPSIS' === $matches[1]) {
|
if ('BINARY' === $matches[1]) {
|
||||||
|
// the binary number can either be an integer or a double, so return a LNUMBER
|
||||||
|
// or DNUMBER respectively
|
||||||
|
$isInt = is_int(bindec($matches[2]));
|
||||||
|
$replace = array(
|
||||||
|
array($isInt ? T_LNUMBER : T_DNUMBER, $matches[2], $this->tokens[$i + 1][2])
|
||||||
|
);
|
||||||
|
} else if ('ELLIPSIS' === $matches[1]) {
|
||||||
$replace = array(
|
$replace = array(
|
||||||
array(self::T_ELLIPSIS, '...', $this->tokens[$i + 1][2])
|
array(self::T_ELLIPSIS, '...', $this->tokens[$i + 1][2])
|
||||||
);
|
);
|
||||||
@ -139,7 +158,7 @@ class Emulative extends \PhpParser\Lexer
|
|||||||
array(self::T_SPACESHIP, '<=>', $this->tokens[$i + 1][2]),
|
array(self::T_SPACESHIP, '<=>', $this->tokens[$i + 1][2]),
|
||||||
);
|
);
|
||||||
} else if ('YIELDFROM' === $matches[1]) {
|
} else if ('YIELDFROM' === $matches[1]) {
|
||||||
$content = hex2bin($matches[2]);
|
$content = $this->hex2bin($matches[2]);
|
||||||
$replace = array(
|
$replace = array(
|
||||||
array(self::T_YIELD_FROM, $content, $this->tokens[$i + 1][2] - substr_count($content, "\n"))
|
array(self::T_YIELD_FROM, $content, $this->tokens[$i + 1][2] - substr_count($content, "\n"))
|
||||||
);
|
);
|
||||||
@ -168,7 +187,9 @@ class Emulative extends \PhpParser\Lexer
|
|||||||
* multichar tokens (like strings) to their original value.
|
* multichar tokens (like strings) to their original value.
|
||||||
*/
|
*/
|
||||||
public function restoreContentCallback(array $matches) {
|
public function restoreContentCallback(array $matches) {
|
||||||
if ('ELLIPSIS' === $matches[1]) {
|
if ('BINARY' === $matches[1]) {
|
||||||
|
return $matches[2];
|
||||||
|
} else if ('ELLIPSIS' === $matches[1]) {
|
||||||
return '...';
|
return '...';
|
||||||
} else if ('POW' === $matches[1]) {
|
} else if ('POW' === $matches[1]) {
|
||||||
return '**';
|
return '**';
|
||||||
@ -179,25 +200,30 @@ class Emulative extends \PhpParser\Lexer
|
|||||||
} else if ('SPACESHIP' === $matches[1]) {
|
} else if ('SPACESHIP' === $matches[1]) {
|
||||||
return '<=>';
|
return '<=>';
|
||||||
} else if ('YIELDFROM' === $matches[1]) {
|
} else if ('YIELDFROM' === $matches[1]) {
|
||||||
return hex2bin($matches[2]);
|
return $this->hex2bin($matches[2]);
|
||||||
} else {
|
} else {
|
||||||
return $matches[0];
|
return $matches[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function hex2bin($str) {
|
||||||
|
// TODO Drop when removing support for PHP 5.3
|
||||||
|
return pack('H*', $str);
|
||||||
|
}
|
||||||
|
|
||||||
public function getNextToken(&$value = null, &$startAttributes = null, &$endAttributes = null) {
|
public function getNextToken(&$value = null, &$startAttributes = null, &$endAttributes = null) {
|
||||||
$token = parent::getNextToken($value, $startAttributes, $endAttributes);
|
$token = parent::getNextToken($value, $startAttributes, $endAttributes);
|
||||||
|
|
||||||
// replace new keywords by their respective tokens. This is not done
|
// replace new keywords by their respective tokens. This is not done
|
||||||
// if we currently are in an object access (e.g. in $obj->namespace
|
// 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)
|
// "namespace" stays a T_STRING tokens and isn't converted to T_NAMESPACE)
|
||||||
if (Tokens::T_STRING === $token && !$this->inObjectAccess) {
|
if (Parser::T_STRING === $token && !$this->inObjectAccess) {
|
||||||
if (isset($this->newKeywords[strtolower($value)])) {
|
if (isset($this->newKeywords[strtolower($value)])) {
|
||||||
return $this->newKeywords[strtolower($value)];
|
return $this->newKeywords[strtolower($value)];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// keep track of whether we currently are in an object access (after ->)
|
// keep track of whether we currently are in an object access (after ->)
|
||||||
$this->inObjectAccess = Tokens::T_OBJECT_OPERATOR === $token;
|
$this->inObjectAccess = Parser::T_OBJECT_OPERATOR === $token;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $token;
|
return $token;
|
||||||
|
@ -22,7 +22,7 @@ class Arg extends NodeAbstract
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(Expr $value, $byRef = false, $unpack = false, array $attributes = array()) {
|
public function __construct(Expr $value, $byRef = false, $unpack = false, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->value = $value;
|
$this->value = $value;
|
||||||
$this->byRef = $byRef;
|
$this->byRef = $byRef;
|
||||||
$this->unpack = $unpack;
|
$this->unpack = $unpack;
|
||||||
|
@ -19,7 +19,7 @@ class Const_ extends NodeAbstract
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct($name, Expr $value, array $attributes = array()) {
|
public function __construct($name, Expr $value, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
$this->value = $value;
|
$this->value = $value;
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ class ArrayDimFetch extends Expr
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(Expr $var, Expr $dim = null, array $attributes = array()) {
|
public function __construct(Expr $var, Expr $dim = null, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->var = $var;
|
$this->var = $var;
|
||||||
$this->dim = $dim;
|
$this->dim = $dim;
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ class ArrayItem extends Expr
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(Expr $value, Expr $key = null, $byRef = false, array $attributes = array()) {
|
public function __construct(Expr $value, Expr $key = null, $byRef = false, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->key = $key;
|
$this->key = $key;
|
||||||
$this->value = $value;
|
$this->value = $value;
|
||||||
$this->byRef = $byRef;
|
$this->byRef = $byRef;
|
||||||
|
@ -16,7 +16,7 @@ class Array_ extends Expr
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(array $items = array(), array $attributes = array()) {
|
public function __construct(array $items = array(), array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->items = $items;
|
$this->items = $items;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ class Assign extends Expr
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(Expr $var, Expr $expr, array $attributes = array()) {
|
public function __construct(Expr $var, Expr $expr, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->var = $var;
|
$this->var = $var;
|
||||||
$this->expr = $expr;
|
$this->expr = $expr;
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ abstract class AssignOp extends Expr
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(Expr $var, Expr $expr, array $attributes = array()) {
|
public function __construct(Expr $var, Expr $expr, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->var = $var;
|
$this->var = $var;
|
||||||
$this->expr = $expr;
|
$this->expr = $expr;
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ class AssignRef extends Expr
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(Expr $var, Expr $expr, array $attributes = array()) {
|
public function __construct(Expr $var, Expr $expr, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->var = $var;
|
$this->var = $var;
|
||||||
$this->expr = $expr;
|
$this->expr = $expr;
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ abstract class BinaryOp extends Expr
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(Expr $left, Expr $right, array $attributes = array()) {
|
public function __construct(Expr $left, Expr $right, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->left = $left;
|
$this->left = $left;
|
||||||
$this->right = $right;
|
$this->right = $right;
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ class BitwiseNot extends Expr
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(Expr $expr, array $attributes = array()) {
|
public function __construct(Expr $expr, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->expr = $expr;
|
$this->expr = $expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ class BooleanNot extends Expr
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(Expr $expr, array $attributes = array()) {
|
public function __construct(Expr $expr, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->expr = $expr;
|
$this->expr = $expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ abstract class Cast extends Expr
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(Expr $expr, array $attributes = array()) {
|
public function __construct(Expr $expr, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->expr = $expr;
|
$this->expr = $expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ class ClassConstFetch extends Expr
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct($class, $name, array $attributes = array()) {
|
public function __construct($class, $name, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->class = $class;
|
$this->class = $class;
|
||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ class Clone_ extends Expr
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(Expr $expr, array $attributes = array()) {
|
public function __construct(Expr $expr, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->expr = $expr;
|
$this->expr = $expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ class Closure extends Expr implements FunctionLike
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(array $subNodes = array(), array $attributes = array()) {
|
public function __construct(array $subNodes = array(), array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->static = isset($subNodes['static']) ? $subNodes['static'] : false;
|
$this->static = isset($subNodes['static']) ? $subNodes['static'] : false;
|
||||||
$this->byRef = isset($subNodes['byRef']) ? $subNodes['byRef'] : false;
|
$this->byRef = isset($subNodes['byRef']) ? $subNodes['byRef'] : false;
|
||||||
$this->params = isset($subNodes['params']) ? $subNodes['params'] : array();
|
$this->params = isset($subNodes['params']) ? $subNodes['params'] : array();
|
||||||
|
@ -19,7 +19,7 @@ class ClosureUse extends Expr
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct($var, $byRef = false, array $attributes = array()) {
|
public function __construct($var, $byRef = false, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->var = $var;
|
$this->var = $var;
|
||||||
$this->byRef = $byRef;
|
$this->byRef = $byRef;
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ class ConstFetch extends Expr
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(Name $name, array $attributes = array()) {
|
public function __construct(Name $name, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ class Empty_ extends Expr
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(Expr $expr, array $attributes = array()) {
|
public function __construct(Expr $expr, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->expr = $expr;
|
$this->expr = $expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ class ErrorSuppress extends Expr
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(Expr $expr, array $attributes = array()) {
|
public function __construct(Expr $expr, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->expr = $expr;
|
$this->expr = $expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ class Eval_ extends Expr
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(Expr $expr, array $attributes = array()) {
|
public function __construct(Expr $expr, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->expr = $expr;
|
$this->expr = $expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ class Exit_ extends Expr
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(Expr $expr = null, array $attributes = array()) {
|
public function __construct(Expr $expr = null, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->expr = $expr;
|
$this->expr = $expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ class FuncCall extends Expr
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct($name, array $args = array(), array $attributes = array()) {
|
public function __construct($name, array $args = array(), array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
$this->args = $args;
|
$this->args = $args;
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ class Include_ extends Expr
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(Expr $expr, $type, array $attributes = array()) {
|
public function __construct(Expr $expr, $type, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->expr = $expr;
|
$this->expr = $expr;
|
||||||
$this->type = $type;
|
$this->type = $type;
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ class Instanceof_ extends Expr
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(Expr $expr, $class, array $attributes = array()) {
|
public function __construct(Expr $expr, $class, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->expr = $expr;
|
$this->expr = $expr;
|
||||||
$this->class = $class;
|
$this->class = $class;
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ class Isset_ extends Expr
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(array $vars, array $attributes = array()) {
|
public function __construct(array $vars, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->vars = $vars;
|
$this->vars = $vars;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ class List_ extends Expr
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(array $vars, array $attributes = array()) {
|
public function __construct(array $vars, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->vars = $vars;
|
$this->vars = $vars;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ class MethodCall extends Expr
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(Expr $var, $name, array $args = array(), array $attributes = array()) {
|
public function __construct(Expr $var, $name, array $args = array(), array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->var = $var;
|
$this->var = $var;
|
||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
$this->args = $args;
|
$this->args = $args;
|
||||||
|
@ -20,7 +20,7 @@ class New_ extends Expr
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct($class, array $args = array(), array $attributes = array()) {
|
public function __construct($class, array $args = array(), array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->class = $class;
|
$this->class = $class;
|
||||||
$this->args = $args;
|
$this->args = $args;
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ class PostDec extends Expr
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(Expr $var, array $attributes = array()) {
|
public function __construct(Expr $var, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->var = $var;
|
$this->var = $var;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ class PostInc extends Expr
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(Expr $var, array $attributes = array()) {
|
public function __construct(Expr $var, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->var = $var;
|
$this->var = $var;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ class PreDec extends Expr
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(Expr $var, array $attributes = array()) {
|
public function __construct(Expr $var, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->var = $var;
|
$this->var = $var;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ class PreInc extends Expr
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(Expr $var, array $attributes = array()) {
|
public function __construct(Expr $var, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->var = $var;
|
$this->var = $var;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ class Print_ extends Expr
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(Expr $expr, array $attributes = array()) {
|
public function __construct(Expr $expr, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->expr = $expr;
|
$this->expr = $expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ class PropertyFetch extends Expr
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(Expr $var, $name, array $attributes = array()) {
|
public function __construct(Expr $var, $name, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->var = $var;
|
$this->var = $var;
|
||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ class ShellExec extends Expr
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(array $parts, array $attributes = array()) {
|
public function __construct(array $parts, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->parts = $parts;
|
$this->parts = $parts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ class StaticCall extends Expr
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct($class, $name, array $args = array(), array $attributes = array()) {
|
public function __construct($class, $name, array $args = array(), array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->class = $class;
|
$this->class = $class;
|
||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
$this->args = $args;
|
$this->args = $args;
|
||||||
|
@ -20,7 +20,7 @@ class StaticPropertyFetch extends Expr
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct($class, $name, array $attributes = array()) {
|
public function __construct($class, $name, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->class = $class;
|
$this->class = $class;
|
||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ class Ternary extends Expr
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(Expr $cond, $if, Expr $else, array $attributes = array()) {
|
public function __construct(Expr $cond, $if, Expr $else, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->cond = $cond;
|
$this->cond = $cond;
|
||||||
$this->if = $if;
|
$this->if = $if;
|
||||||
$this->else = $else;
|
$this->else = $else;
|
||||||
|
@ -16,7 +16,7 @@ class UnaryMinus extends Expr
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(Expr $expr, array $attributes = array()) {
|
public function __construct(Expr $expr, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->expr = $expr;
|
$this->expr = $expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ class UnaryPlus extends Expr
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(Expr $expr, array $attributes = array()) {
|
public function __construct(Expr $expr, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->expr = $expr;
|
$this->expr = $expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ class Variable extends Expr
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct($name, array $attributes = array()) {
|
public function __construct($name, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ class YieldFrom extends Expr
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(Expr $expr, array $attributes = array()) {
|
public function __construct(Expr $expr, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->expr = $expr;
|
$this->expr = $expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ class Yield_ extends Expr
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(Expr $value = null, Expr $key = null, array $attributes = array()) {
|
public function __construct(Expr $value = null, Expr $key = null, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->key = $key;
|
$this->key = $key;
|
||||||
$this->value = $value;
|
$this->value = $value;
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ class Name extends NodeAbstract
|
|||||||
$parts = explode('\\', $parts);
|
$parts = explode('\\', $parts);
|
||||||
}
|
}
|
||||||
|
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->parts = $parts;
|
$this->parts = $parts;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,45 +106,37 @@ class Name extends NodeAbstract
|
|||||||
/**
|
/**
|
||||||
* Sets the whole name.
|
* Sets the whole name.
|
||||||
*
|
*
|
||||||
* @deprecated Create a new Name instead, or manually modify the $parts property
|
|
||||||
*
|
|
||||||
* @param string|array|self $name The name to set the whole name to
|
* @param string|array|self $name The name to set the whole name to
|
||||||
*/
|
*/
|
||||||
public function set($name) {
|
public function set($name) {
|
||||||
$this->parts = self::prepareName($name);
|
$this->parts = $this->prepareName($name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepends a name to this name.
|
* Prepends a name to this name.
|
||||||
*
|
*
|
||||||
* @deprecated Use Name::concat($name1, $name2) instead
|
|
||||||
*
|
|
||||||
* @param string|array|self $name Name to prepend
|
* @param string|array|self $name Name to prepend
|
||||||
*/
|
*/
|
||||||
public function prepend($name) {
|
public function prepend($name) {
|
||||||
$this->parts = array_merge(self::prepareName($name), $this->parts);
|
$this->parts = array_merge($this->prepareName($name), $this->parts);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Appends a name to this name.
|
* Appends a name to this name.
|
||||||
*
|
*
|
||||||
* @deprecated Use Name::concat($name1, $name2) instead
|
|
||||||
*
|
|
||||||
* @param string|array|self $name Name to append
|
* @param string|array|self $name Name to append
|
||||||
*/
|
*/
|
||||||
public function append($name) {
|
public function append($name) {
|
||||||
$this->parts = array_merge($this->parts, self::prepareName($name));
|
$this->parts = array_merge($this->parts, $this->prepareName($name));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the first part of the name.
|
* Sets the first part of the name.
|
||||||
*
|
*
|
||||||
* @deprecated Use concat($first, $name->slice(1)) instead
|
|
||||||
*
|
|
||||||
* @param string|array|self $name The name to set the first part to
|
* @param string|array|self $name The name to set the first part to
|
||||||
*/
|
*/
|
||||||
public function setFirst($name) {
|
public function setFirst($name) {
|
||||||
array_splice($this->parts, 0, 1, self::prepareName($name));
|
array_splice($this->parts, 0, 1, $this->prepareName($name));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -153,47 +145,7 @@ class Name extends NodeAbstract
|
|||||||
* @param string|array|self $name The name to set the last part to
|
* @param string|array|self $name The name to set the last part to
|
||||||
*/
|
*/
|
||||||
public function setLast($name) {
|
public function setLast($name) {
|
||||||
array_splice($this->parts, -1, 1, self::prepareName($name));
|
array_splice($this->parts, -1, 1, $this->prepareName($name));
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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, a Name with an empty parts array is returned. While this is
|
|
||||||
* meaningless in itself, it works correctly in conjunction with concat().
|
|
||||||
*
|
|
||||||
* @param int $offset Offset to start the slice at
|
|
||||||
*
|
|
||||||
* @return static Sliced name
|
|
||||||
*/
|
|
||||||
public function slice($offset) {
|
|
||||||
// TODO negative offset and length
|
|
||||||
if ($offset < 0 || $offset > count($this->parts)) {
|
|
||||||
throw new \OutOfBoundsException(sprintf('Offset %d is out of bounds', $offset));
|
|
||||||
}
|
|
||||||
|
|
||||||
return new static(array_slice($this->parts, $offset), $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.
|
|
||||||
*
|
|
||||||
* @param string|array|self $name1 The first name
|
|
||||||
* @param string|array|self $name2 The second name
|
|
||||||
* @param array $attributes Attributes to assign to concatenated name
|
|
||||||
*
|
|
||||||
* @return static Concatenated name
|
|
||||||
*/
|
|
||||||
public static function concat($name1, $name2, array $attributes = []) {
|
|
||||||
return new static(
|
|
||||||
array_merge(self::prepareName($name1), self::prepareName($name2)), $attributes
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -204,7 +156,7 @@ class Name extends NodeAbstract
|
|||||||
*
|
*
|
||||||
* @return array Prepared name
|
* @return array Prepared name
|
||||||
*/
|
*/
|
||||||
private static function prepareName($name) {
|
protected function prepareName($name) {
|
||||||
if (is_string($name)) {
|
if (is_string($name)) {
|
||||||
return explode('\\', $name);
|
return explode('\\', $name);
|
||||||
} elseif (is_array($name)) {
|
} elseif (is_array($name)) {
|
||||||
|
@ -29,7 +29,7 @@ class Param extends NodeAbstract
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct($name, Expr $default = null, $type = null, $byRef = false, $variadic = false, array $attributes = array()) {
|
public function __construct($name, Expr $default = null, $type = null, $byRef = false, $variadic = false, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->type = $type;
|
$this->type = $type;
|
||||||
$this->byRef = $byRef;
|
$this->byRef = $byRef;
|
||||||
$this->variadic = $variadic;
|
$this->variadic = $variadic;
|
||||||
|
@ -15,8 +15,8 @@ class DNumber extends Scalar
|
|||||||
* @param float $value Value of the number
|
* @param float $value Value of the number
|
||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct($value, array $attributes = array()) {
|
public function __construct($value = 0.0, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->value = $value;
|
$this->value = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,8 +15,8 @@ class Encapsed extends Scalar
|
|||||||
* @param array $parts Encaps list
|
* @param array $parts Encaps list
|
||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(array $parts, array $attributes = array()) {
|
public function __construct(array $parts = array(), array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->parts = $parts;
|
$this->parts = $parts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,26 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace PhpParser\Node\Scalar;
|
|
||||||
|
|
||||||
use PhpParser\Node\Scalar;
|
|
||||||
|
|
||||||
class EncapsedStringPart extends Scalar
|
|
||||||
{
|
|
||||||
/** @var string String value */
|
|
||||||
public $value;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a node representing a string part of an encapsed string.
|
|
||||||
*
|
|
||||||
* @param string $value String value
|
|
||||||
* @param array $attributes Additional attributes
|
|
||||||
*/
|
|
||||||
public function __construct($value, array $attributes = array()) {
|
|
||||||
parent::__construct($attributes);
|
|
||||||
$this->value = $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getSubNodeNames() {
|
|
||||||
return array('value');
|
|
||||||
}
|
|
||||||
}
|
|
@ -15,8 +15,8 @@ class LNumber extends Scalar
|
|||||||
* @param int $value Value of the number
|
* @param int $value Value of the number
|
||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct($value, array $attributes = array()) {
|
public function __construct($value = 0, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->value = $value;
|
$this->value = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ abstract class MagicConst extends Scalar
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(array $attributes = array()) {
|
public function __construct(array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSubNodeNames() {
|
public function getSubNodeNames() {
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
namespace PhpParser\Node\Scalar;
|
namespace PhpParser\Node\Scalar;
|
||||||
|
|
||||||
use PhpParser\Error;
|
|
||||||
use PhpParser\Node\Scalar;
|
use PhpParser\Node\Scalar;
|
||||||
|
|
||||||
class String_ extends Scalar
|
class String_ extends Scalar
|
||||||
@ -27,8 +26,8 @@ class String_ extends Scalar
|
|||||||
* @param string $value Value of the string
|
* @param string $value Value of the string
|
||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct($value, array $attributes = array()) {
|
public function __construct($value = '', array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->value = $value;
|
$this->value = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,11 +41,10 @@ class String_ extends Scalar
|
|||||||
* Parses a string token.
|
* Parses a string token.
|
||||||
*
|
*
|
||||||
* @param string $str String token content
|
* @param string $str String token content
|
||||||
* @param bool $parseUnicodeEscape Whether to parse PHP 7 \u escapes
|
|
||||||
*
|
*
|
||||||
* @return string The parsed string
|
* @return string The parsed string
|
||||||
*/
|
*/
|
||||||
public static function parse($str, $parseUnicodeEscape = true) {
|
public static function parse($str) {
|
||||||
$bLength = 0;
|
$bLength = 0;
|
||||||
if ('b' === $str[0]) {
|
if ('b' === $str[0]) {
|
||||||
$bLength = 1;
|
$bLength = 1;
|
||||||
@ -59,9 +57,7 @@ class String_ extends Scalar
|
|||||||
substr($str, $bLength + 1, -1)
|
substr($str, $bLength + 1, -1)
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return self::parseEscapeSequences(
|
return self::parseEscapeSequences(substr($str, $bLength + 1, -1), '"');
|
||||||
substr($str, $bLength + 1, -1), '"', $parseUnicodeEscape
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,54 +68,31 @@ class String_ extends Scalar
|
|||||||
*
|
*
|
||||||
* @param string $str String without quotes
|
* @param string $str String without quotes
|
||||||
* @param null|string $quote Quote type
|
* @param null|string $quote Quote type
|
||||||
* @param bool $parseUnicodeEscape Whether to parse PHP 7 \u escapes
|
|
||||||
*
|
*
|
||||||
* @return string String with escape sequences parsed
|
* @return string String with escape sequences parsed
|
||||||
*/
|
*/
|
||||||
public static function parseEscapeSequences($str, $quote, $parseUnicodeEscape = true) {
|
public static function parseEscapeSequences($str, $quote) {
|
||||||
if (null !== $quote) {
|
if (null !== $quote) {
|
||||||
$str = str_replace('\\' . $quote, $quote, $str);
|
$str = str_replace('\\' . $quote, $quote, $str);
|
||||||
}
|
}
|
||||||
|
|
||||||
$extra = '';
|
return preg_replace_callback(
|
||||||
if ($parseUnicodeEscape) {
|
'~\\\\([\\\\$nrtfve]|[xX][0-9a-fA-F]{1,2}|[0-7]{1,3})~',
|
||||||
$extra = '|u\{([0-9a-fA-F]+)\}';
|
array(__CLASS__, 'parseCallback'),
|
||||||
|
$str
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return preg_replace_callback(
|
private static function parseCallback($matches) {
|
||||||
'~\\\\([\\\\$nrtfve]|[xX][0-9a-fA-F]{1,2}|[0-7]{1,3}' . $extra . ')~',
|
|
||||||
function($matches) {
|
|
||||||
$str = $matches[1];
|
$str = $matches[1];
|
||||||
|
|
||||||
if (isset(self::$replacements[$str])) {
|
if (isset(self::$replacements[$str])) {
|
||||||
return self::$replacements[$str];
|
return self::$replacements[$str];
|
||||||
} elseif ('x' === $str[0] || 'X' === $str[0]) {
|
} elseif ('x' === $str[0] || 'X' === $str[0]) {
|
||||||
return chr(hexdec($str));
|
return chr(hexdec($str));
|
||||||
} elseif ('u' === $str[0]) {
|
|
||||||
return self::codePointToUtf8(hexdec($matches[2]));
|
|
||||||
} else {
|
} else {
|
||||||
return chr(octdec($str));
|
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');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -129,11 +102,10 @@ class String_ extends Scalar
|
|||||||
*
|
*
|
||||||
* @param string $startToken Doc string start token content (<<<SMTHG)
|
* @param string $startToken Doc string start token content (<<<SMTHG)
|
||||||
* @param string $str String token content
|
* @param string $str String token content
|
||||||
* @param bool $parseUnicodeEscape Whether to parse PHP 7 \u escapes
|
|
||||||
*
|
*
|
||||||
* @return string Parsed string
|
* @return string Parsed string
|
||||||
*/
|
*/
|
||||||
public static function parseDocString($startToken, $str, $parseUnicodeEscape = true) {
|
public static function parseDocString($startToken, $str) {
|
||||||
// strip last newline (thanks tokenizer for sticking it into the string!)
|
// strip last newline (thanks tokenizer for sticking it into the string!)
|
||||||
$str = preg_replace('~(\r\n|\n|\r)\z~', '', $str);
|
$str = preg_replace('~(\r\n|\n|\r)\z~', '', $str);
|
||||||
|
|
||||||
@ -142,6 +114,6 @@ class String_ extends Scalar
|
|||||||
return $str;
|
return $str;
|
||||||
}
|
}
|
||||||
|
|
||||||
return self::parseEscapeSequences($str, null, $parseUnicodeEscape);
|
return self::parseEscapeSequences($str, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ class Break_ extends Node\Stmt
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(Node\Expr $num = null, array $attributes = array()) {
|
public function __construct(Node\Expr $num = null, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->num = $num;
|
$this->num = $num;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ class Case_ extends Node\Stmt
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct($cond, array $stmts = array(), array $attributes = array()) {
|
public function __construct($cond, array $stmts = array(), array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->cond = $cond;
|
$this->cond = $cond;
|
||||||
$this->stmts = $stmts;
|
$this->stmts = $stmts;
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ class Catch_ extends Node\Stmt
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(Node\Name $type, $var, array $stmts = array(), array $attributes = array()) {
|
public function __construct(Node\Name $type, $var, array $stmts = array(), array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->type = $type;
|
$this->type = $type;
|
||||||
$this->var = $var;
|
$this->var = $var;
|
||||||
$this->stmts = $stmts;
|
$this->stmts = $stmts;
|
||||||
|
@ -16,7 +16,7 @@ class ClassConst extends Node\Stmt
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(array $consts, array $attributes = array()) {
|
public function __construct(array $consts, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->consts = $consts;
|
$this->consts = $consts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ class ClassMethod extends Node\Stmt implements FunctionLike
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct($name, array $subNodes = array(), array $attributes = array()) {
|
public function __construct($name, array $subNodes = array(), array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->type = isset($subNodes['type']) ? $subNodes['type'] : 0;
|
$this->type = isset($subNodes['type']) ? $subNodes['type'] : 0;
|
||||||
$this->byRef = isset($subNodes['byRef']) ? $subNodes['byRef'] : false;
|
$this->byRef = isset($subNodes['byRef']) ? $subNodes['byRef'] : false;
|
||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
|
@ -41,7 +41,7 @@ class Class_ extends ClassLike
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct($name, array $subNodes = array(), array $attributes = array()) {
|
public function __construct($name, array $subNodes = array(), array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->type = isset($subNodes['type']) ? $subNodes['type'] : 0;
|
$this->type = isset($subNodes['type']) ? $subNodes['type'] : 0;
|
||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
$this->extends = isset($subNodes['extends']) ? $subNodes['extends'] : null;
|
$this->extends = isset($subNodes['extends']) ? $subNodes['extends'] : null;
|
||||||
|
@ -16,7 +16,7 @@ class Const_ extends Node\Stmt
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(array $consts, array $attributes = array()) {
|
public function __construct(array $consts, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->consts = $consts;
|
$this->consts = $consts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ class Continue_ extends Node\Stmt
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(Node\Expr $num = null, array $attributes = array()) {
|
public function __construct(Node\Expr $num = null, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->num = $num;
|
$this->num = $num;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ class DeclareDeclare extends Node\Stmt
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct($key, Node\Expr $value, array $attributes = array()) {
|
public function __construct($key, Node\Expr $value, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->key = $key;
|
$this->key = $key;
|
||||||
$this->value = $value;
|
$this->value = $value;
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ class Declare_ extends Node\Stmt
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(array $declares, array $stmts, array $attributes = array()) {
|
public function __construct(array $declares, array $stmts, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->declares = $declares;
|
$this->declares = $declares;
|
||||||
$this->stmts = $stmts;
|
$this->stmts = $stmts;
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ class Do_ extends Node\Stmt
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(Node\Expr $cond, array $stmts = array(), array $attributes = array()) {
|
public function __construct(Node\Expr $cond, array $stmts = array(), array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->cond = $cond;
|
$this->cond = $cond;
|
||||||
$this->stmts = $stmts;
|
$this->stmts = $stmts;
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ class Echo_ extends Node\Stmt
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(array $exprs, array $attributes = array()) {
|
public function __construct(array $exprs, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->exprs = $exprs;
|
$this->exprs = $exprs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ class ElseIf_ extends Node\Stmt
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(Node\Expr $cond, array $stmts = array(), array $attributes = array()) {
|
public function __construct(Node\Expr $cond, array $stmts = array(), array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->cond = $cond;
|
$this->cond = $cond;
|
||||||
$this->stmts = $stmts;
|
$this->stmts = $stmts;
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ class Else_ extends Node\Stmt
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(array $stmts = array(), array $attributes = array()) {
|
public function __construct(array $stmts = array(), array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->stmts = $stmts;
|
$this->stmts = $stmts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ class For_ extends Node\Stmt
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(array $subNodes = array(), array $attributes = array()) {
|
public function __construct(array $subNodes = array(), array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->init = isset($subNodes['init']) ? $subNodes['init'] : array();
|
$this->init = isset($subNodes['init']) ? $subNodes['init'] : array();
|
||||||
$this->cond = isset($subNodes['cond']) ? $subNodes['cond'] : array();
|
$this->cond = isset($subNodes['cond']) ? $subNodes['cond'] : array();
|
||||||
$this->loop = isset($subNodes['loop']) ? $subNodes['loop'] : array();
|
$this->loop = isset($subNodes['loop']) ? $subNodes['loop'] : array();
|
||||||
|
@ -29,7 +29,7 @@ class Foreach_ extends Node\Stmt
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(Node\Expr $expr, Node\Expr $valueVar, array $subNodes = array(), array $attributes = array()) {
|
public function __construct(Node\Expr $expr, Node\Expr $valueVar, array $subNodes = array(), array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->expr = $expr;
|
$this->expr = $expr;
|
||||||
$this->keyVar = isset($subNodes['keyVar']) ? $subNodes['keyVar'] : null;
|
$this->keyVar = isset($subNodes['keyVar']) ? $subNodes['keyVar'] : null;
|
||||||
$this->byRef = isset($subNodes['byRef']) ? $subNodes['byRef'] : false;
|
$this->byRef = isset($subNodes['byRef']) ? $subNodes['byRef'] : false;
|
||||||
|
@ -30,7 +30,7 @@ class Function_ extends Node\Stmt implements FunctionLike
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct($name, array $subNodes = array(), array $attributes = array()) {
|
public function __construct($name, array $subNodes = array(), array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->byRef = isset($subNodes['byRef']) ? $subNodes['byRef'] : false;
|
$this->byRef = isset($subNodes['byRef']) ? $subNodes['byRef'] : false;
|
||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
$this->params = isset($subNodes['params']) ? $subNodes['params'] : array();
|
$this->params = isset($subNodes['params']) ? $subNodes['params'] : array();
|
||||||
|
@ -16,7 +16,7 @@ class Global_ extends Node\Stmt
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(array $vars, array $attributes = array()) {
|
public function __construct(array $vars, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->vars = $vars;
|
$this->vars = $vars;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ class Goto_ extends Stmt
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct($name, array $attributes = array()) {
|
public function __construct($name, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,35 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace PhpParser\Node\Stmt;
|
|
||||||
|
|
||||||
use PhpParser\Node\Stmt;
|
|
||||||
use PhpParser\Node\Name;
|
|
||||||
|
|
||||||
class GroupUse extends Stmt
|
|
||||||
{
|
|
||||||
/** @var int Type of group use */
|
|
||||||
public $type;
|
|
||||||
/** @var Name Prefix for uses */
|
|
||||||
public $prefix;
|
|
||||||
/** @var UseUse[] Uses */
|
|
||||||
public $uses;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a group use node.
|
|
||||||
*
|
|
||||||
* @param Name $prefix Prefix for uses
|
|
||||||
* @param UseUse[] $uses Uses
|
|
||||||
* @param int $type Type of group use
|
|
||||||
* @param array $attributes Additional attributes
|
|
||||||
*/
|
|
||||||
public function __construct(Name $prefix, array $uses, $type = Use_::TYPE_NORMAL, array $attributes = array()) {
|
|
||||||
parent::__construct($attributes);
|
|
||||||
$this->type = $type;
|
|
||||||
$this->prefix = $prefix;
|
|
||||||
$this->uses = $uses;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getSubNodeNames() {
|
|
||||||
return array('type', 'prefix', 'uses');
|
|
||||||
}
|
|
||||||
}
|
|
@ -16,7 +16,7 @@ class HaltCompiler extends Stmt
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct($remaining, array $attributes = array()) {
|
public function __construct($remaining, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->remaining = $remaining;
|
$this->remaining = $remaining;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ class If_ extends Node\Stmt
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(Node\Expr $cond, array $subNodes = array(), array $attributes = array()) {
|
public function __construct(Node\Expr $cond, array $subNodes = array(), array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->cond = $cond;
|
$this->cond = $cond;
|
||||||
$this->stmts = isset($subNodes['stmts']) ? $subNodes['stmts'] : array();
|
$this->stmts = isset($subNodes['stmts']) ? $subNodes['stmts'] : array();
|
||||||
$this->elseifs = isset($subNodes['elseifs']) ? $subNodes['elseifs'] : array();
|
$this->elseifs = isset($subNodes['elseifs']) ? $subNodes['elseifs'] : array();
|
||||||
|
@ -16,7 +16,7 @@ class InlineHTML extends Stmt
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct($value, array $attributes = array()) {
|
public function __construct($value, array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->value = $value;
|
$this->value = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ class Interface_ extends ClassLike
|
|||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct($name, array $subNodes = array(), array $attributes = array()) {
|
public function __construct($name, array $subNodes = array(), array $attributes = array()) {
|
||||||
parent::__construct($attributes);
|
parent::__construct(null, $attributes);
|
||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
$this->extends = isset($subNodes['extends']) ? $subNodes['extends'] : array();
|
$this->extends = isset($subNodes['extends']) ? $subNodes['extends'] : array();
|
||||||
$this->stmts = isset($subNodes['stmts']) ? $subNodes['stmts'] : array();
|
$this->stmts = isset($subNodes['stmts']) ? $subNodes['stmts'] : array();
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user