Skip to main content

oni_comb_parser/combinator/
chainr1.rs

1use alloc::vec;
2use alloc::vec::Vec;
3
4use crate::fail::{Fail, PResult};
5use crate::input::Input;
6use crate::parser::Parser;
7
8pub struct ChainR1<P, Op> {
9  pub(crate) operand: P,
10  pub(crate) operator: Op,
11}
12
13impl<I, P, Op, F> Parser<I> for ChainR1<P, Op>
14where
15  I: Input,
16  P: Parser<I>,
17  Op: Parser<I, Output = F, Error = P::Error>,
18  F: FnMut(P::Output, P::Output) -> P::Output,
19{
20  type Error = P::Error;
21  type Output = P::Output;
22
23  #[inline]
24  fn parse_next(&mut self, input: &mut I) -> PResult<Self::Output, Self::Error> {
25    let first = self.operand.parse_next(input)?;
26    let mut operands = vec![first];
27    let mut operators: Vec<F> = Vec::new();
28
29    loop {
30      let cp = input.checkpoint();
31      match self.operator.parse_next(input) {
32        Ok(f) => match self.operand.parse_next(input) {
33          Ok(v) => {
34            operators.push(f);
35            operands.push(v);
36          }
37          Err(Fail::Backtrack(_)) => {
38            input.reset(cp);
39            break;
40          }
41          Err(e) => return Err(e),
42        },
43        Err(Fail::Backtrack(_)) => {
44          input.reset(cp);
45          break;
46        }
47        Err(e) => return Err(e),
48      }
49    }
50
51    // 右から畳む
52    let mut acc = operands.pop().unwrap();
53    while let Some(v) = operands.pop() {
54      let mut f = operators.pop().unwrap();
55      acc = f(v, acc);
56    }
57    Ok(acc)
58  }
59}