From c12450fb4e30c3418555e47d045bb9fd4318a10a Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 29 Jul 2018 13:51:55 +0300 Subject: Introduce red-green syntax tree --- src/lib.rs | 52 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 4 deletions(-) (limited to 'src/lib.rs') diff --git a/src/lib.rs b/src/lib.rs index b90b70c05..cf2e97024 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,7 +12,8 @@ //! [RFC.md]: #![forbid(missing_debug_implementations, unconditional_recursion, future_incompatible)] -#![deny(bad_style, unsafe_code, missing_docs)] +#![deny(bad_style, missing_docs)] +#![allow(missing_docs)] //#![warn(unreachable_pub)] // rust-lang/rust#47816 extern crate unicode_xid; @@ -21,19 +22,24 @@ extern crate text_unit; mod tree; mod lexer; mod parser; +mod yellow; pub mod syntax_kinds; pub use text_unit::{TextRange, TextUnit}; pub use tree::{File, Node, SyntaxKind, Token}; -pub(crate) use tree::{ErrorMsg, FileBuilder, Sink}; +pub(crate) use tree::{ErrorMsg, FileBuilder, Sink, GreenBuilder}; pub use lexer::{next_token, tokenize}; -pub use parser::parse; +pub use yellow::SyntaxNode; +pub(crate) use yellow::SError; +pub use parser::{parse, parse_green}; /// Utilities for simple uses of the parser. pub mod utils { use std::fmt::Write; - use {File, Node}; + use {File, Node, SyntaxNode}; + use std::collections::BTreeSet; + use SError; /// Parse a file and create a string representation of the resulting parse tree. pub fn dump_tree(file: &File) -> String { @@ -65,4 +71,42 @@ pub mod utils { } } } + + /// Parse a file and create a string representation of the resulting parse tree. + pub fn dump_tree_green(syntax: &SyntaxNode) -> String { + 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: &SyntaxNode, buff: &mut String, level: usize, errors: &mut BTreeSet) { + 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)); +// + 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)); + write!(buff, "err: `{}`\n", err.message).unwrap(); + } + + for child in node.children().iter() { + go(child, buff, level + 1, errors) + } + + 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)); + write!(buff, "err: `{}`\n", err.message).unwrap(); + } + } + } } -- cgit v1.2.3