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.
pure-callable, and [@psalm-pure](https://github.com/psalm-pure).Full Changelog: https://github.com/parsica-php/parsica/compare/0.8.2...0.8.3
CypressLab\Curry is abandoned. We forked the library into /src, and added types.CypressLab\Curry directly, either require matteosister/php-curry or change your imports to Parsica\Parsica\Curry. Note that this namespace might change again if we integrate the curry functions into the main Parsica FP code.Full Changelog: https://github.com/parsica-php/parsica/compare/0.8.1...0.8.2
static keyword on all closuresappendSuccess in the Succeed classguardEndOfStream() in StringStreamThese resulted in a small speedup of the JSON Parser example.
+-----------+----------------------+-----+------+-----+------------+-------------+---------+
| benchmark | subject | set | revs | its | mem_peak | mode | rstdev |
+-----------+----------------------+-----+------+-----+------------+-------------+---------+
| JSONBench | bench_json_encode | 0 | 5 | 3 | 1,710,104b | 7.617μs | ±46.68% |
| JSONBench | bench_Parsica_JSON | 0 | 5 | 3 | 2,168,552b | 6,539.741μs | ±5.28% |
| JSONBench | bench_basemax_jpophp | 0 | 5 | 3 | 1,878,760b | 633.373μs | ±24.11% |
+-----------+----------------------+-----+------+-----+------------+-------------+---------+
+-----------+----------------------+-----+------+-----+------------+-------------+----------+
| benchmark | subject | set | revs | its | mem_peak | mode | rstdev |
+-----------+----------------------+-----+------+-----+------------+-------------+----------+
| JSONBench | bench_json_encode | 0 | 5 | 3 | 1,710,200b | 5.978μs | ±29.48% |
| JSONBench | bench_Parsica_JSON | 0 | 5 | 3 | 2,160,184b | 6,256.940μs | ±8.37% |
| JSONBench | bench_basemax_jpophp | 0 | 5 | 3 | 1,878,856b | 633.060μs | ±3.00% |
+-----------+----------------------+-----+------+-----+------------+-------------+----------+
Full Changelog: https://github.com/parsica-php/parsica/compare/0.8.0...0.8.1
strlen() instead of mb_strlen() to find EOFmany() 400% faster by using while instead of recurseThese resulted in a x2 speedup of the JSON Parser example.
Subjects: 3, Assertions: 0, Failures: 0, Errors: 0
suite: 1346290d9eebcc1aade3cbbff1b5f7017d112890, date: 2021-03-20, stime: 10:39:04
+-----------+----------------------+-----+------+-----+------------+--------------+--------------+--------------+--------------+-----------+--------+-----------+
| benchmark | subject | set | revs | its | mem_peak | best | mean | mode | worst | stdev | rstdev | diff |
+-----------+----------------------+-----+------+-----+------------+--------------+--------------+--------------+--------------+-----------+--------+-----------+
| JSONBench | bench_json_encode | 0 | 5 | 3 | 1,709,704b | 5.200μs | 5.467μs | 5.576μs | 5.600μs | 0.189μs | 3.45% | 1.00x |
| JSONBench | bench_Parsica_JSON | 0 | 5 | 3 | 2,195,024b | 10,658.600μs | 11,040.933μs | 10,757.806μs | 11,737.200μs | 493.126μs | 4.47% | 2,019.68x |
| JSONBench | bench_basemax_jpophp | 0 | 5 | 3 | 1,878,400b | 520.600μs | 637.733μs | 571.178μs | 811.000μs | 125.023μs | 19.60% | 116.66x |
+-----------+----------------------+-----+------+-----+------------+--------------+--------------+--------------+--------------+-----------+--------+-----------+
Subjects: 3, Assertions: 0, Failures: 0, Errors: 0
suite: 1346290eaf4ce8a0eb08bdddb54b69d2020be280, date: 2021-03-20, stime: 10:38:11
+-----------+----------------------+-----+------+-----+------------+-------------+-------------+-------------+-------------+-----------+--------+-----------+
| benchmark | subject | set | revs | its | mem_peak | best | mean | mode | worst | stdev | rstdev | diff |
+-----------+----------------------+-----+------+-----+------------+-------------+-------------+-------------+-------------+-----------+--------+-----------+
| JSONBench | bench_json_encode | 0 | 5 | 3 | 1,710,104b | 5.200μs | 5.333μs | 5.388μs | 5.400μs | 0.094μs | 1.77% | 1.00x |
| JSONBench | bench_Parsica_JSON | 0 | 5 | 3 | 2,168,552b | 5,383.000μs | 5,505.267μs | 5,431.564μs | 5,693.200μs | 134.883μs | 2.45% | 1,032.24x |
| JSONBench | bench_basemax_jpophp | 0 | 5 | 3 | 1,878,760b | 541.800μs | 725.133μs | 794.251μs | 853.400μs | 133.036μs | 18.35% | 135.96x |
+-----------+----------------------+-----+------+-----+------------+-------------+-------------+-------------+-------------+-----------+--------+-----------+
As part of the move to the parsica-php organisation, we decided to move the namespace to Parsica. Sorry if this would break your integration with Parsica! We did a minor version update because we don't want to go to a v1.x yet, but want to let you know that there has been a backwards compatibility break.
Fix your composer.json file and make sure you use the correct namespace in your code!
FEATURE: Expression parser. Using a simple interface, you can define parsers for recursive expression languages with different associativity and operators precedence.
FEATURE: Lots of fine grained Psalm type annotations. You should now be able to use Psalm in your own parsers, and get useful warnings if you do something wrong.
FEATURE: Parser#thenEof(). Make sure the parser reached the end of the input by appending ->thenEof()
IMPROVEMENT: Many error messages are now more clear
PERFORMANCE: 10x improvement by generating the error messages lazily. Still a long way before Parsica is performant enough for large scale production usage, but this gives us confidence there's still many low hanging fruits.
DOCS: New tutorial about writing expression parsers
DOCS: New tutorial about dealing with whitespace
DOCS: Added lots of missing API docs
DOCS: Improved the tutorial on types
DOCS: New examples in tests/Examples for expressions and an quick demo of an Excel formula parser
BREAKING: The Fail class no longer does double duty as an exception. Instead, use ParseResult#throw(), which throws a ParserHasFailed exception.
BREAKING: Parser#recurse() doesn't return the parser anymore, and instead returns void.
BREAKING: Parser#construct(ClassName) is removed in favour of map(fn($v) => new ClassName))
... and lots of minor improvements
There's always something you discover right after you tag a release :-D
FEATURE lookahead() combinator DOCS: A large chunk of API documentation was not being rendered FIX: PHPUnit max nesting level was insufficient IMPROVEMENT: reimplemented applicative functors without monads FIX: #10 fail when using applicative functors when the output of the first parser is not a callable
FEATURE: sepBy2 combinator
FEATURE: apply function
FEATURE: integer parser
FEATURE: float parser
FEATURE: Parser#and() is an alias for append()
FEATURE: Parser#then() is an alias for sequence()
DOCS: Misc improvements and additions
BREAKING: removed some helper functions from the JSON parser
BREAKING nicer API for ParserAssertions
FEATURE: Parser errors are now a lot more useful. They show the line and column position where the parser expected something else. Labels are also vastly improved.
BREAKING / FEATURE: Inputs must now be of type Stream. Right now it only comes with a StringStream implementation, but in the future this will allow us to handle different types of input, such as an actual stream.
FEATURE: The new emit() combinator can be used for side effects and for emitting parser events
FEATURE: We implemented a fully compliant JSON parser
FEATURE: zeroOrMore() combinator
FEATURE: map() is now also a function
BREAKING: Parser tracks label so that combinators can combine them into smarter error messages
BREAKING: Removed ParseResult::alternative
BREAKING: When appending with null, the null gets ignored
BREAKING: optional and success now output null instead of empty string
BREAKING: renamed success() and failure() to succeed() and fail()
BREAKING: skipWhile outputs null instead of empty string
BREAKING: skipWhile1 outputs null instead of empty string
...and lots of improvements and additions to the documentation, test coverage, code organisation, Psalm types, ...
Moving out of the proof of concept stage. Parsica now has a usable set of building blocks.
How can I help you explore Laravel packages today?