Skip to main content

Crate php_rs_parser

Crate php_rs_parser 

Source
Expand description

Fast, fault-tolerant PHP parser that produces a fully typed AST.

This crate parses PHP source code (PHP 7.4–8.5, plus PHP 8.6 partial function application) into a php_ast::Program tree, recovering from syntax errors so that downstream tools always receive a complete AST.

§Semantic-rejection responsibility

The parser is fault-tolerant: it always produces an AST and reports every error it can identify before recovering. Its semantic-rejection responsibility is defined externally:

For any input, the parser emits at least one diagnostic iff php -l would reject that input at the configured target PHP version.

Flow-sensitive checks — cross-file resolution, unused variables, dead code, type-mismatched returns — are out of scope and belong in a later semantic layer. Checks decidable from one declaration, one parameter list, one modifier set, or one declaration loop are in scope and use diagnostics::ParseError::Forbidden.

The ===php_error=== section in tests/fixtures/**/*.phpt records php -l output; the fixture runner enforces the rule above by failing CI when PHP rejects an input that the parser silently accepts.

§Quick start

let result = php_rs_parser::parse("<?php echo 'hello';");
assert!(result.errors.is_empty());

§Version-aware parsing

Use parse_with and ParseOptions to target a specific PHP version. Syntax that requires a higher version is still parsed into the AST, but a diagnostics::ParseError::VersionTooLow diagnostic is emitted.

use php_rs_parser::{ParseOptions, PhpVersion};

let result = php_rs_parser::parse_with(
    "<?php enum Status { case Active; }",
    &ParseOptions::default().version(PhpVersion::Php80),
);
assert!(!result.errors.is_empty()); // enums require PHP 8.1

§Multi-file cache

parse returns a ParseResult with no lifetime parameters — fully owned, storable in a HashMap, sendable across threads.

use std::collections::HashMap;
use std::path::PathBuf;

let mut cache: HashMap<PathBuf, php_rs_parser::ParseResult> = HashMap::new();
cache.insert(PathBuf::from("a.php"), php_rs_parser::parse("<?php echo 1;"));

§Arena API (LSP / hot-path usage)

Use parse_arena / ParserContext when you need maximum throughput and can manage the arena lifetime yourself. The returned ArenaParseResult borrows from both the arena and the source string — no allocation copying occurs.

let mut ctx = php_rs_parser::ParserContext::new();

let result = ctx.reparse("<?php echo 1;");
assert!(result.errors.is_empty());
drop(result); // must be dropped before the next reparse

let result = ctx.reparse("<?php echo 2;");
assert!(result.errors.is_empty());

Set ParseOptions::source_map to false when you never need line/column positions — it skips building the source_map::SourceMap and is slightly faster.

Re-exports§

pub use bumpalo;

Modules§

diagnostics
Parse errors and warnings.
source_map
Byte offset to line/column mapping.
version
Target PHP version selection. Target PHP version selection.

Structs§

ArenaParseResult
Arena-allocated result of parsing a PHP source string.
ParseOptions
Options for parse_with, parse_arena_with and ParserContext::with_options.
ParseResult
Lifetime-free result of parsing a PHP source string.
ParserContext
A reusable parse context that keeps a bumpalo::Bump arena alive between re-parses, resetting it (O(1)) instead of dropping and reallocating.

Enums§

PhpVersion
The PHP language version that code is parsed or printed for.

Functions§

parse
Parse PHP source with the default ParseOptions.
parse_arena
Parse PHP source with the default ParseOptions, returning an arena-allocated ArenaParseResult.
parse_arena_with
Parse PHP source with the given options, returning an arena-allocated ArenaParseResult.
parse_with
Parse PHP source with the given options, returning a fully-owned ParseResult.