modifiing grammar for instructions in file

This commit is contained in:
elvis
2025-07-11 23:49:59 +02:00
parent a7b01cb221
commit eeb4743e57
4 changed files with 262 additions and 95 deletions

View File

@ -1,8 +1,11 @@
use reactionsystems::rsprocess::presets;
fn main() { fn main() {
// let now = std::time::Instant::now(); // let now = std::time::Instant::now();
// println!("{}", now.elapsed().as_micros()); // println!("{}", now.elapsed().as_micros());
let (g, t) = reactionsystems::rsprocess::presets::digraph("testing/first.system".into()).unwrap(); match presets::run("testing/first.system".into()) {
Ok(_) => {},
reactionsystems::rsprocess::presets::dot(&g, &t, "testing/first.dot".into()).unwrap(); Err(e) => {println!("{e}")}
}
} }

View File

@ -10,6 +10,8 @@ use crate::rsprocess::structure::{RSset,
RSsystem, RSsystem,
RSreaction}; RSreaction};
use crate::rsprocess::translator::{Translator, IdType}; use crate::rsprocess::translator::{Translator, IdType};
use crate::rsprocess::presets::Instructions;
use crate::rsprocess::presets;
grammar(translator: &mut Translator); grammar(translator: &mut Translator);
@ -19,6 +21,7 @@ grammar(translator: &mut Translator);
// order // order
match { match {
".", ",", ";",
"nill", "nill",
"{", "}", "{", "}",
"[", "]", "[", "]",
@ -27,12 +30,21 @@ match {
"r:", "i:", "p:", "r:", "i:", "p:",
"-", "^", "-", "^",
"true", "false", "true", "false",
"inW", "inR", "inI", "inP" "inW", "inR", "inI", "inP",
"Environment", "Initial Entities", "Context", "Reactions",
"Weights", "Sets",
"Print", "Save",
"Dot", "GraphML", "Serialize",
"Stats", "Target", "Run", "Loop", "Frequency", "LimitFrequency",
"FastFrequency", "Digraph",
"Deserialize"
} else { } else {
r"[0-9]+" => NUMBER r"[0-9]+" => NUMBER
} else { } else {
// r"([[:alpha:]]|\p{Emoji})([[:word:]]|\p{Emoji})*" => WORD // r"([[:alpha:]]|\p{Emoji})([[:word:]]|\p{Emoji})*" => WORD
r"(\p{L}|\p{Emoji})(\p{L}|\p{Emoji}|\p{Dash}|\p{N})*" => WORD r"(\p{L}|\p{Emoji})(\p{L}|\p{Emoji}|\p{Dash}|\p{N})*" => WORD,
} else {
r#"".*""# => PATH,
} else { } else {
_ _
} }
@ -49,6 +61,10 @@ Num: i64 = {
.map_err(|_| ParseError::User { error: "Number is too big" }) .map_err(|_| ParseError::User { error: "Number is too big" })
}; };
Path: String = {
PATH => <>.trim_end_matches("\"").trim_start_matches("\"").to_string()
};
// macro for matching sequence of patterns with C as separator // macro for matching sequence of patterns with C as separator
Separated<T, C>: Vec<T> = { Separated<T, C>: Vec<T> = {
<mut v:(<T> C)+> <e:T?> => match e { <mut v:(<T> C)+> <e:T?> => match e {
@ -181,18 +197,19 @@ Formula_BHML: RSBHML = {
}; };
// ----------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// File Parsing // File Parsing
// ----------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// system // system
// a system is an environment, a set of entities as initial state, a context and // a system is an environment, a set of entities as initial state, a context and
// a set of reaction rules. // a set of reaction rules.
pub System: RSsystem = { pub System: RSsystem = {
"Environment:" <delta: Environment> "Environment" ":" <delta: Environment>
"Initial Entities:" <available_entities: Set> "Initial Entities" ":" <available_entities: Set>
"Context:" <context_process: Context> "Context" ":" <context_process: Context>
"Reactions:" <reaction_rules: Reactions> "Reactions" ":" <reaction_rules: Reactions>
=> RSsystem::from(delta.into(), => RSsystem::from(delta.into(),
available_entities, available_entities,
context_process, context_process,
@ -204,7 +221,68 @@ pub System: RSsystem = {
// entities of equal length. // entities of equal length.
pub Experiment: (Vec<u32>, Vec<RSset>) = { pub Experiment: (Vec<u32>, Vec<RSset>) = {
"Weights:" <w: Separated_Or<Num, ",">> "Weights" ":" <w: Separated_Or<Num, ",">>
"Sets:" <s: Separated_Or<Set_of_entities, ",">> "Sets" ":" <s: Separated_Or<Set_of_entities, ",">>
=> (w.into_iter().map(|x| x as u32).collect::<Vec<_>>(), s), => (w.into_iter().map(|x| x as u32).collect::<Vec<_>>(), s),
} }
// Instruction Parsing
Helper_SO: presets::SaveOptions = {
"Print" =>
presets::SaveOptions {print: true, save: None},
"Save" "(" <p: Path> ")" =>
presets::SaveOptions {print: false, save: Some(vec![p])}
}
SaveOptions: presets::SaveOptions = {
<p: Separated_Or<Helper_SO, ";">> => {
if let Some(a) =
p.into_iter()
.reduce(|mut acc, mut e| {acc.combine(&mut e); acc}) {
a
} else {
presets::SaveOptions::default()
}
}
}
GraphSaveOptions: presets::GraphSaveOptions = {
"Dot" ">" <so: SaveOptions> =>
presets::GraphSaveOptions::Dot { so },
"GraphML" ">" <so: SaveOptions> =>
presets::GraphSaveOptions::GraphML { so },
"Serialize" "(" <path: Path> ")" =>
presets::GraphSaveOptions::Serialize { path },
}
Instruction: presets::Instruction = {
"Stats" ">" <so: SaveOptions> =>
presets::Instruction::Stats { so },
"Target" ">" <so: SaveOptions> =>
presets::Instruction::Target { so },
"Run" ">" <so: SaveOptions> =>
presets::Instruction::Run { so },
"Loop" "(" <symbol: Literal> ")" ">" <so: SaveOptions> =>
presets::Instruction::Loop { symbol, so },
"Frequency" "(" <p: Path> ")" ">" <so: SaveOptions> =>
presets::Instruction::Frequency { experiment: p, so },
"LimitFrequency" "(" <p: Path> ")" ">" <so: SaveOptions> =>
presets::Instruction::LimitFrequency { experiment: p, so },
"FastFrequency" "(" <p: Path> ")" ">" <so: SaveOptions> =>
presets::Instruction::FastFrequency { experiment: p, so },
"Digraph" ">" <gso: Separated_Or<GraphSaveOptions, "|">> =>
presets::Instruction::Digraph { gso },
}
pub Run: presets::Instructions = {
<sys: System> <instr: Separated_Or<Instruction, ",">> =>
Instructions { system: presets::System::RSsystem { sys },
instructions: instr },
"Deserialize" "(" <path: Path> ")" <instr: Separated_Or<Instruction, ",">> =>
Instructions { system: presets::System::Deserialize { path },
instructions: instr },
}

View File

@ -1,6 +1,7 @@
//! Module that holds useful presets for interacting with other modules. //! Module that holds useful presets for interacting with other modules.
use std::env; use std::env;
use std::fmt::Display;
use std::fs; use std::fs;
use std::io; use std::io;
use std::io::prelude::*; use std::io::prelude::*;
@ -18,6 +19,75 @@ use super::structure::{RSset, RSsystem};
use super::translator::Translator; use super::translator::Translator;
use super::*; use super::*;
// -----------------------------------------------------------------------------
// Structures
// -----------------------------------------------------------------------------
#[derive(Debug)]
pub struct SaveOptions {
pub print: bool,
pub save: Option<Vec<String>>
}
impl SaveOptions {
pub fn combine(&mut self, other: &mut Self) {
self.print = self.print || other.print;
match (self.save.is_some(), other.save.is_some()) {
(false, false) |
(true, false) => {}
(false, true) => {
self.save = other.save.to_owned();
},
(true, true) => {
self.save
.as_mut()
.unwrap()
.append(other.save.as_mut().unwrap());}
}
}
pub fn new() -> Self {
SaveOptions { print: false, save: None }
}
}
impl Default for SaveOptions {
fn default() -> Self {
SaveOptions::new()
}
}
#[derive(Debug)]
pub enum GraphSaveOptions {
Dot { so: SaveOptions },
GraphML { so: SaveOptions },
Serialize { path: String }
}
#[derive(Debug)]
pub enum Instruction {
Stats { so: SaveOptions },
Target { so: SaveOptions },
Run { so: SaveOptions },
Loop { symbol: String, so: SaveOptions },
Frequency { experiment: String, so: SaveOptions },
LimitFrequency { experiment: String, so: SaveOptions },
FastFrequency { experiment: String, so: SaveOptions },
Digraph { gso: Vec<GraphSaveOptions> },
}
#[derive(Debug)]
pub enum System {
Deserialize { path: String },
RSsystem { sys: RSsystem }
}
#[derive(Debug)]
pub struct Instructions {
pub system: System,
pub instructions: Vec<Instruction>
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Helper Functions // Helper Functions
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -55,6 +125,77 @@ where
Ok(result) Ok(result)
} }
fn reformat_error<T, S>(
e: ParseError<usize, T, &'static str>
) -> Result<S, String>
where
T: Display
{
match e {
ParseError::ExtraToken { token: (l, t, r) } => {
Err(format!(
"Unexpected token \"{t}\" \
between positions {l} and {r}."
))
},
ParseError::UnrecognizedEof { location: _, expected: _ } => {
Err("End of file encountered while parsing.".into())
},
ParseError::InvalidToken { location } => {
Err(format!("Invalid token at position {location}."))
},
ParseError::UnrecognizedToken { token: (l, t, r), expected }
=> {
Err(format!(
"Unrecognized token \"{t}\" \
between positions {l} and {r}. Expected: {expected:?}"
))
},
ParseError::User { error } => {
Err(error.to_string())
}
}
}
fn parser_system(
translator: &mut Translator,
contents: String
) -> Result<RSsystem, String>
{
match grammar::SystemParser::new()
.parse(translator, &contents)
{
Ok(sys) => Ok(sys),
Err(e) => reformat_error(e)
}
}
fn parser_experiment(
translator: &mut Translator,
contents: String
) -> Result<(Vec<u32>, Vec<RSset>), String>
{
match grammar::ExperimentParser::new()
.parse(translator, &contents)
{
Ok(sys) => Ok(sys),
Err(e) => reformat_error(e)
}
}
fn parser_instructions(
translator: &mut Translator,
contents: String
) -> Result<Instructions, String>
{
match grammar::RunParser::new()
.parse(translator, &contents)
{
Ok(sys) => Ok(sys),
Err(e) => reformat_error(e)
}
}
fn save_file( fn save_file(
contents: String, contents: String,
path_string: String, path_string: String,
@ -81,85 +222,9 @@ fn save_file(
Ok(()) Ok(())
} }
fn parser_system(
translator: &mut Translator,
contents: String
) -> Result<RSsystem, String>
{
match grammar::SystemParser::new()
.parse(translator, &contents)
{
Ok(sys) => Ok(sys),
Err(e) => {
match e {
ParseError::ExtraToken { token: (l, t, r) } => {
Err(format!(
"Unexpected token \"{t}\" \
between positions {l} and {r}."
))
},
ParseError::UnrecognizedEof { location: _, expected: _ } => {
Err("End of file encountered while parsing.".into())
},
ParseError::InvalidToken { location } => {
Err(format!("Invalid token at position {location}."))
},
ParseError::UnrecognizedToken { token: (l, t, r), expected: _ }
=> {
Err(format!(
"Unexpected token \"{t}\" \
between positions {l} and {r}."
))
},
ParseError::User { error } => {
Err(error.to_string())
}
}
}
}
}
fn parser_experiment(
translator: &mut Translator,
contents: String
) -> Result<(Vec<u32>, Vec<RSset>), String>
{
match grammar::ExperimentParser::new()
.parse(translator, &contents)
{
Ok(sys) => Ok(sys),
Err(e) => {
match e {
ParseError::ExtraToken { token: (l, t, r) } => {
Err(format!(
"Unexpected token \"{t}\" \
between positions {l} and {r}."
))
},
ParseError::UnrecognizedEof { location: _, expected: _ } => {
Err("End of file encountered while parsing.".into())
},
ParseError::InvalidToken { location } => {
Err(format!("Invalid token at position {location}."))
},
ParseError::UnrecognizedToken { token: (l, t, r), expected: _ }
=> {
Err(format!(
"Unexpected token \"{t}\" \
between positions {l} and {r}."
))
},
ParseError::User { error } => {
Err(error.to_string())
}
}
}
}
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Methods // main_do
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
/// Prints statistics of the system. /// Prints statistics of the system.
@ -195,10 +260,11 @@ pub fn target(path_string: String) -> Result<(), String> {
Ok(()) Ok(())
} }
/// Finds the list of traversed states in a (deterministic) terminating /// Finds the list of traversed states in a (deterministic) terminating
/// reaction. /// reaction.
/// equivalent to main_do(run,Es) /// equivalent to main_do(run,Es)
pub fn run(path_string: String) -> Result<(), String> { pub fn traversed(path_string: String) -> Result<(), String> {
let mut translator = Translator::new(); let mut translator = Translator::new();
let system = read_file(&mut translator, path_string, parser_system)?; let system = read_file(&mut translator, path_string, parser_system)?;
@ -217,7 +283,7 @@ pub fn run(path_string: String) -> Result<(), String> {
/// Finds the looping list of states in a reaction system with a perpetual /// Finds the looping list of states in a reaction system with a perpetual
/// context IMPORTANT: for loops, we assume Delta defines the process constant /// context. IMPORTANT: for loops, we assume Delta defines the process constant
/// x = Q.x and the context process is x . /// x = Q.x and the context process is x .
/// equivalent to main_do(loop,Es) /// equivalent to main_do(loop,Es)
pub fn hoop(path_string: String) -> Result<(), String> { pub fn hoop(path_string: String) -> Result<(), String> {
@ -347,9 +413,9 @@ pub fn digraph(
} }
// ---------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Output Functions // Output Functions
// ---------------------------------------------------------------------------- // -----------------------------------------------------------------------------
/// Writes the specified graph to a file in .dot format. /// Writes the specified graph to a file in .dot format.
pub fn dot( pub fn dot(
@ -486,3 +552,18 @@ pub fn deserialize(
Err(_) => Err("Error during deserialization.".into()) Err(_) => Err("Error during deserialization.".into())
} }
} }
//------------------------------------------------------------------------------
// Interpreting Instructions
//------------------------------------------------------------------------------
pub fn run(path: String) -> Result<(), String> {
let mut translator = Translator::new();
let instructions = read_file(&mut translator, path, parser_instructions)?;
println!("{:?}", instructions);
Ok(())
}

View File

@ -1,4 +1,9 @@
Environment: [x = {a}.y, y =({a}.x + {b}.y)] Environment: [x = {a}.y, y =({a}.x + {b}.y) ]
Initial Entities: {a, b} Initial Entities: {a, b}
Context: [({a,b}.{a}.{a,c}.x + {a,b}.{a}.{a}.nill)] Context: [({a,b}.{a}.{a,c}.x + {a,b}.{a}.{a}.nill)]
Reactions: ([{a,b}, {c}, {b}]) Reactions: ([{a,b}, {c}, {b}])
Run > Print; Save("testing/asd"),
LimitFrequency("testing/first.experiment") > Print,
Digraph > Dot > Save("testing/asddd")
| Serialize("testing/asdd")