20 breaking releases
new 0.21.0 | Jan 28, 2025 |
---|---|
0.19.0 | Jan 15, 2025 |
0.16.0 | Dec 29, 2024 |
0.14.0 | Jun 27, 2024 |
0.6.0 | Dec 19, 2023 |
#91 in Parser tooling
552 downloads per month
Used in html-string
24KB
495 lines
bparse
A combinatorial approach to matching slices, especially useful for writing lexers and tokenizers.
The crate borrows concepts from other parser-combinator crates but heavily simplifies things by eschewing error management and focusing exclusively on parsing in-memory buffers.
lib.rs
:
Overview
Parsing usually involves going through a sequence of items and branching off based on the element that was seen. This crate simplifies the task of recognizing complex patterns in a slices. It works with any type of slice.
It is made up of three parts:
- The
Pattern
trait: represents the pattern to be recognized. - A list of common functions and combinators for composing
Patterns
together. - The
SliceReader
struct; aCursor
-like wrapper around an input slice that uses patterns to advance its position.
Example
Recognizing JSON numbers can get tricky.
The spec allows for numbers like 12
, -398.42
, and even 12.4e-3
.
Here we incrementally build up a pattern called number
that can recognizes all JSON number forms.
use bparse::{SliceReader, Pattern, range, at_least, optional, byte::oneof};
let sign = optional(oneof(b"-+"));
let onenine = range(b'1', b'9');
let digit = "0".or(onenine);
let digits = at_least(1, digit);
let fraction = optional(".".then(digits));
let exponent = optional("E".then(sign).then(digits).or("e".then(sign).then(digits)));
let integer = onenine
.then(digits)
.or("-".then(onenine).then(digits))
.or("-".then(digit))
.or(digit);
let number = integer.then(fraction).then(exponent);
let input = b"234||344.5||0.43e12";
let mut reader = SliceReader::new(input);
let Some(b"234") = reader.parse(number) else {
panic!();
};
assert!(reader.accept("||"));
let Some(b"344.5") = reader.parse(number) else {
panic!();
};
assert!(reader.accept("||"));
let Some(b"0.43e12") = reader.parse(number) else {
panic!();
};
assert!(reader.eof());