1#[cfg(test)]
2use cfgrammar::Span;
3
4mod cgen_helper;
5#[allow(unused)]
6use cgen_helper::run_test_path;
7
8mod calc_wasm;
9
10#[cfg(test)]
11use cttests_macro::generate_codegen_fail_tests;
12use lrlex::lrlex_mod;
13use lrpar::lrpar_mod;
14#[cfg(test)]
15use lrpar::{Lexeme, Lexer, NonStreamingLexer};
16
17lrlex_mod!("calc_multitypes.l");
18lrpar_mod!("calc_multitypes.y");
19
20lrlex_mod!("calc_actiontype.l");
21lrpar_mod!("calc_actiontype.y");
22
23lrlex_mod!("calc_noactions.l");
24lrpar_mod!("calc_noactions.y");
25
26lrlex_mod!("calc_nodefault_yacckind.l");
27lrpar_mod!("calc_nodefault_yacckind.y");
28
29lrlex_mod!("calc_unsafeaction.l");
30lrpar_mod!("calc_unsafeaction.y");
31
32lrlex_mod!("calc_input.l");
33lrpar_mod!("calc_input.y");
34
35lrlex_mod!("expect.l");
36lrpar_mod!("expect.y");
37
38lrlex_mod!("lexer_lifetime.l");
39lrpar_mod!("lexer_lifetime.y");
40
41lrlex_mod!("lex_flags.l");
42lrpar_mod!("lex_flags.y");
43
44lrlex_mod!("multitypes.l");
45lrpar_mod!("multitypes.y");
46
47lrlex_mod!("parseparam.l");
48lrpar_mod!("parseparam.y");
49
50lrlex_mod!("parseparam_copy.l");
51lrpar_mod!("parseparam_copy.y");
52
53lrlex_mod!("typeparams.l");
54lrpar_mod!("typeparams.y");
55
56lrlex_mod!("passthrough.l");
57lrpar_mod!("passthrough.y");
58
59lrlex_mod!("regex_opt.l");
60lrlex_mod!("regex_opt.y");
61
62lrlex_mod!("span.l");
63lrpar_mod!("span.y");
64
65lrlex_mod!("storaget.l");
66lrpar_mod!("storaget.y");
67
68lrlex_mod!("grmtools_section.l");
69lrpar_mod!("grmtools_section.y");
70
71lrlex_mod!("ast_unmodified.l");
72lrpar_mod!("ast_unmodified.y");
73
74lrlex_mod!("ast_modified.l");
75lrpar_mod!("ast_modified.y");
76
77#[test]
78fn multitypes() {
79 let lexerdef = multitypes_l::lexerdef();
80 let lexer = lexerdef.lexer("aa");
81 let (r, errs) = multitypes_y::parse(&lexer);
82 assert_eq!(r.unwrap().len(), 2);
83 assert_eq!(errs.len(), 0);
84}
85
86#[test]
87fn test_no_actions() {
88 let lexerdef = calc_noactions_l::lexerdef();
89 let lexer = lexerdef.lexer("2+3");
90 if !calc_noactions_y::parse(&lexer).is_empty() {
91 panic!();
92 }
93 let lexer = lexerdef.lexer("2++3");
94 if calc_noactions_y::parse(&lexer).len() != 1 {
95 panic!();
96 }
97}
98
99#[test]
100fn test_basic_actions() {
101 let lexerdef = calc_actiontype_l::lexerdef();
102 let lexer = lexerdef.lexer("2+3");
103 match calc_actiontype_y::parse(&lexer) {
104 (Some(Ok(5)), ref errs) if errs.is_empty() => (),
105 _ => unreachable!(),
106 }
107}
108
109#[test]
110fn test_calc_input() {
111 let lexerdef = calc_input_l::lexerdef();
112 let lexer = lexerdef.lexer("2+3");
113 match calc_input_y::parse(&lexer) {
114 (Some(Ok(5)), ref errs) if errs.is_empty() => (),
115 _ => unreachable!(),
116 }
117}
118
119#[test]
120fn test_nodefault_yacckind() {
121 let lexerdef = calc_nodefault_yacckind_l::lexerdef();
122 let lexer = lexerdef.lexer("2+3");
123 match calc_nodefault_yacckind_y::parse(&lexer) {
124 (Some(Ok(5)), ref errs) if errs.is_empty() => (),
125 _ => unreachable!(),
126 }
127}
128#[test]
129fn test_unsafe_actions() {
130 let lexerdef = calc_unsafeaction_l::lexerdef();
131 let lexer = lexerdef.lexer("2+3");
132 match calc_unsafeaction_y::parse(&lexer) {
133 (Some(Ok(5)), ref errs) if errs.is_empty() => (),
134 _ => unreachable!(),
135 }
136}
137
138#[test]
139fn test_error_recovery_and_actions() {
140 use lrpar::LexParseError;
141
142 let lexerdef = calc_actiontype_l::lexerdef();
143
144 let lexer = lexerdef.lexer("2++3");
145 let (r, errs) = calc_actiontype_y::parse(&lexer);
146 match r {
147 Some(Ok(5)) => (),
148 _ => unreachable!(),
149 }
150 match errs[0] {
151 LexParseError::ParseError(..) => (),
152 _ => unreachable!(),
153 }
154
155 let lexer = lexerdef.lexer("2+3)");
156 let (r, errs) = calc_actiontype_y::parse(&lexer);
157 assert_eq!(r, Some(Ok(5)));
158 assert_eq!(errs.len(), 1);
159 match errs[0] {
160 LexParseError::ParseError(..) => (),
161 _ => unreachable!(),
162 }
163
164 let lexer = lexerdef.lexer("2+3+18446744073709551616");
165 let (r, errs) = calc_actiontype_y::parse(&lexer);
166 assert_eq!(r, Some(Err(())));
167 assert!(errs.is_empty());
168}
169
170#[test]
171fn test_calc_multitypes() {
172 let lexerdef = calc_multitypes_l::lexerdef();
173 let lexer = lexerdef.lexer("1+2*3");
174 let (res, _errs) = calc_multitypes_y::parse(&lexer);
175 assert_eq!(res, Some(Ok(7)));
176
177 let lexer = lexerdef.lexer("1++2");
178 let (res, _errs) = calc_multitypes_y::parse(&lexer);
179 assert_eq!(res, Some(Ok(3)));
180}
181
182#[test]
183fn test_input_lifetime() {
184 let lexerdef = lexer_lifetime_l::lexerdef();
187 let input = "a";
188 let _ = {
189 let lexer = lexerdef.lexer(input);
190 let lx = lexer.iter().next().unwrap().unwrap();
191 lexer.span_str(lx.span())
192 };
193}
194
195#[test]
196fn test_lexer_lifetime() {
197 #[allow(clippy::needless_lifetimes)]
201 pub(crate) fn parse_data<'a>(input: &'a str) -> Option<&'a str> {
202 let lexer_def = crate::lexer_lifetime_l::lexerdef();
203 let l = lexer_def.lexer(input);
204 match crate::lexer_lifetime_y::parse(&l) {
205 (Option::Some(x), _) => Some(x),
206 _ => None,
207 }
208 }
209 parse_data("abc");
210}
211
212#[test]
213fn test_span() {
214 let lexerdef = span_l::lexerdef();
215 let lexer = lexerdef.lexer("2+3");
216 match span_y::parse(&lexer) {
217 (Some(ref spans), _)
218 if spans
219 == &vec![
220 Span::new(0, 1),
221 Span::new(0, 1),
222 Span::new(0, 1),
223 Span::new(2, 3),
224 Span::new(2, 3),
225 Span::new(0, 3),
226 ] => {}
227 _ => unreachable!(),
228 }
229
230 let lexer = lexerdef.lexer("2 + 3");
231 match span_y::parse(&lexer) {
232 (Some(ref spans), _)
233 if spans
234 == &vec![
235 Span::new(0, 1),
236 Span::new(0, 1),
237 Span::new(0, 1),
238 Span::new(4, 5),
239 Span::new(4, 5),
240 Span::new(0, 5),
241 ] => {}
242 _ => unreachable!(),
243 }
244
245 let lexer = lexerdef.lexer("2+3*4");
246 match span_y::parse(&lexer) {
247 (Some(ref spans), _)
248 if spans
249 == &vec![
250 Span::new(0, 1),
251 Span::new(0, 1),
252 Span::new(0, 1),
253 Span::new(2, 3),
254 Span::new(2, 3),
255 Span::new(4, 5),
256 Span::new(2, 5),
257 Span::new(0, 5),
258 ] => {}
259 _ => unreachable!(),
260 }
261
262 let lexer = lexerdef.lexer("2++3");
263 match span_y::parse(&lexer) {
264 (Some(ref spans), _)
265 if spans
266 == &vec![
267 Span::new(0, 1),
268 Span::new(0, 1),
269 Span::new(0, 1),
270 Span::new(3, 4),
271 Span::new(3, 4),
272 Span::new(0, 4),
273 ] => {}
274 _ => unreachable!(),
275 }
276
277 let lexer = lexerdef.lexer("(2)))");
278 match dbg!(span_y::parse(&lexer)) {
279 (Some(ref spans), _)
280 if spans
281 == &vec![
282 Span::new(1, 2),
283 Span::new(1, 2),
284 Span::new(1, 2),
285 Span::new(0, 3),
286 Span::new(0, 3),
287 Span::new(0, 3),
288 ] => {}
289 _ => unreachable!(),
290 }
291}
292
293#[test]
294fn test_parseparam() {
295 let lexerdef = parseparam_l::lexerdef();
296 let lexer = lexerdef.lexer("101");
297 match parseparam_y::parse(&lexer, &3) {
298 (Some(104), _) => (),
299 _ => unreachable!(),
300 }
301}
302
303#[test]
304fn test_parseparam_copy() {
305 let lexerdef = parseparam_copy_l::lexerdef();
306 let lexer = lexerdef.lexer("101");
307 match parseparam_copy_y::parse(&lexer, 3) {
308 (Some(104), _) => (),
309 _ => unreachable!(),
310 }
311}
312
313#[test]
314fn test_typeparams() {
315 let lexerdef = typeparams_l::lexerdef();
316 let lexer = lexerdef.lexer("101");
317 match typeparams_y::parse(&lexer, &3u64) {
318 (Some(104u64), _) => (),
319 _ => unreachable!(),
320 }
321}
322
323#[test]
324fn test_passthrough() {
325 let lexerdef = passthrough_l::lexerdef();
326 let lexer = lexerdef.lexer("101");
327 match passthrough_y::parse(&lexer) {
328 (Some(Ok(ref s)), _) if s == "$101" => (),
329 _ => unreachable!(),
330 }
331}
332
333#[test]
334fn test_storaget() {
335 let lexerdef = storaget_l::lexerdef();
336 let lexer = lexerdef.lexer("glasses, keys, umbrella");
337 let expect = ["glasses", "keys", "umbrella"]
338 .iter()
339 .map(|x| x.to_string())
340 .collect::<Vec<_>>();
341 let (val, e) = storaget_y::parse(&lexer);
342 assert_eq!(val, Some(expect));
343 assert!(e.is_empty());
344}
345
346#[test]
347fn test_expect() {
348 }
350
351#[cfg(all(not(target_arch = "wasm32"), test))]
356#[test]
357fn test_grmtools_section_files() {
358 use glob::glob;
359 use std::fs::File;
360 use std::io::BufReader;
361 use std::io::{BufRead as _, Read as _};
362
363 let manifest_dir = env!("CARGO_MANIFEST_DIR");
364 let examples_glob = format!("{manifest_dir}/../examples/**");
365 let examples_l_glob = format!("{examples_glob}/*.l");
366 let examples_y_glob = format!("{examples_glob}/*.y");
367 let out_dir = env!("OUT_DIR");
368 let cttests_l_glob = format!("{out_dir}/*.l");
369 let cttests_y_glob = format!("{out_dir}/*.y");
370 let files = glob(&examples_l_glob)
371 .unwrap()
372 .chain(glob(&examples_y_glob).unwrap())
373 .chain(glob(&cttests_l_glob).unwrap())
374 .chain(glob(&cttests_y_glob).unwrap())
375 .collect::<Vec<_>>();
376 assert!(!files.is_empty());
377 for file_path in files {
378 let file_path = file_path.unwrap();
379 let mut s = String::new();
380 let mut f = File::open(&file_path).unwrap();
381 let _ = f.read_to_string(&mut s).unwrap();
382 if s.starts_with("%grmtools") {
383 let mut buf = Vec::new();
384 let mut reader = BufReader::new(s.as_bytes());
385 let _ = reader.read_until(b'}', &mut buf);
386 let lexerdef = grmtools_section_l::lexerdef();
387 let s = String::from_utf8(buf).unwrap();
388 let l = lexerdef.lexer(&s);
389 let (yacc_parsed, errs) = grmtools_section_y::parse(&l);
390 let parser = cfgrammar::header::GrmtoolsSectionParser::new(&s, true);
391 let (header_parsed, _) = parser.parse().unwrap();
392 assert_eq!(yacc_parsed.unwrap().unwrap(), header_parsed);
393 assert!(errs.is_empty());
394 }
395 }
396}
397
398#[test]
399fn test_grmtools_section_strings() {
400 let srcs = [
401 "%grmtools{}",
402 "%grmtools{x}",
403 "%grmtools{x,}",
404 "%grmtools{!x}",
405 "%grmtools{!x,}",
406 "%grmtools{x: y}",
407 "%grmtools{x: y,}",
408 "%grmtools{x, y}",
409 "%grmtools{x, y,}",
410 "%grmtools{x, !y}",
411 "%grmtools{x, !y,}",
412 "%grmtools{x: y(z)}",
413 "%grmtools{x: y(z),}",
414 "%grmtools{a, x: y(z),}",
415 "%grmtools{a, x: y(z)}",
416 "%grmtools{a, !b, x: y(z), e: f}",
417 "%grmtools{a, !b, x: y(z), e: f,}",
418 "%grmtools{a, !b, x: w::y(z), e: f}",
419 "%grmtools{a, !b, x: w::y(z), e: f,}",
420 "%grmtools{a, !b, x: w::y(z), e: g::f}",
421 "%grmtools{a, !b, x: w::y(z), e: g::f,}",
422 ];
423
424 let lexerdef = grmtools_section_l::lexerdef();
425 for src in srcs {
426 let l = lexerdef.lexer(src);
427 let (yacc_parsed, errs) = grmtools_section_y::parse(&l);
428 let yacc_parsed = yacc_parsed.unwrap().unwrap();
429 let parser = cfgrammar::header::GrmtoolsSectionParser::new(src, true);
430 let (header_parsed, _) = parser.parse().unwrap();
431 assert_eq!(yacc_parsed, header_parsed);
432 assert!(errs.is_empty());
433 }
434}
435
436#[test]
438fn test_regex_opt() {
439 let lexerdef = regex_opt_l::lexerdef();
440 let lexer = lexerdef.lexer("a");
441 match regex_opt_y::parse(&lexer) {
442 ref errs if errs.is_empty() => (),
443 e => panic!("{:?}", e),
444 }
445}
446
447#[test]
449fn test_lex_flags() {
450 let lexerdef = lex_flags_l::lexerdef();
451 let lexer = lexerdef.lexer("a");
452 match lex_flags_y::parse(&lexer) {
453 ref errs if errs.is_empty() => (),
454 e => panic!("{:?}", e),
455 }
456}
457
458#[test]
459fn ast_unmodified() {
460 let lexerdef = ast_unmodified_l::lexerdef();
461 let lexer = lexerdef.lexer("A: BBBB, CCCCC;");
462 match &ast_unmodified_y::parse(&lexer) {
463 (_, errs) if errs.is_empty() => (),
464 (_, e) => panic!("{:?}", e),
465 }
466}
467
468#[test]
469fn ast_modified() {
470 let lexerdef = ast_modified_l::lexerdef();
471 let lexer = lexerdef.lexer("CCCCC, BBBB");
472 match &ast_modified_y::parse(&lexer) {
473 (_, errs) if errs.is_empty() => (),
474 (_, e) => panic!("{:?}", e),
475 }
476}
477
478#[cfg(test)]
480generate_codegen_fail_tests!("src/ctfails/*.test");