From 92232bea964e2aa76182b4822f2f4353b6052e66 Mon Sep 17 00:00:00 2001 From: h7x4 Date: Tue, 12 Apr 2022 15:02:18 +0200 Subject: [PATCH] Several changes --- Cargo.lock | 56 +++++++++++++++++++++++++++++++++++ Cargo.toml | 8 ++++- src/boolean_algebra/logic.rs | 56 +++++++++++++++++++++++++++++++++++ src/boolean_algebra/parser.rs | 13 ++++---- src/main.rs | 51 ++++++++++++++++++++++++------- src/traits/parser.rs | 6 ++-- src/truthtable/parser.rs | 22 +++++--------- 7 files changed, 177 insertions(+), 35 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0b13d31..372b58a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -58,6 +58,12 @@ version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + [[package]] name = "clap" version = "3.1.1" @@ -88,6 +94,17 @@ dependencies = [ "syn", ] +[[package]] +name = "colored" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3616f750b84d8f0de8a58bda93e08e2a81ad3f523089b05f1dffecab48c6cbd" +dependencies = [ + "atty", + "lazy_static", + "winapi", +] + [[package]] name = "digest" version = "0.8.1" @@ -102,10 +119,19 @@ name = "diskmat_tools" version = "0.1.0" dependencies = [ "clap", + "itertools", + "log", "pest", "pest_derive", + "simple_logger", ] +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + [[package]] name = "fake-simd" version = "0.1.2" @@ -152,6 +178,15 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "itertools" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484" +dependencies = [ + "either", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -164,6 +199,15 @@ version = "0.2.119" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4" +[[package]] +name = "log" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +dependencies = [ + "cfg-if", +] + [[package]] name = "maplit" version = "1.0.2" @@ -288,6 +332,18 @@ dependencies = [ "opaque-debug", ] +[[package]] +name = "simple_logger" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c75a9723083573ace81ad0cdfc50b858aa3c366c48636edb4109d73122a0c0ea" +dependencies = [ + "atty", + "colored", + "log", + "winapi", +] + [[package]] name = "strsim" version = "0.10.0" diff --git a/Cargo.toml b/Cargo.toml index 32d0ccd..3853e29 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,12 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +clap = { version = "3.1.1", features = ["derive"] } +log = "0.4.14" +itertools = "0.8.2" pest = "2.1.3" pest_derive = "2.0" -clap = { version = "3.1.1", features = ["derive"] } + +[dependencies.simple_logger] +default-features = false +features = ["colors"] diff --git a/src/boolean_algebra/logic.rs b/src/boolean_algebra/logic.rs index e69de29..8bb4432 100644 --- a/src/boolean_algebra/logic.rs +++ b/src/boolean_algebra/logic.rs @@ -0,0 +1,56 @@ +// mod parser; +use std::collections::{HashSet, HashMap}; + +use super::parser::{BAPair, BARule}; + +fn extract_base_expressions(pair: &BAPair, expressions: &mut HashSet) { + if pair.as_rule() == BARule::label { + expressions.insert(pair.as_str().to_string()); + } else { + for child_pair in pair.clone().into_inner() { + extract_base_expressions(&child_pair, expressions); + } + } +} + +fn extract_expressions<'a>(pair: &BAPair, expressions: &mut Vec<&BAPair>) { + for child_pair in pair.clone().into_inner() { + extract_expressions(&child_pair, expressions); + } + // if pair.as_rule() == BARule::expression { + // expressions.push(pair); + // } else { + + // } +} + +fn base_expression_combinations(base_expressions: &HashSet) -> Vec> { + let combination_count = 2_u32.pow(base_expressions.len() as u32) as usize; + let ordered_base_expressions: Vec = base_expressions.clone().into_iter().collect(); + let mut combinations: Vec> = Vec::with_capacity(combination_count); + for n in 0..combination_count { + let mut combination: HashMap = HashMap::with_capacity(base_expressions.len()); + for b in 0..base_expressions.len() { + combination.insert(ordered_base_expressions[b as usize].clone(), (n >> b) % 2 == 1); + } + combinations.push(combination); + } + combinations +} + +fn calculate_expression(values: HashMap, pair: BAPair) { + +} + +pub fn generate_truth_table(pair: &BAPair) { + let mut base_expressions = HashSet::new(); + extract_base_expressions(pair, &mut base_expressions); + log::debug!("Base expressions: {:?}", base_expressions); + // log::debug!("Base expressions: {:?}", base_expressions.iter().product::().collect::>()); + + let mut expressions = Vec::new(); + extract_expressions(pair, &mut expressions); + + let combinations = base_expression_combinations(&base_expressions); + log::debug!("{:#?}", combinations); +} \ No newline at end of file diff --git a/src/boolean_algebra/parser.rs b/src/boolean_algebra/parser.rs index 2155fdd..1e8b855 100644 --- a/src/boolean_algebra/parser.rs +++ b/src/boolean_algebra/parser.rs @@ -1,17 +1,18 @@ -use crate::traits::{parser::Pair, self}; +use crate::traits::{self, parser::Pair}; use super::super::traits::graphvizable::Graphvizable; -pub use pest::iterators::Pair as BAPair; use pest::Parser; use pest_derive::Parser; + #[derive(Parser)] #[grammar = "boolean_algebra/boolean_algebra.pest"] pub struct BAParser; pub type BARule = Rule; +pub type BAPair<'a> = pest::iterators::Pair<'a, BARule>; -impl Graphvizable for BAPair<'_, BARule> { +impl Graphvizable for BAPair<'_> { fn print_graphviz_diagram(&self) { let mut i: u64 = 0; println!("digraph parse_tree {{"); @@ -26,7 +27,7 @@ impl Graphvizable for BAPair<'_, BARule> { } } -impl traits::parser:: Parser for BAParser { +impl traits::parser::Parser for BAParser { fn parse(input: &mut String) -> Pair { input.retain(|c| !c.is_whitespace()); let result = >::parse(BARule::boolean_algebra, input.as_str()) @@ -46,7 +47,7 @@ impl traits::parser:: Parser for BAParser { // str += ("}}"); // } -fn _print_g_node(pair: &BAPair, node_name: &str) { +fn _print_g_node(pair: &BAPair, node_name: &str) { if pair.as_rule() == BARule::binop { println!( " {} [label=\"{}\", color=\"brown1\"];", @@ -72,7 +73,7 @@ fn _print_g_node(pair: &BAPair, node_name: &str) { } } -fn _print_graphviz_syntax_tree(pair: &BAPair, i: &mut u64) { +fn _print_graphviz_syntax_tree(pair: &BAPair, i: &mut u64) { let node_name = format!("n{}", *i); _print_g_node(&pair, &node_name); diff --git a/src/main.rs b/src/main.rs index 87d22dc..3365efe 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,13 +2,16 @@ mod boolean_algebra; mod traits; mod truthtable; -use boolean_algebra::parser::BAParser; +use boolean_algebra::{logic::generate_truth_table, parser::BAParser}; use truthtable::parser::TTParser; // use boolean_algebra::parser::parse; // use clap::Parser; // use pest::iterators::Pair; use std::{fs::File, io::Read}; -use traits::{graphvizable::Graphvizable, parser::{Pair, Parser}}; +use traits::{ + graphvizable::Graphvizable, + parser::{Pair, Parser}, +}; /// Simple tool to visualize and process concepts from TMA4140 and MA0301 #[derive(clap::Parser, Debug)] @@ -18,6 +21,14 @@ struct Args { // #[clap(with_name)] // t: String, + /// Debug mode + #[clap(short = 'd', long)] + debug: bool, + + /// Verbose mode + #[clap(short = 'v', long)] + verbose: bool, + /// Input file #[clap(short = 'i', long)] input: Option, @@ -47,13 +58,27 @@ struct Args { fn main() -> std::io::Result<()> { let args = ::parse(); + + log::set_max_level(log::LevelFilter::Info); + + if args.verbose { + log::set_max_level(log::LevelFilter::Warn) + } + + if args.debug { + log::set_max_level(log::LevelFilter::Debug) + } + + simple_logger::SimpleLogger::new().init().unwrap(); + + let mut input = String::new(); let root: Pair = if args.input_text.is_some() { input = args.input_text.unwrap(); match args.t.as_deref() { - Some("ba") => BAParser::parse(&mut input), - Some("tt") => TTParser::parse(&mut input), - _ => panic!("Doesn't recognize file"), + Some("ba") => BAParser::parse(&mut input), + Some("tt") => TTParser::parse(&mut input), + _ => panic!("Doesn't recognize file"), } // parse(&mut input) } else if args.input.is_some() { @@ -62,15 +87,21 @@ fn main() -> std::io::Result<()> { let mut file = File::open(&t)?; file.read_to_string(&mut input)?; match t.split('.').last() { - Some("ba") => BAParser::parse(&mut input), - Some("tt") => TTParser::parse(&mut input), - _ => panic!("Doesn't recognize file"), + Some("ba") => BAParser::parse(&mut input), + Some("tt") => TTParser::parse(&mut input), + _ => panic!("Doesn't recognize file"), } } else { - panic!("Provide an input"); + panic!("Provide an input"); // Err(std::io::Error::new(std::io::ErrorKind::Other, "Provide some kind of input")) }; - root.print_graphviz_diagram(); + match root { + Pair::BAPair(pair) => generate_truth_table(&pair), + _ => (), + } + + // root.print_graphviz_diagram(); + Ok(()) } diff --git a/src/traits/parser.rs b/src/traits/parser.rs index 7322d32..9068c22 100644 --- a/src/traits/parser.rs +++ b/src/traits/parser.rs @@ -1,11 +1,11 @@ -use crate::{boolean_algebra, truthtable}; +use crate::{boolean_algebra::parser::BAPair, truthtable::parser::TTPair}; use super::graphvizable::Graphvizable; pub enum Pair<'a> { - BAPair(pest::iterators::Pair<'a, boolean_algebra::parser::BARule>), - TTPair(pest::iterators::Pair<'a, truthtable::parser::TTRule>), + BAPair(BAPair<'a>), + TTPair(TTPair<'a>), } impl <'a>Graphvizable for Pair<'a> { diff --git a/src/truthtable/parser.rs b/src/truthtable/parser.rs index 68af00e..4a689b5 100644 --- a/src/truthtable/parser.rs +++ b/src/truthtable/parser.rs @@ -1,17 +1,17 @@ -use pest::iterators::Pair as TTPair; use pest::Parser; +use crate::Pair; use crate::traits; use crate::traits::graphvizable::Graphvizable; -use crate::traits::parser::Pair; // use pest_derive::Parser; #[derive(pest_derive::Parser)] #[grammar = "truthtable/truthtable.pest"] pub struct TTParser; pub type TTRule = Rule; +pub type TTPair<'a> = pest::iterators::Pair<'a, TTRule>; -impl Graphvizable for TTPair<'_, TTRule> { +impl Graphvizable for TTPair<'_> { fn graphviz_diagram(&self) -> String { let mut result = String::new(); result += "digraph parse_tree {{\n"; @@ -37,7 +37,7 @@ impl Graphvizable for TTPair<'_, TTRule> { impl traits::parser::Parser for TTParser { fn parse(input: &mut String) -> Pair { - input.retain(|c| !c.is_whitespace()); + // input.retain(|c| !c.is_whitespace()); let result = >::parse(TTRule::truthtable, input.as_str()) .expect("UNSUCCESSFUL PARSE") .next() @@ -46,7 +46,7 @@ impl traits::parser::Parser for TTParser { } } -fn g_node(pair: &TTPair, node_name: &str) -> String { +fn g_node(pair: &TTPair, node_name: &str) -> String { if pair.as_rule() == TTRule::binop { format!( " {} [label=\"{}\", color=\"brown1\"];", @@ -74,7 +74,7 @@ fn g_node(pair: &TTPair, node_name: &str) -> String { } } -fn graphviz_syntax_tree(pair: &TTPair, i: &mut u64) -> String { +fn graphviz_syntax_tree(pair: &TTPair, i: &mut u64) -> String { let node_name = format!("n{}", *i); let mut result: String = String::new(); result += &g_node(&pair, &node_name); @@ -88,7 +88,7 @@ fn graphviz_syntax_tree(pair: &TTPair, i: &mut u64) -> String { result } -fn _print_graphviz_syntax_tree(pair: &TTPair, i: &mut u64) { +fn _print_graphviz_syntax_tree(pair: &TTPair, i: &mut u64) { let node_name = format!("n{}", *i); println!("{}", g_node(&pair, &node_name)); @@ -97,12 +97,4 @@ fn _print_graphviz_syntax_tree(pair: &TTPair, i: &mut u64) { println!(" {} -> n{};", node_name, *i); _print_graphviz_syntax_tree(&inner_pair, i); } -} - -pub fn parse(input: &mut String) -> TTPair { - input.retain(|c| !c.is_whitespace()); - TTParser::parse(TTRule::truthtable, input.as_str()) - .expect("UNSUCCESSFUL PARSE") - .next() - .unwrap() } \ No newline at end of file