parse_it/
lib.rs

1//! # Parse It
2//! 
3//! *A user-friendly, opinionated parser generator for Rust.*
4//! 
5//! ## Example
6//! 
7//! ```rust
8//! use parse_it::{ParseIt, parse_it};
9//! 
10//! #[derive(Debug, Clone)]
11//! pub enum Instr {
12//!     Left,
13//!     Right,
14//!     Incr,
15//!     Decr,
16//!     Read,
17//!     Write,
18//!     Loop(Vec<Self>),
19//! }
20//! 
21//! parse_it! {
22//!     mod parse {
23//!         use super::Instr;
24//! 
25//!         pub Brainfuck -> Vec<Instr> {
26//!             Primitive* => self,
27//!         }
28//! 
29//!         Primitive -> Instr {
30//!             '<' => Instr::Left,
31//!             '>' => Instr::Right,
32//!             '+' => Instr::Incr,
33//!             '-' => Instr::Decr,
34//!             ',' => Instr::Read,
35//!             '.' => Instr::Write,
36//!             '[' Primitive+ ']' => Instr::Loop(self)
37//!         }
38//!     }
39//! }
40//! 
41//! fn main() {
42//!     let parser = parse::Brainfuck::default();
43//!     let src = "--[>--->->->++>-<<<<<-------]>--.>---------.>--..+++.>----.>+++++++++.<<.+++.------.<-.>>+";
44//!     let instrs = parser.parse(src).unwrap();
45//!     println!("{:?}", instrs);
46//! }
47//! ```
48#![warn(missing_docs)]
49#![allow(clippy::needless_doctest_main)]
50
51pub mod lexer;
52pub mod memo;
53pub mod parser;
54
55pub use parse_it_macros::parse_it;
56
57pub use crate::lexer::{CharLexer, Lexer};
58pub use crate::memo::{left_rec, memorize, Memo};
59pub use crate::parser::{Error, ParserState};
60
61/// A parser.
62pub trait ParseIt {
63    /// The lexer type.
64    type Lexer<'a>: Lexer<'a>;
65    /// The parser output type.
66    type Output;
67
68    /// Parse from a [`ParserState`].
69    fn parse_stream(&self, state: &ParserState<Self::Lexer<'_>>) -> Result<Self::Output, Error>;
70
71    /// Parse from a string.
72    fn parse(&self, input: &str) -> Result<Self::Output, Error> {
73        let state = ParserState::new(Self::Lexer::new(input));
74        self.parse_stream(&state)
75    }
76}