diff --git a/sv-parser-parser/Cargo.toml b/sv-parser-parser/Cargo.toml index 2464b2d..24445bc 100644 --- a/sv-parser-parser/Cargo.toml +++ b/sv-parser-parser/Cargo.toml @@ -12,7 +12,7 @@ trace = ["nom-tracable/trace"] nom = "5.0.0" nom_locate = "0.4.0" nom-packrat = {path = "../../nom-packrat/nom-packrat"} -nom-recursive = {path = "../../nom-recursive/nom-recursive"} +nom-recursive = {path = "../../nom-recursive/nom-recursive", features = ["tracer128"]} nom-tracable = {path = "../../nom-tracable/nom-tracable"} str-concat = "*" sv-parser-macros = {path = "../sv-parser-macros"} diff --git a/sv-parser-parser/src/declarations/assertion_declarations.rs b/sv-parser-parser/src/declarations/assertion_declarations.rs index 817c45a..3ebfad2 100644 --- a/sv-parser-parser/src/declarations/assertion_declarations.rs +++ b/sv-parser-parser/src/declarations/assertion_declarations.rs @@ -145,8 +145,8 @@ pub(crate) fn property_instance(s: Span) -> IResult { #[tracable_parser] pub(crate) fn property_list_of_arguments(s: Span) -> IResult { alt(( - property_list_of_arguments_ordered, property_list_of_arguments_named, + property_list_of_arguments_ordered, ))(s) } @@ -1028,8 +1028,8 @@ pub(crate) fn sequence_instance(s: Span) -> IResult { #[tracable_parser] pub(crate) fn sequence_list_of_arguments(s: Span) -> IResult { alt(( - sequence_list_of_arguments_ordered, sequence_list_of_arguments_named, + sequence_list_of_arguments_ordered, ))(s) } diff --git a/sv-parser-parser/src/declarations/interface_declarations.rs b/sv-parser-parser/src/declarations/interface_declarations.rs index ae8ea72..c3bacee 100644 --- a/sv-parser-parser/src/declarations/interface_declarations.rs +++ b/sv-parser-parser/src/declarations/interface_declarations.rs @@ -76,7 +76,7 @@ pub(crate) fn modport_simple_ports_declaration( #[tracable_parser] pub(crate) fn modport_simple_port(s: Span) -> IResult { - alt((modport_simple_port_ordered, modport_simple_port_named))(s) + alt((modport_simple_port_named, modport_simple_port_ordered))(s) } #[tracable_parser] diff --git a/sv-parser-parser/src/declarations/let_declarations.rs b/sv-parser-parser/src/declarations/let_declarations.rs index 5d74627..da8b9c7 100644 --- a/sv-parser-parser/src/declarations/let_declarations.rs +++ b/sv-parser-parser/src/declarations/let_declarations.rs @@ -78,7 +78,7 @@ pub(crate) fn let_expression(s: Span) -> IResult { #[tracable_parser] pub(crate) fn let_list_of_arguments(s: Span) -> IResult { - alt((let_list_of_arguments_ordered, let_list_of_arguments_named))(s) + alt((let_list_of_arguments_named, let_list_of_arguments_ordered))(s) } #[recursive_parser] diff --git a/sv-parser-parser/src/expressions/numbers.rs b/sv-parser-parser/src/expressions/numbers.rs index 5853ccb..0b01e15 100644 --- a/sv-parser-parser/src/expressions/numbers.rs +++ b/sv-parser-parser/src/expressions/numbers.rs @@ -304,6 +304,13 @@ pub(crate) fn z_number_impl(s: Span) -> IResult { #[tracable_parser] pub(crate) fn unbased_unsized_literal(s: Span) -> IResult { - let (s, a) = alt((symbol("'0"), symbol("'1"), symbol("'z"), symbol("'x")))(s)?; + let (s, a) = alt(( + symbol("'0"), + symbol("'1"), + symbol("'z"), + symbol("'x"), + symbol("'Z"), + symbol("'X"), + ))(s)?; Ok((s, UnbasedUnsizedLiteral { nodes: (a,) })) } diff --git a/sv-parser-parser/src/expressions/primaries.rs b/sv-parser-parser/src/expressions/primaries.rs index b89d4f8..f0c4f51 100644 --- a/sv-parser-parser/src/expressions/primaries.rs +++ b/sv-parser-parser/src/expressions/primaries.rs @@ -145,7 +145,7 @@ pub(crate) fn module_path_primary_mintypmax_expression( pub(crate) fn primary(s: Span) -> IResult { alt(( map(keyword("this"), |x| Primary::This(Box::new(x))), - map(symbol("$"), |x| Primary::Dollar(Box::new(x))), + map(keyword("$"), |x| Primary::Dollar(Box::new(x))), map(keyword("null"), |x| Primary::Null(Box::new(x))), map(primary_literal, |x| Primary::PrimaryLiteral(Box::new(x))), primary_hierarchical, diff --git a/sv-parser-parser/src/expressions/strings.rs b/sv-parser-parser/src/expressions/strings.rs index 8af7117..e0c2ae2 100644 --- a/sv-parser-parser/src/expressions/strings.rs +++ b/sv-parser-parser/src/expressions/strings.rs @@ -11,33 +11,31 @@ pub(crate) fn string_literal(s: Span) -> IResult { #[tracable_parser] pub(crate) fn string_literal_impl(s: Span) -> IResult { let (s, a) = tag("\"")(s)?; - let (s, b) = many1(pair(is_not("\\\""), opt(pair(tag("\\"), take(1usize)))))(s)?; + let (s, b) = many0(alt(( + is_not("\\\""), + map(pair(tag("\\"), take(1usize)), |(x, y)| { + concat(x, y).unwrap() + }), + )))(s)?; let (s, c) = tag("\"")(s)?; let mut ret = None; - for (x, y) in b { + for x in b { ret = if let Some(ret) = ret { Some(concat(ret, x).unwrap()) } else { Some(x) }; - if let Some((y, z)) = y { - ret = if let Some(ret) = ret { - Some(concat(ret, y).unwrap()) - } else { - Some(y) - }; - ret = if let Some(ret) = ret { - Some(concat(ret, z).unwrap()) - } else { - Some(z) - }; - } } - let b = ret.unwrap(); - let a = concat(a, b).unwrap(); - let a = concat(a, c).unwrap(); + let a = if let Some(b) = ret { + let a = concat(a, b).unwrap(); + let a = concat(a, c).unwrap(); + a + } else { + let a = concat(a, c).unwrap(); + a + }; Ok((s, into_locate(a))) } diff --git a/sv-parser-parser/src/expressions/subroutine_calls.rs b/sv-parser-parser/src/expressions/subroutine_calls.rs index ac59a07..2115457 100644 --- a/sv-parser-parser/src/expressions/subroutine_calls.rs +++ b/sv-parser-parser/src/expressions/subroutine_calls.rs @@ -88,7 +88,7 @@ pub(crate) fn function_subroutine_call(s: Span) -> IResult IResult { - alt((list_of_arguments_ordered, list_of_arguments_named))(s) + alt((list_of_arguments_named, list_of_arguments_ordered))(s) } #[recursive_parser] diff --git a/sv-parser-parser/src/instantiations/checker_instantiation.rs b/sv-parser-parser/src/instantiations/checker_instantiation.rs index 7db1fa1..df69218 100644 --- a/sv-parser-parser/src/instantiations/checker_instantiation.rs +++ b/sv-parser-parser/src/instantiations/checker_instantiation.rs @@ -21,8 +21,8 @@ pub(crate) fn list_of_checker_port_connections( s: Span, ) -> IResult { alt(( - list_of_checker_port_connections_ordered, list_of_checker_port_connections_named, + list_of_checker_port_connections_ordered, ))(s) } diff --git a/sv-parser-parser/src/instantiations/module_instantiation.rs b/sv-parser-parser/src/instantiations/module_instantiation.rs index 0cf0eb4..6abfac5 100644 --- a/sv-parser-parser/src/instantiations/module_instantiation.rs +++ b/sv-parser-parser/src/instantiations/module_instantiation.rs @@ -26,8 +26,8 @@ pub(crate) fn parameter_value_assignment(s: Span) -> IResult IResult { alt(( - list_of_parameter_assignments_ordered, list_of_parameter_assignments_named, + list_of_parameter_assignments_ordered, ))(s) } @@ -89,8 +89,8 @@ pub(crate) fn name_of_instance(s: Span) -> IResult { #[tracable_parser] pub(crate) fn list_of_port_connections(s: Span) -> IResult { alt(( - list_of_port_connections_ordered, list_of_port_connections_named, + list_of_port_connections_ordered, ))(s) } diff --git a/sv-parser-parser/src/primitive_instances/primitive_instantiation_and_instances.rs b/sv-parser-parser/src/primitive_instances/primitive_instantiation_and_instances.rs index d3987c7..517d331 100644 --- a/sv-parser-parser/src/primitive_instances/primitive_instantiation_and_instances.rs +++ b/sv-parser-parser/src/primitive_instances/primitive_instantiation_and_instances.rs @@ -199,7 +199,10 @@ pub(crate) fn n_input_gate_instance(s: Span) -> IResult IResult { let (s, a) = opt(name_of_instance)(s)?; let (s, b) = paren(tuple(( - list(symbol(","), output_terminal), + list( + terminated(symbol(","), peek(pair(output_terminal, symbol(",")))), + output_terminal, + ), symbol(","), input_terminal, )))(s)?; diff --git a/sv-parser-parser/src/tests.rs b/sv-parser-parser/src/tests.rs index a7d571d..aba68a7 100644 --- a/sv-parser-parser/src/tests.rs +++ b/sv-parser-parser/src/tests.rs @@ -4,14 +4,7 @@ use crate::*; macro_rules! test { ( $x:expr, $y:expr, $z:pat ) => { - #[cfg(not(feature = "trace"))] let info = SpanInfo::default(); - #[cfg(feature = "trace")] - let info = { - let mut info = SpanInfo::default(); - info.tracable_info = TracableInfo::new().forward(true).backward(true); - info - }; let ret = all_consuming($x)(Span::new_extra($y, info)); if let $z = ret { } else { @@ -315,227 +308,226 @@ fn test_net_declaration() { #[test] fn test_data_declaration() { - //test!( - // data_declaration, - // "shortint s1, s2[0:9];", - // Ok((_, DataDeclaration::Variable(_))) - //); - //test!( - // data_declaration, - // "var byte my_byte;", - // Ok((_, DataDeclaration::Variable(_))) - //); - //test!( - // data_declaration, - // "var v;", - // Ok((_, DataDeclaration::Variable(_))) - //); - //test!( - // data_declaration, - // "var [15:0] vw;", - // Ok((_, DataDeclaration::Variable(_))) - //); - //test!( - // data_declaration, - // "var enum bit { clear, error } status;", - // Ok((_, DataDeclaration::Variable(_))) - //); - //test!( - // data_declaration, - // "var reg r;", - // Ok((_, DataDeclaration::Variable(_))) - //); - //test!( - // data_declaration, - // "int i = 0;", - // Ok((_, DataDeclaration::Variable(_))) - //); - //test!( - // data_declaration, - // "logic a;", - // Ok((_, DataDeclaration::Variable(_))) - //); - //test!( - // data_declaration, - // "logic[3:0] v;", - // Ok((_, DataDeclaration::Variable(_))) - //); - //test!( - // data_declaration, - // "logic signed [3:0] signed_reg;", - // Ok((_, DataDeclaration::Variable(_))) - //); - //test!( - // data_declaration, - // "logic [-1:4] b;", - // Ok((_, DataDeclaration::Variable(_))) - //); - //test!( - // data_declaration, - // "logic [4:0] x, y, z;", - // Ok((_, DataDeclaration::Variable(_))) - //); - //test!( - // data_declaration, - // "int unsigned ui;", - // Ok((_, DataDeclaration::Variable(_))) - //); - //test!( - // data_declaration, - // "int signed si;", - // Ok((_, DataDeclaration::Variable(_))) - //); - //test!( - // data_declaration, - // "string myName = default_name;", - // Ok((_, DataDeclaration::Variable(_))) - //); - //test!( - // data_declaration, - // "byte c = \"A\";", - // Ok((_, DataDeclaration::Variable(_))) - //); - //test!( - // data_declaration, - // "bit [10:0] b = \"x41\";", - // Ok((_, DataDeclaration::Variable(_))) - //); - //test!( - // data_declaration, - // "bit [1:4][7:0] h = \"hello\" ;", - // Ok((_, DataDeclaration::Variable(_))) - //); - //test!( - // data_declaration, - // "event done;", - // Ok((_, DataDeclaration::Variable(_))) - //); - //test!( - // data_declaration, - // "event done_too = done;", - // Ok((_, DataDeclaration::Variable(_))) - //); - //test!( - // data_declaration, - // "event empty = null;", - // Ok((_, DataDeclaration::Variable(_))) - //); - //test!( - // data_declaration, - // "typedef int intP;", - // Ok((_, DataDeclaration::TypeDeclaration(_))) - //); - //test!( - // data_declaration, - // "intP a, b;", - // Ok((_, DataDeclaration::Variable(_))) - //); - //test!( - // data_declaration, - // "typedef enum type_identifier;", - // Ok((_, DataDeclaration::TypeDeclaration(_))) - //); - //test!( - // data_declaration, - // "typedef struct type_identifier;", - // Ok((_, DataDeclaration::TypeDeclaration(_))) - //); - //test!( - // data_declaration, - // "typedef union type_identifier;", - // Ok((_, DataDeclaration::TypeDeclaration(_))) - //); - //test!( - // data_declaration, - // "typedef class type_identifier;", - // Ok((_, DataDeclaration::TypeDeclaration(_))) - //); - //test!( - // data_declaration, - // "typedef interface class type_identifier;", - // Ok((_, DataDeclaration::TypeDeclaration(_))) - //); - //test!( - // data_declaration, - // "typedef type_identifier;", - // Ok((_, DataDeclaration::TypeDeclaration(_))) - //); - //test!( - // data_declaration, - // "typedef C::T c_t;", - // Ok((_, DataDeclaration::TypeDeclaration(_))) - //); - //test!( - // data_declaration, - // "enum {red, yellow, green} light1, light2;", - // Ok((_, DataDeclaration::Variable(_))) - //); - //test!( - // data_declaration, - // "enum bit [1:0] {IDLE, XX='x, S1=2'b01, S2=2'b10} state, next;", - // Ok((_, DataDeclaration::Variable(_))) - //); - //test!( - // data_declaration, - // "enum integer {IDLE, XX='x, S1='b01, S2='b10} state, next;", - // Ok((_, DataDeclaration::Variable(_))) - //); - //test!( - // data_declaration, - // "enum integer {IDLE, XX='x, S1='b01, S2='b10} state, next;", - // Ok((_, DataDeclaration::Variable(_))) - //); - //test!( - // data_declaration, - // "enum {bronze=3, silver, gold} medal;", - // Ok((_, DataDeclaration::Variable(_))) - //); - //test!( - // data_declaration, - // "enum {a=3, b=7, c} alphabet;", - // Ok((_, DataDeclaration::Variable(_))) - //); - //test!( - // data_declaration, - // "enum bit [3:0] {bronze='h3, silver, gold='h5} medal2;", - // Ok((_, DataDeclaration::Variable(_))) - //); - //test!( - // data_declaration, - // "integer i_array[*];", - // Ok((_, DataDeclaration::Variable(_))) - //); - //test!( - // data_declaration, - // "bit [20:0] array_b[string];", - // Ok((_, DataDeclaration::Variable(_))) - //); - //test!( - // data_declaration, - // "event ev_array[myClass];", - // Ok((_, DataDeclaration::Variable(_))) - //); - //test!( - // data_declaration, - // "int array_name [*];", - // Ok((_, DataDeclaration::Variable(_))) - //); - //test!( - // data_declaration, - // "int array_name1 [ integer ];", - // Ok((_, DataDeclaration::Variable(_))) - //); - //test!( - // data_declaration, - // "int a[int] = '{default:1};", - // Ok((_, DataDeclaration::Variable(_))) - //); - //test!( - // data_declaration, - // "byte q1[$];", - // Ok((_, DataDeclaration::Variable(_))) - //); - test!(primary, "'{default:1}", Ok((_, _))); + test!( + data_declaration, + "shortint s1, s2[0:9];", + Ok((_, DataDeclaration::Variable(_))) + ); + test!( + data_declaration, + "var byte my_byte;", + Ok((_, DataDeclaration::Variable(_))) + ); + test!( + data_declaration, + "var v;", + Ok((_, DataDeclaration::Variable(_))) + ); + test!( + data_declaration, + "var [15:0] vw;", + Ok((_, DataDeclaration::Variable(_))) + ); + test!( + data_declaration, + "var enum bit { clear, error } status;", + Ok((_, DataDeclaration::Variable(_))) + ); + test!( + data_declaration, + "var reg r;", + Ok((_, DataDeclaration::Variable(_))) + ); + test!( + data_declaration, + "int i = 0;", + Ok((_, DataDeclaration::Variable(_))) + ); + test!( + data_declaration, + "logic a;", + Ok((_, DataDeclaration::Variable(_))) + ); + test!( + data_declaration, + "logic[3:0] v;", + Ok((_, DataDeclaration::Variable(_))) + ); + test!( + data_declaration, + "logic signed [3:0] signed_reg;", + Ok((_, DataDeclaration::Variable(_))) + ); + test!( + data_declaration, + "logic [-1:4] b;", + Ok((_, DataDeclaration::Variable(_))) + ); + test!( + data_declaration, + "logic [4:0] x, y, z;", + Ok((_, DataDeclaration::Variable(_))) + ); + test!( + data_declaration, + "int unsigned ui;", + Ok((_, DataDeclaration::Variable(_))) + ); + test!( + data_declaration, + "int signed si;", + Ok((_, DataDeclaration::Variable(_))) + ); + test!( + data_declaration, + "string myName = default_name;", + Ok((_, DataDeclaration::Variable(_))) + ); + test!( + data_declaration, + "byte c = \"A\";", + Ok((_, DataDeclaration::Variable(_))) + ); + test!( + data_declaration, + "bit [10:0] b = \"x41\";", + Ok((_, DataDeclaration::Variable(_))) + ); + test!( + data_declaration, + "bit [1:4][7:0] h = \"hello\" ;", + Ok((_, DataDeclaration::Variable(_))) + ); + test!( + data_declaration, + "event done;", + Ok((_, DataDeclaration::Variable(_))) + ); + test!( + data_declaration, + "event done_too = done;", + Ok((_, DataDeclaration::Variable(_))) + ); + test!( + data_declaration, + "event empty = null;", + Ok((_, DataDeclaration::Variable(_))) + ); + test!( + data_declaration, + "typedef int intP;", + Ok((_, DataDeclaration::TypeDeclaration(_))) + ); + test!( + data_declaration, + "intP a, b;", + Ok((_, DataDeclaration::Variable(_))) + ); + test!( + data_declaration, + "typedef enum type_identifier;", + Ok((_, DataDeclaration::TypeDeclaration(_))) + ); + test!( + data_declaration, + "typedef struct type_identifier;", + Ok((_, DataDeclaration::TypeDeclaration(_))) + ); + test!( + data_declaration, + "typedef union type_identifier;", + Ok((_, DataDeclaration::TypeDeclaration(_))) + ); + test!( + data_declaration, + "typedef class type_identifier;", + Ok((_, DataDeclaration::TypeDeclaration(_))) + ); + test!( + data_declaration, + "typedef interface class type_identifier;", + Ok((_, DataDeclaration::TypeDeclaration(_))) + ); + test!( + data_declaration, + "typedef type_identifier;", + Ok((_, DataDeclaration::TypeDeclaration(_))) + ); + test!( + data_declaration, + "typedef C::T c_t;", + Ok((_, DataDeclaration::TypeDeclaration(_))) + ); + test!( + data_declaration, + "enum {red, yellow, green} light1, light2;", + Ok((_, DataDeclaration::Variable(_))) + ); + test!( + data_declaration, + "enum bit [1:0] {IDLE, XX='x, S1=2'b01, S2=2'b10} state, next;", + Ok((_, DataDeclaration::Variable(_))) + ); + test!( + data_declaration, + "enum integer {IDLE, XX='x, S1='b01, S2='b10} state, next;", + Ok((_, DataDeclaration::Variable(_))) + ); + test!( + data_declaration, + "enum integer {IDLE, XX='x, S1='b01, S2='b10} state, next;", + Ok((_, DataDeclaration::Variable(_))) + ); + test!( + data_declaration, + "enum {bronze=3, silver, gold} medal;", + Ok((_, DataDeclaration::Variable(_))) + ); + test!( + data_declaration, + "enum {a=3, b=7, c} alphabet;", + Ok((_, DataDeclaration::Variable(_))) + ); + test!( + data_declaration, + "enum bit [3:0] {bronze='h3, silver, gold='h5} medal2;", + Ok((_, DataDeclaration::Variable(_))) + ); + test!( + data_declaration, + "integer i_array[*];", + Ok((_, DataDeclaration::Variable(_))) + ); + test!( + data_declaration, + "bit [20:0] array_b[string];", + Ok((_, DataDeclaration::Variable(_))) + ); + test!( + data_declaration, + "event ev_array[myClass];", + Ok((_, DataDeclaration::Variable(_))) + ); + test!( + data_declaration, + "int array_name [*];", + Ok((_, DataDeclaration::Variable(_))) + ); + test!( + data_declaration, + "int array_name1 [ integer ];", + Ok((_, DataDeclaration::Variable(_))) + ); + test!( + data_declaration, + "int a[int] = '{default:1};", + Ok((_, DataDeclaration::Variable(_))) + ); + test!( + data_declaration, + "byte q1[$];", + Ok((_, DataDeclaration::Variable(_))) + ); } #[test] @@ -566,13 +558,11 @@ fn test_blocking_assignment() { #[test] fn test_primary() { - test!(primary, "2.1ns ", Ok((_, Primary::PrimaryLiteral(_)))); - test!(primary, "40 ps ", Ok((_, Primary::PrimaryLiteral(_)))); test!(primary, "'0", Ok((_, Primary::PrimaryLiteral(_)))); test!(primary, "10", Ok((_, Primary::PrimaryLiteral(_)))); test!(primary, "\"aaa\"", Ok((_, Primary::PrimaryLiteral(_)))); test!(primary, "this ", Ok((_, Primary::This(_)))); - test!(primary, "$", Ok((_, Primary::Dollar(_)))); + test!(primary, "$ ", Ok((_, Primary::Dollar(_)))); test!(primary, "null ", Ok((_, Primary::Null(_)))); } @@ -585,47 +575,6 @@ fn test_cast() { test!(cast, "type_t'(x)", Ok((_, _))); } -#[test] -fn test_number() { - test!(number, "659", Ok((_, Number::IntegralNumber(_)))); - test!(number, "'h 837FF", Ok((_, Number::IntegralNumber(_)))); - test!(number, "'h 837FF", Ok((_, Number::IntegralNumber(_)))); - test!(number, "'o7460", Ok((_, Number::IntegralNumber(_)))); - test!(number, "'4af", Err(_)); - test!(number, "4'b1001", Ok((_, Number::IntegralNumber(_)))); - test!(number, "5 'D 3", Ok((_, Number::IntegralNumber(_)))); - test!(number, "3'b01x", Ok((_, Number::IntegralNumber(_)))); - test!(number, "12'hx", Ok((_, Number::IntegralNumber(_)))); - test!(number, "16'hz", Ok((_, Number::IntegralNumber(_)))); - test!(number, "8 'd -6", Err(_)); - test!(number, "4 'shf", Ok((_, Number::IntegralNumber(_)))); - test!(number, "16'sd?", Ok((_, Number::IntegralNumber(_)))); - test!(number, "27_195_000", Ok((_, Number::IntegralNumber(_)))); - test!( - number, - "16'b0011_0101_0001_1111", - Ok((_, Number::IntegralNumber(_))) - ); - test!( - number, - "32 'h 12ab_f001", - Ok((_, Number::IntegralNumber(_))) - ); - test!(number, "1.2", Ok((_, Number::RealNumber(_)))); - test!(number, "0.1", Ok((_, Number::RealNumber(_)))); - test!(number, "2394.26331", Ok((_, Number::RealNumber(_)))); - test!(number, "1.2E12", Ok((_, Number::RealNumber(_)))); - test!(number, "1.30e-2", Ok((_, Number::RealNumber(_)))); - test!(number, "0.1e-0", Ok((_, Number::RealNumber(_)))); - test!(number, "23E10", Ok((_, Number::RealNumber(_)))); - test!(number, "29E-2", Ok((_, Number::RealNumber(_)))); - test!(number, "236.123_763_e-12", Ok((_, Number::RealNumber(_)))); - test!(number, ".12", Err(_)); - test!(number, "9.", Err(_)); - test!(number, "4.E3", Err(_)); - test!(number, ".2e-7", Err(_)); -} - #[test] fn test_unbased_unsized_literal() { test!(unbased_unsized_literal, "'0", Ok((_, _))); @@ -744,61 +693,12 @@ fn test_string_literal() { test!(string_literal, r#""aaa\"""#, Ok((_, _))); } -#[test] -fn test_identifier() { - test!( - identifier, - "shiftreg_a", - Ok((_, Identifier::SimpleIdentifier(_))) - ); - test!( - identifier, - "_bus3", - Ok((_, Identifier::SimpleIdentifier(_))) - ); - test!( - identifier, - "n$657", - Ok((_, Identifier::SimpleIdentifier(_))) - ); - test!( - identifier, - "\\busa+index", - Ok((_, Identifier::EscapedIdentifier(_))) - ); - test!( - identifier, - "\\-clock", - Ok((_, Identifier::EscapedIdentifier(_))) - ); -} - -#[test] -fn test_system_tf_identifier() { - test!(system_tf_identifier, "$display", Ok((_, _))); -} - #[test] fn test_comment() { test!(comment, "// comment", Ok((_, _))); test!(comment, "/* comment\n\n */", Ok((_, _))); } -#[test] -fn test_attribute_instance() { - test!( - attribute_instance, - "(* full_case, parallel_case *)", - Ok((_, _)) - ); - test!(attribute_instance, "(* full_case=1 *)", Ok((_, _))); - test!( - attribute_instance, - "(* full_case=1, parallel_case = 0 *)", - Ok((_, _)) - ); -} - #[test] fn test_expression() { test!(expression, "(!a ? 0 : !b : 1 : c ? 0 : 1)", Ok((_, _))); @@ -817,4 +717,337 @@ fn test_clause3() { endmodule: mux2to1"##, Ok((_, _)) ); + test!( + program_declaration, + r##"program test (input clk, input [16:1] addr, inout [7:0] data); + initial begin + end + endprogram"##, + Ok((_, _)) + ); + test!( + module_declaration, + r##"module memMod(simple_bus a); // simple_bus interface port + logic avail; + // When memMod is instantiated in module top, a.req is the req + // signal in the sb_intf instance of the 'simple_bus' interface + always @(posedge a.clk) a.gnt <= a.req & avail; + endmodule"##, + Ok((_, _)) + ); + test!( + module_declaration, + r##"module cpuMod(simple_bus b); // simple_bus interface port + endmodule"##, + Ok((_, _)) + ); + test!( + module_declaration, + r##"module top; + logic clk = 0; + simple_bus sb_intf(.clk(clk)); // Instantiate the interface + memMod mem(.a(sb_intf)); // Connect interface to module instance + cpuMod cpu(.b(sb_intf)); // Connect interface to module instance + endmodule"##, + Ok((_, _)) + ); + test!( + package_declaration, + r##"package ComplexPkg; + typedef struct { + shortreal i, r; + } Complex; + + function Complex add(Complex a, b); + add.r = a.r + b.r; + add.i = a.i + b.i; + endfunction + + function Complex mul(Complex a, b); + mul.r = (a.r * b.r) - (a.i * b.i); + mul.i = (a.r * b.i) + (a.i * b.r); + endfunction + endpackage : ComplexPkg"##, + Ok((_, _)) + ); + test!( + module_declaration, + r##"module top; // module with no ports + logic in1, in2, select; // variable declarations + wire out1; // net declaration + + mux2to1 m1 (.a(in1), .b(in2), .sel(select), .y(out1)); // module instance + + endmodule: top"##, + Ok((_, _)) + ); + test!( + module_declaration, + r##"module mux2to1 (input wire a, b, sel, // combined port and type declaration + output logic y); + // netlist using built-in primitive instances + not g1 (sel_n, sel); + and g2 (a_s, a, sel_n); + and g3 (b_s, b, sel); + or g4 (y, a_s, b_s); + endmodule: mux2to1"##, + Ok((_, _)) + ); + test!( + task_declaration, + r##"task t; + int b; + b = 5 + $unit::b; // $unit::b is the one outside + endtask"##, + Ok((_, _)) + ); + test!( + module_declaration, + r##"module D; + timeunit 100ps; + timeprecision 10fs; + endmodule"##, + Ok((_, _)) + ); + test!( + module_declaration, + r##"module E; + timeunit 100ps / 10fs; // timeunit with optional second argument + endmodule"##, + Ok((_, _)) + ); +} + +#[test] +fn test_clause4() { + test!( + module_declaration, + r##"module test; + logic a; + initial begin + a <= 0; + a <= 1; + end + endmodule"##, + Ok((_, _)) + ); + test!( + module_declaration, + r##"module test; + assign p = q; + initial begin + q = 1; + #1 q = 0; + $display(p); + end + endmodule"##, + Ok((_, _)) + ); +} + +#[test] +fn test_clause5() { + test!(identifier, "shiftreg_a", Ok((_, _))); + test!(identifier, "busa_index", Ok((_, _))); + test!(identifier, "error_condition", Ok((_, _))); + test!(identifier, "merge_ab", Ok((_, _))); + test!(identifier, "_bus3", Ok((_, _))); + test!(identifier, "n$657", Ok((_, _))); + test!(identifier, "\\busa+index", Ok((_, _))); + test!(identifier, "\\-clock", Ok((_, _))); + test!(identifier, "\\***error-condition***", Ok((_, _))); + test!(identifier, "\\net1/\\net2", Ok((_, _))); + test!(identifier, "\\{a,b}", Ok((_, _))); + test!(identifier, "\\a*(b+c)", Ok((_, _))); + test!( + subroutine_call_statement, + "$display (\"display a message\");", + Ok((_, _)) + ); + test!(subroutine_call_statement, "$finish;", Ok((_, _))); + test!(primary, "'0", Ok((_, _))); + test!(primary, "'1", Ok((_, _))); + test!(primary, "'X", Ok((_, _))); + test!(primary, "'x", Ok((_, _))); + test!(primary, "'Z", Ok((_, _))); + test!(primary, "'z", Ok((_, _))); + test!(number, "659", Ok((_, Number::IntegralNumber(_)))); + test!(number, "'h 837FF", Ok((_, Number::IntegralNumber(_)))); + test!(number, "'h 837FF", Ok((_, Number::IntegralNumber(_)))); + test!(number, "'o7460", Ok((_, Number::IntegralNumber(_)))); + test!(number, "'4af", Err(_)); + test!(number, "4'b1001", Ok((_, Number::IntegralNumber(_)))); + test!(number, "5 'D 3", Ok((_, Number::IntegralNumber(_)))); + test!(number, "3'b01x", Ok((_, Number::IntegralNumber(_)))); + test!(number, "12'hx", Ok((_, Number::IntegralNumber(_)))); + test!(number, "16'hz", Ok((_, Number::IntegralNumber(_)))); + test!(number, "8 'd -6", Err(_)); + test!(number, "4 'shf", Ok((_, Number::IntegralNumber(_)))); + test!(number, "16'sd?", Ok((_, Number::IntegralNumber(_)))); + test!(number, "27_195_000", Ok((_, Number::IntegralNumber(_)))); + test!( + number, + "16'b0011_0101_0001_1111", + Ok((_, Number::IntegralNumber(_))) + ); + test!( + number, + "32 'h 12ab_f001", + Ok((_, Number::IntegralNumber(_))) + ); + test!(number, "1.2", Ok((_, Number::RealNumber(_)))); + test!(number, "0.1", Ok((_, Number::RealNumber(_)))); + test!(number, "2394.26331", Ok((_, Number::RealNumber(_)))); + test!(number, "1.2E12", Ok((_, Number::RealNumber(_)))); + test!(number, "1.30e-2", Ok((_, Number::RealNumber(_)))); + test!(number, "0.1e-0", Ok((_, Number::RealNumber(_)))); + test!(number, "23E10", Ok((_, Number::RealNumber(_)))); + test!(number, "29E-2", Ok((_, Number::RealNumber(_)))); + test!(number, "236.123_763_e-12", Ok((_, Number::RealNumber(_)))); + test!(number, ".12", Err(_)); + test!(number, "9.", Err(_)); + test!(number, "4.E3", Err(_)); + test!(number, ".2e-7", Err(_)); + test!(primary, "2.1ns ", Ok((_, Primary::PrimaryLiteral(_)))); + test!(primary, "40 ps ", Ok((_, Primary::PrimaryLiteral(_)))); + test!( + subroutine_call_statement, + r##"$display("Humpty Dumpty sat on a wall. \ + Humpty Dumpty had a great fall.");"##, + Ok((_, _)) + ); + test!( + subroutine_call_statement, + r##"$display("Humpty Dumpty sat on a wall.\n\ + Humpty Dumpty had a great fall.");"##, + Ok((_, _)) + ); + test!(module_item, r##"byte c1 = "A" ;"##, Ok((_, _))); + test!(module_item, r##"bit [7:0] d = "\n" ;"##, Ok((_, _))); + test!( + module_item, + r##"bit [8*12:1] stringvar = "Hello world\n";"##, + Ok((_, _)) + ); + test!( + module_item, + r##"bit [0:11] [7:0] stringvar = "Hello world\n" ;"##, + Ok((_, _)) + ); + test!( + module_item, + r##"byte c3 [0:12] = "hello world\n" ;"##, + Ok((_, _)) + ); + test!( + module_item, + r##"typedef struct {int a; shortreal b;} ab;"##, + Ok((_, _)) + ); + test!(module_item, r##"ab c;"##, Ok((_, _))); + test!( + module_item, + r##"c = '{0, 0.0}; // structure literal type determined from + // the left-hand context (c)"##, + Ok((_, _)) + ); + test!( + module_item, + r##"ab abarr[1:0] = '{'{1, 1.0}, '{2, 2.0}};"##, + Ok((_, _)) + ); + test!( + module_item, + r##"c = '{a:0, b:0.0}; // member name and value for that member"##, + Ok((_, _)) + ); + test!( + module_item, + r##"c = '{default:0}; // all elements of structure c are set to 0"##, + Ok((_, _)) + ); + //TODO + //test!( + // module_item, + // r##"d = ab'{int:1, shortreal:1.0}; // data type and default value for all + // // members of that type"##, + // Ok((_, _)) + //); + test!( + module_item, + r##"ab abarr[1:0] = '{'{1, 1.0}, '{2, 2.0}};"##, + Ok((_, _)) + ); + test!( + module_declaration, + r##"module test; + struct {int X,Y,Z;} XYZ = '{3{1}}; + typedef struct {int a,b[4];} ab_t; + int a,b,c; + ab_t v1[1:0] [2:0]; + v1 = '{2{'{3{'{a,'{2{b,c}}}}}}}; + endmodule"##, + Ok((_, _)) + ); + test!( + module_item, + r##"int n[1:2][1:3] = '{'{0,1,2},'{3{4}}};"##, + Ok((_, _)) + ); + test!( + module_item, + r##"int n[1:2][1:6] = '{2{'{3{4, 5}}}}; // same as '{'{4,5,4,5,4,5},'{4,5,4,5,4,5}}"##, + Ok((_, _)) + ); + test!(module_item, r##"typedef int triple [1:3];"##, Ok((_, _))); + test!( + module_item, + r##"triple b = '{1:1, default:0}; // indices 2 and 3 assigned 0"##, + Ok((_, _)) + ); + test!( + attribute_instance, + r##"(* full_case, parallel_case *)"##, + Ok((_, _)) + ); + test!(attribute_instance, r##"(* full_case=1 *)"##, Ok((_, _))); + test!( + attribute_instance, + r##"(* full_case, // no value assigned + parallel_case=1 *)"##, + Ok((_, _)) + ); + test!(attribute_instance, r##"(* full_case *)"##, Ok((_, _))); + test!( + attribute_instance, + r##"(* full_case=1, parallel_case = 0 *)"##, + Ok((_, _)) + ); + test!( + module_item, + r##"(* fsm_state *) logic [7:0] state1;"##, + Ok((_, _)) + ); + test!( + module_item, + r##"(* fsm_state=1 *) logic [3:0] state2, state3;"##, + Ok((_, _)) + ); + test!( + module_item, + r##"a = b + (* mode = "cla" *) c; // sets the value for the attribute mode + // to be the string cla."##, + Ok((_, _)) + ); + //TODO + //test!( + // module_item, + // r##"a = add (* mode = "cla" *) (b, c);"##, + // Ok((_, _)) + //); + test!( + module_item, + r##"a = b ? (* no_glitch *) c : d;"##, + Ok((_, _)) + ); } diff --git a/sv-parser-parser/src/utils.rs b/sv-parser-parser/src/utils.rs index 3f38437..69da96b 100644 --- a/sv-parser-parser/src/utils.rs +++ b/sv-parser-parser/src/utils.rs @@ -295,10 +295,13 @@ pub(crate) fn symbol<'a>(t: &'a str) -> impl Fn(Span<'a>) -> IResult, S pub(crate) fn keyword<'a>(t: &'a str) -> impl Fn(Span<'a>) -> IResult, Keyword> { move |s: Span<'a>| { let (s, x) = map( - ws(terminated( - map(tag(t.clone()), |x: Span| into_locate(x)), - peek(none_of(AZ09_)), - )), + ws(alt(( + all_consuming(map(tag(t.clone()), |x: Span| into_locate(x))), + terminated( + map(tag(t.clone()), |x: Span| into_locate(x)), + peek(none_of(AZ09_)), + ), + ))), |x| Keyword { nodes: x }, )(s)?; Ok((s, x)) @@ -311,10 +314,13 @@ pub(crate) fn keyword<'a>(t: &'a str) -> impl Fn(Span<'a>) -> IResult, let (depth, s) = nom_tracable::forward_trace(s, &format!("keyword(\"{}\")", t)); let body = || { let (s, x) = map( - ws(terminated( - map(tag(t.clone()), |x: Span| into_locate(x)), - peek(none_of(AZ09_)), - )), + ws(alt(( + all_consuming(map(tag(t.clone()), |x: Span| into_locate(x))), + terminated( + map(tag(t.clone()), |x: Span| into_locate(x)), + peek(none_of(AZ09_)), + ), + ))), |x| Keyword { nodes: x }, )(s)?; Ok((s, x)) diff --git a/sv-parser-syntaxtree/src/expressions/primaries.rs b/sv-parser-syntaxtree/src/expressions/primaries.rs index 9aacc70..f11eb17 100644 --- a/sv-parser-syntaxtree/src/expressions/primaries.rs +++ b/sv-parser-syntaxtree/src/expressions/primaries.rs @@ -95,7 +95,7 @@ pub enum Primary { StreamingConcatenation(Box), SequenceMethodCall(Box), This(Box), - Dollar(Box), + Dollar(Box), Null(Box), }