diff options
Diffstat (limited to 'vendor/winnow/src/_topic/why.rs')
-rw-r--r-- | vendor/winnow/src/_topic/why.rs | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/vendor/winnow/src/_topic/why.rs b/vendor/winnow/src/_topic/why.rs new file mode 100644 index 000000000..e28181b1a --- /dev/null +++ b/vendor/winnow/src/_topic/why.rs @@ -0,0 +1,98 @@ +//! # Why `winnow`? +//! +//! To answer this question, it will be useful to contrast this with other approaches to parsing. +//! +//! **Note:** This will focus on principles and priorities. For a deeper and wider wider +//! comparison with other Rust parser libraries, see +//! [parse-rosetta-rs](https://github.com/rosetta-rs/parse-rosetta-rs). +//! +//! ## Hand-written parsers +//! +//! Typically, a hand-written parser gives you the flexibility to get +//! - Fast parse performance +//! - Fast compile-time +//! - Small binary sizes +//! - High quality error message +//! - Fewer dependencies to audit +//! +//! However, this comes at the cost of doing it all yourself, including +//! - Optimizing for each of the above characteristics you are about +//! - Ensuring the safety of any `unsafe` code (buffer overflows being a common bug with parsers) +//! - Being aware of, familiar with, and correctly implement the relevant algorithms. +//! matklad, who has written two rust compile frontends, commented +//! ["I’ve implemented a production-grade Pratt parser once, but I no longer immediately understand that code :-)"](https://matklad.github.io/2020/04/13/simple-but-powerful-pratt-parsing.html) +//! +//! This approach works well if: +//! - Your format is small and is unlikely to change +//! - Your format is large but you have people who can focus solely on parsing, like with large +//! programming languages +//! +//! ## `winnow` +//! +//! Unlike traditional programming language parsers that use +//! [lex](https://en.wikipedia.org/wiki/Lex_(software)) or +//! [yacc](https://en.wikipedia.org/wiki/Yacc), you can think of `winnow` as a general version of +//! the helpers you would create along the way to writing a hand-written parser. +//! +//! `winnow` includes support for: +//! - Zero-copy parsing +//! - [Parse traces][crate::trace] for easier debugging +//! - [Streaming parsing][crate::Partial] for network communication or large file +//! - [Stateful][crate::Stateful] parsers +//! +//! For binary formats, `winnow` includes: +//! - [A hexadecimal view][crate::Bytes] in [traces][crate::trace] +//! - [TLV](https://en.wikipedia.org/wiki/Type-length-value) +//! - Some common parsers to help get started, like numbers +//! +//! For text formats, `winnow` includes: +//! - [Tracking of spans][crate::Located] +//! - [A textual view when parsing as bytes][crate::BStr] in [traces][crate::trace] +//! - Ability to evaluate directly, parse to an AST, or lex and parse the format +//! +//! This works well for: +//! - Prototyping for what will be a hand-written parser +//! - When you to minimize the work to evolve your format +//! - When you don't have contributors focused solely on parsing and your grammar is large enough +//! to be unwieldy to hand write. +//! +//! ## `nom` +//! +//! `winnow` is a fork of the venerable [`nom`](https://crates.io/crates/nom). The difference +//! between them is largely in priorities. `nom` prioritizes: +//! - Lower churn for existing users while `winnow` is trying to find ways to make things better +//! for the parsers yet to be written. +//! - Having a small core, relying on external crates like +//! [`nom-locate`](https://crates.io/crates/nom_locate) and +//! [`nom-supreme`](https://crates.io/crates/nom-supreme), encouraging flexibility among users +//! and to not block users on new features being merged while `winnow` aims to include all the +//! fundamentals for parsing to ensure the experience is cohesive and high quality. +//! +//! ## `chumsky` +//! +//! [`chumsky`](https://crates.io/crates/chumsky) is an up and coming parser-combinator library +//! that includes advanced features like error recovery. +//! +//! Probably the biggest diverging philosophy is `chumsky`s stance: +//! +//! > "If you need to implement either `Parser` or `Strategy` by hand, that's a problem that needs fixing". +//! +//! This is under "batteries included" but it also ties into the feeling that `chumksy` acts more like +//! a framework. Instead of composing together helpers, you are expected to do everything through +//! their system to the point that it is non-trivial to implement their `Parser` trait and are +//! encouraged to use the +//! [`custom`](https://docs.rs/chumsky/0.9.0/chumsky/primitive/fn.custom.html) helper. This +//! requires re-framing everything to fit within their model and makes the code harder to understand +//! and debug as you are working with abstract operations that will eventually be applied +//! rather than directly with the parsers. +//! +//! In contrast, `winnow` is an introspectable toolbox that can easily be customized at any level. +//! Probably the biggest thing that `winnow` loses out on is optimizations from ["parse modes" via +//! GATs](https://github.com/zesterer/chumsky/pull/82) which allows downstream parsers to tell +//! upstream parsers when information will be discarded, allowing bypassing expensive operations, +//! like allocations. This requires a lot more complex interaction with parsers that isn't as +//! trivial to do with bare functions which would lose out on any of that side-band information. +//! Instead, we work around this with things like the [`Accumulate`] trait. + +#![allow(unused_imports)] +use crate::stream::Accumulate; |