Improve debug_dump performance

This commit is contained in:
Aleksey Kladov 2018-07-31 22:14:56 +03:00
parent 5d8cef4c0e
commit 8105c14454
9 changed files with 49 additions and 49 deletions

View file

@ -33,9 +33,7 @@ fn main() -> Result<()> {
.get_matches();
match matches.subcommand() {
("parse", _) => {
let start = Instant::now();
let tree = parse()?;
eprintln!("elapsed {:?}", start.elapsed());
println!("{}", tree);
}
("render-test", Some(matches)) => {
@ -53,7 +51,9 @@ fn main() -> Result<()> {
fn parse() -> Result<String> {
let text = read_stdin()?;
let start = Instant::now();
let file = libsyntax2::parse(text);
eprintln!("elapsed {:?}", start.elapsed());
let tree = libsyntax2::utils::dump_tree(&file);
Ok(tree)
}

View file

@ -8,12 +8,12 @@ pub fn preorder<'a>(root: SyntaxNodeRef<'a>) -> impl Iterator<Item = SyntaxNodeR
}
#[derive(Debug, Copy, Clone)]
enum WalkEvent<'a> {
pub enum WalkEvent<'a> {
Enter(SyntaxNodeRef<'a>),
Exit(SyntaxNodeRef<'a>),
}
fn walk<'a>(root: SyntaxNodeRef<'a>) -> impl Iterator<Item = WalkEvent<'a>> {
pub fn walk<'a>(root: SyntaxNodeRef<'a>) -> impl Iterator<Item = WalkEvent<'a>> {
let mut done = false;
::itertools::unfold(WalkEvent::Enter(root), move |pos| {
if done {

View file

@ -41,8 +41,6 @@ pub use {
yellow::{SyntaxNode, SyntaxNodeRef, SyntaxRoot, TreeRoot},
};
pub(crate) use yellow::SyntaxError;
pub fn parse(text: String) -> SyntaxNode {
let tokens = tokenize(&text);
parser::parse::<yellow::GreenBuilder>(text, &tokens)

View file

@ -1,46 +1,48 @@
use std::{collections::BTreeSet, fmt::Write};
use {SyntaxError, SyntaxNode, SyntaxNodeRef};
use std::{fmt::Write};
use {
SyntaxNode,
algo::walk::{WalkEvent, walk},
};
/// Parse a file and create a string representation of the resulting parse tree.
pub fn dump_tree(syntax: &SyntaxNode) -> String {
let syntax = syntax.as_ref();
let mut errors: BTreeSet<_> = syntax.root.errors.iter().cloned().collect();
let mut result = String::new();
go(syntax, &mut result, 0, &mut errors);
return result;
fn go(
node: SyntaxNodeRef,
buff: &mut String,
level: usize,
errors: &mut BTreeSet<SyntaxError>,
) {
buff.push_str(&String::from(" ").repeat(level));
writeln!(buff, "{:?}", node).unwrap();
let my_errors: Vec<_> = errors
.iter()
.filter(|e| e.offset == node.range().start())
.cloned()
.collect();
for err in my_errors {
errors.remove(&err);
buff.push_str(&String::from(" ").repeat(level));
writeln!(buff, "err: `{}`", err.message).unwrap();
let mut errors: Vec<_> = syntax.root.errors.iter().cloned().collect();
errors.sort_by_key(|e| e.offset);
let mut err_pos = 0;
let mut level = 0;
let mut buf = String::new();
macro_rules! indent {
() => {
for _ in 0..level {
buf.push_str(" ");
}
};
}
for child in node.children() {
go(child, buff, level + 1, errors)
for event in walk(syntax) {
match event {
WalkEvent::Enter(node) => {
indent!();
writeln!(buf, "{:?}", node).unwrap();
if node.first_child().is_none() {
let off = node.range().end();
while err_pos < errors.len() && errors[err_pos].offset <= off {
indent!();
writeln!(buf, "err: `{}`", errors[err_pos].message).unwrap();
err_pos += 1;
}
}
level += 1;
},
WalkEvent::Exit(_) => level -= 1,
}
}
let my_errors: Vec<_> = errors
.iter()
.filter(|e| e.offset == node.range().end())
.cloned()
.collect();
for err in my_errors {
errors.remove(&err);
buff.push_str(&String::from(" ").repeat(level));
writeln!(buff, "err: `{}`", err.message).unwrap();
}
assert_eq!(level, 0);
for err in errors[err_pos..].iter() {
writeln!(buf, "err: `{}`", err.message).unwrap();
}
return buf;
}

View file

@ -1,7 +1,7 @@
FILE@[0; 21)
err: `expected item`
ERROR@[0; 3)
IF_KW@[0; 2)
err: `expected item`
WHITESPACE@[2; 3)
err: `expected item`
ERROR@[3; 10)

View file

@ -9,8 +9,8 @@ FILE@[0; 12)
WHITESPACE@[3; 4)
IDENT@[4; 7) "foo"
COLONCOLON@[7; 9)
err: `expected SEMI`
err: `expected identifier`
err: `expected SEMI`
err: `expected item`
PATH_SEGMENT@[9; 9)
ERROR@[9; 11)

View file

@ -1,7 +1,7 @@
FILE@[0; 31)
err: `expected item`
ERROR@[0; 3)
R_CURLY@[0; 1)
err: `expected item`
WHITESPACE@[1; 3)
STRUCT_ITEM@[3; 14)
STRUCT_KW@[3; 9)

View file

@ -13,8 +13,8 @@ FILE@[0; 18)
L_PAREN@[10; 11)
R_PAREN@[11; 12)
WHITESPACE@[12; 13)
err: `expected SEMI`
err: `expected `;` or `]``
err: `expected SEMI`
err: `expected item`
ERROR@[13; 15)
INT_NUMBER@[13; 15)

View file

@ -8,8 +8,8 @@ FILE@[0; 20)
EQ@[7; 8)
WHITESPACE@[8; 9)
UNSAFE_KW@[9; 15)
err: `expected SEMI`
err: `expected `fn``
err: `expected SEMI`
WHITESPACE@[15; 16)
err: `expected item`
ERROR@[16; 17)