Initial commit
This commit is contained in:
12
src/boolean_algebra/boolean_algebra.pest
Normal file
12
src/boolean_algebra/boolean_algebra.pest
Normal file
@@ -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 }
|
||||
0
src/boolean_algebra/logic.rs
Normal file
0
src/boolean_algebra/logic.rs
Normal file
2
src/boolean_algebra/mod.rs
Normal file
2
src/boolean_algebra/mod.rs
Normal file
@@ -0,0 +1,2 @@
|
||||
pub mod parser;
|
||||
pub mod logic;
|
||||
84
src/boolean_algebra/parser.rs
Normal file
84
src/boolean_algebra/parser.rs
Normal file
@@ -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 = <BAParser as Parser<BARule>>::parse(BARule::boolean_algebra, input.as_str())
|
||||
.expect("UNSUCCESSFUL PARSE")
|
||||
.next()
|
||||
.unwrap();
|
||||
Pair::BAPair(result)
|
||||
}
|
||||
}
|
||||
|
||||
// pub fn format_graphviz_syntax_tree(root: Pair<BARule>, 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<BARule>, 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<BARule>, 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);
|
||||
}
|
||||
}
|
||||
12
src/grammars/grammar.pest
Normal file
12
src/grammars/grammar.pest
Normal file
@@ -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 }
|
||||
76
src/main.rs
Normal file
76
src/main.rs
Normal file
@@ -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<String>,
|
||||
|
||||
/// Input text
|
||||
#[clap(short = 'e', long)]
|
||||
input_text: Option<String>,
|
||||
|
||||
/// Input type
|
||||
#[clap(short, long = "type")]
|
||||
t: Option<String>,
|
||||
|
||||
/// Output file
|
||||
#[clap(short = 'o', long)]
|
||||
output: Option<String>,
|
||||
|
||||
/// 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 = <Args as clap::Parser>::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(())
|
||||
}
|
||||
5
src/traits/graphvizable.rs
Normal file
5
src/traits/graphvizable.rs
Normal file
@@ -0,0 +1,5 @@
|
||||
pub trait Graphvizable {
|
||||
// fn new(name: &'static str) -> Self;
|
||||
fn graphviz_diagram(&self) -> String;
|
||||
fn print_graphviz_diagram(&self);
|
||||
}
|
||||
2
src/traits/mod.rs
Normal file
2
src/traits/mod.rs
Normal file
@@ -0,0 +1,2 @@
|
||||
pub mod graphvizable;
|
||||
pub mod parser;
|
||||
29
src/traits/parser.rs
Normal file
29
src/traits/parser.rs
Normal file
@@ -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;
|
||||
}
|
||||
1
src/truthtable/mod.rs
Normal file
1
src/truthtable/mod.rs
Normal file
@@ -0,0 +1 @@
|
||||
pub mod parser;
|
||||
108
src/truthtable/parser.rs
Normal file
108
src/truthtable/parser.rs
Normal file
@@ -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 = <TTParser as Parser<TTRule>>::parse(TTRule::truthtable, input.as_str())
|
||||
.expect("UNSUCCESSFUL PARSE")
|
||||
.next()
|
||||
.unwrap();
|
||||
Pair::TTPair(result)
|
||||
}
|
||||
}
|
||||
|
||||
fn g_node(pair: &TTPair<TTRule>, 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<TTRule>, 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<TTRule>, 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<TTRule> {
|
||||
input.retain(|c| !c.is_whitespace());
|
||||
TTParser::parse(TTRule::truthtable, input.as_str())
|
||||
.expect("UNSUCCESSFUL PARSE")
|
||||
.next()
|
||||
.unwrap()
|
||||
}
|
||||
21
src/truthtable/truthtable.pest
Normal file
21
src/truthtable/truthtable.pest
Normal file
@@ -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+ }
|
||||
Reference in New Issue
Block a user