2025-05-21 00:03:36 +02:00
|
|
|
use std::rc::Rc;
|
2025-05-14 11:42:19 +02:00
|
|
|
use std::str::FromStr;
|
|
|
|
|
use lalrpop_util::ParseError;
|
2025-07-01 04:04:13 +02:00
|
|
|
use crate::rsprocess::structure::{RSset,
|
|
|
|
|
RSprocess,
|
|
|
|
|
RSenvironment,
|
|
|
|
|
RSassert,
|
|
|
|
|
RSassertOp,
|
|
|
|
|
RSBHML,
|
|
|
|
|
RSsystem,
|
|
|
|
|
RSreaction};
|
2025-06-16 14:46:04 +02:00
|
|
|
use crate::rsprocess::translator::{Translator, IdType};
|
2025-05-14 11:42:19 +02:00
|
|
|
|
2025-06-16 14:46:04 +02:00
|
|
|
grammar(translator: &mut Translator);
|
2025-05-14 11:42:19 +02:00
|
|
|
|
2025-07-01 04:04:13 +02:00
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
// Helpers
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
|
2025-07-03 16:28:28 +02:00
|
|
|
// order
|
|
|
|
|
match {
|
|
|
|
|
r"[0-9]+" => NUMBER
|
|
|
|
|
} else {
|
|
|
|
|
r"([[:alpha:]]|\p{Emoji})([[:word:]]|\p{Emoji})*" => WORD
|
|
|
|
|
} else {
|
|
|
|
|
_
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2025-05-14 12:14:13 +02:00
|
|
|
// matches words (letter followed by numbers, letters or _)
|
2025-07-03 16:28:28 +02:00
|
|
|
Literal: String = {
|
|
|
|
|
WORD => <>.to_string()
|
|
|
|
|
};
|
2025-05-14 11:42:19 +02:00
|
|
|
|
2025-05-14 12:14:13 +02:00
|
|
|
// all numbers are i64
|
2025-05-14 11:42:19 +02:00
|
|
|
Num: i64 = {
|
2025-07-03 16:28:28 +02:00
|
|
|
NUMBER =>? i64::from_str(<>)
|
|
|
|
|
.map_err(|_| ParseError::User { error: "Number is too big" })
|
2025-05-14 11:42:19 +02:00
|
|
|
};
|
|
|
|
|
|
2025-05-14 12:14:13 +02:00
|
|
|
// macro for matching sequence of patterns with C as separator
|
2025-07-02 17:27:36 +02:00
|
|
|
Separated<T, C>: Vec<T> = {
|
2025-05-14 11:42:19 +02:00
|
|
|
<mut v:(<T> C)+> <e:T?> => match e {
|
|
|
|
|
None => v,
|
|
|
|
|
Some(e) => {
|
|
|
|
|
v.push(e);
|
|
|
|
|
v
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2025-07-03 11:09:58 +02:00
|
|
|
Separated_Or<T, C>: Vec<T> = {
|
|
|
|
|
<v: T> => vec![v],
|
|
|
|
|
<v: Separated<T, C>> => v
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-01 04:04:13 +02:00
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
// SetParser
|
|
|
|
|
// -----------------------------------------------------------------------------
|
2025-06-16 14:46:04 +02:00
|
|
|
pub Set: RSset = {
|
2025-05-14 11:42:19 +02:00
|
|
|
<s: Set_of_entities> => s
|
|
|
|
|
};
|
|
|
|
|
|
2025-06-16 14:46:04 +02:00
|
|
|
Set_of_entities: RSset = {
|
2025-05-19 00:10:23 +02:00
|
|
|
"{" "}" => RSset::from(vec![]),
|
2025-07-03 11:09:58 +02:00
|
|
|
"{" <t: Separated_Or<Literal, ",">> "}" =>
|
2025-06-18 11:28:04 +02:00
|
|
|
RSset::from(t.into_iter().map(|t| translator.encode(t)).collect::<Vec<_>>())
|
2025-05-19 00:10:23 +02:00
|
|
|
};
|
|
|
|
|
|
2025-06-12 16:23:39 +02:00
|
|
|
|
2025-07-01 04:04:13 +02:00
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
// ReactionParser
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
pub Reactions: Vec<RSreaction> = {
|
|
|
|
|
"(" ")" => vec![],
|
2025-07-03 11:09:58 +02:00
|
|
|
"(" <s: Separated_Or<Reaction, ";">> ")" => s
|
2025-07-01 04:04:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Reaction: RSreaction = {
|
|
|
|
|
"[" <r: Set> "," <i: Set> "," <p: Set> "]" => RSreaction::from(r, i, p),
|
2025-07-01 19:22:50 +02:00
|
|
|
"[" "r:" <r: Set> "," "i:" <i: Set> "," "p:" <p: Set> "]" =>
|
|
|
|
|
RSreaction::from(r, i, p),
|
2025-07-01 04:04:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
// ContextParser
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
pub Context: RSprocess = {
|
|
|
|
|
"[" "]" => RSprocess::NondeterministicChoice{ children: vec![] },
|
2025-07-03 11:09:58 +02:00
|
|
|
"[" <t: Separated_Or<Boxed_CTX_process, ",">> "]" =>
|
2025-07-01 04:04:13 +02:00
|
|
|
RSprocess::NondeterministicChoice{ children: t }
|
2025-05-14 11:42:19 +02:00
|
|
|
};
|
|
|
|
|
|
2025-06-16 14:46:04 +02:00
|
|
|
Boxed_CTX_process: Rc<RSprocess> = {
|
2025-05-21 00:03:36 +02:00
|
|
|
<t: CTX_process> => Rc::new(t)
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-16 14:46:04 +02:00
|
|
|
CTX_process: RSprocess = {
|
2025-05-19 00:10:23 +02:00
|
|
|
<c: Set_of_entities> "." <k: CTX_process> =>
|
2025-05-21 00:03:36 +02:00
|
|
|
RSprocess::EntitySet{ entities: c, next_process: Rc::new(k) },
|
2025-05-14 11:42:19 +02:00
|
|
|
"(" <k: CTX_process> ")" => k,
|
2025-07-02 17:27:36 +02:00
|
|
|
"(" <k: Separated<CTX_process, "+">> ")" =>
|
2025-07-01 19:22:50 +02:00
|
|
|
RSprocess::Summation{
|
|
|
|
|
children: k.into_iter().map(Rc::new).collect::<Vec<_>>()
|
|
|
|
|
},
|
2025-05-19 00:10:23 +02:00
|
|
|
"<" <n: Num> <k1: CTX_process> ">" "." <k: CTX_process> =>
|
|
|
|
|
RSprocess::WaitEntity{ repeat: n,
|
2025-05-21 00:03:36 +02:00
|
|
|
repeated_process: Rc::new(k1),
|
2025-07-01 19:22:50 +02:00
|
|
|
next_process: Rc::new(k) },
|
2025-07-02 07:30:05 +02:00
|
|
|
"nill" => RSprocess::Nill,
|
2025-05-19 00:10:23 +02:00
|
|
|
<identifier: Literal> =>
|
2025-07-01 19:22:50 +02:00
|
|
|
RSprocess::RecursiveIdentifier{
|
|
|
|
|
identifier: translator.encode(identifier)
|
|
|
|
|
}
|
2025-05-14 11:42:19 +02:00
|
|
|
};
|
|
|
|
|
|
2025-07-01 04:04:13 +02:00
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
// EnvironmentParser
|
|
|
|
|
// -----------------------------------------------------------------------------
|
2025-06-16 14:46:04 +02:00
|
|
|
pub Environment: Box<RSenvironment> = {
|
2025-05-14 11:42:19 +02:00
|
|
|
"[" "]" => Box::new(RSenvironment::new()),
|
2025-07-03 11:09:58 +02:00
|
|
|
"[" <t: Separated_Or<Env_term, ",">> "]" => Box::new(RSenvironment::from(t))
|
2025-05-14 11:42:19 +02:00
|
|
|
};
|
|
|
|
|
|
2025-06-16 14:46:04 +02:00
|
|
|
Env_term: (IdType, RSprocess) = {
|
|
|
|
|
<identifier: Literal> "=" <k: CTX_process> =>
|
2025-06-18 11:28:04 +02:00
|
|
|
(translator.encode(identifier), k)
|
2025-05-14 11:42:19 +02:00
|
|
|
};
|
|
|
|
|
|
2025-07-01 04:04:13 +02:00
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
// AssertParser
|
|
|
|
|
// -----------------------------------------------------------------------------
|
2025-06-16 14:46:04 +02:00
|
|
|
pub Assert: Box<RSassert> = {
|
2025-05-14 11:42:19 +02:00
|
|
|
<f: Formula_Assert> => Box::new(f)
|
|
|
|
|
};
|
|
|
|
|
|
2025-06-16 14:46:04 +02:00
|
|
|
Formula_Assert: RSassert = {
|
2025-05-14 11:42:19 +02:00
|
|
|
"-" <f: Formula_Assert> => RSassert::Not(Box::new(f)),
|
2025-05-19 00:10:23 +02:00
|
|
|
"(" <f1: Formula_Assert> "^" <f2: Formula_Assert> ")" =>
|
|
|
|
|
RSassert::Xor(Box::new(f1), Box::new(f2)),
|
2025-07-02 17:27:36 +02:00
|
|
|
"(" <f: Separated<Formula_Assert, "\\/">> ")" => RSassert::Or(f),
|
|
|
|
|
"(" <f: Separated<Formula_Assert, "/\\">> ")" => RSassert::And(f),
|
2025-05-14 11:42:19 +02:00
|
|
|
<c: Set_of_entities> "inW" => RSassert::Sub(c, RSassertOp::InW),
|
|
|
|
|
<c: Set_of_entities> "inR" => RSassert::Sub(c, RSassertOp::InR),
|
|
|
|
|
<c: Set_of_entities> "inI" => RSassert::Sub(c, RSassertOp::InI),
|
|
|
|
|
<c: Set_of_entities> "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),
|
|
|
|
|
};
|
|
|
|
|
|
2025-07-01 04:04:13 +02:00
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
// BHMLParser
|
|
|
|
|
// -----------------------------------------------------------------------------
|
2025-06-16 14:46:04 +02:00
|
|
|
pub BHML: Box<RSBHML> = {
|
2025-05-14 11:42:19 +02:00
|
|
|
<g: Formula_BHML> => Box::new(g)
|
|
|
|
|
};
|
|
|
|
|
|
2025-06-16 14:46:04 +02:00
|
|
|
Formula_BHML: RSBHML = {
|
2025-05-14 11:42:19 +02:00
|
|
|
"true" => RSBHML::True,
|
|
|
|
|
"false" => RSBHML::False,
|
2025-07-02 17:27:36 +02:00
|
|
|
"(" <g: Separated<Formula_BHML, "\\/">> ")" => RSBHML::Or(g),
|
|
|
|
|
"(" <g: Separated<Formula_BHML, "/\\">> ")" => RSBHML::And(g),
|
2025-05-19 00:10:23 +02:00
|
|
|
"<" <f: Formula_Assert> ">" <g: Formula_BHML> =>
|
|
|
|
|
RSBHML::Diamond(Box::new(f), Box::new(g)),
|
|
|
|
|
"[" <f: Formula_Assert> "]" <g: Formula_BHML> =>
|
|
|
|
|
RSBHML::Box(Box::new(f), Box::new(g)),
|
2025-05-14 11:42:19 +02:00
|
|
|
};
|
2025-07-01 04:04:13 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
// File Parsing
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
// system
|
|
|
|
|
// a system is an environment, a set of entities as initial state, a context and
|
|
|
|
|
// a set of reaction rules.
|
|
|
|
|
|
|
|
|
|
pub System: RSsystem = {
|
|
|
|
|
"Environment:" <delta: Environment>
|
|
|
|
|
"Initial Entities:" <available_entities: Set>
|
|
|
|
|
"Context:" <context_process: Context>
|
|
|
|
|
"Reactions:" <reaction_rules: Reactions>
|
2025-07-01 19:22:50 +02:00
|
|
|
=> RSsystem::from(delta.into(),
|
|
|
|
|
available_entities,
|
|
|
|
|
context_process,
|
|
|
|
|
Rc::new(reaction_rules))
|
2025-07-01 04:04:13 +02:00
|
|
|
}
|
2025-07-02 17:27:36 +02:00
|
|
|
|
|
|
|
|
// experiment
|
|
|
|
|
// an experiment is composed by a sequence of weights and a sequence of sets of
|
|
|
|
|
// entities of equal length.
|
|
|
|
|
|
|
|
|
|
pub Experiment: (Vec<u32>, Vec<RSset>) = {
|
2025-07-03 11:09:58 +02:00
|
|
|
"Weights:" <w: Separated_Or<Num, ",">>
|
|
|
|
|
"Sets:" <s: Separated_Or<Set_of_entities, ",">>
|
|
|
|
|
=> (w.into_iter().map(|x| x as u32).collect::<Vec<_>>(), s),
|
2025-07-02 17:27:36 +02:00
|
|
|
}
|