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