parse_tree 0.0.7

A non-abstract syntax tree type
Documentation
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()
    );
}