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