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