oni_comb_parser/combinator/
chainr1.rs1use 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 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}