Metadata-Version: 2.4
Name: php-parser-py
Version: 1.2.4
Summary: Python wrapper for PHP-Parser using cpg2py
License-File: LICENSE
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.11
Requires-Dist: cpg2py>=1.2.0
Requires-Dist: static-php-py>=0.1.6
Description-Content-Type: text/markdown

# php-parser-py

> *php* + *parser* + *py*: nikic/PHP-Parser, driven from Python.

Parse, query, mutate, and regenerate PHP code in Python through a graph API — no local PHP required.

## Install

```bash
# via uv
uv add php-parser-py

# or via pip
pip install php-parser-py
```

Requires Python >= 3.11.

## Usage

```python
from php_parser_py import parse_file, Modifier

# Parse
ast = parse_file("src/User.php")

# Query
functions = ast.nodes(lambda n: n.node_type == "Stmt_Function")
for func in functions:
    params = [c for c in ast.succ(func) if c.node_type == "Param"]

# Modify structure (copy-on-write: source `ast` is untouched)
modifier = Modifier(ast)
modifier.add_node("new_1", "Stmt_Break")
modifier.add_edge("parent_id", "new_1", field="stmts", index=0)
modified = modifier.ast
```

## API

| Function / Class | Signature | Description |
|-----------------|-----------|-------------|
| `parse_code` | `(code: str) -> list[Node]` | Parse PHP string into statement nodes |
| `parse_file` | `(path: str) -> AST` | Parse single file with project/file structure |
| `parse_project` | `(project_path: str, file_filter?) -> AST` | Parse all PHP files in a directory |
| `Modifier` | `(ast: AST)` | Copy-on-write graph mutation; read result from `modifier.ast` |
| `AST.nodes` | `(predicate?) -> Generator[Node]` | Iterate/filter nodes |
| `AST.succ` | `(node) -> Generator[Node]` | Get children |
| `AST.prev` | `(node) -> Generator[Node]` | Get parents |
| `AST.first_node` | `(predicate) -> Node \| None` | First matching node |
| `Node.node_type` | `-> str` | PHP-Parser node type (e.g. "Stmt_Function") |
| `Node.start_line` | `-> int` | Source line number |

Full specifications in [docs/design-parser.md](docs/design-parser.md) and [docs/design-graph.md](docs/design-graph.md).

## Background

Python wrapper for [nikic/PHP-Parser](https://github.com/nikic/PHP-Parser) built on the [cpg2py](https://pypi.org/project/cpg2py/) graph framework. Ships a static PHP binary in platform-specific wheels; falls back to a `php` on `PATH` when no bundled binary matches the host.

## Documentation

- **[Concepts](docs/concept.md)** — problem scope, data flow, and core terminology.
- **[Design](docs/index.md)** — architecture, class specifications, and mapping rules.
- **[AST Reference](docs/libs/php_parser_ast.md)** — complete table of PHP-Parser node types.
- **[cpg2py API](docs/libs/cpg2py.md)** — graph querying patterns.

## For Agents

Agent-consumable documentation index at `docs/llms.txt` (llmstxt.org format).

## Citation

If you use this project in academic work, please cite our paper. BibTeX (placeholder until the paper is released):

```bibtex
@misc{citation_placeholder,
  title  = {{TODO: paper title — not yet released}},
  author = {{TODO: authors}},
  year   = {{TODO}},
  note   = {Paper not yet released. Citation entry will be updated on publication.}
}
```

## License

GPL-2.0 — see [LICENSE](LICENSE).
