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}