Files
ReactionSystems/src/rsprocess/grammar.lalrpop
2025-07-02 07:30:05 +02:00

178 lines
6.1 KiB
Plaintext

use std::rc::Rc;
use std::str::FromStr;
use lalrpop_util::ParseError;
use crate::rsprocess::structure::{RSset,
RSprocess,
RSenvironment,
RSassert,
RSassertOp,
RSBHML,
RSsystem,
RSreaction};
use crate::rsprocess::translator::{Translator, IdType};
grammar(translator: &mut Translator);
// -----------------------------------------------------------------------------
// Helpers
// -----------------------------------------------------------------------------
// matches words (letter followed by numbers, letters or _)
Literal = { r"[[:alpha:]][[:word:]]*" };
// all numbers are i64
Num: i64 = {
r"[0-9]+" =>? i64::from_str(<>)
.map_err(|_| ParseError::User { error: "Number is too big" })
};
// macro for matching sequence of patterns with C as separator
Separeted<T, C>: Vec<T> = {
<mut v:(<T> C)+> <e:T?> => match e {
None => v,
Some(e) => {
v.push(e);
v
}
}
};
// -----------------------------------------------------------------------------
// SetParser
// -----------------------------------------------------------------------------
pub Set: RSset = {
<s: Set_of_entities> => s
};
Set_of_entities: RSset = {
"{" "}" => RSset::from(vec![]),
"{" <t: Literal> "}" => RSset::from(vec![translator.encode(t)]),
"{" <t: Separeted<Literal, ",">> "}" =>
RSset::from(t.into_iter().map(|t| translator.encode(t)).collect::<Vec<_>>())
};
// -----------------------------------------------------------------------------
// ReactionParser
// -----------------------------------------------------------------------------
pub Reactions: Vec<RSreaction> = {
"(" ")" => vec![],
"(" <r: Reaction> ")" => vec![r],
"(" <s: Separeted<Reaction, ";">> ")" => s
}
Reaction: RSreaction = {
"[" <r: Set> "," <i: Set> "," <p: Set> "]" => RSreaction::from(r, i, p),
"[" "r:" <r: Set> "," "i:" <i: Set> "," "p:" <p: Set> "]" =>
RSreaction::from(r, i, p),
}
// -----------------------------------------------------------------------------
// ContextParser
// -----------------------------------------------------------------------------
pub Context: RSprocess = {
"[" "]" => RSprocess::NondeterministicChoice{ children: vec![] },
"[" <t: CTX_process> "]" =>
RSprocess::NondeterministicChoice{children: vec![Rc::new(t)]},
"[" <t: Separeted<Boxed_CTX_process, ",">> "]" =>
RSprocess::NondeterministicChoice{ children: t }
};
Boxed_CTX_process: Rc<RSprocess> = {
<t: CTX_process> => Rc::new(t)
}
CTX_process: RSprocess = {
<c: Set_of_entities> "." <k: CTX_process> =>
RSprocess::EntitySet{ entities: c, next_process: Rc::new(k) },
"(" <k: CTX_process> ")" => k,
"(" <k: Separeted<CTX_process, "+">> ")" =>
RSprocess::Summation{
children: k.into_iter().map(Rc::new).collect::<Vec<_>>()
},
"<" <n: Num> <k1: CTX_process> ">" "." <k: CTX_process> =>
RSprocess::WaitEntity{ repeat: n,
repeated_process: Rc::new(k1),
next_process: Rc::new(k) },
"nill" => RSprocess::Nill,
<identifier: Literal> =>
RSprocess::RecursiveIdentifier{
identifier: translator.encode(identifier)
}
};
// -----------------------------------------------------------------------------
// EnvironmentParser
// -----------------------------------------------------------------------------
pub Environment: Box<RSenvironment> = {
"[" "]" => Box::new(RSenvironment::new()),
"[" <t:Env_term> "]" => Box::new(RSenvironment::from(vec![t])),
"[" <t: Separeted<Env_term, ",">> "]" => Box::new(RSenvironment::from(t))
};
Env_term: (IdType, RSprocess) = {
<identifier: Literal> "=" <k: CTX_process> =>
(translator.encode(identifier), k)
};
// -----------------------------------------------------------------------------
// AssertParser
// -----------------------------------------------------------------------------
pub Assert: Box<RSassert> = {
<f: Formula_Assert> => Box::new(f)
};
Formula_Assert: RSassert = {
"-" <f: Formula_Assert> => RSassert::Not(Box::new(f)),
"(" <f1: Formula_Assert> "^" <f2: Formula_Assert> ")" =>
RSassert::Xor(Box::new(f1), Box::new(f2)),
"(" <f: Separeted<Formula_Assert, "\\/">> ")" => RSassert::Or(f),
"(" <f: Separeted<Formula_Assert, "/\\">> ")" => RSassert::And(f),
<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),
};
// -----------------------------------------------------------------------------
// BHMLParser
// -----------------------------------------------------------------------------
pub BHML: Box<RSBHML> = {
<g: Formula_BHML> => Box::new(g)
};
Formula_BHML: RSBHML = {
"true" => RSBHML::True,
"false" => RSBHML::False,
"(" <g: Separeted<Formula_BHML, "\\/">> ")" => RSBHML::Or(g),
"(" <g: Separeted<Formula_BHML, "/\\">> ")" => RSBHML::And(g),
"<" <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)),
};
// -----------------------------------------------------------------------------
// 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>
=> RSsystem::from(delta.into(),
available_entities,
context_process,
Rc::new(reaction_rules))
}