From 58e6f57f773d2e08e8460e9c60e05115cfc78c35 Mon Sep 17 00:00:00 2001 From: PlexSheep Date: Sun, 12 Feb 2023 03:50:33 +0100 Subject: [PATCH] brace grouping finally works --- .gitignore | 1 + .swp | Bin 0 -> 12288 bytes .vscode/launch.json | 45 +++++++++++++++ src/expression_parser.rs | 118 +++++++++++++++++++++++++++------------ test.txt | 1 + 5 files changed, 129 insertions(+), 36 deletions(-) create mode 100644 .swp create mode 100644 .vscode/launch.json create mode 100644 test.txt diff --git a/.gitignore b/.gitignore index 4f9eabe..38461ab 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /target /bin/** Cargo.lock +Cargo.lock diff --git a/.swp b/.swp new file mode 100644 index 0000000000000000000000000000000000000000..06b03579f37cfb19f68c52844e9c739e65c11a7c GIT binary patch literal 12288 zcmeI&u@1pd6vpvWi1O$>%6t;8VlBwoN{8Q5$r7Du&Tjc_j#ucA%Sm(_F`CDA%5o5D2&5cs-4Z4wMz z_NaF|ZPRK_zP=+ifB*srAbh#nb=yI(wV@Glp>f8Fo?9(qo&E*v`@Nn#01B!ao&W#< literal 0 HcmV?d00001 diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..6dcd831 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,45 @@ +{ + // Verwendet IntelliSense zum Ermitteln möglicher Attribute. + // Zeigen Sie auf vorhandene Attribute, um die zugehörigen Beschreibungen anzuzeigen. + // Weitere Informationen finden Sie unter https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "lldb", + "request": "launch", + "name": "Debug executable 'rclc'", + "cargo": { + "args": [ + "run", + "--bin=rclc", + "--package=rust_command_line_calculator", + ], + "filter": { + "name": "rclc", + "kind": "bin" + } + }, + "args": ["(())()"], + "cwd": "${workspaceFolder}" + }, + { + "type": "lldb", + "request": "launch", + "name": "Debug unit tests in executable 'rclc'", + "cargo": { + "args": [ + "test", + "--no-run", + "--bin=rclc", + "--package=rust_command_line_calculator", + ], + "filter": { + "name": "rclc", + "kind": "bin" + } + }, + "args": [], + "cwd": "${workspaceFolder}" + } + ] +} \ No newline at end of file diff --git a/src/expression_parser.rs b/src/expression_parser.rs index 3bdb789..0fc4a2f 100644 --- a/src/expression_parser.rs +++ b/src/expression_parser.rs @@ -1,4 +1,6 @@ use std::fmt; +use std::collections::HashMap; +use std::hash::Hash; use regex::Regex; // In an expression like `sqrt(25)` the Task would correspond to `sqrt`. This is the enum to @@ -82,6 +84,59 @@ impl Clone for Expression{ } } +fn find_brace_groups(haystack: String) -> Vec> { + + // TODO add support for diffrent braces + // TODO add error if not all braces are closed + let mut parenthesis_group: Vec<(usize, usize)> = Vec::new(); + let mut parenthesis_open: usize = 0; + let mut parenthesis_open_processed: usize = 0; + let mut parenthesis_closed_processed: usize = 0; + let mut parenthesis_last_opened: Vec = Vec::new(); + //let mut brackets_group: Vec<(usize, usize)> = Vec::new(); + //let mut brackets_open: usize = 0; + //let mut square_braces_group: Vec<(usize, usize)> = Vec::new(); + //let mut square_braces_open: usize = 0; + // first open stuff + for (index, char) in haystack.chars().enumerate() { + match char { + '(' => { + #[cfg(debug_assertions)] + { + dbg!(char); + dbg!(index); + } + parenthesis_group.push((index, 0)); + parenthesis_open = parenthesis_open + 1; + parenthesis_last_opened.push(parenthesis_open_processed); + parenthesis_open_processed = parenthesis_open_processed + 1; + }, + ')' => { + let len = parenthesis_group.len(); + #[cfg(debug_assertions)] + { + dbg!(char); + dbg!(index); + dbg!(parenthesis_last_opened.len()); + dbg!(parenthesis_last_opened[parenthesis_last_opened.len() - 1]); + } + parenthesis_group[parenthesis_last_opened[parenthesis_last_opened.len() - 1]].1 = index; + parenthesis_open = parenthesis_open - 1; + parenthesis_closed_processed = parenthesis_closed_processed + 1; + parenthesis_last_opened.pop(); + // TODO add error if no parenthesis is open yet. + }, + _ => (), + } + } + // now iterate backwards and search for closing things + + let brace_groups = vec![parenthesis_group/*, square_braces_group, brackets_group*/]; + #[cfg(debug_assertions)] + dbg!(&brace_groups); + return brace_groups; +} + /* * Main logic for the Expression struct */ @@ -93,48 +148,25 @@ impl Expression { */ pub fn new(expression_text: String, task: Task) -> Expression { - // find children - // TODO add error for unused task parameters - // TODO add supprot for truly recursie expressions, currently only one expression can be in - // a root expression. - let re_sub_expression = Regex::new(r"\w+\(.+?\)").unwrap(); // FIXME doesnt support nested - // expressions!!! - if re_sub_expression.is_match(&expression_text) { + let re_contains_sub_expression= Regex::new(r"(\(.*\))|(\[.*\])|(\{.*\})").unwrap(); + if re_contains_sub_expression.is_match(expression_text.as_str()) { + let brace_groups: Vec> = find_brace_groups(expression_text.clone()); + + let mut brace_groups_texts: Vec = Vec::new(); let mut children: Vec = Vec::new(); - for sub_expression_text in re_sub_expression.captures_iter(&expression_text) { - // 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(); - #[cfg(debug_assertions)] - dbg!(&task_and_expr); - let task = Task::new(task_and_expr[0], task_and_expr[1]); - let mut expression_inner = task_and_expr[2].clone().to_string(); - #[cfg(debug_assertions)] - dbg!(&expression_inner); - expression_inner.pop(); - #[cfg(debug_assertions)] - dbg!(&expression_inner); - 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(); - #[cfg(debug_assertions)] - dbg!(&task_and_expr); - let task_text = task_and_expr[0].clone().to_lowercase(); - let task = Task::new(&task_text, ""); - let mut expression_inner = task_and_expr[1].clone().to_string(); - expression_inner.pop(); - #[cfg(debug_assertions)] - dbg!(&expression_inner); - children.push(Expression::new(expression_inner, task)); + + for brace_group in brace_groups { + for pair in brace_group { + let text = &expression_text[pair.0..pair.1 + 1]; + let text = &text[1..text.len() - 1]; + dbg!(text); } } - } + } + let expression = Expression { text: expression_text, - // TODO generate these from the text! task: task, complex: false, inner_value: 0.0, @@ -151,3 +183,17 @@ impl Expression { } } +enum Brace { + Open(char), + Closed(char), +} + +impl Brace { + pub fn new(c: char) -> Option { + match c { + '{' | '[' | '(' => Some(Brace::Open(c)), + '}' | ']' | ')' => Some(Brace::Closed(c)), + _ => None, + } + } +} \ No newline at end of file diff --git a/test.txt b/test.txt new file mode 100644 index 0000000..ae08274 --- /dev/null +++ b/test.txt @@ -0,0 +1 @@ +13 + 2525 + sqrt(15 + log_10(100)) + power_10(10)