Name Date Size #Lines LOC

..26-Dec-2020-

scripts/H05-Apr-2021-

tests/H05-Apr-2021-

.appveyor.ymlH A D05-Apr-202110 KiB237227

.editorconfigH A D22-Oct-2020369 2120

.gitignoreH A D06-Dec-2019396 3837

.travis.ymlH A D05-Apr-2021542 2621

LICENSEH A D06-Dec-20191.5 KiB3225

README.mdH A D05-Apr-202120.4 KiB596499

RELEASE_CHECKLISTH A D06-Dec-2019448 1312

ast.cH A D05-Apr-202145 KiB1,5411,294

ast.stub.phpH A D02-Oct-20202.1 KiB7413

ast_arginfo.hH A D07-Oct-20202.3 KiB6246

ast_data.cH A D05-Apr-202129.7 KiB844836

ast_str_defs.hH A D14-Jun-2020701 5552

ast_stub.phpH A D05-Apr-20218.4 KiB332237

config.m4H A D06-Dec-2019225 96

config.w32H A D06-Dec-2019135 95

package.xmlH A D05-Apr-202117.3 KiB467465

php_ast.hH A D05-Apr-20212.7 KiB10765

util.phpH A D26-Oct-20202.3 KiB8370

README.md

1php-ast
2=======
3
4This extension exposes the abstract syntax tree generated by PHP 7.
5
6**This is the documentation for version 1.0.x. See also [documentation for version 0.1.x][v0_1_x].**
7
8Table of Contents
9-----------------
10
11 * [Installation](#installation)
12 * [API overview](#api-overview)
13 * [Basic usage](#basic-usage)
14 * [Example](#example)
15 * [Metadata](#metadata)
16 * [Flags](#flags)
17 * [AST node kinds](#ast-node-kinds)
18 * [AST versioning](#ast-versioning)
19 * [Differences to PHP-Parser](#differences-to-php-parser)
20
21Installation
22------------
23
24**Windows**: Download a [prebuilt Windows DLL](http://windows.php.net/downloads/pecl/releases/ast/)
25and move it into the `ext/` directory of your PHP installation. Furthermore add
26`extension=php_ast.dll` to your `php.ini` file.
27
28**Unix (PECL)**: Run `pecl install ast` and add `extension=ast.so` to your `php.ini`.
29
30**Unix (Compile)**: Compile and install the extension as follows.
31
32```sh
33phpize
34./configure
35make
36sudo make install
37```
38
39Additionally add `extension=ast.so` to your `php.ini` file.
40
41API overview
42------------
43
44Defines:
45
46 * `ast\Node` class
47 * `ast\Metadata` class
48 * `ast\AST_*` kind constants
49 * `ast\flags\*` flag constants
50 * `ast\parse_file(string $filename, int $version)`
51 * `ast\parse_code(string $code, int $version [, string $filename = "string code"])`
52 * `ast\get_kind_name(int $kind)`
53 * `ast\kind_uses_flags(int $kind)`
54 * `ast\get_metadata()`
55 * `ast\get_supported_versions(bool $exclude_deprecated = false)`
56
57Basic usage
58-----------
59
60Code can be parsed using either `ast\parse_code()`, which accepts a code string, or
61`ast\parse_file()`, which accepts a file path. Additionally, both functions require a `$version`
62argument to ensure forward-compatibility. The current version is 70.
63
64```php
65$ast = ast\parse_code('<?php ...', $version=70);
66// or
67$ast = ast\parse_file('file.php', $version=70);
68```
69
70The abstract syntax tree returned by these functions consists of `ast\Node` objects.
71`ast\Node` is declared as follows:
72
73```php
74namespace ast;
75class Node {
76    public $kind;
77    public $flags;
78    public $lineno;
79    public $children;
80}
81```
82
83The `kind` property specifies the type of the node. It is an integral value, which corresponds to
84one of the `ast\AST_*` constants, for example `ast\AST_STMT_LIST`. See the
85[AST node kinds section](#ast-node-kinds) for an overview of the available node kinds.
86
87The `flags` property contains node specific flags. It is always defined, but for most nodes it is
88always zero. See the [flags section](#flags) for a list of flags supported by the different node
89kinds.
90
91The `lineno` property specifies the *starting* line number of the node.
92
93The `children` property contains an array of child-nodes. These children can be either other
94`ast\Node` objects or plain values. There are two general categories of nodes: Normal AST nodes,
95which have a fixed set of named child nodes, as well as list nodes, which have a variable number
96of children. The [AST node kinds section](#ast-node-kinds) contains a list of the child names for
97the different node kinds.
98
99Example
100-------
101
102Simple usage example:
103
104```php
105<?php
106
107$code = <<<'EOC'
108<?php
109$var = 42;
110EOC;
111
112var_dump(ast\parse_code($code, $version=70));
113
114// Output:
115object(ast\Node)#1 (4) {
116  ["kind"]=>
117  int(132)
118  ["flags"]=>
119  int(0)
120  ["lineno"]=>
121  int(1)
122  ["children"]=>
123  array(1) {
124    [0]=>
125    object(ast\Node)#2 (4) {
126      ["kind"]=>
127      int(517)
128      ["flags"]=>
129      int(0)
130      ["lineno"]=>
131      int(2)
132      ["children"]=>
133      array(2) {
134        ["var"]=>
135        object(ast\Node)#3 (4) {
136          ["kind"]=>
137          int(256)
138          ["flags"]=>
139          int(0)
140          ["lineno"]=>
141          int(2)
142          ["children"]=>
143          array(1) {
144            ["name"]=>
145            string(3) "var"
146          }
147        }
148        ["expr"]=>
149        int(42)
150      }
151    }
152  }
153}
154```
155
156The [`util.php`][util] file defines an `ast_dump()` function, which can be used to create a more
157compact and human-readable dump of the AST structure:
158
159```php
160<?php
161
162require 'path/to/util.php';
163
164$code = <<<'EOC'
165<?php
166$var = 42;
167EOC;
168
169echo ast_dump(ast\parse_code($code, $version=70)), "\n";
170
171// Output:
172AST_STMT_LIST
173    0: AST_ASSIGN
174        var: AST_VAR
175            name: "var"
176        expr: 42
177```
178
179To additionally show line numbers pass the `AST_DUMP_LINENOS` option as the second argument to
180`ast_dump()`.
181
182A more substantial AST dump can be found [in the tests][test_dump].
183
184Metadata
185--------
186
187There are a number of functions which provide meta-information for the AST structure:
188
189`ast\get_kind_name()` returns a string name for an integral node kind.
190
191`ast\kind_uses_flags()` determines whether the `flags` of a node kind may ever be non-zero.
192
193`ast\get_metadata()` returns metadata about all AST node kinds. The return value is a map from AST
194node kinds to `ast\Metadata` objects defined as follows.
195
196```php
197namespace ast;
198class Metadata
199{
200    public $kind;
201    public $name;
202    public $flags;
203    public $flagsCombinable;
204}
205```
206
207The `kind` is the integral node kind, while `name` is the same name as returned by the
208`get_kind_name()` function.
209
210`flags` is an array of flag constant names, which may be used by the node kind. `flagsCombinable`
211specifies whether the flag should be checked using `===` (not combinable) or using `&` (combinable).
212Together these two values provide programmatic access to the information listed in the
213[flags section](#flags).
214
215The AST metadata is intended for use in tooling for working the AST, such as AST dumpers.
216
217Flags
218-----
219
220This section lists which flags are used by which AST node kinds. The "combinable" flags can be
221combined using bitwise or and should be checked by using `$ast->flags & ast\flags\FOO`. The
222"exclusive" flags are used standalone and should be checked using `$ast->flags === ast\flags\BAR`.
223
224```
225// Used by ast\AST_NAME (exclusive)
226ast\flags\NAME_FQ (= 0)    // example: \Foo\Bar
227ast\flags\NAME_NOT_FQ      // example: Foo\Bar
228ast\flags\NAME_RELATIVE    // example: namespace\Foo\Bar
229
230// Used by ast\AST_METHOD, ast\AST_PROP_DECL, ast\AST_CLASS_CONST_DECL,
231// ast\AST_PROP_GROUP and ast\AST_TRAIT_ALIAS (combinable)
232ast\flags\MODIFIER_PUBLIC
233ast\flags\MODIFIER_PROTECTED
234ast\flags\MODIFIER_PRIVATE
235ast\flags\MODIFIER_STATIC
236ast\flags\MODIFIER_ABSTRACT
237ast\flags\MODIFIER_FINAL
238
239// Used by ast\AST_CLOSURE, ast\AST_ARROW_FUNC (combinable)
240ast\flags\MODIFIER_STATIC
241
242// Used by ast\AST_FUNC_DECL, ast\AST_METHOD, ast\AST_CLOSURE, ast\AST_ARROW_FUNC (combinable)
243ast\flags\FUNC_RETURNS_REF  // legacy alias: ast\flags\RETURNS_REF
244ast\flags\FUNC_GENERATOR    // used only in PHP >= 7.1
245
246// Used by ast\AST_CLOSURE_VAR
247ast\flags\CLOSURE_USE_REF
248
249// Used by ast\AST_CLASS (combinable since PHP 8.1 enums)
250ast\flags\CLASS_ABSTRACT
251ast\flags\CLASS_FINAL
252ast\flags\CLASS_TRAIT
253ast\flags\CLASS_INTERFACE
254ast\flags\CLASS_ANONYMOUS
255ast\flags\CLASS_ENUM
256
257// Used by ast\AST_PARAM (combinable)
258ast\flags\PARAM_REF
259ast\flags\PARAM_VARIADIC
260ast\flags\PARAM_MODIFIER_PUBLIC (available since 1.0.8, same as ast\flags\MODIFIER_* in PHP >= 8.0)
261ast\flags\PARAM_MODIFIER_PROTECTED (available since 1.0.8)
262ast\flags\PARAM_MODIFIER_PRIVATE (available since 1.0.8)
263
264// Used by ast\AST_TYPE (exclusive)
265ast\flags\TYPE_ARRAY
266ast\flags\TYPE_CALLABLE
267ast\flags\TYPE_VOID
268ast\flags\TYPE_BOOL
269ast\flags\TYPE_LONG
270ast\flags\TYPE_DOUBLE
271ast\flags\TYPE_STRING
272ast\flags\TYPE_ITERABLE
273ast\flags\TYPE_OBJECT
274ast\flags\TYPE_NULL    // php 8.0 union types
275ast\flags\TYPE_FALSE   // php 8.0 union types
276ast\flags\TYPE_STATIC  // php 8.0 static return type
277ast\flags\TYPE_MIXED   // php 8.0 mixed type
278
279// Used by ast\AST_CAST (exclusive)
280ast\flags\TYPE_NULL
281ast\flags\TYPE_BOOL
282ast\flags\TYPE_LONG
283ast\flags\TYPE_DOUBLE
284ast\flags\TYPE_STRING
285ast\flags\TYPE_ARRAY
286ast\flags\TYPE_OBJECT
287
288// Used by ast\AST_UNARY_OP (exclusive)
289ast\flags\UNARY_BOOL_NOT
290ast\flags\UNARY_BITWISE_NOT
291ast\flags\UNARY_MINUS
292ast\flags\UNARY_PLUS
293ast\flags\UNARY_SILENCE
294
295// Used by ast\AST_BINARY_OP and ast\AST_ASSIGN_OP (exclusive)
296ast\flags\BINARY_BITWISE_OR
297ast\flags\BINARY_BITWISE_AND
298ast\flags\BINARY_BITWISE_XOR
299ast\flags\BINARY_CONCAT
300ast\flags\BINARY_ADD
301ast\flags\BINARY_SUB
302ast\flags\BINARY_MUL
303ast\flags\BINARY_DIV
304ast\flags\BINARY_MOD
305ast\flags\BINARY_POW
306ast\flags\BINARY_SHIFT_LEFT
307ast\flags\BINARY_SHIFT_RIGHT
308ast\flags\BINARY_COALESCE
309
310// Used by ast\AST_BINARY_OP (exclusive)
311ast\flags\BINARY_BOOL_AND
312ast\flags\BINARY_BOOL_OR
313ast\flags\BINARY_BOOL_XOR
314ast\flags\BINARY_IS_IDENTICAL
315ast\flags\BINARY_IS_NOT_IDENTICAL
316ast\flags\BINARY_IS_EQUAL
317ast\flags\BINARY_IS_NOT_EQUAL
318ast\flags\BINARY_IS_SMALLER
319ast\flags\BINARY_IS_SMALLER_OR_EQUAL
320ast\flags\BINARY_IS_GREATER
321ast\flags\BINARY_IS_GREATER_OR_EQUAL
322ast\flags\BINARY_SPACESHIP
323
324// Used by ast\AST_MAGIC_CONST (exclusive)
325ast\flags\MAGIC_LINE
326ast\flags\MAGIC_FILE
327ast\flags\MAGIC_DIR
328ast\flags\MAGIC_NAMESPACE
329ast\flags\MAGIC_FUNCTION
330ast\flags\MAGIC_METHOD
331ast\flags\MAGIC_CLASS
332ast\flags\MAGIC_TRAIT
333
334// Used by ast\AST_USE, ast\AST_GROUP_USE and ast\AST_USE_ELEM (exclusive)
335ast\flags\USE_NORMAL
336ast\flags\USE_FUNCTION
337ast\flags\USE_CONST
338
339// Used by ast\AST_INCLUDE_OR_EVAL (exclusive)
340ast\flags\EXEC_EVAL
341ast\flags\EXEC_INCLUDE
342ast\flags\EXEC_INCLUDE_ONCE
343ast\flags\EXEC_REQUIRE
344ast\flags\EXEC_REQUIRE_ONCE
345
346// Used by ast\AST_ARRAY (exclusive), since PHP 7.1
347ast\flags\ARRAY_SYNTAX_SHORT
348ast\flags\ARRAY_SYNTAX_LONG
349ast\flags\ARRAY_SYNTAX_LIST
350
351// Used by ast\AST_ARRAY_ELEM (exclusive)
352ast\flags\ARRAY_ELEM_REF
353
354// Used by ast\AST_DIM (combinable), since PHP 7.4
355ast\flags\DIM_ALTERNATIVE_SYNTAX
356
357// Used by ast\AST_CONDITIONAL (combinable), since PHP 7.4
358ast\flags\PARENTHESIZED_CONDITIONAL
359```
360
361AST node kinds
362--------------
363
364This section lists the AST node kinds that are supported and the names of their child nodes.
365
366```
367AST_ARRAY_ELEM:           value, key
368AST_ARROW_FUNC:           name, docComment, params, stmts, returnType, attributes
369AST_ASSIGN:               var, expr
370AST_ASSIGN_OP:            var, expr
371AST_ASSIGN_REF:           var, expr
372AST_ATTRIBUTE:            class, args            // php 8.0+ attributes (version 80+)
373AST_BINARY_OP:            left, right
374AST_BREAK:                depth
375AST_CALL:                 expr, args
376AST_CAST:                 expr
377AST_CATCH:                class, var, stmts
378AST_CLASS:                name, docComment, extends, implements, stmts, (for enums) type
379AST_CLASS_CONST:          class, const
380AST_CLASS_CONST_GROUP     class, attributes      // version 80+
381AST_CLASS_NAME:           class                  // version 70+
382AST_CLONE:                expr
383AST_CLOSURE:              name, docComment, params, uses, stmts, returnType, attributes
384AST_CLOSURE_VAR:          name
385AST_CONDITIONAL:          cond, true, false
386AST_CONST:                name
387AST_CONST_ELEM:           name, value, docComment
388AST_CONTINUE:             depth
389AST_DECLARE:              declares, stmts
390AST_DIM:                  expr, dim
391AST_DO_WHILE:             stmts, cond
392AST_ECHO:                 expr
393AST_EMPTY:                expr
394AST_ENUM_CASE:            name, expr, attributes // php 8.1+ enums
395AST_EXIT:                 expr
396AST_FOR:                  init, cond, loop, stmts
397AST_FOREACH:              expr, value, key, stmts
398AST_FUNC_DECL:            name, docComment, params, stmts, returnType, attributes
399                          uses                   // prior to version 60
400AST_GLOBAL:               var
401AST_GOTO:                 label
402AST_GROUP_USE:            prefix, uses
403AST_HALT_COMPILER:        offset
404AST_IF_ELEM:              cond, stmts
405AST_INCLUDE_OR_EVAL:      expr
406AST_INSTANCEOF:           expr, class
407AST_ISSET:                var
408AST_LABEL:                name
409AST_MAGIC_CONST:
410AST_MATCH:                cond, stmts            // php 8.0+ match
411AST_MATCH_ARM:            cond, expr             // php 8.0+ match
412AST_METHOD:               name, docComment, params, stmts, returnType, attributes
413                          uses                   // prior to version 60
414AST_METHOD_CALL:          expr, method, args
415AST_METHOD_REFERENCE:     class, method
416AST_NAME:                 name
417AST_NAMED_ARG:            name, expr             // php 8.0 named parameters
418AST_NAMESPACE:            name, stmts
419AST_NEW:                  class, args
420AST_NULLABLE_TYPE:        type                   // Used only since PHP 7.1
421AST_NULLSAFE_METHOD_CALL: expr, method, args     // php 8.0 null safe operator
422AST_NULLSAFE_PROP:        expr, prop             // php 8.0 null safe operator
423AST_PARAM:                type, name, default, attributes, docComment
424AST_POST_DEC:             var
425AST_POST_INC:             var
426AST_PRE_DEC:              var
427AST_PRE_INC:              var
428AST_PRINT:                expr
429AST_PROP:                 expr, prop
430AST_PROP_ELEM:            name, default, docComment
431AST_PROP_GROUP:           type, props, attributes // version 70+
432AST_REF:                  var                    // only used in foreach ($a as &$v)
433AST_RETURN:               expr
434AST_SHELL_EXEC:           expr
435AST_STATIC:               var, default
436AST_STATIC_CALL:          class, method, args
437AST_STATIC_PROP:          class, prop
438AST_SWITCH:               cond, stmts
439AST_SWITCH_CASE:          cond, stmts
440AST_THROW:                expr
441AST_TRAIT_ALIAS:          method, alias
442AST_TRAIT_PRECEDENCE:     method, insteadof
443AST_TRY:                  try, catches, finally
444AST_TYPE:
445AST_UNARY_OP:             expr
446AST_UNPACK:               expr
447AST_UNSET:                var
448AST_USE_ELEM:             name, alias
449AST_USE_TRAIT:            traits, adaptations
450AST_VAR:                  name
451AST_WHILE:                cond, stmts
452AST_YIELD:                value, key
453AST_YIELD_FROM:           expr
454
455// List nodes (numerically indexed children):
456AST_ARG_LIST
457AST_ARRAY
458AST_ATTRIBUTE_LIST        // php 8.0+ attributes (version 80+)
459AST_ATTRIBUTE_GROUP       // php 8.0+ attributes (version 80+)
460AST_CATCH_LIST
461AST_CLASS_CONST_DECL
462AST_CLOSURE_USES
463AST_CONST_DECL
464AST_ENCAPS_LIST           // interpolated string: "foo$bar"
465AST_EXPR_LIST
466AST_IF
467AST_LIST
468AST_MATCH_ARM_LIST        // php 8.0+ match
469AST_NAME_LIST
470AST_PARAM_LIST
471AST_PROP_DECL
472AST_STMT_LIST
473AST_SWITCH_LIST
474AST_TRAIT_ADAPTATIONS
475AST_USE
476AST_TYPE_UNION            // php 8.0+ union types
477```
478
479AST Versioning
480--------------
481
482The `ast\parse_code()` and `ast\parse_file()` functions each accept a required AST `$version`
483argument. The idea behind the AST version is that we may need to change the format of the AST to
484account for new features in newer PHP versions, or to improve it in other ways. Such changes will
485always be made under a new AST version, while previous formats continue to be supported for some
486time.
487
488Old AST versions may be deprecated in minor versions and removed in major versions of the AST extension.
489
490A list of currently supported versions is available through `ast\get_supported_versions()`. The
491function accepts a boolean argument that determines whether deprecated versions should be excluded.
492
493In the following the changes in the respective AST versions, as well as their current support state,
494are listed.
495
496### 80 (current)
497
498Supported since 1.0.10 (2020-09-12).
499
500* `mixed` type hints are now reported as an `AST_TYPE` with type `TYPE_MIXED` instead of an `AST_NAME`.
501* `AST_CLASS_CONST_GROUP` nodes are emitted for class constant declarations wrapping the `AST_CLASS_CONST_DECL` and any attributes.
502  Previously, `AST_CLASS_CONST_DECL` would be emitted.
503* `AST_PARAM`, `AST_CLASS_DECL`, `AST_METHOD`, `AST_PROP_DECL`, `AST_CLOSURE`, `AST_FUNC_DECL`, and `AST_ARROW_FUNC` nodes
504  now contain an attributes child.
505
506### 70 (stable)
507
508Supported since 1.0.1 (2019-02-11).
509
510* `AST_PROP_GROUP` was added to support PHP 7.4's typed properties.
511  The property visibility modifiers are now part of `AST_PROP_GROUP` instead of `AST_PROP_DECL`.
512
513  Note that property group type information is only available with AST versions 70+.
514* `AST_CLASS_NAME` is created instead of `AST_CLASS_CONST` for `SomeClass::class`.
515
516### 60 (stable)
517
518Supported since 0.1.7 (2018-10-06).
519
520* `AST_FUNC_DECL` and `AST_METHOD` no longer generate a `uses` child. Previously this child was
521  always `null`.
522* `AST_CONST_ELEM` now always has a `docComment` child. Previously it was absent on PHP 7.0.
523  On PHP 7.0 the value is always `null`.
524
525### 50 (stable)
526
527Supported since 0.1.5 (2017-07-19).
528
529This is the oldest AST version available in 1.0.0. See the
530[0.1.x AST version changelog][v0_1_x_versions] for information on changes prior to this version.
531
532Differences to PHP-Parser
533-------------------------
534
535Next to php-ast I also maintain the [PHP-Parser][php-parser] library, which has some overlap with
536this extension. This section summarizes the main differences between php-ast and PHP-Parser so you
537may decide which is preferable for your use-case.
538
539The primary difference is that php-ast is a PHP extension (written in C) which exports the AST
540internally used by PHP 7. PHP-Parser on the other hand is library written in PHP. This has a number
541of consequences:
542
543 * php-ast is significantly faster than PHP-Parser, because the AST construction is implemented in
544   C.
545 * php-ast needs to be installed as an extension, on Linux either by compiling it manually or
546   retrieving it from a package manager, on Windows by loading a DLL. PHP-Parser is installed as a
547   Composer dependency.
548 * php-ast only runs on PHP >= 7.0, as prior versions did not use an internal AST. PHP-Parser
549   supports PHP >= 5.5.
550 * php-ast may only parse code that is syntactically valid on the version of PHP it runs on. This
551   means that it's not possible to parse code using features of newer versions (e.g. PHP 7.1 code
552   while running on PHP 7.0). Similarly, it is not possible to parse code that is no longer
553   syntactically valid on the used version (e.g. some PHP 5 code may no longer be parsed -- however
554   most code will work). PHP-Parser supports parsing both newer and older (up to PHP 5.2) versions.
555 * php-ast can only parse code which is syntactically valid, while PHP-Parser can provide a partial
556   AST for code that contains errors (e.g., because it is currently being edited).
557 * php-ast only provides the starting line number (and for declarations the ending line number) of
558   nodes, because this is the only part that PHP itself stores. PHP-Parser provides precise file
559   offsets.
560
561There are a number of differences in the AST representation and available support code:
562
563 * The PHP-Parser library uses a separate class for every node type, with child nodes stored as
564   type-annotated properties. php-ast uses one class for everything, with children stored as
565   arrays. The former approach is friendlier to developers because it has very good IDE integration.
566   The php-ast extension does not use separate classes, because registering hundreds of classes was
567   judged a no-go for a bundled extension.
568 * The PHP-Parser library contains various support code for working with the AST, while php-ast only
569   handles AST construction. The reason for this is that implementing this support code in C is
570   extremely complicated and there is little other benefit to implementing it in C. The main
571   components that PHP-Parser offers that may be of interest are:
572    * Node dumper (human readable representation): While the php-ast extension does not directly
573      implement this, a `ast_dump` function is provided in the `util.php` file.
574    * Pretty printer (converting the AST back to PHP code): This is not provided natively, but the
575      [php-ast-reverter][php-ast-reverter] package implements this functionality.
576    * Name resolution (resolving namespace prefixes and aliases): There is currently no standalone
577      package for this.
578    * AST traversal / visitation: There is currently no standalone package for this either, but
579      implementing a recursive AST walk is easy.
580
581The [tolerant-php-parser-to-php-ast][tolerant-php-parser-to-php-ast] project can convert the AST produced by
582[tolerant-php-parser][tolerant-php-parser] (Another pure PHP parser library) into the format used by the php-ast extension.
583This can be used as a slow fallback in
584case the php-ast extension is not available. It may also be used to produce a partial php-ast output
585for code with syntax errors.
586
587  [parser]: http://lxr.php.net/xref/PHP_TRUNK/Zend/zend_language_parser.y
588  [util]: https://github.com/nikic/php-ast/blob/master/util.php
589  [test_dump]: https://github.com/nikic/php-ast/blob/master/tests/001.phpt
590  [php-parser]: https://github.com/nikic/PHP-Parser
591  [php-ast-reverter]: https://github.com/tpunt/php-ast-reverter
592  [tolerant-php-parser]: https://github.com/Microsoft/tolerant-php-parser
593  [tolerant-php-parser-to-php-ast]: https://github.com/tysonandre/tolerant-php-parser-to-php-ast
594  [v0_1_x]: https://github.com/nikic/php-ast/tree/v0.1.x#php-ast
595  [v0_1_x_versions]: https://github.com/nikic/php-ast/tree/v0.1.x#ast-versioning
596