Add identifier
This commit is contained in:
parent
d6fffe250a
commit
d6f2fbabc2
538
src/identifier.rs
Normal file
538
src/identifier.rs
Normal file
@ -0,0 +1,538 @@
|
|||||||
|
use crate::util::*;
|
||||||
|
use nom::branch::*;
|
||||||
|
use nom::bytes::complete::*;
|
||||||
|
use nom::combinator::*;
|
||||||
|
use nom::multi::*;
|
||||||
|
use nom::sequence::*;
|
||||||
|
use nom::IResult;
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
const AZ_: &str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_";
|
||||||
|
const AZ09_: &str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
|
||||||
|
const AZ09_DOLLAR: &str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_$";
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Identifier<'a> {
|
||||||
|
pub raw: Vec<&'a str>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct ScopedIdentifier<'a> {
|
||||||
|
pub scope: Option<Scope<'a>>,
|
||||||
|
pub identifier: HierarchicalIdentifier<'a>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum Scope<'a> {
|
||||||
|
LocalScope,
|
||||||
|
PackageScope(Identifier<'a>),
|
||||||
|
ClassScope,
|
||||||
|
ImplicitClassHandle,
|
||||||
|
GenerateBlockScope(Vec<GenerateBlockScope<'a>>),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct GenerateBlockScope<'a> {
|
||||||
|
pub identifier: Identifier<'a>,
|
||||||
|
pub constant_expression: Option<ConstantExpression<'a>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct HierarchicalIdentifier<'a> {
|
||||||
|
pub hierarchy: Vec<Hierarchy<'a>>,
|
||||||
|
pub identifier: Identifier<'a>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> From<Identifier<'a>> for HierarchicalIdentifier<'a> {
|
||||||
|
fn from(x: Identifier<'a>) -> Self {
|
||||||
|
HierarchicalIdentifier {
|
||||||
|
hierarchy: vec![],
|
||||||
|
identifier: x,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Hierarchy<'a> {
|
||||||
|
pub identifier: Identifier<'a>,
|
||||||
|
pub constant_bit_select: Option<ConstantBitSelect<'a>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
pub fn array_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn block_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bin_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
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] };
|
||||||
|
Ok((s, Identifier { raw }))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn cell_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn checker_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn class_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn class_variable_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
variable_identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clocking_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn config_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn const_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn constraint_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn covergroup_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn covergroup_variable_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
variable_identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn cover_point_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn cross_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn dynamic_array_variable_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
variable_identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn enum_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
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] }))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn formal_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn formal_port_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn function_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn generate_block_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn genvar_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn hierarchical_array_identifier(s: &str) -> IResult<&str, HierarchicalIdentifier> {
|
||||||
|
hierarchical_identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn hierarchical_block_identifier(s: &str) -> IResult<&str, HierarchicalIdentifier> {
|
||||||
|
hierarchical_identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn hierarchical_event_identifier(s: &str) -> IResult<&str, HierarchicalIdentifier> {
|
||||||
|
hierarchical_identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn hierarchy(s: &str) -> IResult<&str, Hierarchy> {
|
||||||
|
let (s, identifier) = identifier(s)?;
|
||||||
|
let (s, constant_bit_select) = sp(constant_bit_select)(s)?;
|
||||||
|
let (s, _) = sp(tag("."))(s)?;
|
||||||
|
|
||||||
|
let constant_bit_select = Some(constant_bit_select);
|
||||||
|
|
||||||
|
Ok((
|
||||||
|
s,
|
||||||
|
Hierarchy {
|
||||||
|
identifier,
|
||||||
|
constant_bit_select,
|
||||||
|
},
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn hierarchical_identifier(s: &str) -> IResult<&str, HierarchicalIdentifier> {
|
||||||
|
let (s, x) = opt(terminated(tag("$root"), sp(tag("."))))(s)?;
|
||||||
|
let (s, mut hierarchy) = many0(hierarchy)(s)?;
|
||||||
|
let (s, identifier) = sp(identifier)(s)?;
|
||||||
|
|
||||||
|
if let Some(x) = x {
|
||||||
|
hierarchy.insert(
|
||||||
|
0,
|
||||||
|
Hierarchy {
|
||||||
|
identifier: Identifier { raw: vec![x] },
|
||||||
|
constant_bit_select: None,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok((
|
||||||
|
s,
|
||||||
|
HierarchicalIdentifier {
|
||||||
|
hierarchy,
|
||||||
|
identifier,
|
||||||
|
},
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn hierarchical_net_identifier(s: &str) -> IResult<&str, HierarchicalIdentifier> {
|
||||||
|
hierarchical_identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn hierarchical_parameter_identifier(s: &str) -> IResult<&str, HierarchicalIdentifier> {
|
||||||
|
hierarchical_identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn hierarchical_property_identifier(s: &str) -> IResult<&str, HierarchicalIdentifier> {
|
||||||
|
hierarchical_identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn hierarchical_sequence_identifier(s: &str) -> IResult<&str, HierarchicalIdentifier> {
|
||||||
|
hierarchical_identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn hierarchical_task_identifier(s: &str) -> IResult<&str, HierarchicalIdentifier> {
|
||||||
|
hierarchical_identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn hierarchical_tf_identifier(s: &str) -> IResult<&str, HierarchicalIdentifier> {
|
||||||
|
hierarchical_identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn hierarchical_variable_identifier(s: &str) -> IResult<&str, HierarchicalIdentifier> {
|
||||||
|
hierarchical_identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
alt((escaped_identifier, simple_identifier))(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn index_variable_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn interface_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn interface_instance_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn inout_port_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn input_port_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn instance_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn library_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn member_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn method_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn modport_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn module_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn net_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn output_port_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn package_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
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("::")),
|
||||||
|
),
|
||||||
|
))(s)?;
|
||||||
|
Ok((s, Scope::PackageScope(x)))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parameter_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn port_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn production_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn program_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn property_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ps_class_identifier(s: &str) -> IResult<&str, ScopedIdentifier> {
|
||||||
|
let (s, scope) = opt(package_scope)(s)?;
|
||||||
|
let (s, identifier) = sp(class_identifier)(s)?;
|
||||||
|
let identifier = identifier.into();
|
||||||
|
Ok((s, ScopedIdentifier { scope, identifier }))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ps_covergroup_identifier(s: &str) -> IResult<&str, ScopedIdentifier> {
|
||||||
|
let (s, scope) = opt(package_scope)(s)?;
|
||||||
|
let (s, identifier) = sp(covergroup_identifier)(s)?;
|
||||||
|
let identifier = identifier.into();
|
||||||
|
Ok((s, ScopedIdentifier { scope, identifier }))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ps_checker_identifier(s: &str) -> IResult<&str, ScopedIdentifier> {
|
||||||
|
let (s, scope) = opt(package_scope)(s)?;
|
||||||
|
let (s, identifier) = sp(checker_identifier)(s)?;
|
||||||
|
let identifier = identifier.into();
|
||||||
|
Ok((s, ScopedIdentifier { scope, identifier }))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ps_identifier(s: &str) -> IResult<&str, ScopedIdentifier> {
|
||||||
|
let (s, scope) = opt(package_scope)(s)?;
|
||||||
|
let (s, identifier) = sp(identifier)(s)?;
|
||||||
|
let identifier = identifier.into();
|
||||||
|
Ok((s, ScopedIdentifier { scope, identifier }))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ps_or_hierarchical_array_identifier(s: &str) -> IResult<&str, ScopedIdentifier> {
|
||||||
|
let (s, scope) = opt(alt((
|
||||||
|
terminated(implicit_class_handle, sp(tag("."))),
|
||||||
|
class_scope,
|
||||||
|
package_scope,
|
||||||
|
)))(s)?;
|
||||||
|
let (s, identifier) = sp(hierarchical_array_identifier)(s)?;
|
||||||
|
Ok((s, ScopedIdentifier { scope, identifier }))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ps_or_hierarchical_net_identifier(s: &str) -> IResult<&str, ScopedIdentifier> {
|
||||||
|
let (s, scope) = opt(package_scope)(s)?;
|
||||||
|
let (s, identifier) = alt((
|
||||||
|
map(sp(net_identifier), |x| x.into()),
|
||||||
|
sp(hierarchical_net_identifier),
|
||||||
|
))(s)?;
|
||||||
|
Ok((s, ScopedIdentifier { scope, identifier }))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ps_or_hierarchical_property_identifier(s: &str) -> IResult<&str, ScopedIdentifier> {
|
||||||
|
let (s, scope) = opt(package_scope)(s)?;
|
||||||
|
let (s, identifier) = alt((
|
||||||
|
map(sp(property_identifier), |x| x.into()),
|
||||||
|
sp(hierarchical_property_identifier),
|
||||||
|
))(s)?;
|
||||||
|
Ok((s, ScopedIdentifier { scope, identifier }))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ps_or_hierarchical_sequence_identifier(s: &str) -> IResult<&str, ScopedIdentifier> {
|
||||||
|
let (s, scope) = opt(package_scope)(s)?;
|
||||||
|
let (s, identifier) = alt((
|
||||||
|
map(sp(sequence_identifier), |x| x.into()),
|
||||||
|
sp(hierarchical_sequence_identifier),
|
||||||
|
))(s)?;
|
||||||
|
Ok((s, ScopedIdentifier { scope, identifier }))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ps_or_hierarchical_tf_identifier(s: &str) -> IResult<&str, ScopedIdentifier> {
|
||||||
|
let (s, scope) = opt(package_scope)(s)?;
|
||||||
|
let (s, identifier) = alt((
|
||||||
|
map(sp(tf_identifier), |x| x.into()),
|
||||||
|
sp(hierarchical_tf_identifier),
|
||||||
|
))(s)?;
|
||||||
|
Ok((s, ScopedIdentifier { scope, identifier }))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ps_parameter_identifier(s: &str) -> IResult<&str, ScopedIdentifier> {
|
||||||
|
let (s, scope) = opt(alt((package_scope, class_scope, generate_block_scope)))(s)?;
|
||||||
|
let (s, identifier) = sp(parameter_identifier)(s)?;
|
||||||
|
let identifier = identifier.into();
|
||||||
|
Ok((s, ScopedIdentifier { scope, identifier }))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn generate_block_scope(s: &str) -> IResult<&str, Scope> {
|
||||||
|
let (s, x) = many0(tuple((
|
||||||
|
sp(generate_block_identifier),
|
||||||
|
opt(delimited(
|
||||||
|
sp(tag("[")),
|
||||||
|
sp(constant_expression),
|
||||||
|
sp(tag("]")),
|
||||||
|
)),
|
||||||
|
sp(tag(".")),
|
||||||
|
)))(s)?;
|
||||||
|
|
||||||
|
let mut ret = Vec::new();
|
||||||
|
for (identifier, constant_expression, _) in x {
|
||||||
|
ret.push(GenerateBlockScope {
|
||||||
|
identifier,
|
||||||
|
constant_expression,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok((s, Scope::GenerateBlockScope(ret)))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ps_type_identifier(s: &str) -> IResult<&str, ScopedIdentifier> {
|
||||||
|
let (s, scope) = opt(alt((
|
||||||
|
map(terminated(tag("local"), sp(tag("::"))), |_| {
|
||||||
|
Scope::LocalScope
|
||||||
|
}),
|
||||||
|
package_scope,
|
||||||
|
class_scope,
|
||||||
|
)))(s)?;
|
||||||
|
let (s, identifier) = sp(type_identifier)(s)?;
|
||||||
|
let identifier = identifier.into();
|
||||||
|
Ok((s, ScopedIdentifier { scope, identifier }))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn sequence_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn signal_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
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] };
|
||||||
|
Ok((s, Identifier { raw }))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn specparam_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
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] }))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn task_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn tf_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn terminal_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn topmodule_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn type_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn udp_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn variable_identifier(s: &str) -> IResult<&str, Identifier> {
|
||||||
|
identifier(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test() {
|
||||||
|
assert_eq!(
|
||||||
|
format!("{:?}", all_consuming(identifier)("shiftreg_a")),
|
||||||
|
"Ok((\"\", Identifier { raw: [\"shiftreg_a\"] }))"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
format!("{:?}", all_consuming(identifier)("_bus3")),
|
||||||
|
"Ok((\"\", Identifier { raw: [\"_bus\", \"3\"] }))"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
format!("{:?}", all_consuming(identifier)("n$657")),
|
||||||
|
"Ok((\"\", Identifier { raw: [\"n\", \"$657\"] }))"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
format!("{:?}", all_consuming(identifier)("\\busa+index")),
|
||||||
|
"Ok((\"\", Identifier { raw: [\"\\\\\", \"busa+index\"] }))"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
format!("{:?}", all_consuming(identifier)("\\-clock")),
|
||||||
|
"Ok((\"\", Identifier { raw: [\"\\\\\", \"-clock\"] }))"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
format!("{:?}", all_consuming(system_tf_identifier)("$display")),
|
||||||
|
"Ok((\"\", Identifier { raw: [\"$\", \"display\"] }))"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -1 +1,3 @@
|
|||||||
|
pub mod identifier;
|
||||||
pub mod number;
|
pub mod number;
|
||||||
|
pub mod util;
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use crate::util::*;
|
||||||
use nom::branch::*;
|
use nom::branch::*;
|
||||||
use nom::bytes::complete::*;
|
use nom::bytes::complete::*;
|
||||||
use nom::character::complete::*;
|
use nom::character::complete::*;
|
||||||
@ -90,12 +91,10 @@ pub fn integral_number(s: &str) -> IResult<&str, Number> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn decimal_number(s: &str) -> IResult<&str, IntegralNumber> {
|
pub fn decimal_number(s: &str) -> IResult<&str, IntegralNumber> {
|
||||||
let (s, (size, _, decimal_base, _, decimal_value)) = tuple((
|
let (s, (size, decimal_base, decimal_value)) = tuple((
|
||||||
opt(size),
|
opt(size),
|
||||||
space0,
|
sp(decimal_base),
|
||||||
decimal_base,
|
sp(alt((unsigned_number, x_number, z_number))),
|
||||||
space0,
|
|
||||||
alt((unsigned_number, x_number, z_number)),
|
|
||||||
))(s)?;
|
))(s)?;
|
||||||
Ok((
|
Ok((
|
||||||
s,
|
s,
|
||||||
@ -113,8 +112,8 @@ pub fn integral_unsigned_number(s: &str) -> IResult<&str, IntegralNumber> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn binary_number(s: &str) -> IResult<&str, IntegralNumber> {
|
pub fn binary_number(s: &str) -> IResult<&str, IntegralNumber> {
|
||||||
let (s, (size, _, binary_base, _, binary_value)) =
|
let (s, (size, binary_base, binary_value)) =
|
||||||
tuple((opt(size), space0, binary_base, space0, binary_value))(s)?;
|
tuple((opt(size), sp(binary_base), sp(binary_value)))(s)?;
|
||||||
Ok((
|
Ok((
|
||||||
s,
|
s,
|
||||||
IntegralNumber::BinaryNumber(BinaryNumber {
|
IntegralNumber::BinaryNumber(BinaryNumber {
|
||||||
@ -126,8 +125,8 @@ pub fn binary_number(s: &str) -> IResult<&str, IntegralNumber> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn octal_number(s: &str) -> IResult<&str, IntegralNumber> {
|
pub fn octal_number(s: &str) -> IResult<&str, IntegralNumber> {
|
||||||
let (s, (size, _, octal_base, _, octal_value)) =
|
let (s, (size, octal_base, octal_value)) =
|
||||||
tuple((opt(size), space0, octal_base, space0, octal_value))(s)?;
|
tuple((opt(size), sp(octal_base), sp(octal_value)))(s)?;
|
||||||
Ok((
|
Ok((
|
||||||
s,
|
s,
|
||||||
IntegralNumber::OctalNumber(OctalNumber {
|
IntegralNumber::OctalNumber(OctalNumber {
|
||||||
@ -139,8 +138,7 @@ pub fn octal_number(s: &str) -> IResult<&str, IntegralNumber> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn hex_number(s: &str) -> IResult<&str, IntegralNumber> {
|
pub fn hex_number(s: &str) -> IResult<&str, IntegralNumber> {
|
||||||
let (s, (size, _, hex_base, _, hex_value)) =
|
let (s, (size, hex_base, hex_value)) = tuple((opt(size), sp(hex_base), sp(hex_value)))(s)?;
|
||||||
tuple((opt(size), space0, hex_base, space0, hex_value))(s)?;
|
|
||||||
Ok((
|
Ok((
|
||||||
s,
|
s,
|
||||||
IntegralNumber::HexNumber(HexNumber {
|
IntegralNumber::HexNumber(HexNumber {
|
||||||
@ -243,51 +241,23 @@ pub fn hex_value(s: &str) -> IResult<&str, Vec<&str>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn decimal_base(s: &str) -> IResult<&str, &str> {
|
pub fn decimal_base(s: &str) -> IResult<&str, &str> {
|
||||||
alt((
|
alt((tag_no_case("'d"), tag_no_case("'sd")))(s)
|
||||||
tag("'d"),
|
|
||||||
tag("'sd"),
|
|
||||||
tag("'Sd"),
|
|
||||||
tag("'D"),
|
|
||||||
tag("'sD"),
|
|
||||||
tag("'SD"),
|
|
||||||
))(s)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn binary_base(s: &str) -> IResult<&str, &str> {
|
pub fn binary_base(s: &str) -> IResult<&str, &str> {
|
||||||
alt((
|
alt((tag_no_case("'b"), tag_no_case("'sb")))(s)
|
||||||
tag("'b"),
|
|
||||||
tag("'sb"),
|
|
||||||
tag("'Sb"),
|
|
||||||
tag("'B"),
|
|
||||||
tag("'sB"),
|
|
||||||
tag("'SB"),
|
|
||||||
))(s)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn octal_base(s: &str) -> IResult<&str, &str> {
|
pub fn octal_base(s: &str) -> IResult<&str, &str> {
|
||||||
alt((
|
alt((tag_no_case("'o"), tag_no_case("'so")))(s)
|
||||||
tag("'o"),
|
|
||||||
tag("'so"),
|
|
||||||
tag("'So"),
|
|
||||||
tag("'O"),
|
|
||||||
tag("'sO"),
|
|
||||||
tag("'SO"),
|
|
||||||
))(s)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hex_base(s: &str) -> IResult<&str, &str> {
|
pub fn hex_base(s: &str) -> IResult<&str, &str> {
|
||||||
alt((
|
alt((tag_no_case("'h"), tag_no_case("'sh")))(s)
|
||||||
tag("'h"),
|
|
||||||
tag("'sh"),
|
|
||||||
tag("'Sh"),
|
|
||||||
tag("'H"),
|
|
||||||
tag("'sH"),
|
|
||||||
tag("'SH"),
|
|
||||||
))(s)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn x_number(s: &str) -> IResult<&str, Vec<&str>> {
|
pub fn x_number(s: &str) -> IResult<&str, Vec<&str>> {
|
||||||
let (s, x) = alt((tag("x"), tag("X")))(s)?;
|
let (s, x) = tag_no_case("x")(s)?;
|
||||||
fold_many0(
|
fold_many0(
|
||||||
alt((tag("_"), is_a("_"))),
|
alt((tag("_"), is_a("_"))),
|
||||||
vec![x],
|
vec![x],
|
||||||
@ -299,7 +269,7 @@ pub fn x_number(s: &str) -> IResult<&str, Vec<&str>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn z_number(s: &str) -> IResult<&str, Vec<&str>> {
|
pub fn z_number(s: &str) -> IResult<&str, Vec<&str>> {
|
||||||
let (s, x) = alt((tag("z"), tag("Z"), tag("?")))(s)?;
|
let (s, x) = alt((tag_no_case("z"), tag("?")))(s)?;
|
||||||
fold_many0(
|
fold_many0(
|
||||||
alt((tag("_"), is_a("_"))),
|
alt((tag("_"), is_a("_"))),
|
||||||
vec![x],
|
vec![x],
|
||||||
|
44
src/util.rs
Normal file
44
src/util.rs
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
use crate::identifier::*;
|
||||||
|
use nom::character::complete::*;
|
||||||
|
use nom::IResult;
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
pub fn sp<'a, O, F>(f: F) -> impl Fn(&'a str) -> IResult<&'a str, O>
|
||||||
|
where
|
||||||
|
F: Fn(&'a str) -> IResult<&'a str, O>,
|
||||||
|
{
|
||||||
|
move |s: &'a str| {
|
||||||
|
let (s, _) = space0(s)?;
|
||||||
|
let (s, x) = f(s)?;
|
||||||
|
Ok((s, x))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct ConstantBitSelect<'a> {
|
||||||
|
pub raw: Vec<&'a str>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct ConstantExpression<'a> {
|
||||||
|
pub raw: Vec<&'a str>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn implicit_class_handle(s: &str) -> IResult<&str, Scope> {
|
||||||
|
Ok((s, Scope::ImplicitClassHandle))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn class_scope(s: &str) -> IResult<&str, Scope> {
|
||||||
|
Ok((s, Scope::ClassScope))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn constant_bit_select(s: &str) -> IResult<&str, ConstantBitSelect> {
|
||||||
|
Ok((s, ConstantBitSelect { raw: vec![] }))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn constant_expression(s: &str) -> IResult<&str, ConstantExpression> {
|
||||||
|
Ok((s, ConstantExpression { raw: vec![] }))
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user