Minimal Imperative Parsing Library | https://docs.rs/mipl
1use mipl::prelude::*;
2
3mod common;
4use common::*;
5
6/// Assert that two parsers successively yield a certain number
7/// `n` of the same token.
8fn assert_parsers_same_till(
9 mut a: Parser,
10 mut b: Parser,
11 n: usize
12) {
13 let mut i: usize = 0;
14 while i < n {
15 assert_eq!(a.next(), b.next());
16 i += 1;
17 }
18}
19
20fn not_assert_parsers_same_till(
21 mut a: Parser,
22 mut b: Parser,
23 n: usize
24) {
25 let mut i: usize = 0;
26 let mut not: bool = false;
27 while i < n {
28 if a.next() != b.next() {
29 not = true;
30 break;
31 }
32 i += i;
33 }
34 assert!(not)
35}
36
37#[test]
38fn test_collect_until_exact_match_subparser() {
39 let mut parser = setup_space_seps_parser(
40 "a b c d e f g h"
41 );
42 let mut known_subparser = setup_space_seps_parser(
43 "a b c d"
44 );
45
46 let mut subparser = CollectUntil::<ExactMatch>::subparse(
47 "e".to_string(),
48 &mut parser
49 );
50
51 let mut i: usize = 0;
52 while i < 4 {
53 assert_eq!(known_subparser.next(), subparser.next());
54 i += 1;
55 }
56}
57
58#[test]
59fn test_collect_until_is_newline() {
60 let mut parser = setup_space_seps_parser(
61 "a b\n c d e f g h"
62 );
63 let mut known_subparser = setup_space_seps_parser(
64 "a b"
65 );
66
67 let mut subparser = CollectUntil::<IsNewline>::subparse(
68 (),
69 &mut parser
70 );
71
72 let mut i: usize = 0;
73 while i < 2 {
74 assert_eq!(known_subparser.next(), subparser.next());
75 i += 1;
76 }
77}
78
79#[test]
80fn test_collect_while_exact_match() {
81 let mut parser = setup_space_seps_parser(
82 "a a a a e f g h"
83 );
84 let mut known_subparser = setup_space_seps_parser(
85 "a a a a"
86 );
87
88 let mut subparser = CollectWhile::<ExactMatch>::subparse(
89 "a".to_string(),
90 &mut parser
91 );
92
93 let mut i: usize = 0;
94 while i < 4 {
95 assert_eq!(known_subparser.next(), subparser.next());
96 i += 1;
97 }
98}
99
100#[test]
101fn test_collect_if_sequence() {
102 let mut parser = setup_space_seps_parser(
103 "a b c d e f g h i j"
104 );
105 let known_subparser = setup_space_seps_parser(
106 "a b c d"
107 );
108
109 let values: Vec<String> = vec!["a", "b", "c", "d", "e"]
110 .into_iter()
111 .map(String::from)
112 .collect();
113
114 let subparser = CollectIfSeq::<ExactMatch>::subparse(
115 values,
116 &mut parser
117 );
118
119 assert_parsers_same_till(
120 known_subparser,
121 subparser,
122 4
123 );
124}
125
126#[test]
127fn test_collect_if_exact_sequence() {
128 let mut parser = setup_space_seps_parser(
129 "a b c d e f g h i j"
130 );
131 let known_subparser = setup_space_seps_parser(
132 "a b"
133 );
134
135 let values: Vec<String> = vec!["a", "b", "c", "d"]
136 .into_iter()
137 .map(String::from)
138 .collect();
139
140 let subparser = CollectIfExactSeq::<ExactMatch>::subparse(
141 values,
142 &mut parser
143 );
144
145 assert_parsers_same_till(
146 known_subparser,
147 subparser,
148 2
149 );
150}
151
152#[test]
153fn test_fail_collect_if_exact_sequence() {
154 let mut parser = setup_space_seps_parser(
155 "a b c d e f g h i j"
156 );
157 let known_subparser = setup_space_seps_parser(
158 "a b c d"
159 );
160
161 let values: Vec<String> = vec!["a", "b", "c", "d", "f"]
162 .into_iter()
163 .map(String::from)
164 .collect();
165
166 let subparser = CollectIfExactSeq::<ExactMatch>::subparse(
167 values,
168 &mut parser
169 );
170
171 not_assert_parsers_same_till(
172 known_subparser,
173 subparser,
174 4
175 );
176}
177
178#[test]
179fn test_fail_collect_if_exact_keeps_parent_parser_intact() {
180 let mut parser = setup_space_seps_parser(
181 "a b c d"
182 );
183 let initial_parser = parser.clone();
184
185 let values: Vec<String> = vec!["a", "b", "c", "e"]
186 .into_iter()
187 .map(String::from)
188 .collect();
189
190 let _subparser = CollectIfExactSeq::<ExactMatch>::subparse(
191 values,
192 &mut parser
193 );
194
195 println!("{:#?}", parser);
196
197 assert_parsers_same_till(parser, initial_parser, 4);
198}
199
200
201pub 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
229fn test_until_doesnt_eat_ending_states_subparser(parser: &mut Parser) -> Parser {
230 let states: Vec<String> = vec!["*", "#"]
231 .into_iter()
232 .map(String::from)
233 .collect();
234 let _expr_parser = CollectUntil::<OrExactMatch>::subparse(states.clone(), parser);
235 let states_parser = CollectWhile::<OrExactMatch>::subparse(states, parser);
236
237 states_parser
238}
239
240#[test]
241fn test_until_doesnt_eat_ending() {
242 let src = "(l | r) & (~l | ~r) **# 16".to_string();
243
244 let mut flat_parser = tokenize(src);
245
246 let known_parser_a = tokenize("**#".to_string());
247
248 let states_parser = test_until_doesnt_eat_ending_states_subparser(&mut flat_parser);
249
250 assert_parsers_same_till(known_parser_a, states_parser, 3);
251}