82 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			82 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| Introduction
 | |
| ============
 | |
| 
 | |
| This project is a PHP 5.2 to PHP 5.6 parser **written in PHP itself**.
 | |
| 
 | |
| What is this for?
 | |
| -----------------
 | |
| 
 | |
| A parser is useful for [static analysis][0], manipulation of code and basically any other
 | |
| application dealing with code programmatically. A parser constructs an [Abstract Syntax Tree][1]
 | |
| (AST) of the code and thus allows dealing with it in an abstract and robust way.
 | |
| 
 | |
| There are other ways of processing source code. One that PHP supports natively is using the
 | |
| token stream generated by [`token_get_all`][2]. The token stream is much more low level than
 | |
| the AST and thus has different applications: It allows to also analyze the exact formatting of
 | |
| a file. On the other hand the token stream is much harder to deal with for more complex analysis.
 | |
| For example an AST abstracts away the fact that in PHP variables can be written as `$foo`, but also
 | |
| as `$$bar`, `${'foobar'}` or even `${!${''}=barfoo()}`. You don't have to worry about recognizing
 | |
| all the different syntaxes from a stream of tokens.
 | |
| 
 | |
| Another questions is: Why would I want to have a PHP parser *written in PHP*? Well, PHP might not be
 | |
| a language especially suited for fast parsing, but processing the AST is much easier in PHP than it
 | |
| would be in other, faster languages like C. Furthermore the people most probably wanting to do
 | |
| programmatic PHP code analysis are incidentally PHP developers, not C developers.
 | |
| 
 | |
| What can it parse?
 | |
| ------------------
 | |
| 
 | |
| 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
 | |
| version it runs on), additionally a wrapper for emulating new tokens from 5.3, 5.4, 5.5 and 5.6 is provided.
 | |
| This allows to parse PHP 5.6 source code running on PHP 5.3, for example. This emulation is very hacky and not
 | |
| perfect, but it should work well on any sane code.
 | |
| 
 | |
| What output does it produce?
 | |
| ----------------------------
 | |
| 
 | |
| The parser produces an [Abstract Syntax Tree][1] (AST) also known as a node tree. How this looks like
 | |
| can best be seen in an example. The program `<?php echo 'Hi', 'World';` will give you a node tree
 | |
| roughly looking like this:
 | |
| 
 | |
| ```
 | |
| array(
 | |
|     0: Stmt_Echo(
 | |
|         exprs: array(
 | |
|             0: Scalar_String(
 | |
|                 value: Hi
 | |
|             )
 | |
|             1: Scalar_String(
 | |
|                 value: World
 | |
|             )
 | |
|         )
 | |
|     )
 | |
| )
 | |
| ```
 | |
| 
 | |
| This matches the structure of the code: An echo statement, which takes two strings as expressions,
 | |
| with the values `Hi` and `World!`.
 | |
| 
 | |
| You can also see that the AST does not contain any whitespace information (but most comments are saved).
 | |
| So using it for formatting analysis is not possible.
 | |
| 
 | |
| What else can it do?
 | |
| --------------------
 | |
| 
 | |
| Apart from the parser itself this package also bundles support for some other, related features:
 | |
| 
 | |
|  * Support for pretty printing, which is the act of converting an AST into PHP code. Please note
 | |
|    that "pretty printing" does not imply that the output is especially pretty. It's just how it's
 | |
|    called ;)
 | |
|  * Support for serializing and unserializing the node tree to XML
 | |
|  * Support for dumping the node tree in a human readable form (see the section above for an
 | |
|    example of how the output looks like)
 | |
|  * Infrastructure for traversing and changing the AST (node traverser and node visitors)
 | |
|  * A node visitor for resolving namespaced names
 | |
| 
 | |
|  [0]: http://en.wikipedia.org/wiki/Static_program_analysis
 | |
|  [1]: http://en.wikipedia.org/wiki/Abstract_syntax_tree
 | |
|  [2]: http://php.net/token_get_all
 | 
