Releases: parsica-php/parsica
Performance improvements
- PERFORMANCE: use
static
keyword on all closures - PSALM: update some annotations to work with newer psalm versions
- PERFORMANCE: simplify
appendSuccess
in theSucceed
class - PERFORMANCE: reduce indirection with the
guardEndOfStream()
inStringStream
These resulted in a small speedup of the JSON Parser example.
Before changes:
+-----------+----------------------+-----+------+-----+------------+-------------+---------+
| 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% |
+-----------+----------------------+-----+------+-----+------------+-------------+---------+
After changes:
+-----------+----------------------+-----+------+-----+------------+-------------+----------+
| 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% |
+-----------+----------------------+-----+------+-----+------------+-------------+----------+
Performance improvements
- PERFORMANCE: Use
strlen()
instead ofmb_strlen()
to find EOF - DEPENDENCY: Add phpbench as a dev dependency
- PERFORMANCE: Succeed: use property instead of internal getter call on the hot path
- PERFORMANCE: Succeed: use lookup private properties instead of calling getters
- PERFORMANCE: Make
many()
400% faster by using while instead of recurse - PERFORMANCE: Check for empty string comparing to empty string instead of strlen
These resulted in a x2 speedup of the JSON Parser example.
Before changes
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 |
+-----------+----------------------+-----+------+-----+------------+--------------+--------------+--------------+--------------+-----------+--------+-----------+
After changes:
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 |
+-----------+----------------------+-----+------+-----+------------+-------------+-------------+-------------+-------------+-----------+--------+-----------+
Moved the code to Parsica\Parsica namespace
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!
Documentation Fix
- DOCS The new tutorial page on Dealing with Space was not showing up correctly on the website.
Expressions
-
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, useParseResult#throw()
, which throws aParserHasFailed
exception. -
BREAKING:
Parser#recurse()
doesn't return the parser anymore, and instead returns void. -
BREAKING:
Parser#construct(ClassName)
is removed in favour ofmap(fn($v) => new ClassName))
... and lots of minor improvements
Quick documentation fix
There's always something you discover right after you tag a release :-D
Lookahead feature, doc & bug fixes
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
- various minor cleanup
Integer & float parsers, more aliases, and small improvements
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
Stream abstraction, error messages, JSON, combinators
-
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, ...
0.3.1 Documentation fixes
dropped .md from doc links