normalizing expression texts

This commit is contained in:
Christoph J. Scherr 2023-02-12 23:22:57 +01:00
parent eab8d90a65
commit 4dbd9e6afb
2 changed files with 68 additions and 54 deletions

View File

@ -1,7 +1,17 @@
use std::fmt; use std::fmt;
use std::collections::HashMap;
use regex::Regex; use regex::Regex;
pub const OPERATORS: [char; 5] = ['+', '-', '*', '/', '^'];
fn normalize_string(to_normalize: String) -> String {
let mut normalized_text = to_normalize;
normalized_text.retain(|c| !c.is_whitespace());
normalized_text = normalized_text.to_string();
normalized_text
}
// In an expression like `sqrt(25)` the Task would correspond to `sqrt`. This is the enum to // In an expression like `sqrt(25)` the Task would correspond to `sqrt`. This is the enum to
// configure possible Tasks. // configure possible Tasks.
// None means, the Expression doesn't send it's Value to a Task Handler // None means, the Expression doesn't send it's Value to a Task Handler
@ -125,54 +135,54 @@ impl Clone for Expression{
fn find_brace_groups(haystack: String) -> Vec<Vec<(usize, usize)>> { fn find_brace_groups(haystack: String) -> Vec<Vec<(usize, usize)>> {
// TODO add support for diffrent braces // TODO add support for diffrent braces
// TODO add error if not all braces are closed // TODO add error if not all braces are closed
let mut parenthesis_group: Vec<(usize, usize)> = Vec::new(); let mut parenthesis_group: Vec<(usize, usize)> = Vec::new();
let mut parenthesis_open: usize = 0; let mut parenthesis_open: usize = 0;
let mut parenthesis_open_processed: usize = 0; let mut parenthesis_open_processed: usize = 0;
let mut parenthesis_closed_processed: usize = 0; let mut parenthesis_closed_processed: usize = 0;
let mut parenthesis_last_opened: Vec<usize> = Vec::new(); let mut parenthesis_last_opened: Vec<usize> = Vec::new();
//let mut brackets_group: Vec<(usize, usize)> = Vec::new(); //let mut brackets_group: Vec<(usize, usize)> = Vec::new();
//let mut brackets_open: usize = 0; //let mut brackets_open: usize = 0;
//let mut square_braces_group: Vec<(usize, usize)> = Vec::new(); //let mut square_braces_group: Vec<(usize, usize)> = Vec::new();
//let mut square_braces_open: usize = 0; //let mut square_braces_open: usize = 0;
// first open stuff // first open stuff
for (index, char) in haystack.chars().enumerate() { for (index, char) in haystack.chars().enumerate() {
match char { match char {
'(' => { '(' => {
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
{ {
dbg!(char); dbg!(char);
dbg!(index); dbg!(index);
} }
parenthesis_group.push((index, 0)); parenthesis_group.push((index, 0));
parenthesis_open = parenthesis_open + 1; parenthesis_open = parenthesis_open + 1;
parenthesis_last_opened.push(parenthesis_open_processed); parenthesis_last_opened.push(parenthesis_open_processed);
parenthesis_open_processed = parenthesis_open_processed + 1; parenthesis_open_processed = parenthesis_open_processed + 1;
}, },
')' => { ')' => {
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
{ {
dbg!(char); dbg!(char);
dbg!(index); dbg!(index);
dbg!(parenthesis_last_opened.len()); dbg!(parenthesis_last_opened.len());
dbg!(parenthesis_last_opened[parenthesis_last_opened.len() - 1]); dbg!(parenthesis_last_opened[parenthesis_last_opened.len() - 1]);
} }
parenthesis_group[parenthesis_last_opened[parenthesis_last_opened.len() - 1]].1 = index; parenthesis_group[parenthesis_last_opened[parenthesis_last_opened.len() - 1]].1 = index;
parenthesis_open = parenthesis_open - 1; parenthesis_open = parenthesis_open - 1;
parenthesis_closed_processed = parenthesis_closed_processed + 1; parenthesis_closed_processed = parenthesis_closed_processed + 1;
parenthesis_last_opened.pop(); parenthesis_last_opened.pop();
// TODO add error if no parenthesis is open yet. // TODO add error if no parenthesis is open yet.
}, },
_ => (), _ => (),
}
} }
// now iterate backwards and search for closing things }
// now iterate backwards and search for closing things
let brace_groups = vec![parenthesis_group/*, square_braces_group, brackets_group*/]; let brace_groups = vec![parenthesis_group/*, square_braces_group, brackets_group*/];
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
dbg!(&brace_groups); dbg!(&brace_groups);
return brace_groups; return brace_groups;
} }
/* /*
@ -186,6 +196,8 @@ impl Expression {
*/ */
pub fn new(expression_text: String, task: Task) -> Expression { pub fn new(expression_text: String, task: Task) -> Expression {
let expression_text = normalize_string(expression_text);
let re_contains_sub_expression= Regex::new(r"(\(.*\))|(\[.*\])|(\{.*\})").unwrap(); let re_contains_sub_expression= Regex::new(r"(\(.*\))|(\[.*\])|(\{.*\})").unwrap();
if re_contains_sub_expression.is_match(expression_text.as_str()) { if re_contains_sub_expression.is_match(expression_text.as_str()) {
let brace_groups: Vec<Vec<(usize, usize)>> = find_brace_groups(expression_text.clone()); let brace_groups: Vec<Vec<(usize, usize)>> = find_brace_groups(expression_text.clone());
@ -208,11 +220,11 @@ impl Expression {
// TODO check for task parameters // TODO check for task parameters
for (index, char) in possible_task.chars().enumerate() { for (index, char) in possible_task.chars().enumerate() {
stop_at = index; stop_at = index;
if !(char.is_alphanumeric() | (char == '.') | (char == '_')) { if !(char.is_alphanumeric() | (char == '.') | (char == '_')) & (char == '+') {
break; break;
} }
} }
let task_text_full = possible_task.clone()[..stop_at + 1].chars().rev().collect::<String>(); let task_text_full = possible_task.clone()[..stop_at + 0].chars().rev().collect::<String>();
let task: Task; let task: Task;
if task_text_full.contains('_') { if task_text_full.contains('_') {
let split: Vec<&str> = task_text_full.split('_').collect(); let split: Vec<&str> = task_text_full.split('_').collect();
@ -241,7 +253,20 @@ impl Expression {
expression expression
} }
// calculate value for expression.
pub fn process(&self) { pub fn process(&self) {
println!("{}", self.text); let normalized_text = self.normalize_text();
// iterate through chars. Find logical groups, and add them into a hashmap.
let re_numeric = Regex::new(r"\d+(\.\d+)?");
todo!();
// no idea how to do this, seriously, this is so complicated, i wouldn't ever have thought
// this. I probably need to add a enum Operation and an enum Value to create a
// HashMap<String, Value> and match back the Value type to some real usable one? This is so
// complicated.
}
// wrapper for normalize_string()
fn normalize_text(&self) -> String {
normalize_string(self.text.clone())
} }
} }

View File

@ -10,10 +10,6 @@ use expression_parser::Task;
#[derive(Parser)] #[derive(Parser)]
#[command(author, version, about, long_about = None)] #[command(author, version, about, long_about = None)]
struct Arg { struct Arg {
// /// Optional subcommand
// #[command(subcommand)]
// command: Option<Commands>,
///Syntax: '1 + task_param(inner) + 1 '{n} ///Syntax: '1 + task_param(inner) + 1 '{n}
///{n} ///{n}
///Specify an expression, any expression may contain child expressions, which can be denoted{n} ///Specify an expression, any expression may contain child expressions, which can be denoted{n}
@ -38,13 +34,6 @@ struct Arg {
expressions: Vec<String>, expressions: Vec<String>,
} }
//#[derive(Subcommand)]
//enum Commands {
// /// Assert if two expressions are equal to each other
// Equal {
// }
//}
fn main() { fn main() {
let args = Arg::parse(); let args = Arg::parse();
let mut expression_vec: Vec<Expression> = Vec::new(); let mut expression_vec: Vec<Expression> = Vec::new();