mod refn {
use panfix::refn_impl::{parse, Grammar, GrammarBuilder, ParseTree};
use panfix::rule;
fn write_sexpr(out: &mut String, tree: &ParseTree) {
if tree.arity() == 0 {
if tree.name() == "$MissingAtom" {
out.push('?');
} else {
out.push_str(tree.text())
}
} else {
out.push('(');
if tree.name() == "$Juxtapose" {
out.push('J');
} else {
out.push_str(tree.name());
}
for child in tree.children() {
out.push(' ');
write_sexpr(out, child);
}
out.push(')');
}
}
fn run_parser(g: &Grammar, source: &str) -> String {
match parse(g, source) {
Err(err) => format!("{}", err),
Ok(tree) => {
let mut string = String::new();
write_sexpr(&mut string, &tree);
string
}
}
}
#[test]
fn test_basics() {
let g = GrammarBuilder::new()
.subgrammar("main", |builder| {
builder
.regex("Var", "[a-zA-Z]+")
.ops_r(vec![rule!(Dot: _ "." _)])
.ops_l(vec![rule!(Plus: _ "+" _), rule!(Minus: _ "-" _)])
})
.build();
assert_eq!(run_parser(&g, "xyz"), "xyz");
assert_eq!(run_parser(&g, "x+ y"), "(Plus x y)");
assert_eq!(run_parser(&g, "x y z"), "(J x (J y z))");
assert_eq!(run_parser(&g, "x.y.z"), "(Dot x (Dot y z))");
assert_eq!(run_parser(&g, "x-y+y-z"), "(Minus (Plus (Minus x y) y) z)");
assert_eq!(run_parser(&g, "p.x+p.y"), "(Plus (Dot p x) (Dot p y))");
}
}