-
Notifications
You must be signed in to change notification settings - Fork 0
A lightweight parser-combinator library operating on `&str`.
License
X-FRI/fringer
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
+---------+
| Fringer |
+---------+
A lightweight parser-combinator library operating on `&str`.
This crate provides a small set of basic parser primitives and combinators,
allowing you to build complex parsers by composing simple ones.
Contents
--------
1. Overview
2. Installation
3. Usage Examples
4. API Reference
4.1. Core Types
4.2. Primitives
4.3. Combinators
4.4. Initializers
5. Testing
6. Contributing
7. License
1. Overview
-----------
This library defines:
- A `Parser<'a, T>` type: a boxed closure that consumes an `&'a str` and returns either a parsed value of type `T` plus the remaining input, or an error message.
- A `ParseResult<'a, T>` alias for `Result<(T, &'a str), String>`.
- A set of parser primitives (`parse_char`, `any_of`) for matching characters.
- A suite of combinators (`and_then`, `or_else`, `map`, `bind`, `apply`, `many`, `many1`, `opt`, `left`, `right`, `between`, `sep_by1`, `sep_by`) to build and transform parsers.
- Initializer functions (`lift2`, `sequence`, `choice`, `pure`) to lift functions and collections of parsers into composable units.
2. Installation
---------------
Add this library as a dependency in your `Cargo.toml`:
[dependencies]
fringer = "0.4.0"
3. Usage Examples
-----------------
Basic character parsing:
use parser_combinators::primitives::ParserPrimitives;
use parser_combinators::combinators::ParserCombinator;
Parser::parse_char('a').run("abc")
Sequencing and choice:
use parser_combinators::initializer::ParserInitializer;
use parser_combinators::primitives::ParserPrimitives;
use parser_combinators::combinators::ParserCombinator;
// parse a b in sequence
Parser::sequence(vec![Parser::parse_char('a'), Parser::parse_char('b')]).run("abcd")
// parse either 'ab' or 'cd'
Parser::choice(vec![
Parser::parse_char('a')
.and_then(Parser::parse_char('b'))
.map(|(x, y)| format!("AB: {}{}", x, y)),
Parser::parse_char('c')
.and_then(Parser::parse_char('d'))
.map(|(x, y)| format!("CD: {}{}", x, y)),
])
Combining functions:
// lift a two-argument function
let pair = Parser::lift2(|x,y| (x,y),
Parser::parse_char('x'),
Parser::parse_char('y'));
Repetition and optional:
let many_a = Parser::parse_char('a').many(); // zero or more 'a'
let some_a = Parser::parse_char('a').many1(); // one or more 'a'
let opt_a = Parser::parse_char('a').opt(); // optional 'a'
Separated lists:
let comma_sep = Parser::parse_char(',');
let list1 = Parser::parse_char('a').sep_by1(comma_sep.clone());
let list0 = Parser::parse_char('a').sep_by(comma_sep);
4. API Reference
----------------
4.1 Core Types
type ParseResult<'a, T> = Result<(T, &'a str), String>
- On success: `Ok((parsed_value, remaining_input))`
- On failure: `Err(error_message)`
struct Parser<'a, T>(Box<dyn Fn(&'a str) -> ParseResult<'a, T> + 'a>)
- Wraps a closure implementing the parsing logic.
- Construct with `Parser::new(f)`.
Method:
run(&self, input: &'a str) -> ParseResult<'a, T>
4.2 Primitives (`ParserPrimitives`)
fn parse_char(expected: char) -> Parser<'a, char>
- Matches exactly one character.
- Error if no input or mismatch.
fn any_of(chars: Vec<char>) -> Parser<'a, char>
- Matches any one character from the provided set.
- Error if no input or character not in set.
4.3 Combinators (`ParserCombinator`)
fn and_then<B>(self, p: Parser<'a, B>) -> Parser<'a, (A, B)>
fn or_else(self, p: Parser<'a, A>) -> Parser<'a, A>
fn map<B, F>(self, f: F) -> Parser<'a, B> where F: Fn(A) -> B
fn bind<B, F>(self, f: F) -> Parser<'a, B> where F: Fn(A) -> Parser<'a, B>
fn apply<B, C>(self, pa: Parser<'a, B>) -> Parser<'a, C> where A: Fn(B) -> C
fn many(self) -> Parser<'a, Vec<A>>
fn many1(self) -> Parser<'a, Vec<A>>
fn opt(self) -> Parser<'a, Option<A>>
fn left<B>(self, pb: Parser<'a, B>) -> Parser<'a, A>
fn right<B>(self, pb: Parser<'a, B>) -> Parser<'a, B>
fn between<B, C>(self, p2: Parser<'a, B>, p3: Parser<'a, C>) -> Parser<'a, B>
fn sep_by1<S>(self, sep: Parser<'a, S>) -> Parser<'a, Vec<A>>
fn sep_by<S>(self, sep: Parser<'a, S>) -> Parser<'a, Vec<A>>
4.4 Initializers (`ParserInitializer`)
fn lift2<B, C, F>(f: F, pa: Parser<'a, A>, pb: Parser<'a, B>) -> Parser<'a, C> where F: Fn(A, B) -> C
fn sequence(parsers: Vec<Parser<'a, A>>) -> Parser<'a, Vec<A>>
fn choice(parsers: Vec<Parser<'a, A>>) -> Parser<'a, A>
- Panics if the vector is empty.
fn pure<F>(f: F) -> Parser<'a, A> where F: Fn() -> A
- Always succeeds without consuming input.
5. Testing
----------
Unit tests are provided in `src/lib.rs`. Run them with:
cargo test
They cover basic combinators, primitives, initializers, and error cases.
6. Contributing
---------------
Contributions, bug reports, and pull requests are welcome.
Please follow standard Rust formatting (`rustfmt`) and ensure all tests pass.
7. License
----------
This project is licensed under the MIT License. See `LICENSE` for details.
About
A lightweight parser-combinator library operating on `&str`.
Resources
License
Stars
Watchers
Forks
Releases
No releases published
Packages 0
No packages published