Skip to content

Releases: drhagen/parsita

Parsita 2.2.1

26 Nov 19:28
Compare
Choose a tag to compare

The only publicly visibly changes in this release improve support for mypy by re-exporting all public members using the X as X syntax.

Parsita 2.2.0

21 Nov 02:04
Compare
Choose a tag to compare
  • Added support for Python 3.13 (#109)
  • Dropped support for Python 3.8 (#109)
    • Refactored to use some >=3.9 features (#111)
  • Added py.pyted and run mypy on the source in CI (#115)
    • This was best effort as Python's type system lacks the features needed to describe a parser combinator system
  • Fixed the repr of some parsers (#114)

Parsita 2.1.1

06 Oct 09:27
Compare
Choose a tag to compare

This is a maintenance release to document compatibility with recent versions of dependencies. There is no change to the code of Parsita.

Parsita 2.1.0

27 Jun 00:13
Compare
Choose a tag to compare

This is a quick follow-on to the 2.0.0 release. I neglected to make some methods private that were supposed to be private. Because the 2.0.0 release was only three days ago, I hope this will be fine. This is just a bugfix release for anyone who combines the built-in parsers to make their parsers (most users). But this is a severely breaking change for any custom parsers (inherit from Parser rather than use them).

  • Made Parser.consume private
    • Renamed consume to _consume
    • Renamed cached_consume to consume
    • This is the breaking change for custom parsers. Custom parsers now need to override _consume instead of consume and need to call consume instead of cached_consume. This actually brings the 2.x branch a little bit closer to the 1.x branch.
  • Renamed StringReader.current_line to _current_line
  • Moved Parser.handle_other to a global function
    • Export this function as parsita.parsers.wrap_literal
    • Use wrap_literal for all the parsers, not just the operators
      • Literal wrapping now applies to all non-Parser objects, not just str
      • pred now wraps literals like the other parsers, rather than requiring a proper Parser object

Parsita 2.0.0

23 Jun 10:11
Compare
Choose a tag to compare

This second major release doubles down on the ease-of-use promise of Parsita. The interface has been simplified and the amount of global mutable state needed to perform Parsita's magic has been drastically reduced. The internals have been totally rewritten to eliminate the possibility catastrophic backtracking, a rare and confusing property of some parsers.

Code that runs on 1.x will need to be modified to run on run on 2.x. The 1.8.0 release was made to ease the transition. Code written for 1.7.2 and earlier will produce deprecation warnings when run in 1.8.0. Code that has been modified to no longer produce those deprecation warnings should run without further modifications on 2.0.0.

  • Replace GeneralParsers and TextParsers with ParserContext, which behaves like a TextParsers with a default whitespace of None
    • The separate parser contexts were always kind of confusing and, in reality, not all that different. Both could parse text. The only advantage of TextParsers was its whitespace option. Add that to GeneralParsers and TextParsers is no longer needed and ParserContext is born.
  • Replace the custom parsita.Result with returns.result.Result
    • Result, Success, and Failure are now simple reexports of the classes from returns.result
    • Result.or_die() and Success.value have been replaced by Result.unwrap()
    • Failure.message has been replaced by str(Result.failure())
  • Replace the internal parsing engine with a packrat parser
    • Every time a parser finishes at a particular location in the input, a packrat parser caches the response. This guarantees that the time the parser takes to parse is linear in the input. It should no longer possible to write a parser that appears to hang on a small amount of input.
    • This is only a breaking change for custom parser classes (i.e. those that inherit from Parser instead of being built from combinations of other parsers). Classes that inherit from Parsers need to adopt the following changes:
      • consume is now an abstract protected method. consume must be implemented in concrete subclasses of Parser, but is invoked by cached_consumed only and should not be directly invoked by other parsers.
      • Invoke cached_consume on inner parsers instead of consume directly
      • Return None on failure instead of Backtrack
      • No need to do status.merge anymore
  • Raise custom RecursionError instead of using the builtin one when Parsita detects infinite recursion
    • It has parser and context attributes to store useful state about the parsing at the failure
  • ParseError now has attributes (farthest and expected) so that the state can be queried instead of lost in the string
  • Remove parsita.options.parse_method global mutable state
    • Parser.parse is now a normal method instead of being extracted from global mutable state at parser instantiation
  • Remove parsita.options.handle_literal global mutable state
    • LiteralParser now handles everything. It has a specialization for StringReader for performance.
  • Drop support for Python 3.7

Parsita 1.8.0

23 Jun 09:14
Compare
Choose a tag to compare

This is likely to be the last minor release in the 1.x series. It is mainly intended to ease the transition to version 2. Bug fixes will continue to be made to the 1.8.x series, but new features will be added only to the 2.x series unless backporting is not particularly painful.

  • Create ParserContext as a new context that behaves like TextParsers, but has a default whitespace of None.
    • TextParsers and GeneralParsers are now deprecated in favor of ParserContext, which will be the only context starting in 2.0.0.
  • Parsita Result now inherits from returns.Result.
    • The inheritance purely implements the Parsita-specific methods (Result.or_die, Success.value Failure.message) and deprecates them to ease transition to 2.0.0, when Parsita will reexport the classes from Returns unmodified.
  • Failure now wraps the ParseError exception rather than a string. Failure.message still gives a string.
    • This makes room for ParseError keeping useful information as attributes rather than the information being destroyed into a string.
  • Make reg work in a GeneralParsers context and on bytes (contributed by Chris Wheeler).
    • Add .drop to the Reader base class
    • Add efficient .drop method to the SequenceReader class
    • Change RegexParser to allow bytes

Code that runs in Parsita 1.x should run in 1.8.0, though with with deprecation warnings. Code that runs in 1.8.0 without deprecation warnings should run in Parsita 2.x. Note that this only applies to code that uses the Parsita parsers. If you wrote your own parser (i.e. you inherit from Parser), it's just going to have be fixed in 2.0; the internals of Parsita were changed to much to have custom parsers work in both versions.

Parsita 1.7.2

31 Mar 01:26
d354482
Compare
Choose a tag to compare

Maintenance release with no change in behavior:

  • Added Python 3.11 support

Parsita 1.7.1

26 Jul 18:33
Compare
Choose a tag to compare

One bugfix:

  • The TransformationParser (aka >=) now propagates the farthest error correctly

Parsita 1.7.0

01 Jan 19:37
Compare
Choose a tag to compare

New features proposed and drafted by @lostinplace:

  • Added the debug parser to make it easy to print or callback from a particular parser for debugging purposes (#28)
  • Added the until parser to capture all input until a parser matches (#29)
  • Added min and max to rep and repsep to constrain the minimum and maximum number of times each will match

Parsita 1.6.1

06 Oct 15:15
Compare
Choose a tag to compare

Maintenance release with no change in behavior:

  • Add support for Python 3.10