1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
use std::{cell::RefCell, marker::PhantomData, rc::Rc};

use crate::{PResult, Parser, ParserInput};

#[derive(Clone)]
pub struct Recursive<T> {
    parser: RecursiveRef<T>,
    _t: PhantomData<T>,
}

impl<T> Recursive<T> {
    pub fn declarative<P: Parser<T> + 'static>(decl: impl FnOnce(RecursiveRef<T>) -> P) -> Self {
        let mut rf = RecursiveRef::new();

        let parser = decl(rf.clone());

        rf.finish(Box::new(parser));

        Self {
            parser: rf,
            _t: PhantomData,
        }
    }

    pub fn declarative_with_value<P: Parser<T> + 'static, R>(
        decl: impl FnOnce(RecursiveRef<T>) -> (P, R),
    ) -> (Self, R) {
        let mut rf = RecursiveRef::new();

        let (parser, ret) = decl(rf.clone());

        rf.finish(Box::new(parser));

        (
            Self {
                parser: rf,
                _t: PhantomData,
            },
            ret,
        )
    }
}

impl<T> Parser<T> for Recursive<T> {
    fn parse_inner(&self, input: &mut ParserInput) -> PResult<T> {
        self.parser.parse(input)
    }
}

pub struct RecursiveRef<T> {
    parser_ref: Rc<RefCell<Option<Box<dyn Parser<T>>>>>,
}

// NOTE: This is required because of https://github.com/rust-lang/rust/issues/26925
impl<T> Clone for RecursiveRef<T> {
    fn clone(&self) -> Self {
        Self {
            parser_ref: self.parser_ref.clone(),
        }
    }
}

impl<T> RecursiveRef<T> {
    fn new() -> Self {
        Self {
            parser_ref: Rc::new(RefCell::new(None)),
        }
    }

    fn finish(&mut self, inner: Box<dyn Parser<T>>) {
        assert!(
            self.parser_ref.borrow().is_none(),
            "Cannot replace a weak parser reference's inner value twice"
        );

        *self.parser_ref.borrow_mut() = Some(inner);
    }
}

impl<T> Parser<T> for RecursiveRef<T> {
    fn parse_inner(&self, input: &mut ParserInput) -> PResult<T> {
        self.parser_ref
            .borrow()
            .as_ref()
            .expect("Weak parser reference was not created yet :(")
            .parse(input)
    }
}