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