1 | //! Combinators applying their child parser multiple times |
2 | |
3 | use crate::error::ErrMode; |
4 | use crate::error::ErrorKind; |
5 | use crate::error::ParseError; |
6 | use crate::stream::Accumulate; |
7 | use crate::stream::Range; |
8 | use crate::stream::Stream; |
9 | use crate::trace::trace; |
10 | use crate::IResult; |
11 | use crate::Parser; |
12 | |
13 | /// [`Accumulate`] the output of a parser into a container, like `Vec` |
14 | /// |
15 | /// This stops before `n` when the parser returns [`ErrMode::Backtrack`]. To instead chain an error up, see |
16 | /// [`cut_err`][crate::combinator::cut_err]. |
17 | /// |
18 | /// # Arguments |
19 | /// * `m` The minimum number of iterations. |
20 | /// * `n` The maximum number of iterations. |
21 | /// * `f` The parser to apply. |
22 | /// |
23 | /// To recognize a series of tokens, [`Accumulate`] into a `()` and then [`Parser::recognize`]. |
24 | /// |
25 | /// **Warning:** If the parser passed to `repeat` accepts empty inputs |
26 | /// (like `alpha0` or `digit0`), `repeat` will return an error, |
27 | /// to prevent going into an infinite loop. |
28 | /// |
29 | /// # Example |
30 | /// |
31 | /// Zero or more reptitions: |
32 | /// ```rust |
33 | /// # #[cfg (feature = "std" )] { |
34 | /// # use winnow::{error::ErrMode, error::ErrorKind, error::Needed}; |
35 | /// # use winnow::prelude::*; |
36 | /// use winnow::combinator::repeat; |
37 | /// use winnow::token::tag; |
38 | /// |
39 | /// fn parser(s: &str) -> IResult<&str, Vec<&str>> { |
40 | /// repeat(0.., "abc" ).parse_next(s) |
41 | /// } |
42 | /// |
43 | /// assert_eq!(parser("abcabc" ), Ok(("" , vec!["abc" , "abc" ]))); |
44 | /// assert_eq!(parser("abc123" ), Ok(("123" , vec!["abc" ]))); |
45 | /// assert_eq!(parser("123123" ), Ok(("123123" , vec![]))); |
46 | /// assert_eq!(parser("" ), Ok(("" , vec![]))); |
47 | /// # } |
48 | /// ``` |
49 | /// |
50 | /// One or more reptitions: |
51 | /// ```rust |
52 | /// # #[cfg (feature = "std" )] { |
53 | /// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, error::Needed}; |
54 | /// # use winnow::prelude::*; |
55 | /// use winnow::combinator::repeat; |
56 | /// use winnow::token::tag; |
57 | /// |
58 | /// fn parser(s: &str) -> IResult<&str, Vec<&str>> { |
59 | /// repeat(1.., "abc" ).parse_next(s) |
60 | /// } |
61 | /// |
62 | /// assert_eq!(parser("abcabc" ), Ok(("" , vec!["abc" , "abc" ]))); |
63 | /// assert_eq!(parser("abc123" ), Ok(("123" , vec!["abc" ]))); |
64 | /// assert_eq!(parser("123123" ), Err(ErrMode::Backtrack(Error::new("123123" , ErrorKind::Tag)))); |
65 | /// assert_eq!(parser("" ), Err(ErrMode::Backtrack(Error::new("" , ErrorKind::Tag)))); |
66 | /// # } |
67 | /// ``` |
68 | /// |
69 | /// Fixed number of repeitions: |
70 | /// ```rust |
71 | /// # #[cfg (feature = "std" )] { |
72 | /// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, error::Needed}; |
73 | /// # use winnow::prelude::*; |
74 | /// use winnow::combinator::repeat; |
75 | /// use winnow::token::tag; |
76 | /// |
77 | /// fn parser(s: &str) -> IResult<&str, Vec<&str>> { |
78 | /// repeat(2, "abc" ).parse_next(s) |
79 | /// } |
80 | /// |
81 | /// assert_eq!(parser("abcabc" ), Ok(("" , vec!["abc" , "abc" ]))); |
82 | /// assert_eq!(parser("abc123" ), Err(ErrMode::Backtrack(Error::new("123" , ErrorKind::Tag)))); |
83 | /// assert_eq!(parser("123123" ), Err(ErrMode::Backtrack(Error::new("123123" , ErrorKind::Tag)))); |
84 | /// assert_eq!(parser("" ), Err(ErrMode::Backtrack(Error::new("" , ErrorKind::Tag)))); |
85 | /// assert_eq!(parser("abcabcabc" ), Ok(("abc" , vec!["abc" , "abc" ]))); |
86 | /// # } |
87 | /// ``` |
88 | /// |
89 | /// Arbitrary reptitions: |
90 | /// ```rust |
91 | /// # #[cfg (feature = "std" )] { |
92 | /// # use winnow::{error::ErrMode, error::ErrorKind, error::Needed}; |
93 | /// # use winnow::prelude::*; |
94 | /// use winnow::combinator::repeat; |
95 | /// use winnow::token::tag; |
96 | /// |
97 | /// fn parser(s: &str) -> IResult<&str, Vec<&str>> { |
98 | /// repeat(0..=2, "abc" ).parse_next(s) |
99 | /// } |
100 | /// |
101 | /// assert_eq!(parser("abcabc" ), Ok(("" , vec!["abc" , "abc" ]))); |
102 | /// assert_eq!(parser("abc123" ), Ok(("123" , vec!["abc" ]))); |
103 | /// assert_eq!(parser("123123" ), Ok(("123123" , vec![]))); |
104 | /// assert_eq!(parser("" ), Ok(("" , vec![]))); |
105 | /// assert_eq!(parser("abcabcabc" ), Ok(("abc" , vec!["abc" , "abc" ]))); |
106 | /// # } |
107 | /// ``` |
108 | #[doc (alias = "many0" )] |
109 | #[doc (alias = "count" )] |
110 | #[doc (alias = "many0_count" )] |
111 | #[doc (alias = "many1" )] |
112 | #[doc (alias = "many1_count" )] |
113 | #[doc (alias = "many_m_n" )] |
114 | #[doc (alias = "repeated" )] |
115 | #[doc (alias = "skip_many" )] |
116 | #[doc (alias = "skip_many1" )] |
117 | #[inline (always)] |
118 | pub fn repeat<I, O, C, E, F>(range: impl Into<Range>, mut f: F) -> impl Parser<I, C, E> |
119 | where |
120 | I: Stream, |
121 | C: Accumulate<O>, |
122 | F: Parser<I, O, E>, |
123 | E: ParseError<I>, |
124 | { |
125 | let Range { |
126 | start_inclusive: usize, |
127 | end_inclusive: Option, |
128 | } = range.into(); |
129 | trace(name:"repeat" , parser:move |i: I| { |
130 | match (start_inclusive, end_inclusive) { |
131 | (0, None) => repeat0_(&mut f, i), |
132 | (1, None) => repeat1_(&mut f, i), |
133 | (start: usize, end: Option) if Some(start) == end => repeat_n_(count:start, &mut f, i), |
134 | (start: usize, end: Option) => repeat_m_n_(min:start, max:end.unwrap_or(usize::MAX), &mut f, input:i), |
135 | } |
136 | }) |
137 | } |
138 | |
139 | /// Deprecated, replaced by [`repeat`] |
140 | #[deprecated (since = "0.4.6" , note = "Replaced with `repeat`" )] |
141 | #[inline (always)] |
142 | pub fn repeat0<I, O, C, E, F>(f: F) -> impl Parser<I, C, E> |
143 | where |
144 | I: Stream, |
145 | C: Accumulate<O>, |
146 | F: Parser<I, O, E>, |
147 | E: ParseError<I>, |
148 | { |
149 | repeat(range:0.., f) |
150 | } |
151 | |
152 | fn repeat0_<I, O, C, E, F>(f: &mut F, mut i: I) -> IResult<I, C, E> |
153 | where |
154 | I: Stream, |
155 | C: Accumulate<O>, |
156 | F: Parser<I, O, E>, |
157 | E: ParseError<I>, |
158 | { |
159 | let mut acc: C = C::initial(capacity:None); |
160 | loop { |
161 | let len: usize = i.eof_offset(); |
162 | match f.parse_next(input:i.clone()) { |
163 | Err(ErrMode::Backtrack(_)) => return Ok((i, acc)), |
164 | Err(e: ErrMode) => return Err(e), |
165 | Ok((i1: I, o: O)) => { |
166 | // infinite loop check: the parser must always consume |
167 | if i1.eof_offset() == len { |
168 | return Err(ErrMode::assert(input:i, _message:"`repeat` parsers must always consume" )); |
169 | } |
170 | |
171 | i = i1; |
172 | acc.accumulate(acc:o); |
173 | } |
174 | } |
175 | } |
176 | } |
177 | |
178 | /// Deprecated, replaced by [`repeat`] |
179 | #[deprecated (since = "0.4.6" , note = "Replaced with `repeat`" )] |
180 | #[inline (always)] |
181 | pub fn repeat1<I, O, C, E, F>(f: F) -> impl Parser<I, C, E> |
182 | where |
183 | I: Stream, |
184 | C: Accumulate<O>, |
185 | F: Parser<I, O, E>, |
186 | E: ParseError<I>, |
187 | { |
188 | repeat(range:1.., f) |
189 | } |
190 | |
191 | fn repeat1_<I, O, C, E, F>(f: &mut F, mut i: I) -> IResult<I, C, E> |
192 | where |
193 | I: Stream, |
194 | C: Accumulate<O>, |
195 | F: Parser<I, O, E>, |
196 | E: ParseError<I>, |
197 | { |
198 | match f.parse_next(i.clone()) { |
199 | Err(e) => Err(e.append(i, ErrorKind::Many)), |
200 | Ok((i1, o)) => { |
201 | let mut acc = C::initial(None); |
202 | acc.accumulate(o); |
203 | i = i1; |
204 | |
205 | loop { |
206 | let len = i.eof_offset(); |
207 | match f.parse_next(i.clone()) { |
208 | Err(ErrMode::Backtrack(_)) => return Ok((i, acc)), |
209 | Err(e) => return Err(e), |
210 | Ok((i1, o)) => { |
211 | // infinite loop check: the parser must always consume |
212 | if i1.eof_offset() == len { |
213 | return Err(ErrMode::assert(i, "`repeat` parsers must always consume" )); |
214 | } |
215 | |
216 | i = i1; |
217 | acc.accumulate(o); |
218 | } |
219 | } |
220 | } |
221 | } |
222 | } |
223 | } |
224 | |
225 | /// [`Accumulate`] the output of parser `f` into a container, like `Vec`, until the parser `g` |
226 | /// produces a result. |
227 | /// |
228 | /// Returns a tuple of the results of `f` in a `Vec` and the result of `g`. |
229 | /// |
230 | /// `f` keeps going so long as `g` produces [`ErrMode::Backtrack`]. To instead chain an error up, see [`cut_err`][crate::combinator::cut_err]. |
231 | /// |
232 | /// To recognize a series of tokens, [`Accumulate`] into a `()` and then [`Parser::recognize`]. |
233 | /// |
234 | /// # Example |
235 | /// |
236 | /// ```rust |
237 | /// # #[cfg (feature = "std" )] { |
238 | /// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, error::Needed}; |
239 | /// # use winnow::prelude::*; |
240 | /// use winnow::combinator::repeat_till0; |
241 | /// use winnow::token::tag; |
242 | /// |
243 | /// fn parser(s: &str) -> IResult<&str, (Vec<&str>, &str)> { |
244 | /// repeat_till0("abc" , "end" ).parse_next(s) |
245 | /// }; |
246 | /// |
247 | /// assert_eq!(parser("abcabcend" ), Ok(("" , (vec!["abc" , "abc" ], "end" )))); |
248 | /// assert_eq!(parser("abc123end" ), Err(ErrMode::Backtrack(Error::new("123end" , ErrorKind::Tag)))); |
249 | /// assert_eq!(parser("123123end" ), Err(ErrMode::Backtrack(Error::new("123123end" , ErrorKind::Tag)))); |
250 | /// assert_eq!(parser("" ), Err(ErrMode::Backtrack(Error::new("" , ErrorKind::Tag)))); |
251 | /// assert_eq!(parser("abcendefg" ), Ok(("efg" , (vec!["abc" ], "end" )))); |
252 | /// # } |
253 | /// ``` |
254 | #[doc (alias = "many_till0" )] |
255 | pub fn repeat_till0<I, O, C, P, E, F, G>(mut f: F, mut g: G) -> impl Parser<I, (C, P), E> |
256 | where |
257 | I: Stream, |
258 | C: Accumulate<O>, |
259 | F: Parser<I, O, E>, |
260 | G: Parser<I, P, E>, |
261 | E: ParseError<I>, |
262 | { |
263 | trace("repeat_till0" , move |mut i: I| { |
264 | let mut res = C::initial(None); |
265 | loop { |
266 | let len = i.eof_offset(); |
267 | match g.parse_next(i.clone()) { |
268 | Ok((i1, o)) => return Ok((i1, (res, o))), |
269 | Err(ErrMode::Backtrack(_)) => { |
270 | match f.parse_next(i.clone()) { |
271 | Err(e) => return Err(e.append(i, ErrorKind::Many)), |
272 | Ok((i1, o)) => { |
273 | // infinite loop check: the parser must always consume |
274 | if i1.eof_offset() == len { |
275 | return Err(ErrMode::assert( |
276 | i, |
277 | "`repeat` parsers must always consume" , |
278 | )); |
279 | } |
280 | |
281 | res.accumulate(o); |
282 | i = i1; |
283 | } |
284 | } |
285 | } |
286 | Err(e) => return Err(e), |
287 | } |
288 | } |
289 | }) |
290 | } |
291 | |
292 | /// [`Accumulate`] the output of a parser, interleaed with `sep` |
293 | /// |
294 | /// This stops when either parser returns [`ErrMode::Backtrack`]. To instead chain an error up, see |
295 | /// [`cut_err`][crate::combinator::cut_err]. |
296 | /// |
297 | /// # Arguments |
298 | /// * `parser` Parses the elements of the list. |
299 | /// * `sep` Parses the separator between list elements. |
300 | /// |
301 | /// # Example |
302 | /// |
303 | /// ```rust |
304 | /// # #[cfg (feature = "std" )] { |
305 | /// # use winnow::{error::ErrMode, error::ErrorKind, error::Needed}; |
306 | /// # use winnow::prelude::*; |
307 | /// use winnow::combinator::separated0; |
308 | /// use winnow::token::tag; |
309 | /// |
310 | /// fn parser(s: &str) -> IResult<&str, Vec<&str>> { |
311 | /// separated0("abc" , "|" ).parse_next(s) |
312 | /// } |
313 | /// |
314 | /// assert_eq!(parser("abc|abc|abc" ), Ok(("" , vec!["abc" , "abc" , "abc" ]))); |
315 | /// assert_eq!(parser("abc123abc" ), Ok(("123abc" , vec!["abc" ]))); |
316 | /// assert_eq!(parser("abc|def" ), Ok(("|def" , vec!["abc" ]))); |
317 | /// assert_eq!(parser("" ), Ok(("" , vec![]))); |
318 | /// assert_eq!(parser("def|abc" ), Ok(("def|abc" , vec![]))); |
319 | /// # } |
320 | /// ``` |
321 | #[doc (alias = "sep_by" )] |
322 | #[doc (alias = "separated_list0" )] |
323 | pub fn separated0<I, O, C, O2, E, P, S>(mut parser: P, mut sep: S) -> impl Parser<I, C, E> |
324 | where |
325 | I: Stream, |
326 | C: Accumulate<O>, |
327 | P: Parser<I, O, E>, |
328 | S: Parser<I, O2, E>, |
329 | E: ParseError<I>, |
330 | { |
331 | trace("separated0" , move |mut i: I| { |
332 | let mut res = C::initial(None); |
333 | |
334 | match parser.parse_next(i.clone()) { |
335 | Err(ErrMode::Backtrack(_)) => return Ok((i, res)), |
336 | Err(e) => return Err(e), |
337 | Ok((i1, o)) => { |
338 | res.accumulate(o); |
339 | i = i1; |
340 | } |
341 | } |
342 | |
343 | loop { |
344 | let len = i.eof_offset(); |
345 | match sep.parse_next(i.clone()) { |
346 | Err(ErrMode::Backtrack(_)) => return Ok((i, res)), |
347 | Err(e) => return Err(e), |
348 | Ok((i1, _)) => { |
349 | // infinite loop check: the parser must always consume |
350 | if i1.eof_offset() == len { |
351 | return Err(ErrMode::assert(i, "sep parsers must always consume" )); |
352 | } |
353 | |
354 | match parser.parse_next(i1.clone()) { |
355 | Err(ErrMode::Backtrack(_)) => return Ok((i, res)), |
356 | Err(e) => return Err(e), |
357 | Ok((i2, o)) => { |
358 | res.accumulate(o); |
359 | i = i2; |
360 | } |
361 | } |
362 | } |
363 | } |
364 | } |
365 | }) |
366 | } |
367 | |
368 | /// [`Accumulate`] the output of a parser, interleaed with `sep` |
369 | /// |
370 | /// Fails if the element parser does not produce at least one element.$ |
371 | /// |
372 | /// This stops when either parser returns [`ErrMode::Backtrack`]. To instead chain an error up, see |
373 | /// [`cut_err`][crate::combinator::cut_err]. |
374 | /// |
375 | /// # Arguments |
376 | /// * `sep` Parses the separator between list elements. |
377 | /// * `f` Parses the elements of the list. |
378 | /// |
379 | /// # Example |
380 | /// |
381 | /// ```rust |
382 | /// # #[cfg (feature = "std" )] { |
383 | /// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, error::Needed}; |
384 | /// # use winnow::prelude::*; |
385 | /// use winnow::combinator::separated1; |
386 | /// use winnow::token::tag; |
387 | /// |
388 | /// fn parser(s: &str) -> IResult<&str, Vec<&str>> { |
389 | /// separated1("abc" , "|" ).parse_next(s) |
390 | /// } |
391 | /// |
392 | /// assert_eq!(parser("abc|abc|abc" ), Ok(("" , vec!["abc" , "abc" , "abc" ]))); |
393 | /// assert_eq!(parser("abc123abc" ), Ok(("123abc" , vec!["abc" ]))); |
394 | /// assert_eq!(parser("abc|def" ), Ok(("|def" , vec!["abc" ]))); |
395 | /// assert_eq!(parser("" ), Err(ErrMode::Backtrack(Error::new("" , ErrorKind::Tag)))); |
396 | /// assert_eq!(parser("def|abc" ), Err(ErrMode::Backtrack(Error::new("def|abc" , ErrorKind::Tag)))); |
397 | /// # } |
398 | /// ``` |
399 | #[doc (alias = "sep_by1" )] |
400 | #[doc (alias = "separated_list1" )] |
401 | pub fn separated1<I, O, C, O2, E, P, S>(mut parser: P, mut sep: S) -> impl Parser<I, C, E> |
402 | where |
403 | I: Stream, |
404 | C: Accumulate<O>, |
405 | P: Parser<I, O, E>, |
406 | S: Parser<I, O2, E>, |
407 | E: ParseError<I>, |
408 | { |
409 | trace("separated1" , move |mut i: I| { |
410 | let mut res = C::initial(None); |
411 | |
412 | // Parse the first element |
413 | match parser.parse_next(i.clone()) { |
414 | Err(e) => return Err(e), |
415 | Ok((i1, o)) => { |
416 | res.accumulate(o); |
417 | i = i1; |
418 | } |
419 | } |
420 | |
421 | loop { |
422 | let len = i.eof_offset(); |
423 | match sep.parse_next(i.clone()) { |
424 | Err(ErrMode::Backtrack(_)) => return Ok((i, res)), |
425 | Err(e) => return Err(e), |
426 | Ok((i1, _)) => { |
427 | // infinite loop check: the parser must always consume |
428 | if i1.eof_offset() == len { |
429 | return Err(ErrMode::assert(i, "sep parsers must always consume" )); |
430 | } |
431 | |
432 | match parser.parse_next(i1.clone()) { |
433 | Err(ErrMode::Backtrack(_)) => return Ok((i, res)), |
434 | Err(e) => return Err(e), |
435 | Ok((i2, o)) => { |
436 | res.accumulate(o); |
437 | i = i2; |
438 | } |
439 | } |
440 | } |
441 | } |
442 | } |
443 | }) |
444 | } |
445 | |
446 | /// Alternates between two parsers, merging the results (left associative) |
447 | /// |
448 | /// This stops when either parser returns [`ErrMode::Backtrack`]. To instead chain an error up, see |
449 | /// [`cut_err`][crate::combinator::cut_err]. |
450 | /// |
451 | /// # Example |
452 | /// |
453 | /// ```rust |
454 | /// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, error::Needed}; |
455 | /// # use winnow::prelude::*; |
456 | /// use winnow::combinator::separated_foldl1; |
457 | /// use winnow::ascii::dec_int; |
458 | /// |
459 | /// fn parser(s: &str) -> IResult<&str, i32> { |
460 | /// separated_foldl1(dec_int, "-" , |l, _, r| l - r).parse_next(s) |
461 | /// } |
462 | /// |
463 | /// assert_eq!(parser("9-3-5" ), Ok(("" , 1))); |
464 | /// assert_eq!(parser("" ), Err(ErrMode::Backtrack(Error::new("" , ErrorKind::Slice)))); |
465 | /// assert_eq!(parser("def|abc" ), Err(ErrMode::Backtrack(Error::new("def|abc" , ErrorKind::Slice)))); |
466 | /// ``` |
467 | pub fn separated_foldl1<I, O, O2, E, P, S, Op>( |
468 | mut parser: P, |
469 | mut sep: S, |
470 | op: Op, |
471 | ) -> impl Parser<I, O, E> |
472 | where |
473 | I: Stream, |
474 | P: Parser<I, O, E>, |
475 | S: Parser<I, O2, E>, |
476 | E: ParseError<I>, |
477 | Op: Fn(O, O2, O) -> O, |
478 | { |
479 | trace("separated_foldl1" , move |i: I| { |
480 | let (mut i, mut ol) = parser.parse_next(i)?; |
481 | |
482 | loop { |
483 | let len = i.eof_offset(); |
484 | match sep.parse_next(i.clone()) { |
485 | Err(ErrMode::Backtrack(_)) => return Ok((i, ol)), |
486 | Err(e) => return Err(e), |
487 | Ok((i1, s)) => { |
488 | // infinite loop check: the parser must always consume |
489 | if i1.eof_offset() == len { |
490 | return Err(ErrMode::assert(i, "`repeat` parsers must always consume" )); |
491 | } |
492 | |
493 | match parser.parse_next(i1.clone()) { |
494 | Err(ErrMode::Backtrack(_)) => return Ok((i, ol)), |
495 | Err(e) => return Err(e), |
496 | Ok((i2, or)) => { |
497 | ol = op(ol, s, or); |
498 | i = i2; |
499 | } |
500 | } |
501 | } |
502 | } |
503 | } |
504 | }) |
505 | } |
506 | |
507 | /// Alternates between two parsers, merging the results (right associative) |
508 | /// |
509 | /// This stops when either parser returns [`ErrMode::Backtrack`]. To instead chain an error up, see |
510 | /// [`cut_err`][crate::combinator::cut_err]. |
511 | /// |
512 | /// # Example |
513 | /// |
514 | /// ``` |
515 | /// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, error::Needed}; |
516 | /// # use winnow::prelude::*; |
517 | /// use winnow::combinator::separated_foldr1; |
518 | /// use winnow::ascii::dec_uint; |
519 | /// |
520 | /// fn parser(s: &str) -> IResult<&str, u32> { |
521 | /// separated_foldr1(dec_uint, "^" , |l: u32, _, r: u32| l.pow(r)).parse_next(s) |
522 | /// } |
523 | /// |
524 | /// assert_eq!(parser("2^3^2" ), Ok(("" , 512))); |
525 | /// assert_eq!(parser("2" ), Ok(("" , 2))); |
526 | /// assert_eq!(parser("" ), Err(ErrMode::Backtrack(Error::new("" , ErrorKind::Slice)))); |
527 | /// assert_eq!(parser("def|abc" ), Err(ErrMode::Backtrack(Error::new("def|abc" , ErrorKind::Slice)))); |
528 | /// ``` |
529 | #[cfg (feature = "alloc" )] |
530 | pub fn separated_foldr1<I, O, O2, E, P, S, Op>( |
531 | mut parser: P, |
532 | mut sep: S, |
533 | op: Op, |
534 | ) -> impl Parser<I, O, E> |
535 | where |
536 | I: Stream, |
537 | P: Parser<I, O, E>, |
538 | S: Parser<I, O2, E>, |
539 | E: ParseError<I>, |
540 | Op: Fn(O, O2, O) -> O, |
541 | { |
542 | trace(name:"separated_foldr1" , parser:move |i: I| { |
543 | let (i: I, ol: O) = parser.parse_next(input:i)?; |
544 | let (i: I, all: Vec<(O2, O)>): (_, crate::lib::std::vec::Vec<(O2, O)>) = |
545 | repeat(0.., (sep.by_ref(), parser.by_ref())).parse_next(input:i)?; |
546 | if let Some((s: O2, or: O)) = allimpl Iterator |
547 | .into_iter() |
548 | .rev() |
549 | .reduce(|(sr: O2, or: O), (sl: O2, ol: O)| (sl, op(ol, sr, or))) |
550 | { |
551 | let merged: O = op(ol, s, or); |
552 | Ok((i, merged)) |
553 | } else { |
554 | Ok((i, ol)) |
555 | } |
556 | }) |
557 | } |
558 | |
559 | fn repeat_m_n_<I, O, C, E, F>( |
560 | min: usize, |
561 | max: usize, |
562 | parse: &mut F, |
563 | mut input: I, |
564 | ) -> IResult<I, C, E> |
565 | where |
566 | I: Stream, |
567 | C: Accumulate<O>, |
568 | F: Parser<I, O, E>, |
569 | E: ParseError<I>, |
570 | { |
571 | if min > max { |
572 | return Err(ErrMode::Cut(E::from_error_kind(input, ErrorKind::Many))); |
573 | } |
574 | |
575 | let mut res = C::initial(Some(min)); |
576 | for count in 0..max { |
577 | let len = input.eof_offset(); |
578 | match parse.parse_next(input.clone()) { |
579 | Ok((tail, value)) => { |
580 | // infinite loop check: the parser must always consume |
581 | if tail.eof_offset() == len { |
582 | return Err(ErrMode::assert( |
583 | input, |
584 | "`repeat` parsers must always consume" , |
585 | )); |
586 | } |
587 | |
588 | res.accumulate(value); |
589 | input = tail; |
590 | } |
591 | Err(ErrMode::Backtrack(e)) => { |
592 | if count < min { |
593 | return Err(ErrMode::Backtrack(e.append(input, ErrorKind::Many))); |
594 | } else { |
595 | return Ok((input, res)); |
596 | } |
597 | } |
598 | Err(e) => { |
599 | return Err(e); |
600 | } |
601 | } |
602 | } |
603 | |
604 | Ok((input, res)) |
605 | } |
606 | |
607 | /// Deprecated, replaced by [`repeat`] |
608 | #[deprecated (since = "0.4.6" , note = "Replaced with `repeat`" )] |
609 | #[inline (always)] |
610 | pub fn count<I, O, C, E, F>(f: F, count: usize) -> impl Parser<I, C, E> |
611 | where |
612 | I: Stream, |
613 | C: Accumulate<O>, |
614 | F: Parser<I, O, E>, |
615 | E: ParseError<I>, |
616 | { |
617 | repeat(range:count, f) |
618 | } |
619 | |
620 | fn repeat_n_<I, O, C, E, F>(count: usize, f: &mut F, i: I) -> IResult<I, C, E> |
621 | where |
622 | I: Stream, |
623 | C: Accumulate<O>, |
624 | F: Parser<I, O, E>, |
625 | E: ParseError<I>, |
626 | { |
627 | let mut input: I = i.clone(); |
628 | let mut res: C = C::initial(capacity:Some(count)); |
629 | |
630 | for _ in 0..count { |
631 | let input_: I = input.clone(); |
632 | match f.parse_next(input_) { |
633 | Ok((i: I, o: O)) => { |
634 | res.accumulate(acc:o); |
635 | input = i; |
636 | } |
637 | Err(e: ErrMode) => { |
638 | return Err(e.append(input:i, kind:ErrorKind::Many)); |
639 | } |
640 | } |
641 | } |
642 | |
643 | Ok((input, res)) |
644 | } |
645 | |
646 | /// Repeats the embedded parser, filling the given slice with results. |
647 | /// |
648 | /// This parser fails if the input runs out before the given slice is full. |
649 | /// |
650 | /// # Arguments |
651 | /// * `f` The parser to apply. |
652 | /// * `buf` The slice to fill |
653 | /// |
654 | /// # Example |
655 | /// |
656 | /// ```rust |
657 | /// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, error::Needed}; |
658 | /// # use winnow::prelude::*; |
659 | /// use winnow::combinator::fill; |
660 | /// use winnow::token::tag; |
661 | /// |
662 | /// fn parser(s: &str) -> IResult<&str, [&str; 2]> { |
663 | /// let mut buf = ["" , "" ]; |
664 | /// let (rest, ()) = fill("abc" , &mut buf).parse_next(s)?; |
665 | /// Ok((rest, buf)) |
666 | /// } |
667 | /// |
668 | /// assert_eq!(parser("abcabc" ), Ok(("" , ["abc" , "abc" ]))); |
669 | /// assert_eq!(parser("abc123" ), Err(ErrMode::Backtrack(Error::new("123" , ErrorKind::Tag)))); |
670 | /// assert_eq!(parser("123123" ), Err(ErrMode::Backtrack(Error::new("123123" , ErrorKind::Tag)))); |
671 | /// assert_eq!(parser("" ), Err(ErrMode::Backtrack(Error::new("" , ErrorKind::Tag)))); |
672 | /// assert_eq!(parser("abcabcabc" ), Ok(("abc" , ["abc" , "abc" ]))); |
673 | /// ``` |
674 | pub fn fill<'a, I, O, E, F>(mut f: F, buf: &'a mut [O]) -> impl Parser<I, (), E> + 'a |
675 | where |
676 | I: Stream + 'a, |
677 | F: Parser<I, O, E> + 'a, |
678 | E: ParseError<I> + 'a, |
679 | { |
680 | trace(name:"fill" , parser:move |i: I| { |
681 | let mut input: I = i.clone(); |
682 | |
683 | for elem: &mut O in buf.iter_mut() { |
684 | let input_: I = input.clone(); |
685 | match f.parse_next(input_) { |
686 | Ok((i: I, o: O)) => { |
687 | *elem = o; |
688 | input = i; |
689 | } |
690 | Err(e: ErrMode) => { |
691 | return Err(e.append(input:i, kind:ErrorKind::Many)); |
692 | } |
693 | } |
694 | } |
695 | |
696 | Ok((input, ())) |
697 | }) |
698 | } |
699 | |
700 | /// Repeats the embedded parser `m..=n` times, calling `g` to gather the results |
701 | /// |
702 | /// This stops before `n` when the parser returns [`ErrMode::Backtrack`]. To instead chain an error up, see |
703 | /// [`cut_err`][crate::combinator::cut_err]. |
704 | /// |
705 | /// # Arguments |
706 | /// * `m` The minimum number of iterations. |
707 | /// * `n` The maximum number of iterations. |
708 | /// * `f` The parser to apply. |
709 | /// * `init` A function returning the initial value. |
710 | /// * `g` The function that combines a result of `f` with |
711 | /// the current accumulator. |
712 | /// |
713 | /// **Warning:** If the parser passed to `fold_repeat` accepts empty inputs |
714 | /// (like `alpha0` or `digit0`), `fold_repeat` will return an error, |
715 | /// to prevent going into an infinite loop. |
716 | /// |
717 | /// # Example |
718 | /// |
719 | /// Zero or more repetitions: |
720 | /// ```rust |
721 | /// # use winnow::{error::ErrMode, error::ErrorKind, error::Needed}; |
722 | /// # use winnow::prelude::*; |
723 | /// use winnow::combinator::fold_repeat; |
724 | /// use winnow::token::tag; |
725 | /// |
726 | /// fn parser(s: &str) -> IResult<&str, Vec<&str>> { |
727 | /// fold_repeat( |
728 | /// 0.., |
729 | /// "abc" , |
730 | /// Vec::new, |
731 | /// |mut acc: Vec<_>, item| { |
732 | /// acc.push(item); |
733 | /// acc |
734 | /// } |
735 | /// ).parse_next(s) |
736 | /// } |
737 | /// |
738 | /// assert_eq!(parser("abcabc" ), Ok(("" , vec!["abc" , "abc" ]))); |
739 | /// assert_eq!(parser("abc123" ), Ok(("123" , vec!["abc" ]))); |
740 | /// assert_eq!(parser("123123" ), Ok(("123123" , vec![]))); |
741 | /// assert_eq!(parser("" ), Ok(("" , vec![]))); |
742 | /// ``` |
743 | /// |
744 | /// One or more repetitions: |
745 | /// ```rust |
746 | /// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, error::Needed}; |
747 | /// # use winnow::prelude::*; |
748 | /// use winnow::combinator::fold_repeat; |
749 | /// use winnow::token::tag; |
750 | /// |
751 | /// fn parser(s: &str) -> IResult<&str, Vec<&str>> { |
752 | /// fold_repeat( |
753 | /// 1.., |
754 | /// "abc" , |
755 | /// Vec::new, |
756 | /// |mut acc: Vec<_>, item| { |
757 | /// acc.push(item); |
758 | /// acc |
759 | /// } |
760 | /// ).parse_next(s) |
761 | /// } |
762 | /// |
763 | /// assert_eq!(parser("abcabc" ), Ok(("" , vec!["abc" , "abc" ]))); |
764 | /// assert_eq!(parser("abc123" ), Ok(("123" , vec!["abc" ]))); |
765 | /// assert_eq!(parser("123123" ), Err(ErrMode::Backtrack(Error::new("123123" , ErrorKind::Many)))); |
766 | /// assert_eq!(parser("" ), Err(ErrMode::Backtrack(Error::new("" , ErrorKind::Many)))); |
767 | /// ``` |
768 | /// |
769 | /// Arbitrary number of repetitions: |
770 | /// ```rust |
771 | /// # use winnow::{error::ErrMode, error::ErrorKind, error::Needed}; |
772 | /// # use winnow::prelude::*; |
773 | /// use winnow::combinator::fold_repeat; |
774 | /// use winnow::token::tag; |
775 | /// |
776 | /// fn parser(s: &str) -> IResult<&str, Vec<&str>> { |
777 | /// fold_repeat( |
778 | /// 0..=2, |
779 | /// "abc" , |
780 | /// Vec::new, |
781 | /// |mut acc: Vec<_>, item| { |
782 | /// acc.push(item); |
783 | /// acc |
784 | /// } |
785 | /// ).parse_next(s) |
786 | /// } |
787 | /// |
788 | /// assert_eq!(parser("abcabc" ), Ok(("" , vec!["abc" , "abc" ]))); |
789 | /// assert_eq!(parser("abc123" ), Ok(("123" , vec!["abc" ]))); |
790 | /// assert_eq!(parser("123123" ), Ok(("123123" , vec![]))); |
791 | /// assert_eq!(parser("" ), Ok(("" , vec![]))); |
792 | /// assert_eq!(parser("abcabcabc" ), Ok(("abc" , vec!["abc" , "abc" ]))); |
793 | /// ``` |
794 | #[doc (alias = "fold_many0" )] |
795 | #[doc (alias = "fold_many1" )] |
796 | #[doc (alias = "fold_many_m_n" )] |
797 | #[inline (always)] |
798 | pub fn fold_repeat<I, O, E, F, G, H, R>( |
799 | range: impl Into<Range>, |
800 | mut f: F, |
801 | mut init: H, |
802 | mut g: G, |
803 | ) -> impl Parser<I, R, E> |
804 | where |
805 | I: Stream, |
806 | F: Parser<I, O, E>, |
807 | G: FnMut(R, O) -> R, |
808 | H: FnMut() -> R, |
809 | E: ParseError<I>, |
810 | { |
811 | let Range { |
812 | start_inclusive: usize, |
813 | end_inclusive: Option, |
814 | } = range.into(); |
815 | trace(name:"fold_repeat" , parser:move |i: I| { |
816 | match (start_inclusive, end_inclusive) { |
817 | (0, None) => fold_repeat0_(&mut f, &mut init, &mut g, i), |
818 | (1, None) => fold_repeat1_(&mut f, &mut init, &mut g, i), |
819 | (start: usize, end: Option) => fold_repeat_m_n_( |
820 | min:start, |
821 | max:end.unwrap_or(usize::MAX), |
822 | &mut f, |
823 | &mut init, |
824 | &mut g, |
825 | input:i, |
826 | ), |
827 | } |
828 | }) |
829 | } |
830 | |
831 | /// Deprecated, replaced by [`fold_repeat`] |
832 | #[deprecated (since = "0.4.6" , note = "Replaced with `fold_repeat`" )] |
833 | #[inline (always)] |
834 | pub fn fold_repeat0<I, O, E, F, G, H, R>(mut f: F, mut init: H, mut g: G) -> impl Parser<I, R, E> |
835 | where |
836 | I: Stream, |
837 | F: Parser<I, O, E>, |
838 | G: FnMut(R, O) -> R, |
839 | H: FnMut() -> R, |
840 | E: ParseError<I>, |
841 | { |
842 | trace(name:"fold_repeat0" , parser:move |i: I| { |
843 | fold_repeat0_(&mut f, &mut init, &mut g, i) |
844 | }) |
845 | } |
846 | |
847 | fn fold_repeat0_<I, O, E, F, G, H, R>(f: &mut F, init: &mut H, g: &mut G, i: I) -> IResult<I, R, E> |
848 | where |
849 | I: Stream, |
850 | F: Parser<I, O, E>, |
851 | G: FnMut(R, O) -> R, |
852 | H: FnMut() -> R, |
853 | E: ParseError<I>, |
854 | { |
855 | let mut res = init(); |
856 | let mut input = i; |
857 | |
858 | loop { |
859 | let i_ = input.clone(); |
860 | let len = input.eof_offset(); |
861 | match f.parse_next(i_) { |
862 | Ok((i, o)) => { |
863 | // infinite loop check: the parser must always consume |
864 | if i.eof_offset() == len { |
865 | return Err(ErrMode::assert(i, "`repeat` parsers must always consume" )); |
866 | } |
867 | |
868 | res = g(res, o); |
869 | input = i; |
870 | } |
871 | Err(ErrMode::Backtrack(_)) => { |
872 | return Ok((input, res)); |
873 | } |
874 | Err(e) => { |
875 | return Err(e); |
876 | } |
877 | } |
878 | } |
879 | } |
880 | |
881 | /// Deprecated, replaced by [`fold_repeat`] |
882 | #[deprecated (since = "0.4.6" , note = "Replaced with `fold_repeat`" )] |
883 | #[inline (always)] |
884 | pub fn fold_repeat1<I, O, E, F, G, H, R>(mut f: F, mut init: H, mut g: G) -> impl Parser<I, R, E> |
885 | where |
886 | I: Stream, |
887 | F: Parser<I, O, E>, |
888 | G: FnMut(R, O) -> R, |
889 | H: FnMut() -> R, |
890 | E: ParseError<I>, |
891 | { |
892 | trace(name:"fold_repeat1" , parser:move |i: I| { |
893 | fold_repeat1_(&mut f, &mut init, &mut g, i) |
894 | }) |
895 | } |
896 | |
897 | fn fold_repeat1_<I, O, E, F, G, H, R>(f: &mut F, init: &mut H, g: &mut G, i: I) -> IResult<I, R, E> |
898 | where |
899 | I: Stream, |
900 | F: Parser<I, O, E>, |
901 | G: FnMut(R, O) -> R, |
902 | H: FnMut() -> R, |
903 | E: ParseError<I>, |
904 | { |
905 | let _i = i.clone(); |
906 | let init = init(); |
907 | match f.parse_next(_i) { |
908 | Err(ErrMode::Backtrack(_)) => Err(ErrMode::from_error_kind(i, ErrorKind::Many)), |
909 | Err(e) => Err(e), |
910 | Ok((i1, o1)) => { |
911 | let mut acc = g(init, o1); |
912 | let mut input = i1; |
913 | |
914 | loop { |
915 | let _input = input.clone(); |
916 | let len = input.eof_offset(); |
917 | match f.parse_next(_input) { |
918 | Err(ErrMode::Backtrack(_)) => { |
919 | break; |
920 | } |
921 | Err(e) => return Err(e), |
922 | Ok((i, o)) => { |
923 | // infinite loop check: the parser must always consume |
924 | if i.eof_offset() == len { |
925 | return Err(ErrMode::assert(i, "`repeat` parsers must always consume" )); |
926 | } |
927 | |
928 | acc = g(acc, o); |
929 | input = i; |
930 | } |
931 | } |
932 | } |
933 | |
934 | Ok((input, acc)) |
935 | } |
936 | } |
937 | } |
938 | |
939 | fn fold_repeat_m_n_<I, O, E, F, G, H, R>( |
940 | min: usize, |
941 | max: usize, |
942 | parse: &mut F, |
943 | init: &mut H, |
944 | fold: &mut G, |
945 | mut input: I, |
946 | ) -> IResult<I, R, E> |
947 | where |
948 | I: Stream, |
949 | F: Parser<I, O, E>, |
950 | G: FnMut(R, O) -> R, |
951 | H: FnMut() -> R, |
952 | E: ParseError<I>, |
953 | { |
954 | if min > max { |
955 | return Err(ErrMode::Cut(E::from_error_kind(input, ErrorKind::Many))); |
956 | } |
957 | |
958 | let mut acc = init(); |
959 | for count in 0..max { |
960 | let len = input.eof_offset(); |
961 | match parse.parse_next(input.clone()) { |
962 | Ok((tail, value)) => { |
963 | // infinite loop check: the parser must always consume |
964 | if tail.eof_offset() == len { |
965 | return Err(ErrMode::assert( |
966 | input, |
967 | "`repeat` parsers must always consume" , |
968 | )); |
969 | } |
970 | |
971 | acc = fold(acc, value); |
972 | input = tail; |
973 | } |
974 | //FInputXMError: handle failure properly |
975 | Err(ErrMode::Backtrack(err)) => { |
976 | if count < min { |
977 | return Err(ErrMode::Backtrack(err.append(input, ErrorKind::Many))); |
978 | } else { |
979 | break; |
980 | } |
981 | } |
982 | Err(e) => return Err(e), |
983 | } |
984 | } |
985 | |
986 | Ok((input, acc)) |
987 | } |
988 | |