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//! #[parser]
23//! mod parse {
24//! use super::Instr;
25//!
26//! pub Brainfuck -> Vec<Instr> {
27//! Primitive* => self,
28//! }
29//!
30//! Primitive -> Instr {
31//! '<' => Instr::Left,
32//! '>' => Instr::Right,
33//! '+' => Instr::Incr,
34//! '-' => Instr::Decr,
35//! ',' => Instr::Read,
36//! '.' => Instr::Write,
37//! '[' Primitive+ ']' => Instr::Loop(self)
38//! }
39//! }
40//! }
41//!
42//! fn main() {
43//! let parser = parse::Brainfuck::default();
44//! let src = "--[>--->->->++>-<<<<<-------]>--.>---------.>--..+++.>----.>+++++++++.<<.+++.------.<-.>>+";
45//! let instrs = parser.parse(src).unwrap();
46//! println!("{:?}", instrs);
47//! }
48//! ```
49#![warn(missing_docs)]
50#![allow(clippy::needless_doctest_main)]
51
52pub mod lexer;
53pub mod memo;
54pub mod parser;
55
56pub use parse_it_macros::parse_it;
57
58pub use crate::{
59 lexer::{CharLexer, Lexer},
60 memo::{left_rec, memorize, Memo},
61 parser::{Error, ParserState},
62};
63
64/// A parser.
65pub trait ParseIt {
66 /// The lexer type.
67 type Lexer<'a>: Lexer<'a>;
68 /// The parser output type.
69 type Output;
70
71 /// Parse from a [`ParserState`].
72 fn parse_stream(&self, state: &mut ParserState<Self::Lexer<'_>>)
73 -> Result<Self::Output, Error>;
74
75 /// Parse from a string.
76 fn parse(&self, input: &str) -> Result<Self::Output, Error> {
77 let mut state = ParserState::new(Self::Lexer::new(input));
78 self.parse_stream(&mut state)
79 }
80}