From fcc1f33e7bb14d0e074049ec8298c9c9343a1261 Mon Sep 17 00:00:00 2001 From: PlexSheep Date: Sat, 11 Feb 2023 18:42:18 +0100 Subject: [PATCH] child expressions parsing --- src/expression_parser.rs | 69 ++++++++++++++++++++++++++++++++++++---- src/main.rs | 35 ++++++++++---------- 2 files changed, 80 insertions(+), 24 deletions(-) diff --git a/src/expression_parser.rs b/src/expression_parser.rs index 8e1e359..a8c4fed 100644 --- a/src/expression_parser.rs +++ b/src/expression_parser.rs @@ -5,11 +5,11 @@ use regex::Regex; // configure possible Tasks. // None means, the Expression doesn't send it's Value to a Task Handler #[derive(Debug)] // automatically generate Debug Formatter -enum Task { +pub enum Task { None, Sqrt, Power, - Log, + Log(u64), } // How to clone a Task, i was supprised I had to do it myself. @@ -20,11 +20,23 @@ impl Clone for Task { Task::None => Task::None, Task::Sqrt => Task::Sqrt, Task::Power => Task::Power, - Task::Log => Task::Log, + Task::Log(base) => Task::Log(*base), // TODO add base for log } } } +impl Task { + pub fn new(task_text: &str) -> Task { + match task_text { + "none" => Task::None, + "sqrt" => Task::Sqrt, + "power"|"pow" => Task::Power, + "log"|"ln" => Task::Log(10), // TODO add base + // what to do if a bad task was given: + &_ => {eprintln!("Bad Task: {}", task_text); std::process::exit(1); }, + } + } +} // An Expression is something that can be calculated. 20+5 is an expression. Expressions can // contain other // Expressions and have tasks: 20+sqrt(20+5) @@ -75,21 +87,59 @@ impl Clone for Expression{ impl Expression { /* * Main function for making text into Expression + * example: "12 + log_10(10 + 15) + 3" + * has a sub expression log_10(10 + 5), which has Task::Log with base 10 */ - pub fn new(expression_text: String) -> Expression { + pub fn new(expression_text: String, task: Task) -> Expression { // find children - let re_sub_expression = Regex::new(r"\w+\(.+\)").unwrap(); + // TODO add error for unused task parameters + let re_sub_expression = Regex::new(r"\w+\(.+?\)").unwrap(); if re_sub_expression.is_match(&expression_text) { + let mut children: Vec = Vec::new(); for sub_expression_text in re_sub_expression.captures_iter(&expression_text) { - println!("{}", &sub_expression_text[0]); + // if any task parameters are set ( syntax: task_para(expression) ) + if sub_expression_text[0].contains('_') { + let task_and_expr: Vec<&str> = sub_expression_text[0].split(['_', '(']).collect(); + + let task_text = task_and_expr[0].clone().to_lowercase(); + let task_param = task_and_expr[1].clone().to_string(); + let task = match task_text.as_str() { + "none" => Task::None, + "sqrt" => Task::Sqrt, + "power" => Task::Power, + "log" => {let base: u64 = task_param.parse().unwrap(); Task::Log(base)}, + // what to do if a bad task was given: + &_ => {eprintln!("Bad Task: {}", task_text); std::process::exit(1); }, + }; + let expression_inner = task_and_expr[2].clone().to_string(); + children.push(Expression::new(expression_inner, task)); + } + // if there are no parameters we need to do diffrent splitting and assume defaults + else { + let task_and_expr: Vec<&str> = sub_expression_text[0].split(['(']).collect(); + + let task_text = task_and_expr[0].clone().to_lowercase(); + let task = match task_text.as_str() { + "none" => Task::None, + "sqrt" => Task::Sqrt, + "power" => Task::Power, + "log" => Task::Log(10), + // what to do if a bad task was given: + &_ => {eprintln!("Bad Task: {}", task_text); std::process::exit(1); }, + }; + let expression_inner = task_and_expr[1].clone().to_string(); + children.push(Expression::new(expression_inner, task)); + } } + #[cfg(debug_assertions)] + dbg!(children); } let expression = Expression { text: expression_text, // TODO generate these from the text! - task: Task::None, + task: task, complex: false, inner_value: 0.0, outer_value: 0.0, @@ -97,4 +147,9 @@ impl Expression { }; expression } + + pub fn process(&self) { + println!("{}", self.text); + } } + diff --git a/src/main.rs b/src/main.rs index 4e5100d..fc8e00d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,32 +4,30 @@ mod expression_parser; mod linear_algebra; use expression_parser::Expression; +use expression_parser::Task; #[derive(Parser)] #[command(author, version, about, long_about = None)] struct Arg { +// /// Optional subcommand +// #[command(subcommand)] +// command: Option, + /// Show verbose output #[arg(short, long)] verbose: bool, - /// Show debug output - #[arg(short, long, default_value_t = false)] - debug: bool, - - #[command(subcommand)] - command: Option, - /// An expression that should be used to calculate something - expression_texts: Vec, + expressions: Vec, } -#[derive(Subcommand)] -enum Commands { - /// Assert if two expressions are equal to each other - Equal { - } -} +//#[derive(Subcommand)] +//enum Commands { +// /// Assert if two expressions are equal to each other +// Equal { +// } +//} fn main() { let args = Arg::parse(); @@ -40,11 +38,14 @@ fn main() { // TODO implement splitting of expressions, currently they are made only into a single big // expression text let mut expression_texts_concat: Vec = Vec::new(); - expression_texts_concat.push(args.expression_texts.join(" ").trim().to_string()); + expression_texts_concat.push(args.expressions.join(" ").trim().to_string()); for expression_text in expression_texts_concat { - expression_vec.push(Expression::new(expression_text)); + expression_vec.push(Expression::new(expression_text, Task::None)); + } + + for expression in expression_vec { + expression.process(); } - dbg!(expression_vec); }