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 // ----------------------------------------------------------------------------- // order match { r"[0-9]+" => NUMBER } else { // r"([[:alpha:]]|\p{Emoji})([[:word:]]|\p{Emoji})*" => WORD r"(\p{L}|\p{Emoji})(\p{L}|\p{Emoji}|\p{Dash}|\p{N})*" => WORD } else { _ } // matches words (letter followed by numbers, letters or _) Literal: String = { WORD => <>.to_string() }; // all numbers are i64 Num: i64 = { NUMBER =>? i64::from_str(<>) .map_err(|_| ParseError::User { error: "Number is too big" }) }; // macro for matching sequence of patterns with C as separator Separated: Vec = { C)+> => match e { None => v, Some(e) => { v.push(e); v } } }; Separated_Or: Vec = { => vec![v], > => v } // ----------------------------------------------------------------------------- // SetParser // ----------------------------------------------------------------------------- pub Set: RSset = { => s }; Set_of_entities: RSset = { "{" "}" => RSset::from(vec![]), "{" > "}" => RSset::from(t.into_iter().map(|t| translator.encode(t)).collect::>()) }; // ----------------------------------------------------------------------------- // ReactionParser // ----------------------------------------------------------------------------- pub Reactions: Vec = { "(" ")" => vec![], "(" > ")" => s } Reaction: RSreaction = { "[" "," "," "]" => RSreaction::from(r, i, p), "[" "r:" "," "i:" "," "p:" "]" => RSreaction::from(r, i, p), } // ----------------------------------------------------------------------------- // ContextParser // ----------------------------------------------------------------------------- pub Context: RSprocess = { "[" "]" => RSprocess::NondeterministicChoice{ children: vec![] }, "[" > "]" => RSprocess::NondeterministicChoice{ children: t } }; Boxed_CTX_process: Rc = { => Rc::new(t) } CTX_process: RSprocess = { "." => RSprocess::EntitySet{ entities: c, next_process: Rc::new(k) }, "(" ")" => k, "(" > ")" => RSprocess::Summation{ children: k.into_iter().map(Rc::new).collect::>() }, "<" ">" "." => RSprocess::WaitEntity{ repeat: n, repeated_process: Rc::new(k1), next_process: Rc::new(k) }, "nill" => RSprocess::Nill, => RSprocess::RecursiveIdentifier{ identifier: translator.encode(identifier) } }; // ----------------------------------------------------------------------------- // EnvironmentParser // ----------------------------------------------------------------------------- pub Environment: Box = { "[" "]" => Box::new(RSenvironment::new()), "[" > "]" => Box::new(RSenvironment::from(t)) }; Env_term: (IdType, RSprocess) = { "=" => (translator.encode(identifier), k) }; // ----------------------------------------------------------------------------- // AssertParser // ----------------------------------------------------------------------------- pub Assert: Box = { => Box::new(f) }; Formula_Assert: RSassert = { "-" => 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), }; // ----------------------------------------------------------------------------- // BHMLParser // ----------------------------------------------------------------------------- pub BHML: Box = { => Box::new(g) }; Formula_BHML: RSBHML = { "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)), }; // ----------------------------------------------------------------------------- // 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:" "Initial Entities:" "Context:" "Reactions:" => RSsystem::from(delta.into(), available_entities, context_process, Rc::new(reaction_rules)) } // experiment // an experiment is composed by a sequence of weights and a sequence of sets of // entities of equal length. pub Experiment: (Vec, Vec) = { "Weights:" > "Sets:" > => (w.into_iter().map(|x| x as u32).collect::>(), s), }