···5///
6/// Said concrete pattern here is provided by
7/// the generic parameter `Op`.
8-pub struct CollectTill<Op: ConcreteParser>(Op);
9-impl<Op> ConcreteSubparser<Op> for CollectTill<Op>
10where
11 Op: ConcreteParser
12{
···20 let mut tokens: Tokens = Tokens::new_empty();
2122 loop {
23- if let Some(_token) = op.try_next_token(parser) {
24 break;
25 } else {
26 if let Some(token) = parser.next() {
···5///
6/// Said concrete pattern here is provided by
7/// the generic parameter `Op`.
8+pub struct CollectUntill<Op: ConcreteParser>(Op);
9+impl<Op> ConcreteSubparser<Op> for CollectUntill<Op>
10where
11 Op: ConcreteParser
12{
···20 let mut tokens: Tokens = Tokens::new_empty();
2122 loop {
23+ if let Some(_token) = op.peek_for_token(parser) {
24 break;
25 } else {
26 if let Some(token) = parser.next() {
+73-4
tests/test_subparser.rs
···35}
3637#[test]
38-fn test_collect_till_exact_match_subparser() {
39 let mut parser = setup_space_seps_parser(
40 "a b c d e f g h"
41 );
···43 "a b c d"
44 );
4546- let mut subparser = CollectTill::<ExactMatch>::subparse(
47 "e".to_string(),
48 &mut parser
49 );
···56}
5758#[test]
59-fn test_collect_till_is_newline() {
60 let mut parser = setup_space_seps_parser(
61 "a b\n c d e f g h"
62 );
···64 "a b"
65 );
6667- let mut subparser = CollectTill::<IsNewline>::subparse(
68 (),
69 &mut parser
70 );
···195 println!("{:#?}", parser);
196197 assert_parsers_same_till(parser, initial_parser, 4);
000000000000000000000000000000000000000000000000000000000000000000000198}
···35}
3637#[test]
38+fn test_collect_untill_exact_match_subparser() {
39 let mut parser = setup_space_seps_parser(
40 "a b c d e f g h"
41 );
···43 "a b c d"
44 );
4546+ let mut subparser = CollectUntill::<ExactMatch>::subparse(
47 "e".to_string(),
48 &mut parser
49 );
···56}
5758#[test]
59+fn test_collect_untill_is_newline() {
60 let mut parser = setup_space_seps_parser(
61 "a b\n c d e f g h"
62 );
···64 "a b"
65 );
6667+ let mut subparser = CollectUntill::<IsNewline>::subparse(
68 (),
69 &mut parser
70 );
···195 println!("{:#?}", parser);
196197 assert_parsers_same_till(parser, initial_parser, 4);
198+}
199+200+201+pub fn tokenize(src: String) -> Parser {
202+ let del_param = DelimitersParam{
203+ discard: DiscardDelimiters::new(
204+ vec![
205+ ' ',
206+ '\n',
207+ '\t'
208+ ]
209+ ),
210+ keep: KeepDelimiters::new(
211+ vec![
212+ '(',
213+ ')',
214+ '~',
215+ '&',
216+ '|',
217+ '=',
218+ '>',
219+ '<',
220+ '*',
221+ '#'
222+ ]
223+ )
224+ };
225+226+ Parser::from(src, del_param)
227+}
228+229+#[derive(Debug)]
230+pub struct Parsers {
231+ /// The parser for expressions
232+ expr_parser: Parser,
233+ /// The parser for initial configuration
234+ states_parser: Parser,
235+ /// The number of steps to take
236+ steps: usize
237+}
238+impl Parsers {
239+ pub fn new(parser: &mut Parser) -> Option<Self> {
240+ let states = vec!["*", "#"];
241+ let expr_parser = CollectUntill::<OrExactMatch>::subparse(states.clone(), parser);
242+ let states_parser = CollectWhile::<OrExactMatch>::subparse(states, parser);
243+ let steps: usize = match parser.next() {
244+ Some(Token::Str(s)) => s.parse().ok(),
245+ _ => None
246+ }?;
247+248+ Some(Parsers {
249+ expr_parser,
250+ states_parser,
251+ steps
252+ })
253+ }
254+}
255+256+#[test]
257+fn test_until_doesnt_eat_ending() {
258+ let src = "(l | r) & (~l | ~r) **# 16".to_string();
259+260+ let mut flat_parser = tokenize(src);
261+262+ let known_parser_a = tokenize("**#".to_string());
263+264+ let parsers = Parsers::new(&mut flat_parser).unwrap();
265+266+ assert_parsers_same_till(known_parser_a, parsers.states_parser, 3);
267}