annotate vendor/nikic/php-parser/doc/3_Other_node_tree_representations.markdown @ 0:4c8ae668cc8c

Initial import (non-working)
author Chris Cannam
date Wed, 29 Nov 2017 16:09:58 +0000
parents
children
rev   line source
Chris@0 1 Other node tree representations
Chris@0 2 ===============================
Chris@0 3
Chris@0 4 It is possible to convert the AST into several textual representations, which serve different uses.
Chris@0 5
Chris@0 6 Simple serialization
Chris@0 7 --------------------
Chris@0 8
Chris@0 9 It is possible to serialize the node tree using `serialize()` and also unserialize it using
Chris@0 10 `unserialize()`. The output is not human readable and not easily processable from anything
Chris@0 11 but PHP, but it is compact and generates quickly. The main application thus is in caching.
Chris@0 12
Chris@0 13 Human readable dumping
Chris@0 14 ----------------------
Chris@0 15
Chris@0 16 Furthermore it is possible to dump nodes into a human readable format using the `dump` method of
Chris@0 17 `PhpParser\NodeDumper`. This can be used for debugging.
Chris@0 18
Chris@0 19 ```php
Chris@0 20 $code = <<<'CODE'
Chris@0 21 <?php
Chris@0 22
Chris@0 23 function printLine($msg) {
Chris@0 24 echo $msg, "\n";
Chris@0 25 }
Chris@0 26
Chris@0 27 printLine('Hello World!!!');
Chris@0 28 CODE;
Chris@0 29
Chris@0 30 $parser = (new PhpParser\ParserFactory)->create(PhpParser\ParserFactory::PREFER_PHP7);
Chris@0 31 $nodeDumper = new PhpParser\NodeDumper;
Chris@0 32
Chris@0 33 try {
Chris@0 34 $stmts = $parser->parse($code);
Chris@0 35
Chris@0 36 echo $nodeDumper->dump($stmts), "\n";
Chris@0 37 } catch (PhpParser\Error $e) {
Chris@0 38 echo 'Parse Error: ', $e->getMessage();
Chris@0 39 }
Chris@0 40 ```
Chris@0 41
Chris@0 42 The above script will have an output looking roughly like this:
Chris@0 43
Chris@0 44 ```
Chris@0 45 array(
Chris@0 46 0: Stmt_Function(
Chris@0 47 byRef: false
Chris@0 48 params: array(
Chris@0 49 0: Param(
Chris@0 50 name: msg
Chris@0 51 default: null
Chris@0 52 type: null
Chris@0 53 byRef: false
Chris@0 54 )
Chris@0 55 )
Chris@0 56 stmts: array(
Chris@0 57 0: Stmt_Echo(
Chris@0 58 exprs: array(
Chris@0 59 0: Expr_Variable(
Chris@0 60 name: msg
Chris@0 61 )
Chris@0 62 1: Scalar_String(
Chris@0 63 value:
Chris@0 64
Chris@0 65 )
Chris@0 66 )
Chris@0 67 )
Chris@0 68 )
Chris@0 69 name: printLine
Chris@0 70 )
Chris@0 71 1: Expr_FuncCall(
Chris@0 72 name: Name(
Chris@0 73 parts: array(
Chris@0 74 0: printLine
Chris@0 75 )
Chris@0 76 )
Chris@0 77 args: array(
Chris@0 78 0: Arg(
Chris@0 79 value: Scalar_String(
Chris@0 80 value: Hello World!!!
Chris@0 81 )
Chris@0 82 byRef: false
Chris@0 83 )
Chris@0 84 )
Chris@0 85 )
Chris@0 86 )
Chris@0 87 ```
Chris@0 88
Chris@0 89 JSON encoding
Chris@0 90 -------------
Chris@0 91
Chris@0 92 Nodes (and comments) implement the `JsonSerializable` interface. As such, it is possible to JSON
Chris@0 93 encode the AST directly using `json_encode()`:
Chris@0 94
Chris@0 95 ```php
Chris@0 96 $code = <<<'CODE'
Chris@0 97 <?php
Chris@0 98
Chris@0 99 function printLine($msg) {
Chris@0 100 echo $msg, "\n";
Chris@0 101 }
Chris@0 102
Chris@0 103 printLine('Hello World!!!');
Chris@0 104 CODE;
Chris@0 105
Chris@0 106 $parser = (new PhpParser\ParserFactory)->create(PhpParser\ParserFactory::PREFER_PHP7);
Chris@0 107 $nodeDumper = new PhpParser\NodeDumper;
Chris@0 108
Chris@0 109 try {
Chris@0 110 $stmts = $parser->parse($code);
Chris@0 111
Chris@0 112 echo json_encode($stmts, JSON_PRETTY_PRINT), "\n";
Chris@0 113 } catch (PhpParser\Error $e) {
Chris@0 114 echo 'Parse Error: ', $e->getMessage();
Chris@0 115 }
Chris@0 116 ```
Chris@0 117
Chris@0 118 This will result in the following output (which includes attributes):
Chris@0 119
Chris@0 120 ```json
Chris@0 121 [
Chris@0 122 {
Chris@0 123 "nodeType": "Stmt_Function",
Chris@0 124 "byRef": false,
Chris@0 125 "name": "printLine",
Chris@0 126 "params": [
Chris@0 127 {
Chris@0 128 "nodeType": "Param",
Chris@0 129 "type": null,
Chris@0 130 "byRef": false,
Chris@0 131 "variadic": false,
Chris@0 132 "name": "msg",
Chris@0 133 "default": null,
Chris@0 134 "attributes": {
Chris@0 135 "startLine": 3,
Chris@0 136 "endLine": 3
Chris@0 137 }
Chris@0 138 }
Chris@0 139 ],
Chris@0 140 "returnType": null,
Chris@0 141 "stmts": [
Chris@0 142 {
Chris@0 143 "nodeType": "Stmt_Echo",
Chris@0 144 "exprs": [
Chris@0 145 {
Chris@0 146 "nodeType": "Expr_Variable",
Chris@0 147 "name": "msg",
Chris@0 148 "attributes": {
Chris@0 149 "startLine": 4,
Chris@0 150 "endLine": 4
Chris@0 151 }
Chris@0 152 },
Chris@0 153 {
Chris@0 154 "nodeType": "Scalar_String",
Chris@0 155 "value": "\n",
Chris@0 156 "attributes": {
Chris@0 157 "startLine": 4,
Chris@0 158 "endLine": 4,
Chris@0 159 "kind": 2
Chris@0 160 }
Chris@0 161 }
Chris@0 162 ],
Chris@0 163 "attributes": {
Chris@0 164 "startLine": 4,
Chris@0 165 "endLine": 4
Chris@0 166 }
Chris@0 167 }
Chris@0 168 ],
Chris@0 169 "attributes": {
Chris@0 170 "startLine": 3,
Chris@0 171 "endLine": 5
Chris@0 172 }
Chris@0 173 },
Chris@0 174 {
Chris@0 175 "nodeType": "Expr_FuncCall",
Chris@0 176 "name": {
Chris@0 177 "nodeType": "Name",
Chris@0 178 "parts": [
Chris@0 179 "printLine"
Chris@0 180 ],
Chris@0 181 "attributes": {
Chris@0 182 "startLine": 7,
Chris@0 183 "endLine": 7
Chris@0 184 }
Chris@0 185 },
Chris@0 186 "args": [
Chris@0 187 {
Chris@0 188 "nodeType": "Arg",
Chris@0 189 "value": {
Chris@0 190 "nodeType": "Scalar_String",
Chris@0 191 "value": "Hello World!!!",
Chris@0 192 "attributes": {
Chris@0 193 "startLine": 7,
Chris@0 194 "endLine": 7,
Chris@0 195 "kind": 1
Chris@0 196 }
Chris@0 197 },
Chris@0 198 "byRef": false,
Chris@0 199 "unpack": false,
Chris@0 200 "attributes": {
Chris@0 201 "startLine": 7,
Chris@0 202 "endLine": 7
Chris@0 203 }
Chris@0 204 }
Chris@0 205 ],
Chris@0 206 "attributes": {
Chris@0 207 "startLine": 7,
Chris@0 208 "endLine": 7
Chris@0 209 }
Chris@0 210 }
Chris@0 211 ]
Chris@0 212 ```
Chris@0 213
Chris@0 214 There is currently no mechanism to convert JSON back into a node tree. Furthermore, not all ASTs
Chris@0 215 can be JSON encoded. In particular, JSON only supports UTF-8 strings.
Chris@0 216
Chris@0 217 Serialization to XML
Chris@0 218 --------------------
Chris@0 219
Chris@0 220 It is also possible to serialize the node tree to XML using `PhpParser\Serializer\XML->serialize()`
Chris@0 221 and to unserialize it using `PhpParser\Unserializer\XML->unserialize()`. This is useful for
Chris@0 222 interfacing with other languages and applications or for doing transformation using XSLT.
Chris@0 223
Chris@0 224 ```php
Chris@0 225 <?php
Chris@0 226 $code = <<<'CODE'
Chris@0 227 <?php
Chris@0 228
Chris@0 229 function printLine($msg) {
Chris@0 230 echo $msg, "\n";
Chris@0 231 }
Chris@0 232
Chris@0 233 printLine('Hello World!!!');
Chris@0 234 CODE;
Chris@0 235
Chris@0 236 $parser = (new PhpParser\ParserFactory)->create(PhpParser\ParserFactory::PREFER_PHP7);
Chris@0 237 $serializer = new PhpParser\Serializer\XML;
Chris@0 238
Chris@0 239 try {
Chris@0 240 $stmts = $parser->parse($code);
Chris@0 241
Chris@0 242 echo $serializer->serialize($stmts);
Chris@0 243 } catch (PhpParser\Error $e) {
Chris@0 244 echo 'Parse Error: ', $e->getMessage();
Chris@0 245 }
Chris@0 246 ```
Chris@0 247
Chris@0 248 Produces:
Chris@0 249
Chris@0 250 ```xml
Chris@0 251 <?xml version="1.0" encoding="UTF-8"?>
Chris@0 252 <AST xmlns:node="http://nikic.github.com/PHPParser/XML/node" xmlns:subNode="http://nikic.github.com/PHPParser/XML/subNode" xmlns:scalar="http://nikic.github.com/PHPParser/XML/scalar">
Chris@0 253 <scalar:array>
Chris@0 254 <node:Stmt_Function line="2">
Chris@0 255 <subNode:byRef>
Chris@0 256 <scalar:false/>
Chris@0 257 </subNode:byRef>
Chris@0 258 <subNode:params>
Chris@0 259 <scalar:array>
Chris@0 260 <node:Param line="2">
Chris@0 261 <subNode:name>
Chris@0 262 <scalar:string>msg</scalar:string>
Chris@0 263 </subNode:name>
Chris@0 264 <subNode:default>
Chris@0 265 <scalar:null/>
Chris@0 266 </subNode:default>
Chris@0 267 <subNode:type>
Chris@0 268 <scalar:null/>
Chris@0 269 </subNode:type>
Chris@0 270 <subNode:byRef>
Chris@0 271 <scalar:false/>
Chris@0 272 </subNode:byRef>
Chris@0 273 </node:Param>
Chris@0 274 </scalar:array>
Chris@0 275 </subNode:params>
Chris@0 276 <subNode:stmts>
Chris@0 277 <scalar:array>
Chris@0 278 <node:Stmt_Echo line="3">
Chris@0 279 <subNode:exprs>
Chris@0 280 <scalar:array>
Chris@0 281 <node:Expr_Variable line="3">
Chris@0 282 <subNode:name>
Chris@0 283 <scalar:string>msg</scalar:string>
Chris@0 284 </subNode:name>
Chris@0 285 </node:Expr_Variable>
Chris@0 286 <node:Scalar_String line="3">
Chris@0 287 <subNode:value>
Chris@0 288 <scalar:string>
Chris@0 289 </scalar:string>
Chris@0 290 </subNode:value>
Chris@0 291 </node:Scalar_String>
Chris@0 292 </scalar:array>
Chris@0 293 </subNode:exprs>
Chris@0 294 </node:Stmt_Echo>
Chris@0 295 </scalar:array>
Chris@0 296 </subNode:stmts>
Chris@0 297 <subNode:name>
Chris@0 298 <scalar:string>printLine</scalar:string>
Chris@0 299 </subNode:name>
Chris@0 300 </node:Stmt_Function>
Chris@0 301 <node:Expr_FuncCall line="6">
Chris@0 302 <subNode:name>
Chris@0 303 <node:Name line="6">
Chris@0 304 <subNode:parts>
Chris@0 305 <scalar:array>
Chris@0 306 <scalar:string>printLine</scalar:string>
Chris@0 307 </scalar:array>
Chris@0 308 </subNode:parts>
Chris@0 309 </node:Name>
Chris@0 310 </subNode:name>
Chris@0 311 <subNode:args>
Chris@0 312 <scalar:array>
Chris@0 313 <node:Arg line="6">
Chris@0 314 <subNode:value>
Chris@0 315 <node:Scalar_String line="6">
Chris@0 316 <subNode:value>
Chris@0 317 <scalar:string>Hello World!!!</scalar:string>
Chris@0 318 </subNode:value>
Chris@0 319 </node:Scalar_String>
Chris@0 320 </subNode:value>
Chris@0 321 <subNode:byRef>
Chris@0 322 <scalar:false/>
Chris@0 323 </subNode:byRef>
Chris@0 324 </node:Arg>
Chris@0 325 </scalar:array>
Chris@0 326 </subNode:args>
Chris@0 327 </node:Expr_FuncCall>
Chris@0 328 </scalar:array>
Chris@0 329 </AST>
Chris@0 330 ```