Skip to main content

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}