Add attributes/operators

This commit is contained in:
dalance 2019-06-28 15:43:05 +09:00
parent a207cabb16
commit ade1ca229a
3 changed files with 197 additions and 0 deletions

60
src/attributes.rs Normal file
View File

@ -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<AttrSpec<'a>>,
}
#[derive(Debug)]
pub struct AttrSpec<'a> {
pub attr_name: Identifier<'a>,
pub rvalue: Option<ConstantExpression<'a>>,
}
// -----------------------------------------------------------------------------
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 *)")
// ),
// ""
//);
}
}

View File

@ -1,4 +1,6 @@
pub mod attributes;
pub mod comments; pub mod comments;
pub mod identifiers; pub mod identifiers;
pub mod numbers; pub mod numbers;
pub mod operators;
pub mod util; pub mod util;

135
src/operators.rs Normal file
View File

@ -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: \"||\" }))"
);
}
}