diff --git a/src/attributes.rs b/src/attributes.rs index 43152f7..eb53621 100644 --- a/src/attributes.rs +++ b/src/attributes.rs @@ -48,21 +48,21 @@ mod tests { "{:?}", all_consuming(attribute_instance)("(* full_case, parallel_case *)") ), - "Ok((\"\", AttributeInstance { attr_spec: [AttrSpec { attr_name: Identifier { raw: [\"full_case\"] }, rvalue: None }, AttrSpec { attr_name: Identifier { raw: [\"parallel_case\"] }, rvalue: None }] }))" + "Ok((\"\", AttributeInstance { attr_spec: [AttrSpec { attr_name: Identifier { raw: \"full_case\" }, rvalue: None }, AttrSpec { attr_name: Identifier { raw: \"parallel_case\" }, rvalue: None }] }))" ); assert_eq!( format!( "{:?}", all_consuming(attribute_instance)("(* full_case=1 *)") ), - "Ok((\"\", AttributeInstance { attr_spec: [AttrSpec { attr_name: Identifier { raw: [\"full_case\"] }, rvalue: Some(Nullary(PrimaryLiteral(Number(IntegralNumber(UnsignedNumber(\"1\")))))) }] }))" + "Ok((\"\", AttributeInstance { attr_spec: [AttrSpec { attr_name: Identifier { raw: \"full_case\" }, rvalue: Some(Nullary(PrimaryLiteral(Number(IntegralNumber(UnsignedNumber(\"1\")))))) }] }))" ); assert_eq!( format!( "{:?}", all_consuming(attribute_instance)("(* full_case=1, parallel_case = 0 *)") ), - "Ok((\"\", AttributeInstance { attr_spec: [AttrSpec { attr_name: Identifier { raw: [\"full_case\"] }, rvalue: Some(Nullary(PrimaryLiteral(Number(IntegralNumber(UnsignedNumber(\"1\")))))) }, AttrSpec { attr_name: Identifier { raw: [\"parallel_case\"] }, rvalue: Some(Nullary(PrimaryLiteral(Number(IntegralNumber(UnsignedNumber(\"0\")))))) }] }))" + "Ok((\"\", AttributeInstance { attr_spec: [AttrSpec { attr_name: Identifier { raw: \"full_case\" }, rvalue: Some(Nullary(PrimaryLiteral(Number(IntegralNumber(UnsignedNumber(\"1\")))))) }, AttrSpec { attr_name: Identifier { raw: \"parallel_case\" }, rvalue: Some(Nullary(PrimaryLiteral(Number(IntegralNumber(UnsignedNumber(\"0\")))))) }] }))" ); } } diff --git a/src/identifiers.rs b/src/identifiers.rs index 15bde82..3a9ef69 100644 --- a/src/identifiers.rs +++ b/src/identifiers.rs @@ -16,7 +16,7 @@ const AZ09_DOLLAR: &str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0 #[derive(Debug)] pub struct Identifier<'a> { - pub raw: Vec<&'a str>, + pub raw: &'a str, } #[derive(Debug)] @@ -78,7 +78,11 @@ pub fn bin_identifier(s: &str) -> IResult<&str, Identifier> { pub fn c_identifier(s: &str) -> IResult<&str, Identifier> { let (s, x) = is_a(AZ_)(s)?; let (s, y) = opt(is_a(AZ09_))(s)?; - let raw = if let Some(y) = y { vec![x, y] } else { vec![x] }; + let raw = if let Some(y) = y { + str_concat::concat(x, y).unwrap() + } else { + x + }; Ok((s, Identifier { raw })) } @@ -141,7 +145,12 @@ pub fn enum_identifier(s: &str) -> IResult<&str, Identifier> { pub fn escaped_identifier(s: &str) -> IResult<&str, Identifier> { let (s, x) = tag("\\")(s)?; let (s, y) = is_not(" \t\r\n")(s)?; - Ok((s, Identifier { raw: vec![x, y] })) + Ok(( + s, + Identifier { + raw: str_concat::concat(x, y).unwrap(), + }, + )) } pub fn formal_identifier(s: &str) -> IResult<&str, Identifier> { @@ -201,7 +210,7 @@ pub fn hierarchical_identifier(s: &str) -> IResult<&str, HierarchicalIdentifier> hierarchy.insert( 0, Hierarchy { - identifier: Identifier { raw: vec![x] }, + identifier: Identifier { raw: x }, constant_bit_select: None, }, ); @@ -307,10 +316,7 @@ pub fn package_identifier(s: &str) -> IResult<&str, Identifier> { pub fn package_scope(s: &str) -> IResult<&str, Scope> { let (s, x) = alt(( terminated(package_identifier, sp(tag("::"))), - terminated( - map(tag("$unit"), |x| Identifier { raw: vec![x] }), - sp(tag("::")), - ), + terminated(map(tag("$unit"), |x| Identifier { raw: x }), sp(tag("::"))), ))(s)?; Ok((s, Scope::PackageScope(x))) } @@ -462,7 +468,11 @@ pub fn signal_identifier(s: &str) -> IResult<&str, Identifier> { pub fn simple_identifier(s: &str) -> IResult<&str, Identifier> { let (s, x) = is_a(AZ_)(s)?; let (s, y) = opt(is_a(AZ09_DOLLAR))(s)?; - let raw = if let Some(y) = y { vec![x, y] } else { vec![x] }; + let raw = if let Some(y) = y { + str_concat::concat(x, y).unwrap() + } else { + x + }; Ok((s, Identifier { raw })) } @@ -473,7 +483,12 @@ pub fn specparam_identifier(s: &str) -> IResult<&str, Identifier> { pub fn system_tf_identifier(s: &str) -> IResult<&str, Identifier> { let (s, x) = tag("$")(s)?; let (s, y) = is_a(AZ09_DOLLAR)(s)?; - Ok((s, Identifier { raw: vec![x, y] })) + Ok(( + s, + Identifier { + raw: str_concat::concat(x, y).unwrap(), + }, + )) } pub fn task_identifier(s: &str) -> IResult<&str, Identifier> { @@ -514,27 +529,27 @@ mod tests { fn test() { assert_eq!( format!("{:?}", all_consuming(identifier)("shiftreg_a")), - "Ok((\"\", Identifier { raw: [\"shiftreg_a\"] }))" + "Ok((\"\", Identifier { raw: \"shiftreg_a\" }))" ); assert_eq!( format!("{:?}", all_consuming(identifier)("_bus3")), - "Ok((\"\", Identifier { raw: [\"_bus\", \"3\"] }))" + "Ok((\"\", Identifier { raw: \"_bus3\" }))" ); assert_eq!( format!("{:?}", all_consuming(identifier)("n$657")), - "Ok((\"\", Identifier { raw: [\"n\", \"$657\"] }))" + "Ok((\"\", Identifier { raw: \"n$657\" }))" ); assert_eq!( format!("{:?}", all_consuming(identifier)("\\busa+index")), - "Ok((\"\", Identifier { raw: [\"\\\\\", \"busa+index\"] }))" + "Ok((\"\", Identifier { raw: \"\\\\busa+index\" }))" ); assert_eq!( format!("{:?}", all_consuming(identifier)("\\-clock")), - "Ok((\"\", Identifier { raw: [\"\\\\\", \"-clock\"] }))" + "Ok((\"\", Identifier { raw: \"\\\\-clock\" }))" ); assert_eq!( format!("{:?}", all_consuming(system_tf_identifier)("$display")), - "Ok((\"\", Identifier { raw: [\"$\", \"display\"] }))" + "Ok((\"\", Identifier { raw: \"$display\" }))" ); } } diff --git a/src/lvalues.rs b/src/lvalues.rs index 0a6a7aa..617f8fc 100644 --- a/src/lvalues.rs +++ b/src/lvalues.rs @@ -173,43 +173,43 @@ mod tests { fn test() { assert_eq!( format!("{:?}", all_consuming(net_lvalue)("a")), - "Ok((\"\", Identifier(NetLvalueIdentifier { identifier: ScopedIdentifier { scope: None, identifier: HierarchicalIdentifier { hierarchy: [], identifier: Identifier { raw: [\"a\"] } } }, select: ConstantSelect { member: None, bit_select: [], part_select_range: None } })))" + "Ok((\"\", Identifier(NetLvalueIdentifier { identifier: ScopedIdentifier { scope: None, identifier: HierarchicalIdentifier { hierarchy: [], identifier: Identifier { raw: \"a\" } } }, select: ConstantSelect { member: None, bit_select: [], part_select_range: None } })))" ); assert_eq!( format!("{:?}", all_consuming(net_lvalue)("a[1][2]")), - "Ok((\"\", Identifier(NetLvalueIdentifier { identifier: ScopedIdentifier { scope: None, identifier: HierarchicalIdentifier { hierarchy: [], identifier: Identifier { raw: [\"a\"] } } }, select: ConstantSelect { member: None, bit_select: [Nullary(PrimaryLiteral(Number(IntegralNumber(UnsignedNumber(\"1\"))))), Nullary(PrimaryLiteral(Number(IntegralNumber(UnsignedNumber(\"2\")))))], part_select_range: None } })))" + "Ok((\"\", Identifier(NetLvalueIdentifier { identifier: ScopedIdentifier { scope: None, identifier: HierarchicalIdentifier { hierarchy: [], identifier: Identifier { raw: \"a\" } } }, select: ConstantSelect { member: None, bit_select: [Nullary(PrimaryLiteral(Number(IntegralNumber(UnsignedNumber(\"1\"))))), Nullary(PrimaryLiteral(Number(IntegralNumber(UnsignedNumber(\"2\")))))], part_select_range: None } })))" ); assert_eq!( format!("{:?}", all_consuming(net_lvalue)("a[1][10:5]")), - "Ok((\"\", Identifier(NetLvalueIdentifier { identifier: ScopedIdentifier { scope: None, identifier: HierarchicalIdentifier { hierarchy: [], identifier: Identifier { raw: [\"a\"] } } }, select: ConstantSelect { member: None, bit_select: [Nullary(PrimaryLiteral(Number(IntegralNumber(UnsignedNumber(\"1\")))))], part_select_range: Some(Range((Nullary(PrimaryLiteral(Number(IntegralNumber(UnsignedNumber(\"10\"))))), Nullary(PrimaryLiteral(Number(IntegralNumber(UnsignedNumber(\"5\")))))))) } })))" + "Ok((\"\", Identifier(NetLvalueIdentifier { identifier: ScopedIdentifier { scope: None, identifier: HierarchicalIdentifier { hierarchy: [], identifier: Identifier { raw: \"a\" } } }, select: ConstantSelect { member: None, bit_select: [Nullary(PrimaryLiteral(Number(IntegralNumber(UnsignedNumber(\"1\")))))], part_select_range: Some(Range((Nullary(PrimaryLiteral(Number(IntegralNumber(UnsignedNumber(\"10\"))))), Nullary(PrimaryLiteral(Number(IntegralNumber(UnsignedNumber(\"5\")))))))) } })))" ); assert_eq!( format!("{:?}", all_consuming(net_lvalue)("{a, b[1], c}")), - "Ok((\"\", Lvalue([Identifier(NetLvalueIdentifier { identifier: ScopedIdentifier { scope: None, identifier: HierarchicalIdentifier { hierarchy: [], identifier: Identifier { raw: [\"a\"] } } }, select: ConstantSelect { member: None, bit_select: [], part_select_range: None } }), Identifier(NetLvalueIdentifier { identifier: ScopedIdentifier { scope: None, identifier: HierarchicalIdentifier { hierarchy: [], identifier: Identifier { raw: [\"b\"] } } }, select: ConstantSelect { member: None, bit_select: [Nullary(PrimaryLiteral(Number(IntegralNumber(UnsignedNumber(\"1\")))))], part_select_range: None } }), Identifier(NetLvalueIdentifier { identifier: ScopedIdentifier { scope: None, identifier: HierarchicalIdentifier { hierarchy: [], identifier: Identifier { raw: [\"c\"] } } }, select: ConstantSelect { member: None, bit_select: [], part_select_range: None } })])))" + "Ok((\"\", Lvalue([Identifier(NetLvalueIdentifier { identifier: ScopedIdentifier { scope: None, identifier: HierarchicalIdentifier { hierarchy: [], identifier: Identifier { raw: \"a\" } } }, select: ConstantSelect { member: None, bit_select: [], part_select_range: None } }), Identifier(NetLvalueIdentifier { identifier: ScopedIdentifier { scope: None, identifier: HierarchicalIdentifier { hierarchy: [], identifier: Identifier { raw: \"b\" } } }, select: ConstantSelect { member: None, bit_select: [Nullary(PrimaryLiteral(Number(IntegralNumber(UnsignedNumber(\"1\")))))], part_select_range: None } }), Identifier(NetLvalueIdentifier { identifier: ScopedIdentifier { scope: None, identifier: HierarchicalIdentifier { hierarchy: [], identifier: Identifier { raw: \"c\" } } }, select: ConstantSelect { member: None, bit_select: [], part_select_range: None } })])))" ); assert_eq!( format!("{:?}", all_consuming(variable_lvalue)("a")), - "Ok((\"\", Identifier(VariableLvalueIdentifier { scope: None, identifier: HierarchicalIdentifier { hierarchy: [], identifier: Identifier { raw: [\"a\"] } }, select: Select { member: None, bit_select: [], part_select_range: None } })))" + "Ok((\"\", Identifier(VariableLvalueIdentifier { scope: None, identifier: HierarchicalIdentifier { hierarchy: [], identifier: Identifier { raw: \"a\" } }, select: Select { member: None, bit_select: [], part_select_range: None } })))" ); assert_eq!( format!("{:?}", all_consuming(variable_lvalue)("a[1][2]")), - "Ok((\"\", Identifier(VariableLvalueIdentifier { scope: None, identifier: HierarchicalIdentifier { hierarchy: [], identifier: Identifier { raw: [\"a\"] } }, select: Select { member: None, bit_select: [Nullary(PrimaryLiteral(Number(IntegralNumber(UnsignedNumber(\"1\"))))), Nullary(PrimaryLiteral(Number(IntegralNumber(UnsignedNumber(\"2\")))))], part_select_range: None } })))" + "Ok((\"\", Identifier(VariableLvalueIdentifier { scope: None, identifier: HierarchicalIdentifier { hierarchy: [], identifier: Identifier { raw: \"a\" } }, select: Select { member: None, bit_select: [Nullary(PrimaryLiteral(Number(IntegralNumber(UnsignedNumber(\"1\"))))), Nullary(PrimaryLiteral(Number(IntegralNumber(UnsignedNumber(\"2\")))))], part_select_range: None } })))" ); assert_eq!( format!("{:?}", all_consuming(variable_lvalue)("a[1][10:5]")), - "Ok((\"\", Identifier(VariableLvalueIdentifier { scope: None, identifier: HierarchicalIdentifier { hierarchy: [], identifier: Identifier { raw: [\"a\"] } }, select: Select { member: None, bit_select: [Nullary(PrimaryLiteral(Number(IntegralNumber(UnsignedNumber(\"1\")))))], part_select_range: Some(Range((Nullary(PrimaryLiteral(Number(IntegralNumber(UnsignedNumber(\"10\"))))), Nullary(PrimaryLiteral(Number(IntegralNumber(UnsignedNumber(\"5\")))))))) } })))" + "Ok((\"\", Identifier(VariableLvalueIdentifier { scope: None, identifier: HierarchicalIdentifier { hierarchy: [], identifier: Identifier { raw: \"a\" } }, select: Select { member: None, bit_select: [Nullary(PrimaryLiteral(Number(IntegralNumber(UnsignedNumber(\"1\")))))], part_select_range: Some(Range((Nullary(PrimaryLiteral(Number(IntegralNumber(UnsignedNumber(\"10\"))))), Nullary(PrimaryLiteral(Number(IntegralNumber(UnsignedNumber(\"5\")))))))) } })))" ); assert_eq!( format!("{:?}", all_consuming(variable_lvalue)("{a, b[1], c}")), - "Ok((\"\", Lvalue([Identifier(VariableLvalueIdentifier { scope: None, identifier: HierarchicalIdentifier { hierarchy: [], identifier: Identifier { raw: [\"a\"] } }, select: Select { member: None, bit_select: [], part_select_range: None } }), Identifier(VariableLvalueIdentifier { scope: None, identifier: HierarchicalIdentifier { hierarchy: [], identifier: Identifier { raw: [\"b\"] } }, select: Select { member: None, bit_select: [Nullary(PrimaryLiteral(Number(IntegralNumber(UnsignedNumber(\"1\")))))], part_select_range: None } }), Identifier(VariableLvalueIdentifier { scope: None, identifier: HierarchicalIdentifier { hierarchy: [], identifier: Identifier { raw: [\"c\"] } }, select: Select { member: None, bit_select: [], part_select_range: None } })])))" + "Ok((\"\", Lvalue([Identifier(VariableLvalueIdentifier { scope: None, identifier: HierarchicalIdentifier { hierarchy: [], identifier: Identifier { raw: \"a\" } }, select: Select { member: None, bit_select: [], part_select_range: None } }), Identifier(VariableLvalueIdentifier { scope: None, identifier: HierarchicalIdentifier { hierarchy: [], identifier: Identifier { raw: \"b\" } }, select: Select { member: None, bit_select: [Nullary(PrimaryLiteral(Number(IntegralNumber(UnsignedNumber(\"1\")))))], part_select_range: None } }), Identifier(VariableLvalueIdentifier { scope: None, identifier: HierarchicalIdentifier { hierarchy: [], identifier: Identifier { raw: \"c\" } }, select: Select { member: None, bit_select: [], part_select_range: None } })])))" ); assert_eq!( format!("{:?}", all_consuming(nonrange_variable_lvalue)("a")), - "Ok((\"\", NonrangeVariableLvalue { scope: None, identifier: HierarchicalIdentifier { hierarchy: [], identifier: Identifier { raw: [\"a\"] } }, select: Select { member: None, bit_select: [], part_select_range: None } }))" + "Ok((\"\", NonrangeVariableLvalue { scope: None, identifier: HierarchicalIdentifier { hierarchy: [], identifier: Identifier { raw: \"a\" } }, select: Select { member: None, bit_select: [], part_select_range: None } }))" ); assert_eq!( format!("{:?}", all_consuming(nonrange_variable_lvalue)("a[1][2]")), - "Ok((\"\", NonrangeVariableLvalue { scope: None, identifier: HierarchicalIdentifier { hierarchy: [], identifier: Identifier { raw: [\"a\"] } }, select: Select { member: None, bit_select: [Nullary(PrimaryLiteral(Number(IntegralNumber(UnsignedNumber(\"1\"))))), Nullary(PrimaryLiteral(Number(IntegralNumber(UnsignedNumber(\"2\")))))], part_select_range: None } }))" + "Ok((\"\", NonrangeVariableLvalue { scope: None, identifier: HierarchicalIdentifier { hierarchy: [], identifier: Identifier { raw: \"a\" } }, select: Select { member: None, bit_select: [Nullary(PrimaryLiteral(Number(IntegralNumber(UnsignedNumber(\"1\"))))), Nullary(PrimaryLiteral(Number(IntegralNumber(UnsignedNumber(\"2\")))))], part_select_range: None } }))" ); } } diff --git a/src/primaries.rs b/src/primaries.rs index 732cee8..aabf677 100644 --- a/src/primaries.rs +++ b/src/primaries.rs @@ -643,7 +643,7 @@ mod tests { ); assert_eq!( format!("{:?}", all_consuming(primary)("\"aaa\"")), - "Ok((\"\", PrimaryLiteral(StringLiteral(StringLiteral { raw: [\"aaa\"] }))))" + "Ok((\"\", PrimaryLiteral(StringLiteral(StringLiteral { raw: \"aaa\" }))))" ); //assert_eq!( // format!("{:?}", all_consuming(primary)("this")), @@ -659,7 +659,7 @@ mod tests { //); assert_eq!( format!("{:?}", all_consuming(primary)("this . super.a")), - "Ok((\"\", Hierarchical(PrimaryHierarchical { qualifier: Some(ClassQualifier(ClassQualifier { local: false, scope: Some(ImplicitClassHandle(ThisSuper)) })), identifier: HierarchicalIdentifier { hierarchy: [], identifier: Identifier { raw: [\"a\"] } }, select: Select { member: None, bit_select: [], part_select_range: None } })))" + "Ok((\"\", Hierarchical(PrimaryHierarchical { qualifier: Some(ClassQualifier(ClassQualifier { local: false, scope: Some(ImplicitClassHandle(ThisSuper)) })), identifier: HierarchicalIdentifier { hierarchy: [], identifier: Identifier { raw: \"a\" } }, select: Select { member: None, bit_select: [], part_select_range: None } })))" ); assert_eq!( format!("{:?}", all_consuming(module_path_primary)("10")), diff --git a/src/strings.rs b/src/strings.rs index 21cccc3..6365206 100644 --- a/src/strings.rs +++ b/src/strings.rs @@ -8,7 +8,7 @@ use nom::IResult; #[derive(Debug)] pub struct StringLiteral<'a> { - pub raw: Vec<&'a str>, + pub raw: &'a str, } // ----------------------------------------------------------------------------- @@ -18,15 +18,29 @@ pub fn string_literal(s: &str) -> IResult<&str, StringLiteral> { let (s, x) = many1(pair(is_not("\\\""), opt(pair(tag("\\"), take(1usize)))))(s)?; let (s, _) = tag("\"")(s)?; - let mut raw = Vec::new(); + let mut raw = None; for (x, y) in x { - raw.push(x); + raw = if let Some(raw) = raw { + Some(str_concat::concat(raw, x).unwrap()) + } else { + Some(x) + }; if let Some((y, z)) = y { - raw.push(y); - raw.push(z); + raw = if let Some(raw) = raw { + Some(str_concat::concat(raw, y).unwrap()) + } else { + Some(y) + }; + raw = if let Some(raw) = raw { + Some(str_concat::concat(raw, z).unwrap()) + } else { + Some(z) + }; } } + let raw = raw.unwrap(); + Ok((s, StringLiteral { raw })) } @@ -40,15 +54,15 @@ mod tests { fn test() { assert_eq!( format!("{:?}", all_consuming(string_literal)("\"aaa aaaa\"")), - "Ok((\"\", StringLiteral { raw: [\"aaa aaaa\"] }))" + "Ok((\"\", StringLiteral { raw: \"aaa aaaa\" }))" ); assert_eq!( format!("{:?}", all_consuming(string_literal)(r#""aaa\" aaaa""#)), - "Ok((\"\", StringLiteral { raw: [\"aaa\", \"\\\\\", \"\\\"\", \" aaaa\"] }))" + "Ok((\"\", StringLiteral { raw: \"aaa\\\\\\\" aaaa\" }))" ); assert_eq!( format!("{:?}", all_consuming(string_literal)(r#""aaa\"""#)), - "Ok((\"\", StringLiteral { raw: [\"aaa\", \"\\\\\", \"\\\"\"] }))" + "Ok((\"\", StringLiteral { raw: \"aaa\\\\\\\"\" }))" ); } }