pub struct Builder<K> { /* private fields */ }Expand description
Assembles a Node tree from a stream of start_node / token /
finish_node calls — the shape a parser drives as it recognises the grammar.
The builder keeps a stack of open nodes. start_node
opens one, token appends a leaf to whichever node is
innermost, and finish_node closes the innermost node
and folds it into its parent. When the outermost node closes it becomes the
root, and finish hands it back.
Misuse is never a panic. The first structural fault — an unbalanced close, a
token at the root, a second root — is remembered and returned from
finish as a BuildError, so a parser can drive the
builder on its hot path without wrapping every call in a Result.
§Examples
Build (1) — a parenthesised literal — and read it back losslessly:
use syntax_lang::{Builder, Span, Token};
let mut b = Builder::new();
b.start_node("paren");
b.token(Token::new("(", Span::new(0, 1)));
b.start_node("lit");
b.token(Token::new("num", Span::new(1, 2)));
b.finish_node(); // close "lit"
b.token(Token::new(")", Span::new(2, 3)));
b.finish_node(); // close "paren"
let root = b.finish().expect("balanced");
assert_eq!(root.kind(), &"paren");
assert_eq!(root.span(), Span::new(0, 3));
assert_eq!(root.text("(1)"), Some("(1)"));
let kinds: Vec<_> = root.tokens().map(|t| *t.kind()).collect();
assert_eq!(kinds, ["(", "num", ")"]);Implementations§
Source§impl<K> Builder<K>
impl<K> Builder<K>
Sourcepub const fn new() -> Self
pub const fn new() -> Self
Creates an empty builder.
§Examples
use syntax_lang::Builder;
let b = Builder::<&str>::new();
assert!(b.is_empty());Sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Whether nothing has been built yet — no open nodes and no completed root.
§Examples
use syntax_lang::{Builder, Span, Token};
let mut b = Builder::new();
assert!(b.is_empty());
b.start_node("root");
assert!(!b.is_empty());
b.token(Token::new("t", Span::new(0, 1)));
b.finish_node();
let _ = b.finish();Sourcepub fn start_node(&mut self, kind: K)
pub fn start_node(&mut self, kind: K)
Opens a new node of kind. Tokens and child nodes added until the matching
finish_node become its children.
Starting a second node once the root has already closed records
BuildError::MultipleRoots; the call is otherwise infallible.
§Examples
use syntax_lang::{Builder, Span, Token};
let mut b = Builder::new();
b.start_node("root");
b.token(Token::new("t", Span::new(0, 1)));
b.finish_node();
assert!(b.finish().is_ok());Sourcepub fn token(&mut self, token: Token<K>)
pub fn token(&mut self, token: Token<K>)
Appends token as a leaf of the innermost open node.
Pushing a token with no node open records BuildError::TokenOutsideNode,
since a tree’s root must be a node rather than a bare token.
§Examples
use syntax_lang::{BuildError, Builder, Span, Token};
let mut b = Builder::new();
b.token(Token::new("t", Span::new(0, 1))); // no node open yet
assert_eq!(b.finish(), Err(BuildError::TokenOutsideNode));Sourcepub fn finish_node(&mut self)
pub fn finish_node(&mut self)
Closes the innermost open node, folding it into its parent — or promoting it to the root when it is the outermost node.
Closing with no node open records BuildError::UnbalancedFinish.
§Examples
use syntax_lang::{Builder, Span, Token};
let mut b = Builder::new();
b.start_node("outer");
b.start_node("inner");
b.token(Token::new("t", Span::new(0, 1)));
b.finish_node(); // close "inner"
b.finish_node(); // close "outer"
let root = b.finish().expect("balanced");
assert_eq!(root.child_nodes().count(), 1);Sourcepub fn finish(self) -> Result<Node<K>, BuildError>
pub fn finish(self) -> Result<Node<K>, BuildError>
Consumes the builder, returning the finished root node.
Returns the first recorded BuildError if the call sequence was
unbalanced, BuildError::UnclosedNodes if nodes are still open, or
BuildError::EmptyTree if no node was ever started.
§Examples
use syntax_lang::{BuildError, Builder};
let b = Builder::<&str>::new();
assert_eq!(b.finish(), Err(BuildError::EmptyTree));