Name Date Size #Lines LOC

..31-Aug-2021-

.github/workflows/H17-Apr-2021-

ci/H27-Nov-2021-

scripts/H24-Jul-2021-

tests/H27-Nov-2021-

.appveyor.ymlH A D27-Nov-202110.7 KiB257247

.dockerignoreH A D17-Apr-2021448 4140

.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 D24-Jul-202120.8 KiB612509

RELEASE_CHECKLISTH A D06-Dec-2019448 1312

ast.cH A D27-Nov-202146 KiB1,5811,327

ast.stub.phpH A D27-Nov-20211.4 KiB4213

ast_arginfo.hH A D27-Nov-20212.3 KiB6246

ast_data.cH A D24-Jul-202126.4 KiB680672

ast_str_defs.hH A D14-Jun-2020701 5552

ast_stub.phpH A D27-Nov-20218.6 KiB338241

config.m4H A D06-Dec-2019225 96

config.w32H A D06-Dec-2019135 95

package.xmlH A D27-Nov-202120.5 KiB559557

php_ast.hH A D27-Nov-20212.7 KiB10766

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 90.
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_PROP_GROUP,
231// ast\AST_CLASS_CONST_DECL, ast\AST_CLASS_CONST_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
238ast\flags\MODIFIER_READONLY
239
240// Used by ast\AST_CLOSURE, ast\AST_ARROW_FUNC (combinable)
241ast\flags\MODIFIER_STATIC
242
243// Used by ast\AST_FUNC_DECL, ast\AST_METHOD, ast\AST_CLOSURE, ast\AST_ARROW_FUNC (combinable)
244ast\flags\FUNC_RETURNS_REF  // legacy alias: ast\flags\RETURNS_REF
245ast\flags\FUNC_GENERATOR    // used only in PHP >= 7.1
246
247// Used by ast\AST_CLOSURE_VAR
248ast\flags\CLOSURE_USE_REF
249
250// Used by ast\AST_CLASS (combinable since PHP 8.1 enums)
251ast\flags\CLASS_ABSTRACT
252ast\flags\CLASS_FINAL
253ast\flags\CLASS_TRAIT
254ast\flags\CLASS_INTERFACE
255ast\flags\CLASS_ANONYMOUS
256ast\flags\CLASS_ENUM
257
258// Used by ast\AST_PARAM (combinable)
259ast\flags\PARAM_REF
260ast\flags\PARAM_VARIADIC
261ast\flags\PARAM_MODIFIER_PUBLIC (available since 1.0.8, same as ast\flags\MODIFIER_* in PHP >= 8.0)
262ast\flags\PARAM_MODIFIER_PROTECTED (available since 1.0.8)
263ast\flags\PARAM_MODIFIER_PRIVATE (available since 1.0.8)
264
265// Used by ast\AST_TYPE (exclusive)
266ast\flags\TYPE_ARRAY
267ast\flags\TYPE_CALLABLE
268ast\flags\TYPE_VOID
269ast\flags\TYPE_BOOL
270ast\flags\TYPE_LONG
271ast\flags\TYPE_DOUBLE
272ast\flags\TYPE_STRING
273ast\flags\TYPE_ITERABLE
274ast\flags\TYPE_OBJECT
275ast\flags\TYPE_NULL    // php 8.0 union types
276ast\flags\TYPE_FALSE   // php 8.0 union types
277ast\flags\TYPE_STATIC  // php 8.0 static return type
278ast\flags\TYPE_MIXED   // php 8.0 mixed type
279ast\flags\TYPE_NEVER   // php 8.1 never type
280
281// Used by ast\AST_CAST (exclusive)
282ast\flags\TYPE_NULL
283ast\flags\TYPE_BOOL
284ast\flags\TYPE_LONG
285ast\flags\TYPE_DOUBLE
286ast\flags\TYPE_STRING
287ast\flags\TYPE_ARRAY
288ast\flags\TYPE_OBJECT
289
290// Used by ast\AST_UNARY_OP (exclusive)
291ast\flags\UNARY_BOOL_NOT
292ast\flags\UNARY_BITWISE_NOT
293ast\flags\UNARY_MINUS
294ast\flags\UNARY_PLUS
295ast\flags\UNARY_SILENCE
296
297// Used by ast\AST_BINARY_OP and ast\AST_ASSIGN_OP (exclusive)
298ast\flags\BINARY_BITWISE_OR
299ast\flags\BINARY_BITWISE_AND
300ast\flags\BINARY_BITWISE_XOR
301ast\flags\BINARY_CONCAT
302ast\flags\BINARY_ADD
303ast\flags\BINARY_SUB
304ast\flags\BINARY_MUL
305ast\flags\BINARY_DIV
306ast\flags\BINARY_MOD
307ast\flags\BINARY_POW
308ast\flags\BINARY_SHIFT_LEFT
309ast\flags\BINARY_SHIFT_RIGHT
310ast\flags\BINARY_COALESCE
311
312// Used by ast\AST_BINARY_OP (exclusive)
313ast\flags\BINARY_BOOL_AND
314ast\flags\BINARY_BOOL_OR
315ast\flags\BINARY_BOOL_XOR
316ast\flags\BINARY_IS_IDENTICAL
317ast\flags\BINARY_IS_NOT_IDENTICAL
318ast\flags\BINARY_IS_EQUAL
319ast\flags\BINARY_IS_NOT_EQUAL
320ast\flags\BINARY_IS_SMALLER
321ast\flags\BINARY_IS_SMALLER_OR_EQUAL
322ast\flags\BINARY_IS_GREATER
323ast\flags\BINARY_IS_GREATER_OR_EQUAL
324ast\flags\BINARY_SPACESHIP
325
326// Used by ast\AST_MAGIC_CONST (exclusive)
327ast\flags\MAGIC_LINE
328ast\flags\MAGIC_FILE
329ast\flags\MAGIC_DIR
330ast\flags\MAGIC_NAMESPACE
331ast\flags\MAGIC_FUNCTION
332ast\flags\MAGIC_METHOD
333ast\flags\MAGIC_CLASS
334ast\flags\MAGIC_TRAIT
335
336// Used by ast\AST_USE, ast\AST_GROUP_USE and ast\AST_USE_ELEM (exclusive)
337ast\flags\USE_NORMAL
338ast\flags\USE_FUNCTION
339ast\flags\USE_CONST
340
341// Used by ast\AST_INCLUDE_OR_EVAL (exclusive)
342ast\flags\EXEC_EVAL
343ast\flags\EXEC_INCLUDE
344ast\flags\EXEC_INCLUDE_ONCE
345ast\flags\EXEC_REQUIRE
346ast\flags\EXEC_REQUIRE_ONCE
347
348// Used by ast\AST_ARRAY (exclusive), since PHP 7.1
349ast\flags\ARRAY_SYNTAX_SHORT
350ast\flags\ARRAY_SYNTAX_LONG
351ast\flags\ARRAY_SYNTAX_LIST
352
353// Used by ast\AST_ARRAY_ELEM (exclusive)
354ast\flags\ARRAY_ELEM_REF
355
356// Used by ast\AST_DIM (combinable), since PHP 7.4
357ast\flags\DIM_ALTERNATIVE_SYNTAX
358
359// Used by ast\AST_CONDITIONAL (combinable), since PHP 7.4
360ast\flags\PARENTHESIZED_CONDITIONAL
361```
362
363AST node kinds
364--------------
365
366This section lists the AST node kinds that are supported and the names of their child nodes.
367
368```
369AST_ARRAY_ELEM:           value, key
370AST_ARROW_FUNC:           name, docComment, params, stmts, returnType, attributes
371AST_ASSIGN:               var, expr
372AST_ASSIGN_OP:            var, expr
373AST_ASSIGN_REF:           var, expr
374AST_ATTRIBUTE:            class, args            // php 8.0+ attributes (version 80+)
375AST_BINARY_OP:            left, right
376AST_BREAK:                depth
377AST_CALL:                 expr, args
378AST_CALLABLE_CONVERT:                            // php 8.1+ first-class callable syntax
379AST_CAST:                 expr
380AST_CATCH:                class, var, stmts
381AST_CLASS:                name, docComment, extends, implements, stmts, (for enums) type
382AST_CLASS_CONST:          class, const
383AST_CLASS_CONST_GROUP     class, attributes      // version 80+
384AST_CLASS_NAME:           class                  // version 70+
385AST_CLONE:                expr
386AST_CLOSURE:              name, docComment, params, uses, stmts, returnType, attributes
387AST_CLOSURE_VAR:          name
388AST_CONDITIONAL:          cond, true, false
389AST_CONST:                name
390AST_CONST_ELEM:           name, value, docComment
391AST_CONTINUE:             depth
392AST_DECLARE:              declares, stmts
393AST_DIM:                  expr, dim
394AST_DO_WHILE:             stmts, cond
395AST_ECHO:                 expr
396AST_EMPTY:                expr
397AST_ENUM_CASE:            name, expr, docComment, attributes // php 8.1+ enums
398AST_EXIT:                 expr
399AST_FOR:                  init, cond, loop, stmts
400AST_FOREACH:              expr, value, key, stmts
401AST_FUNC_DECL:            name, docComment, params, stmts, returnType, attributes
402                          uses                   // prior to version 60
403AST_GLOBAL:               var
404AST_GOTO:                 label
405AST_GROUP_USE:            prefix, uses
406AST_HALT_COMPILER:        offset
407AST_IF_ELEM:              cond, stmts
408AST_INCLUDE_OR_EVAL:      expr
409AST_INSTANCEOF:           expr, class
410AST_ISSET:                var
411AST_LABEL:                name
412AST_MAGIC_CONST:
413AST_MATCH:                cond, stmts            // php 8.0+ match
414AST_MATCH_ARM:            cond, expr             // php 8.0+ match
415AST_METHOD:               name, docComment, params, stmts, returnType, attributes
416                          uses                   // prior to version 60
417AST_METHOD_CALL:          expr, method, args
418AST_METHOD_REFERENCE:     class, method
419AST_NAME:                 name
420AST_NAMED_ARG:            name, expr             // php 8.0 named parameters
421AST_NAMESPACE:            name, stmts
422AST_NEW:                  class, args
423AST_NULLABLE_TYPE:        type                   // Used only since PHP 7.1
424AST_NULLSAFE_METHOD_CALL: expr, method, args     // php 8.0 null safe operator
425AST_NULLSAFE_PROP:        expr, prop             // php 8.0 null safe operator
426AST_PARAM:                type, name, default, attributes, docComment
427AST_POST_DEC:             var
428AST_POST_INC:             var
429AST_PRE_DEC:              var
430AST_PRE_INC:              var
431AST_PRINT:                expr
432AST_PROP:                 expr, prop
433AST_PROP_ELEM:            name, default, docComment
434AST_PROP_GROUP:           type, props, attributes // version 70+
435AST_REF:                  var                    // only used in foreach ($a as &$v)
436AST_RETURN:               expr
437AST_SHELL_EXEC:           expr
438AST_STATIC:               var, default
439AST_STATIC_CALL:          class, method, args
440AST_STATIC_PROP:          class, prop
441AST_SWITCH:               cond, stmts
442AST_SWITCH_CASE:          cond, stmts
443AST_THROW:                expr
444AST_TRAIT_ALIAS:          method, alias
445AST_TRAIT_PRECEDENCE:     method, insteadof
446AST_TRY:                  try, catches, finally
447AST_TYPE:
448AST_UNARY_OP:             expr
449AST_UNPACK:               expr
450AST_UNSET:                var
451AST_USE_ELEM:             name, alias
452AST_USE_TRAIT:            traits, adaptations
453AST_VAR:                  name
454AST_WHILE:                cond, stmts
455AST_YIELD:                value, key
456AST_YIELD_FROM:           expr
457
458// List nodes (numerically indexed children):
459AST_ARG_LIST
460AST_ARRAY
461AST_ATTRIBUTE_LIST        // php 8.0+ attributes (version 80+)
462AST_ATTRIBUTE_GROUP       // php 8.0+ attributes (version 80+)
463AST_CATCH_LIST
464AST_CLASS_CONST_DECL
465AST_CLOSURE_USES
466AST_CONST_DECL
467AST_ENCAPS_LIST           // interpolated string: "foo$bar"
468AST_EXPR_LIST
469AST_IF
470AST_LIST
471AST_MATCH_ARM_LIST        // php 8.0+ match
472AST_NAME_LIST
473AST_PARAM_LIST
474AST_PROP_DECL
475AST_STMT_LIST
476AST_SWITCH_LIST
477AST_TRAIT_ADAPTATIONS
478AST_USE
479AST_TYPE_UNION            // php 8.0+ union types
480AST_TYPE_INTERSECTION     // php 8.1+ intersection types
481```
482
483AST Versioning
484--------------
485
486The `ast\parse_code()` and `ast\parse_file()` functions each accept a required AST `$version`
487argument. The idea behind the AST version is that we may need to change the format of the AST to
488account for new features in newer PHP versions, or to improve it in other ways. Such changes will
489always be made under a new AST version, while previous formats continue to be supported for some
490time.
491
492Old AST versions may be deprecated in minor versions and removed in major versions of the AST extension.
493
494A list of currently supported versions is available through `ast\get_supported_versions()`. The
495function accepts a boolean argument that determines whether deprecated versions should be excluded.
496
497In the following the changes in the respective AST versions, as well as their current support state,
498are listed.
499
500### 90 (current)
501
502Supported since 1.0.14 (2021-07-24)
503
504* Same as AST version 85.
505
506### 85 (stable)
507
508Supported since 1.0.11 (2021-04-20)
509
510* Add a `type` child node (for enum type) for all AST_CLASS nodes.
511
512### 80 (stable)
513
514Supported since 1.0.10 (2020-09-12).
515
516* `mixed` type hints are now reported as an `AST_TYPE` with type `TYPE_MIXED` instead of an `AST_NAME`.
517* `AST_CLASS_CONST_GROUP` nodes are emitted for class constant declarations wrapping the `AST_CLASS_CONST_DECL` and any attributes.
518  Previously, `AST_CLASS_CONST_DECL` would be emitted.
519* `AST_PARAM`, `AST_CLASS_DECL`, `AST_METHOD`, `AST_PROP_DECL`, `AST_CLOSURE`, `AST_FUNC_DECL`, and `AST_ARROW_FUNC` nodes
520  now contain an attributes child.
521
522### 70 (stable)
523
524Supported since 1.0.1 (2019-02-11).
525
526* `AST_PROP_GROUP` was added to support PHP 7.4's typed properties.
527  The property visibility modifiers are now part of `AST_PROP_GROUP` instead of `AST_PROP_DECL`.
528
529  Note that property group type information is only available with AST versions 70+.
530* `AST_CLASS_NAME` is created instead of `AST_CLASS_CONST` for `SomeClass::class`.
531
532### 60 (stable)
533
534Supported since 0.1.7 (2018-10-06).
535
536* `AST_FUNC_DECL` and `AST_METHOD` no longer generate a `uses` child. Previously this child was
537  always `null`.
538* `AST_CONST_ELEM` now always has a `docComment` child. Previously it was absent on PHP 7.0.
539  On PHP 7.0 the value is always `null`.
540
541### 50 (stable)
542
543Supported since 0.1.5 (2017-07-19).
544
545This is the oldest AST version available in 1.0.0. See the
546[0.1.x AST version changelog][v0_1_x_versions] for information on changes prior to this version.
547
548Differences to PHP-Parser
549-------------------------
550
551Next to php-ast I also maintain the [PHP-Parser][php-parser] library, which has some overlap with
552this extension. This section summarizes the main differences between php-ast and PHP-Parser so you
553may decide which is preferable for your use-case.
554
555The primary difference is that php-ast is a PHP extension (written in C) which exports the AST
556internally used by PHP 7. PHP-Parser on the other hand is library written in PHP. This has a number
557of consequences:
558
559 * php-ast is significantly faster than PHP-Parser, because the AST construction is implemented in
560   C.
561 * php-ast needs to be installed as an extension, on Linux either by compiling it manually or
562   retrieving it from a package manager, on Windows by loading a DLL. PHP-Parser is installed as a
563   Composer dependency.
564 * php-ast only runs on PHP >= 7.0, as prior versions did not use an internal AST. PHP-Parser
565   supports PHP >= 5.5.
566 * php-ast may only parse code that is syntactically valid on the version of PHP it runs on. This
567   means that it's not possible to parse code using features of newer versions (e.g. PHP 7.1 code
568   while running on PHP 7.0). Similarly, it is not possible to parse code that is no longer
569   syntactically valid on the used version (e.g. some PHP 5 code may no longer be parsed -- however
570   most code will work). PHP-Parser supports parsing both newer and older (up to PHP 5.2) versions.
571 * php-ast can only parse code which is syntactically valid, while PHP-Parser can provide a partial
572   AST for code that contains errors (e.g., because it is currently being edited).
573 * php-ast only provides the starting line number (and for declarations the ending line number) of
574   nodes, because this is the only part that PHP itself stores. PHP-Parser provides precise file
575   offsets.
576
577There are a number of differences in the AST representation and available support code:
578
579 * The PHP-Parser library uses a separate class for every node type, with child nodes stored as
580   type-annotated properties. php-ast uses one class for everything, with children stored as
581   arrays. The former approach is friendlier to developers because it has very good IDE integration.
582   The php-ast extension does not use separate classes, because registering hundreds of classes was
583   judged a no-go for a bundled extension.
584 * The PHP-Parser library contains various support code for working with the AST, while php-ast only
585   handles AST construction. The reason for this is that implementing this support code in C is
586   extremely complicated and there is little other benefit to implementing it in C. The main
587   components that PHP-Parser offers that may be of interest are:
588    * Node dumper (human readable representation): While the php-ast extension does not directly
589      implement this, a `ast_dump` function is provided in the `util.php` file.
590    * Pretty printer (converting the AST back to PHP code): This is not provided natively, but the
591      [php-ast-reverter][php-ast-reverter] package implements this functionality.
592    * Name resolution (resolving namespace prefixes and aliases): There is currently no standalone
593      package for this.
594    * AST traversal / visitation: There is currently no standalone package for this either, but
595      implementing a recursive AST walk is easy.
596
597The [tolerant-php-parser-to-php-ast][tolerant-php-parser-to-php-ast] project can convert the AST produced by
598[tolerant-php-parser][tolerant-php-parser] (Another pure PHP parser library) into the format used by the php-ast extension.
599This can be used as a slow fallback in
600case the php-ast extension is not available. It may also be used to produce a partial php-ast output
601for code with syntax errors.
602
603  [parser]: http://lxr.php.net/xref/PHP_TRUNK/Zend/zend_language_parser.y
604  [util]: https://github.com/nikic/php-ast/blob/master/util.php
605  [test_dump]: https://github.com/nikic/php-ast/blob/master/tests/001.phpt
606  [php-parser]: https://github.com/nikic/PHP-Parser
607  [php-ast-reverter]: https://github.com/tpunt/php-ast-reverter
608  [tolerant-php-parser]: https://github.com/Microsoft/tolerant-php-parser
609  [tolerant-php-parser-to-php-ast]: https://github.com/tysonandre/tolerant-php-parser-to-php-ast
610  [v0_1_x]: https://github.com/nikic/php-ast/tree/v0.1.x#php-ast
611  [v0_1_x_versions]: https://github.com/nikic/php-ast/tree/v0.1.x#ast-versioning
612