left_rec

Function left_rec 

Source
pub fn left_rec<L: LexIt + Clone, T: Clone>(
    state: &mut ParserState<'_, L>,
    memo: &Memo<Cursor, Option<T>>,
    parser: impl FnMut(&mut ParserState<'_, L>) -> Result<T, Error>,
) -> Result<T, Error>
Expand description

Left recursion support.

Wrapping a parser in left_rec allows it to be left-recursive. This is crucial for parsing left-recursive grammars, as recursive descent parsers often fail to handle them.

The left_rec function solves this problem by employing memoization. The algorithm used is based on this blog post.

fn parse(
    state: &mut ParserState<CharLexer>,
    memo: &Memo<Cursor, Option<String>>,
) -> Result<String, Error> {
    left_rec(state, memo, |state| {
        let fork = &mut state.fork();
        if let Ok(mut s) = parse(fork, memo) {
            state.advance_to(fork);
            s.push(state.parse_char('b')?);
            Ok(s)
        } else {
            state.parse_char('a').map(|_| String::from("a"))
        }
    })
}

let mut state = ParserState::new("abbbb");
assert_eq!(parse(&mut state, &Memo::default()).unwrap(), "abbbb");