lex_just_parse/parser.rs
1//! Combinator parsing utilities.
2//!
3//! Provides the core `Parser` type and related type definitions
4//! for building lexer-driven parsers.
5
6use crate::lexer::Lexer;
7
8/// A mutable reference to a `Lexer`, commonly used by parser functions to consume tokens.
9pub type RefLexer<'lex> = &'lex mut Lexer<'lex>;
10
11/// Represents a typical parser function signature that takes a lexer reference and returns a `Parser` result.
12pub type ParserFn<'lex, T, E> = fn(lex: RefLexer) -> Parser<T, E>;
13
14#[macro_export]
15/// The `?` operator for [`Parser`]
16macro_rules! try_parse {
17 ($f:expr) => {
18 match $f {
19 Parser::Success(lexer, expr) => (lexer, expr),
20 Parser::Fail(lexer, e) => return Parser::Fail(lexer, e),
21 }
22 };
23}
24
25/// Represents the result of a parsing operation.
26///
27/// A parser either succeeds with an advanced lexer and a parsed value `T`, or fails
28/// and returns the unchanged lexer state along with an error `E`.
29pub enum Parser<'lex, T, E> {
30 Success(RefLexer<'lex>, T),
31 Fail(RefLexer<'lex>, E),
32}
33
34impl<'lex, T, E> Parser<'lex, T, E> {
35 /// Chains another parsing attempt if the current parser failed.
36 pub fn or_else<F>(self, f: F) -> Self
37 where
38 F: FnOnce(RefLexer) -> Parser<T, E>,
39 {
40 match self {
41 Parser::Success(..) => self,
42 Parser::Fail(lexer, ..) => f(lexer),
43 }
44 }
45
46 /// Chains a subsequent parser if the current parser succeeds.
47 pub fn and_then<U, F>(self, f: F) -> Parser<'lex, U, E>
48 where
49 F: FnOnce(RefLexer<'lex>, T) -> Parser<'lex, U, E>,
50 {
51 match self {
52 Parser::Success(lexer, e) => f(lexer, e),
53 Parser::Fail(lexer, e) => Parser::Fail(lexer, e),
54 }
55 }
56
57 /// Converts this parser result into a standard `Result`,
58 /// returning the parsed item or the lexer and error pair upon failure.
59 pub fn success(self) -> Result<T, (RefLexer<'lex>, E)> {
60 match self {
61 Parser::Success(_, e) => Ok(e),
62 Parser::Fail(lex, e) => Err((lex, e)),
63 }
64 }
65}