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>
impl<'a, L: Lexer<'a>> ParserState<L>
Sourcepub fn parse(&self, token: L::Token) -> Result<L::Token, Error>
pub fn parse(&self, token: L::Token) -> Result<L::Token, Error>
Consume the next token if it matches the given token.
Sourcepub fn advance_to(&self, other: &Self)
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.
Sourcepub fn advance_to_pos(&self, pos: L::Position)
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.