extern crate parse_tree;
use parse_tree::{
Symbol, ParseTree, PtNodeId,
algo::{AsParseTree, GetSymbol, GetText},
};
const WHITESPACE: Symbol = Symbol(0);
const NUMBER: Symbol = Symbol(1);
const STAR: Symbol = Symbol(2);
const MUL_EXPR: Symbol = Symbol(3);
struct TestTree {
text: String,
tree: ParseTree,
}
impl AsParseTree for TestTree {
fn as_parse_tree(&self) -> &ParseTree {
&self.tree
}
}
impl GetText for TestTree {
fn get_text(&self, id: PtNodeId) -> String {
let range = self.tree[id].range();
self.text[range].to_owned()
}
}
impl GetSymbol for TestTree {
fn get_symbol(&self, id: PtNodeId) -> String {
let symbol = self.tree[id].symbol();
let name = match symbol {
WHITESPACE => "WHITESPACE",
NUMBER => "NUMBER",
STAR => "STAR",
MUL_EXPR => "MUL_EXPR",
_ => panic!("unknown symbol: {:?}", symbol)
};
name.to_owned()
}
}
#[test]
fn top_down() {
let text = "46 * 2";
let tree = {
let mut builder = parse_tree::TopDownBuilder::new();
builder.start_internal(MUL_EXPR);
builder.leaf(NUMBER, 2.into());
builder.leaf(WHITESPACE, 1.into());
builder.leaf(STAR, 1.into());
builder.leaf(WHITESPACE, 1.into());
builder.leaf(NUMBER, 1.into());
builder.finish_internal();
builder.finish()
};
let tree = TestTree {
text: text.to_string(),
tree
};
let debug = parse_tree::algo::debug_dump(&tree);
assert_eq!(
debug.trim(),
r#"
MUL_EXPR@[0; 6)
NUMBER@[0; 2) "46"
WHITESPACE@[2; 3)
STAR@[3; 4) "*"
WHITESPACE@[4; 5)
NUMBER@[5; 6) "2"
"#.trim()
);
}
#[test]
fn bottom_up() {
let text = "46 * 2";
let tree = {
let mut builder = parse_tree::BottomUpBuilder::new();
builder.shift(NUMBER, 2.into());
builder.shift(WHITESPACE, 1.into());
builder.shift(STAR, 1.into());
builder.shift(WHITESPACE, 1.into());
builder.shift(NUMBER, 1.into());
builder.reduce(MUL_EXPR, 5);
builder.finish()
};
let tree = TestTree {
text: text.to_string(),
tree
};
let debug = parse_tree::algo::debug_dump(&tree);
assert_eq!(
debug.trim(),
r#"
MUL_EXPR@[0; 6)
NUMBER@[0; 2) "46"
WHITESPACE@[2; 3)
STAR@[3; 4) "*"
WHITESPACE@[4; 5)
NUMBER@[5; 6) "2"
"#.trim()
);
}