commit 1d1a72f32248e0dce696b227d59d97497ea4a663 Author: h7x4 Date: Thu Mar 3 12:53:48 2022 +0100 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..0b13d31 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,376 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "block-buffer" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" +dependencies = [ + "block-padding", + "byte-tools", + "byteorder", + "generic-array", +] + +[[package]] +name = "block-padding" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" +dependencies = [ + "byte-tools", +] + +[[package]] +name = "byte-tools" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "clap" +version = "3.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d76c22c9b9b215eeb8d016ad3a90417bd13cb24cf8142756e6472445876cab7" +dependencies = [ + "atty", + "bitflags", + "clap_derive", + "indexmap", + "lazy_static", + "os_str_bytes", + "strsim", + "termcolor", + "textwrap", +] + +[[package]] +name = "clap_derive" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fd1122e63869df2cb309f449da1ad54a7c6dfeb7c7e6ccd8e0825d9eb93bb72" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "digest" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" +dependencies = [ + "generic-array", +] + +[[package]] +name = "diskmat_tools" +version = "0.1.0" +dependencies = [ + "clap", + "pest", + "pest_derive", +] + +[[package]] +name = "fake-simd" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" + +[[package]] +name = "generic-array" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" +dependencies = [ + "typenum", +] + +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" + +[[package]] +name = "heck" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "indexmap" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.119" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4" + +[[package]] +name = "maplit" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" + +[[package]] +name = "memchr" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" + +[[package]] +name = "opaque-debug" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" + +[[package]] +name = "os_str_bytes" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64" +dependencies = [ + "memchr", +] + +[[package]] +name = "pest" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" +dependencies = [ + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "833d1ae558dc601e9a60366421196a8d94bc0ac980476d0b67e1d0988d72b2d0" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pest_meta" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d" +dependencies = [ + "maplit", + "pest", + "sha-1", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "sha-1" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df" +dependencies = [ + "block-buffer", + "digest", + "fake-simd", + "opaque-debug", +] + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "syn" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "termcolor" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "textwrap" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80" + +[[package]] +name = "typenum" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" + +[[package]] +name = "ucd-trie" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..32d0ccd --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "diskmat_tools" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +pest = "2.1.3" +pest_derive = "2.0" +clap = { version = "3.1.1", features = ["derive"] } diff --git a/example_files/boolean_algebra/ex1.ba b/example_files/boolean_algebra/ex1.ba new file mode 100644 index 0000000..0ebb375 --- /dev/null +++ b/example_files/boolean_algebra/ex1.ba @@ -0,0 +1 @@ +A(B + (AQ))C+C(A + !(B!Q)) \ No newline at end of file diff --git a/example_files/boolean_algebra/ex2.ba b/example_files/boolean_algebra/ex2.ba new file mode 100644 index 0000000..4002070 --- /dev/null +++ b/example_files/boolean_algebra/ex2.ba @@ -0,0 +1 @@ +A(A + B + (AQ + ((BQ)(BQA)))(A)(B)(C) + (A!CA)C(!A))C+C(A + !(B!Q)(!A)) + (K) \ No newline at end of file diff --git a/example_files/matrix/example1.mx b/example_files/matrix/example1.mx new file mode 100644 index 0000000..8c4a013 --- /dev/null +++ b/example_files/matrix/example1.mx @@ -0,0 +1,4 @@ +0110 +1001 +1001 +0110 diff --git a/example_files/truthtable/ex1.tt b/example_files/truthtable/ex1.tt new file mode 100644 index 0000000..731b7d0 --- /dev/null +++ b/example_files/truthtable/ex1.tt @@ -0,0 +1 @@ +p, q, s, p and q, E p iff q, p iff (q and s), E not ((not p and q) or (not p and not q)) or (p and q) \ No newline at end of file diff --git a/src/boolean_algebra/boolean_algebra.pest b/src/boolean_algebra/boolean_algebra.pest new file mode 100644 index 0000000..c8e0368 --- /dev/null +++ b/src/boolean_algebra/boolean_algebra.pest @@ -0,0 +1,12 @@ +boolean_algebra = { SOI ~ expression ~ EOI } +expression = { negatable_term ~ (binop ~ negatable_term)* } +negatable_term = _{ negated | term } +negated = ${ negation ~ term } +term = _{ label | "(" ~ expression ~ ")" } + +negation = _{ "!" | "~" } +binop = @{ or_op | and_op } + and_op = _{ "" } + or_op = _{ "+" } + +label = @{ ASCII_ALPHA } \ No newline at end of file diff --git a/src/boolean_algebra/logic.rs b/src/boolean_algebra/logic.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/boolean_algebra/mod.rs b/src/boolean_algebra/mod.rs new file mode 100644 index 0000000..9156c50 --- /dev/null +++ b/src/boolean_algebra/mod.rs @@ -0,0 +1,2 @@ +pub mod parser; +pub mod logic; \ No newline at end of file diff --git a/src/boolean_algebra/parser.rs b/src/boolean_algebra/parser.rs new file mode 100644 index 0000000..2155fdd --- /dev/null +++ b/src/boolean_algebra/parser.rs @@ -0,0 +1,84 @@ +use crate::traits::{parser::Pair, self}; + +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; + +impl Graphvizable for BAPair<'_, BARule> { + fn print_graphviz_diagram(&self) { + let mut i: u64 = 0; + println!("digraph parse_tree {{"); + println!("ratio = fill;"); + println!("node [style=filled];"); + _print_graphviz_syntax_tree(self, &mut i); + println!("}}"); + } + + fn graphviz_diagram(&self) -> String { + todo!() + } +} + +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()) + .expect("UNSUCCESSFUL PARSE") + .next() + .unwrap(); + Pair::BAPair(result) + } +} + +// pub fn format_graphviz_syntax_tree(root: Pair, output: &mut str) { +// let mut i: u64 = 0; +// str += ("digraph parse_tree {{"); +// str += ("ratio = fill;"); +// str += ("node [style=filled];"); +// _print_graphviz_syntax_tree(root, &mut i); +// str += ("}}"); +// } + +fn _print_g_node(pair: &BAPair, node_name: &str) { + if pair.as_rule() == BARule::binop { + println!( + " {} [label=\"{}\", color=\"brown1\"];", + node_name, + pair.as_str() + ); + } else if pair.as_rule() == BARule::label { + println!( + " {} [label=\"{}\", color=\"lightgoldenrod1\"];", + node_name, + pair.as_str() + ); + } else if pair.as_rule() == BARule::negated { + println!(" {} [label=\"~\", color=\"orange\"];", node_name); + } else if pair.as_rule() == BARule::expression { + println!( + " {} [label=\"{}\", color=\"chartreuse2\"];", + node_name, + pair.as_str() + ); + } else { + println!(" {} [label=\"{:?}\"];", node_name, pair.as_rule()); + } +} + +fn _print_graphviz_syntax_tree(pair: &BAPair, i: &mut u64) { + let node_name = format!("n{}", *i); + _print_g_node(&pair, &node_name); + + for inner_pair in pair.clone().into_inner() { + *i += 1; + println!(" {} -> n{};", node_name, *i); + _print_graphviz_syntax_tree(&inner_pair, i); + } +} diff --git a/src/grammars/grammar.pest b/src/grammars/grammar.pest new file mode 100644 index 0000000..fa998f1 --- /dev/null +++ b/src/grammars/grammar.pest @@ -0,0 +1,12 @@ +WHITESPACE = _{ " " } + +int = @{ ASCII_NONZERO_DIGIT ~ ASCII_DIGIT* } +float = @{ int ~ "." ~ ASCII_DIGIT+ } +num = @{ float | int } + +operator = _{ "+" | "-" | "*" | "/" } + +expr = { term ~ (operator ~ term)* } +term = _{ num | "(" ~ expr ~ ")" } + +calculation = _{ SOI ~ expr ~ EOI } diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..87d22dc --- /dev/null +++ b/src/main.rs @@ -0,0 +1,76 @@ +mod boolean_algebra; +mod traits; +mod truthtable; + +use boolean_algebra::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}}; + +/// Simple tool to visualize and process concepts from TMA4140 and MA0301 +#[derive(clap::Parser, Debug)] +#[clap(author, version, about, long_about = None)] +struct Args { + /// + // #[clap(with_name)] + // t: String, + + /// Input file + #[clap(short = 'i', long)] + input: Option, + + /// Input text + #[clap(short = 'e', long)] + input_text: Option, + + /// Input type + #[clap(short, long = "type")] + t: Option, + + /// Output file + #[clap(short = 'o', long)] + output: Option, + + /// Print syntax tree + #[clap(short = 's', long)] + export_syntax_tree: bool, +} + +// union Rule { +// ba: boolean_algebra::parser::BARule, +// tt: truthtable::parser::TTRule, +// } + +fn main() -> std::io::Result<()> { + let args = ::parse(); + + 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"), + } + // parse(&mut input) + } else if args.input.is_some() { + // } else { + let t = args.input.unwrap(); + 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"), + } + } else { + panic!("Provide an input"); + // Err(std::io::Error::new(std::io::ErrorKind::Other, "Provide some kind of input")) + }; + + root.print_graphviz_diagram(); + Ok(()) +} diff --git a/src/traits/graphvizable.rs b/src/traits/graphvizable.rs new file mode 100644 index 0000000..dc0465e --- /dev/null +++ b/src/traits/graphvizable.rs @@ -0,0 +1,5 @@ +pub trait Graphvizable { + // fn new(name: &'static str) -> Self; + fn graphviz_diagram(&self) -> String; + fn print_graphviz_diagram(&self); +} \ No newline at end of file diff --git a/src/traits/mod.rs b/src/traits/mod.rs new file mode 100644 index 0000000..33796cf --- /dev/null +++ b/src/traits/mod.rs @@ -0,0 +1,2 @@ +pub mod graphvizable; +pub mod parser; \ No newline at end of file diff --git a/src/traits/parser.rs b/src/traits/parser.rs new file mode 100644 index 0000000..7322d32 --- /dev/null +++ b/src/traits/parser.rs @@ -0,0 +1,29 @@ + +use crate::{boolean_algebra, truthtable}; + +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>), +} + +impl <'a>Graphvizable for Pair<'a> { + fn graphviz_diagram(&self) -> String { + match &self { + Pair::BAPair(pair) => pair.graphviz_diagram(), + Pair::TTPair(pair) => pair.graphviz_diagram() + } + } + + fn print_graphviz_diagram(&self) { + match &self { + Pair::BAPair(pair) => pair.print_graphviz_diagram(), + Pair::TTPair(pair) => pair.print_graphviz_diagram() + } + } +} + +pub trait Parser { + fn parse(input: &mut String) -> Pair; +} \ No newline at end of file diff --git a/src/truthtable/mod.rs b/src/truthtable/mod.rs new file mode 100644 index 0000000..b2819a7 --- /dev/null +++ b/src/truthtable/mod.rs @@ -0,0 +1 @@ +pub mod parser; \ No newline at end of file diff --git a/src/truthtable/parser.rs b/src/truthtable/parser.rs new file mode 100644 index 0000000..68af00e --- /dev/null +++ b/src/truthtable/parser.rs @@ -0,0 +1,108 @@ +use pest::iterators::Pair as TTPair; +use pest::Parser; + +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; + +impl Graphvizable for TTPair<'_, TTRule> { + fn graphviz_diagram(&self) -> String { + let mut result = String::new(); + result += "digraph parse_tree {{\n"; + result += "ratio = fill;\n"; + result += "node [style=filled];\n"; + + let mut i: u64 = 0; + result += &graphviz_syntax_tree(&self, &mut i); + + result += "}}\n"; + result + } + + fn print_graphviz_diagram(&self) { + let mut i: u64 = 0; + println!("digraph parse_tree {{"); + println!("ratio = fill;"); + println!("node [style=filled];"); + _print_graphviz_syntax_tree(&self, &mut i); + println!("}}"); + } +} + +impl traits::parser::Parser for TTParser { + fn parse(input: &mut String) -> Pair { + input.retain(|c| !c.is_whitespace()); + let result = >::parse(TTRule::truthtable, input.as_str()) + .expect("UNSUCCESSFUL PARSE") + .next() + .unwrap(); + Pair::TTPair(result) + } +} + +fn g_node(pair: &TTPair, node_name: &str) -> String { + if pair.as_rule() == TTRule::binop { + format!( + " {} [label=\"{}\", color=\"brown1\"];", + node_name, + pair.as_str() + ) + } else if pair.as_rule() == TTRule::label { + format!( + " {} [label=\"{}\", color=\"lightgoldenrod1\"];", + node_name, + pair.as_str() + ) + // } else if pair.as_rule() == BARule::emphazised { + // println!(" {} [label=\"E\", color=\"aqua\"];", node_name); + } else if pair.as_rule() == TTRule::negated { + format!(" {} [label=\"~\", color=\"orange\"];", node_name) + } else if pair.as_rule() == TTRule::expression { + format!( + " {} [label=\"{}\", color=\"chartreuse2\"];", + node_name, + pair.as_str() + ) + } else { + format!(" {} [label=\"{:?}\"];", node_name, pair.as_rule()) + } +} + +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); + + for inner_pair in pair.clone().into_inner() { + *i += 1; + result += &format!(" {} -> n{};", node_name, *i); + result += &graphviz_syntax_tree(&inner_pair, i); + } + + result +} + +fn _print_graphviz_syntax_tree(pair: &TTPair, i: &mut u64) { + let node_name = format!("n{}", *i); + println!("{}", g_node(&pair, &node_name)); + + for inner_pair in pair.clone().into_inner() { + *i += 1; + 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 diff --git a/src/truthtable/truthtable.pest b/src/truthtable/truthtable.pest new file mode 100644 index 0000000..a4c2bae --- /dev/null +++ b/src/truthtable/truthtable.pest @@ -0,0 +1,21 @@ +WHITESPACE = _{ " " } + +truthtable = { SOI ~ column_list ~ EOI } + +column_list = _{ column ~ (", " ~ column)* } + +column = _{ emphazised | expression } +emphazised = { "E" ~ expression } +expression = { negatable_term ~ (binop ~ negatable_term)* } +negatable_term = _{ negated | term } +negated = { negation ~ term } +term = _{ label | "(" ~ expression ~ ")" } + +negation = _{ "not" | "!" | "~" } +binop = @{ and_op | or_op | iff_op | if_op } + and_op = _{ "and" | "^" | "&&" } + or_op = _{ "or" | "v" | "||" } + if_op = _{ "if" | "->" } + iff_op = _{ "iff" | "<->" | "<>" } + +label = @{ ASCII_ALPHA+ } \ No newline at end of file