From ade1ca229a3909459bc21a024323f5a2409efeb4 Mon Sep 17 00:00:00 2001 From: dalance Date: Fri, 28 Jun 2019 15:43:05 +0900 Subject: [PATCH] Add attributes/operators --- src/attributes.rs | 60 +++++++++++++++++++++ src/lib.rs | 2 + src/operators.rs | 135 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 197 insertions(+) create mode 100644 src/attributes.rs create mode 100644 src/operators.rs diff --git a/src/attributes.rs b/src/attributes.rs new file mode 100644 index 0000000..3106bfb --- /dev/null +++ b/src/attributes.rs @@ -0,0 +1,60 @@ +use crate::identifiers::*; +use crate::util::*; +use nom::bytes::complete::*; +use nom::combinator::*; +use nom::multi::*; +use nom::sequence::*; +use nom::IResult; + +// ----------------------------------------------------------------------------- + +#[derive(Debug)] +pub struct AttributeInstance<'a> { + pub attr_spec: Vec>, +} +#[derive(Debug)] +pub struct AttrSpec<'a> { + pub attr_name: Identifier<'a>, + pub rvalue: Option>, +} + +// ----------------------------------------------------------------------------- + +pub fn attribute_instance(s: &str) -> IResult<&str, AttributeInstance> { + let (s, _) = tag("(*")(s)?; + let (s, attr_spec) = separated_nonempty_list(sp(tag(",")), sp(attr_spec))(s)?; + let (s, _) = sp(tag("*)"))(s)?; + Ok((s, AttributeInstance { attr_spec })) +} + +pub fn attr_spec(s: &str) -> IResult<&str, AttrSpec> { + let (s, attr_name) = identifier(s)?; + let (s, rvalue) = opt(preceded(sp(tag("=")), sp(constant_expression)))(s)?; + Ok((s, AttrSpec { attr_name, rvalue })) +} + +// ----------------------------------------------------------------------------- + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test() { + assert_eq!( + format!( + "{:?}", + 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 }] }))" + ); + // TODO after constant_expression + //assert_eq!( + // format!( + // "{:?}", + // all_consuming(attribute_instance)("(* full_case=1 *)") + // ), + // "" + //); + } +} diff --git a/src/lib.rs b/src/lib.rs index 38325d8..2c8163d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,6 @@ +pub mod attributes; pub mod comments; pub mod identifiers; pub mod numbers; +pub mod operators; pub mod util; diff --git a/src/operators.rs b/src/operators.rs new file mode 100644 index 0000000..3788c3a --- /dev/null +++ b/src/operators.rs @@ -0,0 +1,135 @@ +use nom::branch::*; +use nom::bytes::complete::*; +use nom::IResult; + +// ----------------------------------------------------------------------------- + +#[derive(Debug)] +pub struct Operator<'a> { + pub raw: &'a str, +} + +// ----------------------------------------------------------------------------- + +pub fn unary_operator(s: &str) -> IResult<&str, Operator> { + let (s, raw) = alt(( + tag("+"), + tag("-"), + tag("!"), + tag("&"), + tag("|"), + tag("~&"), + tag("~|"), + tag("~^"), + tag("^~"), + tag("^"), + tag("~"), + ))(s)?; + Ok((s, Operator { raw })) +} + +pub fn binary_operator(s: &str) -> IResult<&str, Operator> { + let (s, raw) = alt(( + alt(( + tag("+"), + tag("-"), + tag("**"), + tag("*"), + tag("/"), + tag("%"), + tag("==="), + tag("==?"), + tag("=="), + tag("!=="), + tag("!=?"), + tag("!="), + tag("&&"), + tag("||"), + )), + alt(( + tag("&"), + tag("|"), + tag("^~"), + tag("^"), + tag("~^"), + tag(">>>"), + tag(">>"), + tag("<<<"), + tag("<<"), + tag("->"), + tag("<->"), + tag("<="), + tag("<"), + tag(">="), + tag(">"), + )), + ))(s)?; + Ok((s, Operator { raw })) +} + +pub fn inc_or_dec_operator(s: &str) -> IResult<&str, Operator> { + let (s, raw) = alt((tag("++"), tag("--")))(s)?; + Ok((s, Operator { raw })) +} + +pub fn unary_module_path_operator(s: &str) -> IResult<&str, Operator> { + let (s, raw) = alt(( + tag("!"), + tag("&"), + tag("|"), + tag("~&"), + tag("~|"), + tag("~^"), + tag("^~"), + tag("^"), + tag("~"), + ))(s)?; + Ok((s, Operator { raw })) +} + +pub fn binary_module_path_operator(s: &str) -> IResult<&str, Operator> { + let (s, raw) = alt(( + tag("=="), + tag("!="), + tag("&&"), + tag("||"), + tag("&"), + tag("|"), + tag("^~"), + tag("^"), + tag("~^"), + ))(s)?; + Ok((s, Operator { raw })) +} + +// ----------------------------------------------------------------------------- + +#[cfg(test)] +mod tests { + use super::*; + use nom::combinator::*; + + #[test] + fn test() { + assert_eq!( + format!("{:?}", all_consuming(unary_operator)("~")), + "Ok((\"\", Operator { raw: \"~\" }))" + ); + assert_eq!( + format!("{:?}", all_consuming(binary_operator)(">>>")), + "Ok((\"\", Operator { raw: \">>>\" }))" + ); + assert_eq!( + format!("{:?}", all_consuming(inc_or_dec_operator)("++")), + "Ok((\"\", Operator { raw: \"++\" }))" + ); + assert_eq!( + format!("{:?}", all_consuming(unary_module_path_operator)("^~")), + "Ok((\"\", Operator { raw: \"^~\" }))" + ); + assert_eq!( + format!("{:?}", all_consuming(binary_module_path_operator)("||")), + "Ok((\"\", Operator { raw: \"||\" }))" + ); + } +}