diff --git a/CHANGELOG.md b/CHANGELOG.md index a89c881..97788f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ * [Fixed] hierarchical this bug * [Fixed] hierarchical delay value bug * [Fixed] const class new bug +* [Fixed] missing all_consuming of pp_parser +* [Fixed] typo 'triwand' +* [Fixed] arguments of text_macro_usage ## [v0.3.6](https://github.com/dalance/sv-parser/compare/v0.3.5...v0.3.6) - 2019-11-05 diff --git a/sv-parser-error/src/lib.rs b/sv-parser-error/src/lib.rs index af3288e..1200343 100644 --- a/sv-parser-error/src/lib.rs +++ b/sv-parser-error/src/lib.rs @@ -22,6 +22,8 @@ pub enum ErrorKind { DefineArgNotFound(String), #[fail(display = "Define not found: {}", _0)] DefineNotFound(String), + #[fail(display = "Define must have argument")] + DefineNoArgs, } // ----------------------------------------------------------------------------- diff --git a/sv-parser-parser/src/expressions/expressions.rs b/sv-parser-parser/src/expressions/expressions.rs index f68ccc4..95244b1 100644 --- a/sv-parser-parser/src/expressions/expressions.rs +++ b/sv-parser-parser/src/expressions/expressions.rs @@ -183,10 +183,10 @@ pub(crate) fn constant_param_expression(s: Span) -> IResult IResult { alt(( - map(data_type, |x| ParamExpression::DataType(Box::new(x))), - map(mintypmax_expression, |x| { + map(terminated(mintypmax_expression, peek(none_of("#"))), |x| { ParamExpression::MintypmaxExpression(Box::new(x)) }), + map(data_type, |x| ParamExpression::DataType(Box::new(x))), map(symbol("$"), |x| ParamExpression::Dollar(Box::new(x))), ))(s) } diff --git a/sv-parser-parser/src/expressions/primaries.rs b/sv-parser-parser/src/expressions/primaries.rs index 466c62c..abd40ac 100644 --- a/sv-parser-parser/src/expressions/primaries.rs +++ b/sv-parser-parser/src/expressions/primaries.rs @@ -6,6 +6,8 @@ use crate::*; #[packrat_parser] pub(crate) fn constant_primary(s: Span) -> IResult { alt(( + // BNF-WA + map(keyword("$"), |x| ConstantPrimary::Dollar(Box::new(x))), map(keyword("null"), |x| ConstantPrimary::Null(Box::new(x))), map(constant_assignment_pattern_expression, |x| { ConstantPrimary::ConstantAssignmentPatternExpression(Box::new(x)) diff --git a/sv-parser-parser/src/general/compiler_directives.rs b/sv-parser-parser/src/general/compiler_directives.rs index fdfdd9e..ddb49ee 100644 --- a/sv-parser-parser/src/general/compiler_directives.rs +++ b/sv-parser-parser/src/general/compiler_directives.rs @@ -154,7 +154,9 @@ pub(crate) fn angle_bracket_literal_impl(s: Span) -> IResult { pub(crate) fn text_macro_definition(s: Span) -> IResult { let (s, a) = symbol("`")(s)?; let (s, b) = keyword("define")(s)?; + begin_keywords("directive"); let (s, c) = text_macro_name(s)?; + end_keywords(); let (s, d) = opt(macro_text)(s)?; Ok(( s, @@ -255,7 +257,7 @@ pub(crate) fn text_macro_usage(s: Span) -> IResult { #[tracable_parser] #[packrat_parser] pub(crate) fn list_of_actual_arguments(s: Span) -> IResult { - let (s, a) = list(symbol(","), actual_argument)(s)?; + let (s, a) = list(symbol(","), opt(actual_argument))(s)?; Ok((s, ListOfActualArguments { nodes: (a,) })) } @@ -555,7 +557,7 @@ pub(crate) fn default_nettype_value(s: Span) -> IResult 1; payload.size == len ; } + constraint G { len > 1; payload.size == len ; } - // function void post_randomize; crc = payload.sum; endfunction - // endclass + function void post_randomize; crc = payload.sum; endfunction + endclass - // initial begin - // send: begin // Create random packet and transmit - // byte q[$]; - // Packet p = new; - // void'(p.randomize()); - // q = {<< byte{p.header, p.len, p.payload, p.crc}}; // pack - // stream = {stream, q}; // append to stream - // end + initial begin + send: begin // Create random packet and transmit + byte q[$]; + Packet p = new; + void'(p.randomize()); + q = {<< byte{p.header, p.len, p.payload, p.crc}}; // pack + stream = {stream, q}; // append to stream + end - // receive: begin // Receive packet, unpack, and remove - // byte q[$]; - // Packet p = new; - // {<< byte{ p.header, p.len, p.payload with [0 +: p.len], p.crc }} = stream; - // stream = stream[ $bits(p) / 8 : $ ]; // remove packet - // end - // end"##, - // Ok((_, _)) - //); + receive: begin // Receive packet, unpack, and remove + byte q[$]; + Packet p = new; + {<< byte{ p.header, p.len, p.payload with [0 +: p.len], p.crc }} = stream; + stream = stream[ $bits(p) / 8 : $ ]; // remove packet + end + end"##, + Ok((_, _)) + ); test!( many1(module_item), r##"initial begin @@ -15848,7 +15853,7 @@ mod spec { fn debug() { test!( source_text, - r##"module a; initial begin #a.b; end endmodule"##, + r##"module a; b #( .a(a+1)) a (); endmodule"##, Ok((_, _)) ); nom_tracable::cumulative_histogram(); diff --git a/sv-parser-pp/src/preprocess.rs b/sv-parser-pp/src/preprocess.rs index e3a47ae..06113ec 100644 --- a/sv-parser-pp/src/preprocess.rs +++ b/sv-parser-pp/src/preprocess.rs @@ -1,5 +1,6 @@ use crate::range::Range; use failure::ResultExt; +use nom::combinator::all_consuming; use nom_greedyerror::error_position; use std::collections::{BTreeMap, HashMap}; use std::convert::TryInto; @@ -110,7 +111,7 @@ fn preprocess_str, U: AsRef>( } let span = Span::new_extra(&s, SpanInfo::default()); - let (_, pp_text) = pp_parser(span).map_err(|x| match x { + let (_, pp_text) = all_consuming(pp_parser)(span).map_err(|x| match x { nom::Err::Incomplete(_) => ErrorKind::Parse(None), nom::Err::Error(e) => { if let Some(pos) = error_position(&e) { @@ -406,27 +407,45 @@ fn resolve_text_macro_usage, U: AsRef>( let id = identifier((&name.nodes.0).into(), &s).unwrap(); let mut actual_args = Vec::new(); + let no_args = args.is_none(); if let Some(args) = args { let (_, ref args, _) = args.nodes; let (ref args,) = args.nodes; for arg in args.contents() { - let (ref arg,) = arg.nodes; - let arg = arg.str(&s); - actual_args.push(arg); + if let Some(arg) = arg { + let (ref arg,) = arg.nodes; + let arg = arg.str(&s); + actual_args.push(Some(arg)); + } else { + actual_args.push(None); + } } } let define = defines.get(&id); if let Some(Some(define)) = define { let mut arg_map = HashMap::new(); + + if !define.arguments.is_empty() && no_args { + return Err(ErrorKind::DefineNoArgs.into()); + } + for (i, (arg, default)) in define.arguments.iter().enumerate() { - let value = if let Some(actual_arg) = actual_args.get(i) { - *actual_arg - } else { - if let Some(default) = default { - default - } else { - return Err(ErrorKind::DefineArgNotFound(String::from(arg)).into()); + let value = match actual_args.get(i) { + Some(Some(actual_arg)) => *actual_arg, + Some(None) => { + if let Some(default) = default { + default + } else { + "" + } + } + None => { + if let Some(default) = default { + default + } else { + return Err(ErrorKind::DefineArgNotFound(String::from(arg)).into()); + } } }; arg_map.insert(String::from(arg), value); diff --git a/sv-parser-syntaxtree/src/expressions/primaries.rs b/sv-parser-syntaxtree/src/expressions/primaries.rs index d4a3ecf..7681c83 100644 --- a/sv-parser-syntaxtree/src/expressions/primaries.rs +++ b/sv-parser-syntaxtree/src/expressions/primaries.rs @@ -19,6 +19,7 @@ pub enum ConstantPrimary { ConstantAssignmentPatternExpression(Box), TypeReference(Box), Null(Box), + Dollar(Box), } #[derive(Clone, Debug, PartialEq, Node)] diff --git a/sv-parser-syntaxtree/src/general/compiler_directives.rs b/sv-parser-syntaxtree/src/general/compiler_directives.rs index 3b1e76d..4d91b52 100644 --- a/sv-parser-syntaxtree/src/general/compiler_directives.rs +++ b/sv-parser-syntaxtree/src/general/compiler_directives.rs @@ -102,7 +102,7 @@ pub struct TextMacroUsage { #[derive(Clone, Debug, PartialEq, Node)] pub struct ListOfActualArguments { - pub nodes: (List,), + pub nodes: (List>,), } #[derive(Clone, Debug, PartialEq, Node)]