Minimal Imperative Parsing Library | https://docs.rs/mipl
1use crate::prelude::*;
2
3/// Consume a sequence of tokens into a new parser while the
4/// concrete parsers return something. Stop consuming once
5/// all values are exhausted, or if one of then returned
6/// `None`.
7pub struct CollectIfSeq<Cp: ConcreteParser>(Cp);
8impl<Cp> VariadicConcreteSubparser<Cp> for CollectIfSeq<Cp>
9where
10 Cp: ConcreteParser
11{
12 fn subparse
13 (values: Vec<Cp::Input>, parser: &mut Parser) -> Parser
14 where
15 Cp: concrete_parser::ContainerCp
16 {
17 let mut tokens = Tokens::new_empty();
18
19 for v in values {
20 let cp = Cp::new(v);
21
22 if let Some(token) = cp.try_next_token(parser) {
23 tokens.add_token(token);
24 }
25 }
26
27 Parser::new(tokens)
28 }
29}
30
31/// Consume a sequence of tokens into a new parser **if**
32/// the coming sequence of tokens match a sequence.
33pub struct CollectIfExactSeq<Cp: ConcreteParser>(Cp);
34impl<Cp> VariadicConcreteSubparser<Cp> for CollectIfExactSeq<Cp>
35where
36 Cp: ConcreteParser
37{
38 fn subparse
39 (values: Vec<Cp::Input>, parser: &mut Parser) -> Parser
40 where
41 Cp: concrete_parser::ContainerCp
42 {
43 let mut toks_buffer: Tokens = Tokens::new_empty();
44
45 let mut exact: bool = true;
46
47 for v in values {
48 let cp = Cp::new(v);
49
50 if let Some(token) = cp.try_next_token(parser) {
51 toks_buffer.add_token(token)
52 } else {
53 if let Some(token) = parser.next() {
54 toks_buffer.add_token(token);
55 }
56 exact = false;
57 }
58 }
59
60 if exact {
61 Parser::new(toks_buffer)
62 } else {
63 parser.extend(toks_buffer);
64 Parser::new_empty()
65 }
66 }
67}