Parser: extract sink trait

This commit is contained in:
Aleksey Kladov 2018-01-01 00:13:56 +03:00
parent 8c478a794c
commit 9ed73378ce
4 changed files with 48 additions and 39 deletions

View File

@ -7,6 +7,6 @@
pub mod syntax_kinds;
pub use text::{TextUnit, TextRange};
pub use tree::{SyntaxKind, Token, FileBuilder, File, Node};
pub use tree::{SyntaxKind, Token, FileBuilder, Sink, File, Node};
pub use lexer::{next_token, tokenize};
pub use parser::parse;

View File

@ -1,4 +1,4 @@
use {Token, File, FileBuilder};
use {Token, File, FileBuilder, Sink};
use syntax_kinds::*;

View File

@ -1,6 +1,13 @@
use {SyntaxKind, TextUnit, TextRange};
use super::{NodeData, NodeIdx, File};
pub trait Sink {
fn leaf(&mut self, kind: SyntaxKind, len: TextUnit);
fn start_internal(&mut self, kind: SyntaxKind);
fn finish_internal(&mut self);
}
pub struct FileBuilder {
text: String,
nodes: Vec<NodeData>,
@ -8,6 +15,44 @@ pub struct FileBuilder {
pos: TextUnit,
}
impl Sink for FileBuilder {
fn leaf(&mut self, kind: SyntaxKind, len: TextUnit) {
let leaf = NodeData {
kind,
range: TextRange::from_len(self.pos, len),
parent: None,
first_child: None,
next_sibling: None,
};
self.pos += len;
let id = self.push_child(leaf);
self.add_len(id);
}
fn start_internal(&mut self, kind: SyntaxKind) {
let node = NodeData {
kind,
range: TextRange::from_len(self.pos, 0.into()),
parent: None,
first_child: None,
next_sibling: None,
};
let id = if self.in_progress.is_empty() {
self.new_node(node)
} else {
self.push_child(node)
};
self.in_progress.push((id, None))
}
fn finish_internal(&mut self) {
let (id, _) = self.in_progress.pop().unwrap();
if !self.in_progress.is_empty() {
self.add_len(id);
}
}
}
impl FileBuilder {
pub fn new(text: String) -> FileBuilder {
FileBuilder {
@ -27,42 +72,6 @@ pub fn finish(self) -> File {
}
}
pub fn leaf(&mut self, kind: SyntaxKind, len: TextUnit) {
let leaf = NodeData {
kind,
range: TextRange::from_len(self.pos, len),
parent: None,
first_child: None,
next_sibling: None,
};
self.pos += len;
let id = self.push_child(leaf);
self.add_len(id);
}
pub fn start_internal(&mut self, kind: SyntaxKind) {
let node = NodeData {
kind,
range: TextRange::from_len(self.pos, 0.into()),
parent: None,
first_child: None,
next_sibling: None,
};
let id = if self.in_progress.is_empty() {
self.new_node(node)
} else {
self.push_child(node)
};
self.in_progress.push((id, None))
}
pub fn finish_internal(&mut self) {
let (id, _) = self.in_progress.pop().unwrap();
if !self.in_progress.is_empty() {
self.add_len(id);
}
}
fn new_node(&mut self, data: NodeData) -> NodeIdx {
let id = NodeIdx(self.nodes.len() as u32);
self.nodes.push(data);

View File

@ -4,7 +4,7 @@
use std::fmt;
mod file_builder;
pub use self::file_builder::FileBuilder;
pub use self::file_builder::{FileBuilder, Sink};
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct SyntaxKind(pub(crate) u32);