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