Minimal Imperative Parsing Library | https://docs.rs/mipl
at main 67 lines 1.8 kB view raw
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}