diff --git a/CHANGELOG.md b/CHANGELOG.md index 8dec17c..b07b398 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## [Unreleased](https://github.com/dalance/sv-parser/compare/v0.8.3...Unreleased) - ReleaseDate +* [Added] incomplete option [#19](https://github.com/dalance/sv-parser/issues/19) * [Changed] keep text_macro_definition after preprocess [#19](https://github.com/dalance/sv-parser/issues/19) ## [v0.8.3](https://github.com/dalance/sv-parser/compare/v0.8.2...v0.8.3) - 2020-11-06 diff --git a/sv-parser-parser/src/source_text/system_verilog_source_text.rs b/sv-parser-parser/src/source_text/system_verilog_source_text.rs index d1b3b8a..bc87d60 100644 --- a/sv-parser-parser/src/source_text/system_verilog_source_text.rs +++ b/sv-parser-parser/src/source_text/system_verilog_source_text.rs @@ -7,8 +7,8 @@ use crate::*; pub(crate) fn source_text(s: Span) -> IResult { let (s, a) = many0(white_space)(s)?; let (s, b) = opt(timeunits_declaration)(s)?; - let (s, c) = many_till(description, eof)(s)?; - Ok((s, SourceText { nodes: (a, b, c.0) })) + let (s, c) = many0(description)(s)?; + Ok((s, SourceText { nodes: (a, b, c) })) } #[tracable_parser] diff --git a/sv-parser-parser/src/utils.rs b/sv-parser-parser/src/utils.rs index 7918a8a..1e2cbab 100644 --- a/sv-parser-parser/src/utils.rs +++ b/sv-parser-parser/src/utils.rs @@ -301,16 +301,6 @@ where // ----------------------------------------------------------------------------- -pub(crate) fn eof(s: Span) -> IResult { - use nom::InputLength; - - if s.input_len() == 0 { - Ok((s, s)) - } else { - Err(Err::Error(make_error(s, ErrorKind::Eof))) - } -} - #[tracable_parser] #[packrat_parser] pub(crate) fn white_space(s: Span) -> IResult { diff --git a/sv-parser/examples/module_list.rs b/sv-parser/examples/module_list.rs index bab0f0b..dce7864 100644 --- a/sv-parser/examples/module_list.rs +++ b/sv-parser/examples/module_list.rs @@ -14,7 +14,7 @@ fn main() { let includes: Vec = Vec::new(); // Parse - let result = parse_sv(&path, &defines, &includes, false); + let result = parse_sv(&path, &defines, &includes, false, false); if let Ok((syntax_tree, _)) = result { // &SyntexTree is iterable diff --git a/sv-parser/examples/parse_sv.rs b/sv-parser/examples/parse_sv.rs index aee7f25..943f6fe 100644 --- a/sv-parser/examples/parse_sv.rs +++ b/sv-parser/examples/parse_sv.rs @@ -25,6 +25,10 @@ struct Opt { #[structopt(short = "p", long = "pp")] pub pp: bool, + /// Allow incomplete source code + #[structopt(long = "incomplete")] + pub incomplete: bool, + /// Quiet #[structopt(short = "q", long = "quiet")] pub quiet: bool, @@ -44,7 +48,7 @@ fn main() { _ => (), } } else { - match parse_sv(&path, &defines, &opt.includes, false) { + match parse_sv(&path, &defines, &opt.includes, false, opt.incomplete) { Ok((syntax_tree, new_defines)) => { if opt.tree { println!("{}", syntax_tree); diff --git a/sv-parser/src/lib.rs b/sv-parser/src/lib.rs index 66acc49..9df2cc6 100644 --- a/sv-parser/src/lib.rs +++ b/sv-parser/src/lib.rs @@ -97,17 +97,23 @@ pub fn parse_sv, U: AsRef, V: BuildHasher>( pre_defines: &HashMap, V>, include_paths: &[U], ignore_include: bool, + allow_incomplete: bool, ) -> Result<(SyntaxTree, Defines), Error> { let (text, defines) = preprocess(path, pre_defines, include_paths, false, ignore_include)?; - parse_sv_pp(text, defines) + parse_sv_pp(text, defines, allow_incomplete) } pub fn parse_sv_pp( text: PreprocessedText, defines: Defines, + allow_incomplete: bool, ) -> Result<(SyntaxTree, Defines), Error> { let span = Span::new_extra(text.text(), SpanInfo::default()); - let result = all_consuming(sv_parser)(span); + let result = if allow_incomplete { + sv_parser(span) + } else { + all_consuming(sv_parser)(span) + }; match result { Ok((_, x)) => Ok(( SyntaxTree { @@ -142,6 +148,7 @@ pub fn parse_sv_str, U: AsRef, V: BuildHasher>( pre_defines: &HashMap, V>, include_paths: &[U], ignore_include: bool, + allow_incomplete: bool, ) -> Result<(SyntaxTree, Defines), Error> { let (text, defines) = preprocess_str( s, @@ -152,7 +159,7 @@ pub fn parse_sv_str, U: AsRef, V: BuildHasher>( false, 0, )?; - parse_sv_pp(text, defines) + parse_sv_pp(text, defines, allow_incomplete) } pub fn parse_lib, U: AsRef, V: BuildHasher>( @@ -160,9 +167,10 @@ pub fn parse_lib, U: AsRef, V: BuildHasher>( pre_defines: &HashMap, V>, include_paths: &[U], ignore_include: bool, + allow_incomplete: bool, ) -> Result<(SyntaxTree, Defines), Error> { let (text, defines) = preprocess(path, pre_defines, include_paths, false, ignore_include)?; - parse_lib_pp(text, defines) + parse_lib_pp(text, defines, allow_incomplete) } pub fn parse_lib_str, U: AsRef, V: BuildHasher>( @@ -171,6 +179,7 @@ pub fn parse_lib_str, U: AsRef, V: BuildHasher>( pre_defines: &HashMap, V>, include_paths: &[U], ignore_include: bool, + allow_incomplete: bool, ) -> Result<(SyntaxTree, Defines), Error> { let (text, defines) = preprocess_str( s, @@ -181,15 +190,20 @@ pub fn parse_lib_str, U: AsRef, V: BuildHasher>( false, 0, )?; - parse_lib_pp(text, defines) + parse_lib_pp(text, defines, allow_incomplete) } pub fn parse_lib_pp( text: PreprocessedText, defines: Defines, + allow_incomplete: bool, ) -> Result<(SyntaxTree, Defines), Error> { let span = Span::new_extra(text.text(), SpanInfo::default()); - let result = all_consuming(lib_parser)(span); + let result = if allow_incomplete { + all_consuming(lib_parser)(span) + } else { + lib_parser(span) + }; match result { Ok((_, x)) => Ok(( SyntaxTree { @@ -258,7 +272,7 @@ mod test { fn test() { let src = "/* comment */"; let (syntax_tree, _) = - parse_sv_str(src, PathBuf::from(""), &HashMap::new(), &[""], false).unwrap(); + parse_sv_str(src, PathBuf::from(""), &HashMap::new(), &[""], false, false).unwrap(); let comment = unwrap_node!(&syntax_tree, Comment); assert!(comment.is_some()); }