oni-comb-parser
A parser-monad combinator library for Rust. The core crate of oni-comb-rs.
Features
- Parsec-style recursive descent — LL(1) by default, LL(*) with
attempt - Full type class hierarchy — Functor (
map) / Applicative (zip) / Alternative (or) / Monad (flat_map) - Zero-cost combinator composition — Applicative combinators are concrete types on the stack, zero heap allocation
- Backtrack / Cut error control —
orrecovers fromBacktrack;Cutpropagates.attempt/cutto control - Structured errors —
ParseErrorwith position, expected tokens, and.context()labels - Generic Input trait —
StrInput<'a>for&str,ByteInput<'a>for&[u8] no_stdsupport —#![no_std]withalloc
Quickstart
use *;
// Match 'a' or 'b'
let mut parser = char.or;
let mut input = new;
assert_eq!;
// Identifier: letter/_ followed by alphanumeric/_
let mut input = new;
let = satisfy
.zip
.parse_next
.unwrap;
assert_eq!;
assert_eq!;
// Integer
let mut int_parser = take_while1
.map;
let mut input = new;
assert_eq!;
Available Parsers
Text Parsers
| Function | Description | Output |
|---|---|---|
char(c) |
Match a specific character | char |
tag(s) |
Match a specific string | &str |
satisfy(f) |
Match a character satisfying predicate | char |
take_while0(f) |
Consume 0+ matching characters | &str |
take_while1(f) |
Consume 1+ matching characters | &str |
eof() |
Match end of input | () |
whitespace0() / whitespace1() |
Consume ASCII whitespace | &str |
identifier() |
ASCII identifier [a-zA-Z_][a-zA-Z0-9_]* |
&str |
integer() |
Signed integer | i64 |
quoted_string() |
JSON-compliant double-quoted string (borrows when unescaped) | Cow<'a, str> |
escaped(open, close, esc, handler) |
Generic escaped string | String |
lexeme(p) |
Run parser then consume trailing whitespace | P::Output |
between(l, p, r) |
Run l, p, r and return p's value | P::Output |
recursive(f) |
Build recursive parser | P::Output |
fn_parser(f) |
Wrap function as Parser | O |
Combinators (ParserExt)
| Method | Type Class | Description |
|---|---|---|
.map(f) |
Functor | Transform success value |
.zip(p) |
Applicative | Sequence two parsers, return pair |
.zip_left(p) |
Applicative | Run both, keep left |
.zip_right(p) |
Applicative | Run both, keep right |
.or(p) |
Alternative | Try right if left backtracks |
.flat_map(f) |
Monad | Context-sensitive branching |
.attempt() |
— | Downgrade Cut to Backtrack |
.cut() |
— | Upgrade Backtrack to Cut |
.optional() |
— | Convert Backtrack to None |
.many0() / .many1() |
— | Repeat 0+ / 1+ times |
.many0_fold(init, f) / .many1_fold(init, f) |
— | Fold 0+ / 1+ elements (zero-allocation) |
.many0_into(c) / .many1_into(c) |
— | Collect into custom Extend container |
.sep_by0(sep) / .sep_by1(sep) |
— | Separated repetition |
.sep_by0_fold(sep, init, f) / .sep_by1_fold(sep, init, f) |
— | Fold separated elements (zero-allocation) |
.sep_by0_into(sep, c) / .sep_by1_into(sep, c) |
— | Collect separated elements into custom container |
.chainl1(op) / .chainr1(op) |
— | Operator associativity chains |
.context(label) |
— | Add error context label |
.map_res(f, label) |
— | Transform with fallible function |
Input Types
| Type | Token | Slice | Use Case |
|---|---|---|---|
StrInput<'a> |
char |
&'a str |
Text parsing (default) |
ByteInput<'a> |
u8 |
&'a [u8] |
Binary protocol parsing |
Build & Test
# Benchmarks
License
Licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT License (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.