Command-line utilty to print the parse tree

This commit is contained in:
Aleksey Kladov 2018-01-22 02:12:26 +03:00
parent c8cf1d8cda
commit 05ad469ac3
3 changed files with 57 additions and 32 deletions

20
src/bin/parse-rust.rs Normal file
View file

@ -0,0 +1,20 @@
extern crate libsyntax2;
use std::io::Read;
use libsyntax2::{tokenize, parse};
use libsyntax2::utils::dump_tree;
fn main() {
let text = read_input();
let tokens = tokenize(&text);
let file = parse(text, &tokens);
let tree = dump_tree(&file);
println!("{}", tree);
}
fn read_input() -> String {
let mut buff = String::new();
::std::io::stdin().read_to_string(&mut buff).unwrap();
buff
}

View file

@ -10,3 +10,38 @@ pub use text::{TextUnit, TextRange};
pub use tree::{SyntaxKind, Token, FileBuilder, Sink, File, Node}; pub use tree::{SyntaxKind, Token, FileBuilder, Sink, File, Node};
pub use lexer::{next_token, tokenize}; pub use lexer::{next_token, tokenize};
pub use parser::parse; pub use parser::parse;
pub mod utils {
use std::fmt::Write;
use {File, Node};
pub fn dump_tree(file: &File) -> String {
let mut result = String::new();
go(file.root(), &mut result, 0);
return result;
fn go(node: Node, buff: &mut String, level: usize) {
buff.push_str(&String::from(" ").repeat(level));
write!(buff, "{:?}\n", node).unwrap();
let my_errors = node.errors().filter(|e| e.after_child().is_none());
let parent_errors = node.parent().into_iter()
.flat_map(|n| n.errors())
.filter(|e| e.after_child() == Some(node));
for err in my_errors {
buff.push_str(&String::from(" ").repeat(level));
write!(buff, "err: `{}`\n", err.message()).unwrap();
}
for child in node.children() {
go(child, buff, level + 1)
}
for err in parent_errors {
buff.push_str(&String::from(" ").repeat(level));
write!(buff, "err: `{}`\n", err.message()).unwrap();
}
}
}
}

View file

@ -2,9 +2,8 @@ extern crate file;
extern crate libsyntax2; extern crate libsyntax2;
extern crate testutils; extern crate testutils;
use std::fmt::Write; use libsyntax2::{tokenize, parse};
use libsyntax2::utils::dump_tree;
use libsyntax2::{tokenize, parse, Node, File};
use testutils::dir_tests; use testutils::dir_tests;
#[test] #[test]
@ -18,32 +17,3 @@ fn parser_tests() {
} }
) )
} }
fn dump_tree(file: &File) -> String {
let mut result = String::new();
go(file.root(), &mut result, 0);
return result;
fn go(node: Node, buff: &mut String, level: usize) {
buff.push_str(&String::from(" ").repeat(level));
write!(buff, "{:?}\n", node).unwrap();
let my_errors = node.errors().filter(|e| e.after_child().is_none());
let parent_errors = node.parent().into_iter()
.flat_map(|n| n.errors())
.filter(|e| e.after_child() == Some(node));
for err in my_errors {
buff.push_str(&String::from(" ").repeat(level));
write!(buff, "err: `{}`\n", err.message()).unwrap();
}
for child in node.children() {
go(child, buff, level + 1)
}
for err in parent_errors {
buff.push_str(&String::from(" ").repeat(level));
write!(buff, "err: `{}`\n", err.message()).unwrap();
}
}
}