+2
-2
src/parser/subparser.rs
+2
-2
src/parser/subparser.rs
+3
-3
src/parser/subparser/collect_till.rs
src/parser/subparser/collect_untill.rs
+3
-3
src/parser/subparser/collect_till.rs
src/parser/subparser/collect_untill.rs
···
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>
10
where
11
Op: ConcreteParser
12
{
···
20
let mut tokens: Tokens = Tokens::new_empty();
21
22
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>
10
where
11
Op: ConcreteParser
12
{
···
20
let mut tokens: Tokens = Tokens::new_empty();
21
22
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
+73
-4
tests/test_subparser.rs
···
35
}
36
37
#[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
);
45
46
-
let mut subparser = CollectTill::<ExactMatch>::subparse(
47
"e".to_string(),
48
&mut parser
49
);
···
56
}
57
58
#[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
);
66
67
-
let mut subparser = CollectTill::<IsNewline>::subparse(
68
(),
69
&mut parser
70
);
···
195
println!("{:#?}", parser);
196
197
assert_parsers_same_till(parser, initial_parser, 4);
198
}
···
35
}
36
37
#[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
);
45
46
+
let mut subparser = CollectUntill::<ExactMatch>::subparse(
47
"e".to_string(),
48
&mut parser
49
);
···
56
}
57
58
#[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
);
66
67
+
let mut subparser = CollectUntill::<IsNewline>::subparse(
68
(),
69
&mut parser
70
);
···
195
println!("{:#?}", parser);
196
197
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
}