diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..c2f4eef --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "reactionsystems" +version = "0.1.0" +edition = "2024" + +[build-dependencies] +lalrpop = "0.22" + +[dependencies] +dot = "0.1" +lalrpop-util = { version = "0.22", features = ["lexer", "unicode"] } diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..ca5c283 --- /dev/null +++ b/build.rs @@ -0,0 +1,3 @@ +fn main() { + lalrpop::process_root().unwrap(); +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..009287a --- /dev/null +++ b/src/main.rs @@ -0,0 +1,16 @@ +mod rsprocess; +use lalrpop_util::lalrpop_mod; +use std::io; + +fn main() -> Result<(), Box> { + lalrpop_mod!(grammar, "/rsprocess/grammar.rs"); + + let mut buffer = String::new(); + let i = io::stdin(); + i.read_line(&mut buffer).expect("Can't read stdin"); + + let result = grammar::BHMLParser::new().parse(&buffer).unwrap(); + println!("{:?}", result); + + Ok(()) +} diff --git a/src/rsprocess/grammar.lalrpop b/src/rsprocess/grammar.lalrpop new file mode 100644 index 0000000..ae77337 --- /dev/null +++ b/src/rsprocess/grammar.lalrpop @@ -0,0 +1,88 @@ +use std::str::FromStr; +use lalrpop_util::ParseError; +use crate::rsprocess::{RSprocess, RSenvironment, RSassert, RSassertOp, RSBHML}; + +grammar; + +Literal = { r"[[:alpha:]][[:word:]]*" }; + +Num: i64 = { + r"[0-9]+" =>? i64::from_str(<>) + .map_err(|_| ParseError::User { error: "Number is too big" }) +}; + +Comma: Vec = { + C)+> => match e { + None => v, + Some(e) => { + v.push(e); + v + } + } +}; + +pub Set: Vec<&'input str> = { + => s +}; + +pub Context: Box> = { + "[" "]" => Box::new(RSprocess::Nill), + "[" "]" => Box::new(t), + "[" > "]" => Box::new(RSprocess::NondeterministicChoice{children: t}) +}; + +CTX_process: RSprocess<'input> = { + "." => RSprocess::EntitySet{entities: c, next_process: Box::new(k)}, + "(" ")" => k, + "(" > ")" => RSprocess::Summation{children: k}, + "<" ">" "." => RSprocess::WaitEntity{repeat: n, repeated_process: Box::new(k1), next_process: Box::new(k)}, + "nil" => RSprocess::Nill, + => RSprocess::ConstantIdentifier{identifier: identifier} +}; + +Set_of_entities: Vec<&'input str> = { + "{" "}" => vec![], + "{" "}" => vec![t], + "{" > "}" => {t.sort(); t} +}; + +pub Environment: Box> = { + "[" "]" => Box::new(RSenvironment::new()), + "[" > "]" => Box::new(RSenvironment::from(t)) +}; + +Env_term: (&'input str, Box>) = { + "=" => (identifier, Box::new(k)) +}; + +pub Assert: Box> = { + => Box::new(f) +}; + +Formula_Assert: RSassert<'input> = { + "-" => RSassert::Not(Box::new(f)), + "(" "^" ")" => RSassert::Xor(Box::new(f1), Box::new(f2)), + "(" > ")" => RSassert::Or(f), + "(" > ")" => RSassert::And(f), + "inW" => RSassert::Sub(c, RSassertOp::InW), + "inR" => RSassert::Sub(c, RSassertOp::InR), + "inI" => RSassert::Sub(c, RSassertOp::InI), + "inP" => RSassert::Sub(c, RSassertOp::InP), + "?" "inW" => RSassert::NonEmpty(RSassertOp::InW), + "?" "inR" => RSassert::NonEmpty(RSassertOp::InR), + "?" "inI" => RSassert::NonEmpty(RSassertOp::InI), + "?" "inP" => RSassert::NonEmpty(RSassertOp::InP), +}; + +pub BHML: Box> = { + => Box::new(g) +}; + +Formula_BHML: RSBHML<'input> = { + "true" => RSBHML::True, + "false" => RSBHML::False, + "(" > ")" => RSBHML::Or(g), + "(" > ")" => RSBHML::And(g), + "<" ">" => RSBHML::Diamond(Box::new(f), Box::new(g)), + "[" "]" => RSBHML::Box(Box::new(f), Box::new(g)), +}; diff --git a/src/rsprocess/mod.rs b/src/rsprocess/mod.rs new file mode 100644 index 0000000..e51ece5 --- /dev/null +++ b/src/rsprocess/mod.rs @@ -0,0 +1,74 @@ +use std::collections::BTreeMap; + +#[derive(Clone, Debug)] +#[allow(dead_code)] +pub enum RSprocess<'a> { + Nill, + ConstantIdentifier{identifier: &'a str}, + EntitySet{entities: Vec<&'a str>, next_process: Box>}, + WaitEntity{repeat: i64, repeated_process: Box>, next_process: Box>}, + NondeterministicChoice{children: Vec>}, + Summation{children: Vec>} +} + +#[derive(Clone, Debug)] +#[allow(dead_code)] +pub struct RSenvironment<'a> { + definitions: BTreeMap<&'a str, Box>>, +} + +impl<'a> RSenvironment<'a> { + pub fn new() -> RSenvironment<'a> { + RSenvironment{definitions: BTreeMap::new()} + } +} + +impl<'a, const N: usize> From<[(&'a str, Box>); N]> for RSenvironment<'a> { + fn from(arr: [(&'a str, Box>); N]) -> Self { + RSenvironment{definitions: BTreeMap::from(arr)} + } +} + +impl<'a> From<&[(&'a str, Box>)]> for RSenvironment<'a> { + fn from(arr: &[(&'a str, Box>)]) -> Self { + RSenvironment{definitions: BTreeMap::from_iter(arr.to_vec())} + } +} + +impl<'a> From>)>> for RSenvironment<'a> { + fn from(arr: Vec<(&'a str, Box>)>) -> Self { + RSenvironment{definitions: BTreeMap::from_iter(arr)} + } +} + +#[derive(Clone, Debug)] +#[allow(dead_code)] +pub enum RSassertOp { + InW, + InR, + InI, + InP +} + + +#[derive(Clone, Debug)] +#[allow(dead_code)] +pub enum RSassert<'a> { + Not(Box>), + Xor(Box>, Box>), + Or(Vec>), + And(Vec>), + Sub(Vec<&'a str>, RSassertOp), + NonEmpty(RSassertOp) +} + +#[derive(Clone, Debug)] +#[allow(dead_code)] +pub enum RSBHML<'a> { + True, + False, + Or(Vec>), + And(Vec>), + Diamond(Box>, Box>), + Box(Box>, Box>) +}