ParserState

Struct ParserState 

Source
pub struct ParserState<'a, L> { /* private fields */ }
Expand description

The inner state of a parser.

ParserState is a cursor over the lexer and keeps track of the current position in the source code. It is used to drive the parsing process.

§Writing a Parser

A parser is a function Fn(&ParserState) -> Result<T, Error>, that takes a &ParserState as input and returns the parsed result or an error.

The common use case is to call the parse method to read a token from the lexer and advance the state by one token.

fn parse_abc(state: &mut ParserState<CharLexer>) -> Result<char, Error> {
    state.parse_char('a')?;
    state.parse_char('b')?;
    state.parse_char('c')?;
    Ok('c')
}

let mut state = ParserState::new("abc");
parse_abc(&mut state).unwrap();
assert!(state.is_empty());

Please note that ParserState uses interior mutability to share its state between parsers. This means that even if a parser takes a &ParserState, the state can still be mutated.

§Speculative Parsing

ParserState allows you to create a fork of the current state via the fork method, and join it back to the original state later via the advance_to method. This is useful for speculative parsing.

It’s important to note that ParserState can only move forward and not backward. When joining a fork back to the original state, it must be ensured that the fork is at a position beyond or equal to the original state.

fn parse_option(
    state: &mut ParserState<CharLexer>,
    parser: impl Fn(&mut ParserState<CharLexer>) -> Result<char, Error>
) -> Result<Option<char>, Error> {
    let fork = &mut state.fork();
    match parser(fork) {
        Ok(c) => {
            state.advance_to(fork);
            Ok(Some(c))
        }
        Err(_) => Ok(None),
    }
}

let mut state = ParserState::new("aaa");
assert_eq!(parse_option(&mut state, |state| state.parse_char('a')).unwrap(), Some('a'));
assert_eq!(parse_option(&mut state, |state| state.parse_char('b')).unwrap(), None);

Implementations§

Source§

impl<'a, L: LexIt + Clone> ParserState<'a, L>

Source

pub fn new(input: &'a str) -> Self

Create a new parser state from the given lexer.

Source

pub fn cursor(&self) -> Cursor

Get the current parsing position.

Source

pub fn parse_with<T>( &mut self, matches: impl FnOnce(L::Token<'a>) -> Option<T>, ) -> Result<T, Error>

Consume the next token if it matches the given token.

Source

pub fn parse_type<T>(&mut self) -> Result<T, Error>
where L::Token<'a>: TryConvert<T>, T: PartialEq,

Parse a token that can be converted to the given type.

Source

pub fn parse_char(&mut self, c: char) -> Result<char, Error>

Parse a token that exactly matches the given character.

Source

pub fn parse_str(&mut self, literal: &'a str) -> Result<&str, Error>

Parse a token that exactly matches the given string.

Source

pub fn error(&self) -> Error

Report an error at the current position.

Source

pub fn is_empty(&self) -> bool

Whether the parser is at the end of the input.

Source

pub fn advance_to(&mut self, other: &Self)

Advance the state to the given state.

§Panics

Panics if the given state is before the current state.

Source

pub fn advance_to_cursor(&mut self, cursor: Cursor)

Advance the state to the given position.

§Panics

Panics if the given position is before the current position.

Source

pub fn fork(&self) -> Self

Create a fork of the current state for speculative parsing.

Source

pub fn push(&self, name: &'static str)

Push the given name onto the stack (for debugging purposes).

Source

pub fn pop(&self)

Pop the last name from the stack (for debugging purposes).

Source

pub fn debug(&self) -> String

Get the current stack (for debugging purposes).

Auto Trait Implementations§

§

impl<'a, L> Freeze for ParserState<'a, L>
where L: Freeze,

§

impl<'a, L> !RefUnwindSafe for ParserState<'a, L>

§

impl<'a, L> !Send for ParserState<'a, L>

§

impl<'a, L> !Sync for ParserState<'a, L>

§

impl<'a, L> Unpin for ParserState<'a, L>
where L: Unpin,

§

impl<'a, L> !UnwindSafe for ParserState<'a, L>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.