parsica-php/parsica
Parsica is a PHP parser combinator library for building custom parsers from small reusable pieces. Compose complex grammars with a fluent API, parse strings into structured results, and handle errors cleanly—ideal for DSLs, config formats, and language tooling.
Begin by installing via Composer: composer require parsica-php/parsica. The entry point is the Parsica\Parser namespace, where core primitives like Parser::char(), Parser::string(), and Parser::digit() live. Your first use case is often parsing a simple expression—e.g., parsing "hello 123" into ['greeting' => 'hello', 'number' => 123]. Start by chaining Parser::string('hello'), Parser::whitespace(), and Parser::integer() with Parser::sequence() (or P::sequence()), then run with ->parse('hello 123'). The result is a Result object—either Success (with value and remaining) or Failure (with message, position, and context). Check the examples/ folder in the repo for quick, practical demos.
email() using string() + char('@') + many() + dot()) and compose them into complex parsers via sequence(), choice(), optional(), many(), and between().map() and flatMap() on results for transformations without side effects.Parser::expected(string $description) to inject semantic context (e.g., expected('end-of-line')) and failWith(string $message) for custom error messaging—great for validating DSL syntax.statement(), expression(), term()), then parse entire files or protocols. Parsica integrates cleanly into Laravel commands (e.g., a custom config parser) or Symfony console tools.Success/Failure results and extracted values. Use var_dump($result) during dev; final tests rely on strict assertions.many() and optional() are greedy and may consume more than intended. Use lookAhead() for non-consuming checks or between() with notWhite() to avoid ambiguity (e.g., in CSV-like formats).trim() won’t help—Parsica treats whitespace literally. Use Parser::whitespace() or define whitespace() once and consistently (e.g., space: Parser = whitespace()->repeat(0)).Parser::withPosition() or post-process Failure->position with a helper. Wrap parsers with description() to enrich output: Parser::digit()->description('digit').Parser::fromCallable() sparingly—prefer combinators over raw callables to maintain composability.choice() with overlapping prefixes—reorder alternatives from most specific to least. For high-throughput parsing, consider caching frequently used parser compositions.How can I help you explore Laravel packages today?