1#![deny(warnings)]
2
3use crate::ebnf::ParserBuilder;
4use earlgrey::{EarleyParser, EarleyForest};
5use std::fmt::Debug;
6
7#[derive(Clone,Debug)]
8pub enum Sexpr {
9 Atom(String),
10 List(Vec<Sexpr>),
11}
12
13#[derive(Debug,Clone,PartialEq)]
14pub enum Tree {
15 Leaf(String, String),
18 Node(String, Vec<Tree>),
20}
21
22impl Sexpr {
23 pub fn print(&self) -> String {
24 let mut out = String::new();
25 self.print_helper("", &mut out);
26 out
27 }
28
29 fn print_helper(&self, indent: &str, out: &mut String) {
30 match *self {
31 Sexpr::Atom(ref lexeme) =>
32 *out += &format!("\u{2500} {}\n", lexeme),
33 Sexpr::List(ref subn) => {
34 let (first, rest) = subn.split_first().unwrap();
35 let (last, rest) = rest.split_last().unwrap();
36 *out += &format!("\u{252c}");
37 first.print_helper(&format!("{}\u{2502}", indent), out);
38 for mid in rest {
39 *out += &format!("{}\u{251c}", indent);
40 mid.print_helper(&format!("{}\u{2502}", indent), out);
41 }
42 *out += &format!("{}\u{2570}", indent);
43 last.print_helper(&format!("{} ", indent), out);
44 }
45 }
46 }
47}
48
49impl ParserBuilder {
50 pub fn treeficator<SI>(self, grammar: &str, start: &str)
51 -> impl Fn(SI) -> Result<Vec<Tree>, String>
52 where SI: Iterator, SI::Item: AsRef<str> + Debug
53 {
54 let grammar = ParserBuilder::parse_grammar(self.0, grammar)
57 .unwrap_or_else(|e| panic!("treeficator error: {:?}", e))
58 .into_grammar(start)
59 .unwrap_or_else(|e| panic!("treeficator error: {:?}", e));
60 let mut tree_builder = EarleyForest::new(
62 |sym, tok| Tree::Leaf(sym.to_string(), tok.to_string()));
63 for rule in grammar.rules.iter().map(|r| r.to_string()) {
64 tree_builder.action(
65 &rule.clone(), move |nodes| Tree::Node(rule.clone(), nodes));
66 }
67 let parser = EarleyParser::new(grammar);
69 move |tokenizer| tree_builder.eval_all(&parser.parse(tokenizer)?)
70 }
71
72 pub fn sexprificator<SI>(self, grammar: &str, start: &str)
73 -> impl Fn(SI) -> Result<Vec<Sexpr>, String>
74 where SI: Iterator, SI::Item: AsRef<str> + Debug
75 {
76 let grammar = ParserBuilder::parse_grammar(self.0, grammar)
79 .unwrap_or_else(|e| panic!("treeficator error: {:?}", e))
80 .into_grammar(start)
81 .unwrap_or_else(|e| panic!("treeficator error: {:?}", e));
82 let mut tree_builder = EarleyForest::new(
84 |_, tok| Sexpr::Atom(tok.to_string()));
85 for rule in &grammar.rules {
86 tree_builder.action(&rule.to_string(),
87 move |mut nodes| match nodes.len() {
88 1 => nodes.swap_remove(0),
89 _ => Sexpr::List(nodes),
90 });
91 }
92 let parser = EarleyParser::new(grammar);
94 move |tokenizer| tree_builder.eval_all(&parser.parse(tokenizer)?)
95 }
96}