Struct ParserState

Source
pub struct ParserState<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: &ParserState<CharLexer>) -> Result<char, Error> {
    state.parse('a')?;
    state.parse('b')?;
    state.parse('c')?;
    Ok('c')
}

let state = ParserState::new(CharLexer::new("abc"));
parse_abc(&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: &ParserState<CharLexer>,
    parser: impl Fn(&ParserState<CharLexer>) -> Result<char, Error>
) -> Result<Option<char>, Error> {
    let fork = state.fork();
    match parser(&fork) {
        Ok(c) => {
            state.advance_to(&fork);
            Ok(Some(c))
        }
        Err(_) => Ok(None),
    }
}

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

Implementations§

Source§

impl<'a, L: Lexer<'a>> ParserState<L>

Source

pub fn new(lexer: L) -> Self

Create a new parser state from the given lexer.

Source

pub fn pos(&self) -> L::Position

Get the current parsing position.

Source

pub fn parse(&self, token: L::Token) -> Result<L::Token, Error>

Consume the next token if it matches the given token.

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(&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_pos(&self, pos: L::Position)

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<L> !Freeze for ParserState<L>

§

impl<L> !RefUnwindSafe for ParserState<L>

§

impl<L> !Send for ParserState<L>

§

impl<L> !Sync for ParserState<L>

§

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

§

impl<L> !UnwindSafe for ParserState<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.