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//!         type Lexer = parse_it::CharLexer;
27//!
28//!         pub Brainfuck -> Vec<Instr> {
29//!             Primitive* => self,
30//!         }
31//!
32//!         Primitive -> Instr {
33//!             '<' => Instr::Left,
34//!             '>' => Instr::Right,
35//!             '+' => Instr::Incr,
36//!             '-' => Instr::Decr,
37//!             ',' => Instr::Read,
38//!             '.' => Instr::Write,
39//!             '[' Primitive+ ']' => Instr::Loop(self)
40//!         }
41//!     }
42//! }
43//!
44//! fn main() {
45//!     let parser = parse::Brainfuck::default();
46//!     let src = "--[>--->->->++>-<<<<<-------]>--.>---------.>--..+++.>----.>+++++++++.<<.+++.------.<-.>>+";
47//!     let instrs = parser.parse(src).unwrap();
48//!     println!("{:?}", instrs);
49//! }
50//! ```
51#![warn(missing_docs)]
52#![allow(clippy::needless_doctest_main)]
53
54pub mod lexer;
55pub mod memo;
56pub mod parser;
57
58pub use parse_it_macros::parse_it;
59
60pub use crate::{
61    lexer::{CharLexer, Cursor, LexerState},
62    memo::{left_rec, memorize, Memo},
63    parser::{Error, ParserState},
64};
65
66/// A lexer.
67pub trait LexIt {
68    /// The token type.
69    type Token<'a>;
70
71    /// Create a new lexer instance.
72    fn new() -> Self;
73
74    /// Get the next token from the lexer.
75    fn next<'a>(&self, lexbuf: &mut LexerState<'a>) -> Option<Self::Token<'a>>;
76}
77
78/// A parser.
79pub trait ParseIt {
80    /// The lexer type.
81    type Lexer: LexIt + Clone;
82    /// The parser output type.
83    type Output;
84
85    /// Parse from a [`ParserState`].
86    fn parse_stream<'a>(
87        &self,
88        state: &mut ParserState<'a, Self::Lexer>,
89    ) -> Result<Self::Output, Error>;
90
91    /// Parse from a string.
92    fn parse(&self, input: &str) -> Result<Self::Output, Error> {
93        let mut state = ParserState::new(input);
94        self.parse_stream(&mut state)
95    }
96}
97
98#[doc(hidden)]
99#[macro_export]
100macro_rules! identity {
101    ($expr:expr) => {
102        $expr
103    };
104}