|
1 | 1 | use cfgrammar::{ |
2 | 2 | Location, RIdx, Span, TIdx, |
3 | | - header::{GrmtoolsSectionParser, Header, HeaderError, HeaderValue, Value}, |
| 3 | + header::{GrmtoolsSectionParser, Header, HeaderError, HeaderValue, Setting, Value}, |
4 | 4 | markmap::Entry, |
5 | 5 | yacc::{YaccGrammar, YaccKind, YaccOriginalActionKind, ast::ASTWithValidityInfo}, |
6 | 6 | }; |
@@ -495,7 +495,7 @@ impl fmt::Display for NimbleparseError { |
495 | 495 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
496 | 496 | match self { |
497 | 497 | Self::Source { src_path, errs } => { |
498 | | - writeln!(f, "While parsing: {}", src_path.display())?; |
| 498 | + writeln!(f, "While parsing {}:", src_path.display())?; |
499 | 499 | for e in errs { |
500 | 500 | writeln!(f, "{}", e)? |
501 | 501 | } |
@@ -543,77 +543,99 @@ where |
543 | 543 | } |
544 | 544 |
|
545 | 545 | fn parse_many(self, input_paths: &[String]) -> Result<(), NimbleparseError> { |
546 | | - let input_paths = if input_paths.is_empty() { |
| 546 | + let mut paths = Vec::new(); |
| 547 | + if !input_paths.is_empty() { |
| 548 | + paths.extend( |
| 549 | + input_paths |
| 550 | + .iter() |
| 551 | + .map(PathBuf::from) |
| 552 | + .collect::<Vec<PathBuf>>(), |
| 553 | + ); |
| 554 | + } else { |
547 | 555 | // If given no input paths, try to find some with `test_files` in the header. |
548 | | - if let Some(HeaderValue(_, val)) = self.header.get("test_files") { |
549 | | - let s = val.expect_string_with_context("'test_files' in %grmtools")?; |
550 | | - if let Some(yacc_y_path_dir) = self.yacc_y_path.parent() { |
551 | | - let joined = yacc_y_path_dir.join(s); |
552 | | - let joined = joined.as_os_str().to_str(); |
553 | | - if let Some(s) = joined { |
554 | | - let mut paths = glob::glob(s)?.peekable(); |
555 | | - if paths.peek().is_none() { |
556 | | - return Err(NimbleparseError::Other( |
557 | | - format!("'test_files' glob '{}' matched no paths", s) |
558 | | - .to_string() |
559 | | - .into(), |
560 | | - )); |
561 | | - } |
562 | | - let mut input_paths = Vec::new(); |
563 | | - for path in paths { |
564 | | - let path = path?; |
565 | | - if let Some(ext) = path.extension() { |
566 | | - if let Some(ext) = ext.to_str() { |
567 | | - if ext.starts_with("grm") { |
568 | | - Err(NimbleparseError::Other( |
569 | | - "test_files extensions beginning with `grm` are reserved." |
570 | | - .into(), |
571 | | - ))? |
| 556 | + match self.header.get("test_files") { |
| 557 | + Some(HeaderValue(_, Value::Setting(Setting::Array(test_globs, _, _)))) => { |
| 558 | + for setting in test_globs { |
| 559 | + match setting { |
| 560 | + Setting::String(s, _) => { |
| 561 | + if let Some(yacc_y_path_dir) = self.yacc_y_path.parent() { |
| 562 | + let joined = yacc_y_path_dir.join(s); |
| 563 | + let joined = joined.as_os_str().to_str(); |
| 564 | + if let Some(s) = joined { |
| 565 | + let mut glob_paths = glob::glob(s)?.peekable(); |
| 566 | + if glob_paths.peek().is_none() { |
| 567 | + return Err(NimbleparseError::Other( |
| 568 | + format!( |
| 569 | + "'test_files' glob '{}' matched no paths", |
| 570 | + s |
| 571 | + ) |
| 572 | + .to_string() |
| 573 | + .into(), |
| 574 | + )); |
| 575 | + } |
| 576 | + for path in glob_paths { |
| 577 | + let path = path?; |
| 578 | + if let Some(ext) = path.extension() { |
| 579 | + if let Some(ext) = ext.to_str() { |
| 580 | + if ext.starts_with("grm") { |
| 581 | + Err(NimbleparseError::Other( |
| 582 | + "test_files extensions beginning with `grm` are reserved." |
| 583 | + .into(), |
| 584 | + ))? |
| 585 | + } |
| 586 | + } |
| 587 | + } |
| 588 | + paths.push(path); |
| 589 | + } |
| 590 | + } else { |
| 591 | + return Err(NimbleparseError::Other( |
| 592 | + format!( |
| 593 | + "Unable to convert joined path to str {} with glob '{}'", |
| 594 | + self.yacc_y_path.display(), |
| 595 | + s |
| 596 | + ) |
| 597 | + .into(), |
| 598 | + )); |
572 | 599 | } |
| 600 | + } else { |
| 601 | + return Err(NimbleparseError::Other( |
| 602 | + format!( |
| 603 | + "Unable to find parent path for {}", |
| 604 | + self.yacc_y_path.display() |
| 605 | + ) |
| 606 | + .into(), |
| 607 | + )); |
573 | 608 | } |
574 | 609 | } |
575 | | - input_paths.push(path); |
| 610 | + |
| 611 | + _ => { |
| 612 | + return Err(NimbleparseError::Other( |
| 613 | + "Expected string values in `test_files`".into(), |
| 614 | + )); |
| 615 | + } |
576 | 616 | } |
577 | | - input_paths |
578 | | - } else { |
579 | | - return Err(NimbleparseError::Other( |
580 | | - format!( |
581 | | - "Unable to convert joined path to str {} with glob '{}'", |
582 | | - self.yacc_y_path.display(), |
583 | | - s |
584 | | - ) |
585 | | - .into(), |
586 | | - )); |
587 | 617 | } |
588 | | - } else { |
| 618 | + } |
| 619 | + Some(_) => { |
589 | 620 | return Err(NimbleparseError::Other( |
590 | | - format!( |
591 | | - "Unable to find parent path for {}", |
592 | | - self.yacc_y_path.display() |
593 | | - ) |
594 | | - .into(), |
| 621 | + "Expected Array of string values in `test_files`".into(), |
| 622 | + )); |
| 623 | + } |
| 624 | + None => { |
| 625 | + return Err(NimbleparseError::Other( |
| 626 | + "Missing <input file> argument".into(), |
595 | 627 | )); |
596 | 628 | } |
597 | | - } else { |
598 | | - return Err(NimbleparseError::Other( |
599 | | - "Missing <input file> argument".into(), |
600 | | - )); |
601 | 629 | } |
602 | | - } else { |
603 | | - // Just convert the given arguments to paths. |
604 | | - input_paths |
605 | | - .iter() |
606 | | - .map(PathBuf::from) |
607 | | - .collect::<Vec<PathBuf>>() |
608 | 630 | }; |
609 | | - if input_paths.is_empty() { |
| 631 | + if paths.is_empty() { |
610 | 632 | return Err(NimbleparseError::Other( |
611 | 633 | "Missing <input file> argument".into(), |
612 | 634 | )); |
613 | 635 | } |
614 | 636 | let pb = RTParserBuilder::new(&self.grm, &self.stable).recoverer(self.recoverykind); |
615 | 637 | // Actually parse the given arguments or the `test_files` specified in the grammar. |
616 | | - for input_path in input_paths { |
| 638 | + for input_path in paths { |
617 | 639 | let input = read_file(&input_path); |
618 | 640 | let lexer = self.lexerdef.lexer(&input); |
619 | 641 | let (pt, errs) = |
|
0 commit comments