diskmat-tools/src/truthtable/parser.rs

108 lines
3.1 KiB
Rust

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()
}