From a5dc5f1b5cc7932477225128b2c6c9e8dff9cd73 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 8 Aug 2018 21:14:18 +0300 Subject: Improve tree building --- Cargo.toml | 3 +++ cli/src/main.rs | 1 + src/yellow/builder.rs | 39 +++++++++++++++++++++------------------ src/yellow/green.rs | 35 ++++++++--------------------------- src/yellow/mod.rs | 2 +- 5 files changed, 34 insertions(+), 46 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c343ac57b..f03ce76c9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,3 +16,6 @@ parking_lot = "0.6.0" [dev-dependencies] testutils = { path = "./tests/testutils" } + +[profile.release] +debug = true \ No newline at end of file diff --git a/cli/src/main.rs b/cli/src/main.rs index e5b1aae46..f6c66743f 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -47,6 +47,7 @@ fn main() -> Result<()> { println!("{}", file.syntax_tree()); } eprintln!("parsing: {:?}", elapsed); + ::std::mem::forget(file); } ("symbols", _) => { let file = file()?; diff --git a/src/yellow/builder.rs b/src/yellow/builder.rs index dbe646cd7..70869952c 100644 --- a/src/yellow/builder.rs +++ b/src/yellow/builder.rs @@ -1,14 +1,14 @@ use { parser_impl::Sink, - yellow::{GreenNode, GreenNodeBuilder, SyntaxError, SyntaxNode, SyntaxRoot}, + yellow::{GreenNode, SyntaxError, SyntaxNode, SyntaxRoot}, SyntaxKind, TextRange, TextUnit, }; pub(crate) struct GreenBuilder<'a> { text: &'a str, - stack: Vec, + parents: Vec<(SyntaxKind, usize)>, + children: Vec, pos: TextUnit, - root: Option, errors: Vec, } @@ -18,9 +18,9 @@ impl<'a> Sink<'a> for GreenBuilder<'a> { fn new(text: &'a str) -> Self { GreenBuilder { text, - stack: Vec::new(), + parents: Vec::new(), + children: Vec::new(), pos: 0.into(), - root: None, errors: Vec::new(), } } @@ -29,23 +29,24 @@ impl<'a> Sink<'a> for GreenBuilder<'a> { let range = TextRange::offset_len(self.pos, len); self.pos += len; let text = &self.text[range]; - let leaf = GreenNodeBuilder::new_leaf(kind, text); - let parent = self.stack.last_mut().unwrap(); - parent.push_child(leaf) + self.children.push( + GreenNode::new_leaf(kind, text) + ); } fn start_internal(&mut self, kind: SyntaxKind) { - self.stack.push(GreenNodeBuilder::new_internal(kind)) + let len = self.children.len(); + self.parents.push((kind, len)); } fn finish_internal(&mut self) { - let builder = self.stack.pop().unwrap(); - let node = builder.build(); - if let Some(parent) = self.stack.last_mut() { - parent.push_child(node); - } else { - self.root = Some(node); - } + let (kind, first_child) = self.parents.pop().unwrap(); + let children = self.children + .drain(first_child..) + .collect(); + self.children.push( + GreenNode::new_branch(kind, children) + ); } fn error(&mut self, message: String) { @@ -55,8 +56,10 @@ impl<'a> Sink<'a> for GreenBuilder<'a> { }) } - fn finish(self) -> SyntaxNode { - let root = SyntaxRoot::new(self.root.unwrap(), self.errors); + fn finish(mut self) -> SyntaxNode { + assert_eq!(self.children.len(), 1); + let root = self.children.pop().unwrap(); + let root = SyntaxRoot::new(root, self.errors); SyntaxNode::new_owned(root) } } diff --git a/src/yellow/green.rs b/src/yellow/green.rs index 26df76af6..5b4ce313a 100644 --- a/src/yellow/green.rs +++ b/src/yellow/green.rs @@ -12,6 +12,14 @@ pub(crate) enum GreenNode { } impl GreenNode { + pub(crate) fn new_leaf(kind: SyntaxKind, text: &str) -> GreenNode { + GreenNode::Leaf(GreenLeaf::new(kind, text)) + } + + pub(crate) fn new_branch(kind: SyntaxKind, children: Vec) -> GreenNode { + GreenNode::Branch(Arc::new(GreenBranch::new(kind, children))) + } + pub fn kind(&self) -> SyntaxKind { match self { GreenNode::Leaf(l) => l.kind(), @@ -46,33 +54,6 @@ impl GreenNode { } } -pub(crate) struct GreenNodeBuilder { - kind: SyntaxKind, - children: Vec, -} - -impl GreenNodeBuilder { - pub(crate) fn new_leaf(kind: SyntaxKind, text: &str) -> GreenNode { - GreenNode::Leaf(GreenLeaf::new(kind, text)) - } - - pub(crate) fn new_internal(kind: SyntaxKind) -> GreenNodeBuilder { - GreenNodeBuilder { - kind, - children: Vec::new(), - } - } - - pub(crate) fn push_child(&mut self, node: GreenNode) { - self.children.push(node) - } - - pub(crate) fn build(self) -> GreenNode { - let branch = GreenBranch::new(self.kind, self.children); - GreenNode::Branch(Arc::new(branch)) - } -} - #[test] fn assert_send_sync() { fn f() {} diff --git a/src/yellow/mod.rs b/src/yellow/mod.rs index f20be356d..1b5d4e4df 100644 --- a/src/yellow/mod.rs +++ b/src/yellow/mod.rs @@ -6,7 +6,7 @@ mod syntax; pub use self::syntax::{SyntaxNode, SyntaxNodeRef, SyntaxRoot, TreeRoot}; pub(crate) use self::{ builder::GreenBuilder, - green::{GreenNode, GreenNodeBuilder}, + green::GreenNode, red::RedNode, syntax::SyntaxError, }; -- cgit v1.2.3