php-parser-py 0.1.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,29 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2011, Nikita Popov
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions are met:
8
+
9
+ 1. Redistributions of source code must retain the above copyright notice, this
10
+ list of conditions and the following disclaimer.
11
+
12
+ 2. Redistributions in binary form must reproduce the above copyright notice,
13
+ this list of conditions and the following disclaimer in the documentation
14
+ and/or other materials provided with the distribution.
15
+
16
+ 3. Neither the name of the copyright holder nor the names of its
17
+ contributors may be used to endorse or promote products derived from
18
+ this software without specific prior written permission.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Binary file
@@ -0,0 +1,190 @@
1
+ Metadata-Version: 2.3
2
+ Name: php-parser-py
3
+ Version: 0.1.1
4
+ Summary: Python wrapper for PHP-Parser using cpg2py
5
+ Author: samhsu-dev
6
+ Author-email: samhsu-dev <yxu166@jh.edu>
7
+ Requires-Dist: cpg2py>=1.1.0
8
+ Requires-Dist: static-php-py
9
+ Requires-Python: >=3.11
10
+ Description-Content-Type: text/markdown
11
+
12
+ # php-parser-py
13
+
14
+ Python wrapper for PHP-Parser using cpg2py's graph framework.
15
+
16
+ ## Overview
17
+
18
+ `php-parser-py` provides a Python interface to [PHP-Parser](https://github.com/nikic/PHP-Parser), enabling Abstract Syntax Tree (AST) parsing and manipulation of PHP code. The library integrates with [cpg2py](https://github.com/jhu-seclab/cpg2py)'s graph framework for powerful graph-based code analysis.
19
+
20
+ ## Features
21
+
22
+ - **Native PHP-Parser Integration**: Delegates all parsing and code generation to PHP-Parser for maximum compatibility
23
+ - **Zero-Configuration PHP**: Bundled PHP binaries via static-php-py - no system PHP installation required
24
+ - **Graph-Based Analysis**: Uses cpg2py's graph framework for AST traversal and querying
25
+ - **Dynamic Node Types**: No hardcoded PHP node types - all types come from PHP-Parser's JSON output
26
+ - **Lossless Round-Trip**: Parse → Modify → Generate code with full fidelity
27
+ - **Cross-Platform Support**: Pre-built PHP 8.4 binaries for Linux (x86_64/aarch64), macOS (x86_64/arm64), and Windows (x64)
28
+
29
+ ## Installation
30
+
31
+ ```bash
32
+ pip install php-parser-py
33
+ ```
34
+
35
+ **Note**: Platform-specific wheels include pre-built PHP 8.4 binaries. No separate PHP installation required!
36
+
37
+ ## Quick Start
38
+
39
+ ### Parse PHP Code
40
+
41
+ ```python
42
+ from php_parser_py import parse
43
+
44
+ # Parse PHP code
45
+ code = """<?php
46
+ function greet($name) {
47
+ echo "Hello, $name!";
48
+ }
49
+ """
50
+
51
+ ast = parse(code)
52
+
53
+ # Query nodes by type
54
+ for func in ast.nodes(lambda n: n.label == "Stmt_Function"):
55
+ name = func.get_property("name")
56
+ print(f"Found function: {name}")
57
+ ```
58
+
59
+ ### Parse PHP File
60
+
61
+ ```python
62
+ from php_parser_py import parse_file
63
+
64
+ ast = parse_file("example.php")
65
+ ```
66
+
67
+ ### Traverse AST
68
+
69
+ ```python
70
+ # Find all echo statements
71
+ for echo in ast.nodes(lambda n: n.label == "Stmt_Echo"):
72
+ print(f"Echo at line {echo.get_property('startLine')}")
73
+
74
+ # Get children of a node
75
+ for child in ast.children(some_node):
76
+ print(f"Child type: {child.label}")
77
+
78
+ # Get all descendants
79
+ for descendant in ast.descendants(some_node):
80
+ print(f"Descendant: {descendant.label}")
81
+ ```
82
+
83
+ ### Generate PHP Code
84
+
85
+ ```python
86
+ from php_parser_py import parse, PrettyPrinter
87
+
88
+ # Parse code
89
+ ast = parse("<?php echo 'hello';")
90
+
91
+ # Modify AST (example: change properties)
92
+ # ... modify nodes as needed ...
93
+
94
+ # Generate code
95
+ printer = PrettyPrinter()
96
+ generated_code = printer.print(ast)
97
+ print(generated_code)
98
+ ```
99
+
100
+ ## Advanced Usage
101
+
102
+ ### Custom PHP Binary
103
+
104
+ If you need to use a specific PHP version or custom binary:
105
+
106
+ ```python
107
+ from php_parser_py import Parser
108
+ from pathlib import Path
109
+
110
+ # Use local PHP binary
111
+ parser = Parser(php_binary_path=Path("/usr/local/bin/php"))
112
+ ast = parser.parse("<?php echo 'hello';")
113
+
114
+ # Or download from remote URL
115
+ parser = Parser(php_binary_url="https://example.com/php-8.4.zip")
116
+ ast = parser.parse("<?php echo 'hello';")
117
+ ```
118
+
119
+ ## API Reference
120
+
121
+ ### Main Functions
122
+
123
+ - **`parse(code: str) -> AST`**: Parse PHP code string and return AST
124
+ - **`parse_file(path: str) -> AST`**: Parse PHP file and return AST
125
+
126
+ ### Classes
127
+
128
+ - **`AST`**: Represents the complete AST as a graph
129
+ - `node(id)`: Get node by ID
130
+ - `nodes(predicate)`: Iterate nodes matching predicate
131
+ - `first_node(predicate)`: Get first matching node
132
+ - `children(node)`: Get child nodes
133
+ - `descendants(node)`: Get all descendants
134
+ - `to_json()`: Reconstruct PHP-Parser JSON
135
+
136
+ - **`Node`**: Wraps a single AST node
137
+ - `id`: Node identifier
138
+ - `label`: Node type (e.g., "Stmt_Function")
139
+ - `properties`: All node properties
140
+ - `get_property(*names)`: Get property value
141
+
142
+ - **`Parser`**: Parses PHP code
143
+ - `__init__(php_binary_path=None, php_binary_url=None)`: Initialize parser
144
+ - `php_binary_path`: Optional path to local PHP binary
145
+ - `php_binary_url`: Optional URL to download PHP binary from
146
+ - `parse(code, prefix="")`: Parse code string
147
+ - `prefix`: Optional prefix for node IDs (useful for multi-file parsing)
148
+ - `parse_file(path, prefix=None)`: Parse file
149
+ - `prefix`: Optional prefix (auto-generated from file path if not provided)
150
+
151
+ - **`PrettyPrinter`**: Generates PHP code
152
+ - `__init__(php_binary_path=None, php_binary_url=None)`: Initialize printer
153
+ - `php_binary_path`: Optional path to local PHP binary
154
+ - `php_binary_url`: Optional URL to download PHP binary from
155
+ - `print(ast)`: Generate code from AST
156
+
157
+ ### Exceptions
158
+
159
+ - **`ParseError`**: Raised when PHP-Parser reports syntax error
160
+ - **`RunnerError`**: Raised when PHP execution fails
161
+
162
+ ## Architecture
163
+
164
+ The library follows a delegation-based architecture:
165
+
166
+ 1. **PHP-Parser** handles all parsing and code generation
167
+ 2. **cpg2py Storage** stores the AST as a graph
168
+ 3. **Python classes** provide convenient access to the graph
169
+
170
+ This design ensures:
171
+ - No need to maintain PHP node type definitions in Python
172
+ - Automatic compatibility with PHP-Parser updates
173
+ - Full access to PHP-Parser's features
174
+
175
+ ## Requirements
176
+
177
+ - Python >= 3.11
178
+ - cpg2py
179
+ - static-php-py (bundled PHP binaries)
180
+
181
+ ## License
182
+
183
+ MIT License - see LICENSE file for details.
184
+
185
+ ## Documentation
186
+
187
+ For detailed design documentation, see:
188
+ - [Design Document](docs/design.md)
189
+ - [Idea Document](docs/idea.md)
190
+ - [API Demo](docs/api_demo.ipynb)
@@ -0,0 +1,16 @@
1
+ php_parser_py/__init__.py,sha256=-XSNHcVejEr0sasn7QU-Ly_UmhdcFbNvIrFXxaLxImQ,2095
2
+ php_parser_py/_ast.py,sha256=y_YUeLkd40LNH-kEHJX1vbLVK7u2XZROgHLmCUtIrkk,6405
3
+ php_parser_py/_edge.py,sha256=gIWkL-EhsLOWj4BuOwKHh5mHSC2z4Qk-ZxygCF7uPqk,3775
4
+ php_parser_py/_node.py,sha256=8YZfXjKf_4lf1R29UxxByw_iN2pBlTK6HNbx0z-9uWU,5654
5
+ php_parser_py/_parser.py,sha256=s35wKG7uoL0alut-tBVzmDVse-f-tivh-3T6B06b_bc,6885
6
+ php_parser_py/_printer.py,sha256=XwhJWiVI8h0jhQE8FA6vzMKAHVJ2ktQbL-omcQhMet4,1371
7
+ php_parser_py/_resources.py,sha256=jYPhMjyGX86IvT-JWT33fzF7CEaUr6t_gZRGuGbBRZ8,4487
8
+ php_parser_py/_runner.py,sha256=J9-fBUwAIYonvWjHrtTkSUzMSTXLF4BC5XxDD1klmwc,7653
9
+ php_parser_py/exceptions.py,sha256=cqGfU64-jXzJ9Y0edlMMZUzmMyClco0t-e33p5r90TA,1351
10
+ php_parser_py/resources/php-parser-4.19.4.zip,sha256=ND6zsylItt4owMoQnq-3id_ScMAXEfVyHzzRi0wKthQ,144334
11
+ php_parser_py/vendor/.extracted,sha256=35VHVRaR8xmvJSW2J6Z8MXxiFVnsRgeuJJPNS_5yzB8,64
12
+ php_parser_py/vendor/LICENSE.txt,sha256=3YWeEH-sn4ekQTq4w8lvDxYRoX9Zai21YqWk9JBMHpc,1520
13
+ php_parser_py/vendor/php-parser.phar,sha256=xeuVm4n37yt_DX3pNH1Ugc1ihGtoC97b7ao7a-AGjTk,1009441
14
+ php_parser_py-0.1.1.dist-info/WHEEL,sha256=XV0cjMrO7zXhVAIyyc8aFf1VjZ33Fen4IiJk5zFlC3g,80
15
+ php_parser_py-0.1.1.dist-info/METADATA,sha256=taZyq_b2_CuZU0WqjfdSvSeKBMd4htqSdRCh2x_io8c,5420
16
+ php_parser_py-0.1.1.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: uv 0.9.26
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any