greenwood
- code :: https://github.com/halostatue/greenwood
- issues :: https://github.com/halostatue/greenwood/issues
A generic trivia-preserving concrete syntax tree (CST) library for Gleam.
Overview
Greenwood provides an immutable concrete syntax tree parameterized by node and
token kind, with associated trivia and structural transformation primitives.
Greenwood syntax trees are format-agnostic and parsers supply their own kind
types.
Installation
gleam add greenwood@1Further documentation can be found at https://greenwood.hexdocs.pm.
A Deeper Dive
Function Groups
There are six types of functions in the Greenwood interface:
builder: construct Greenwood treesquery: interrogate a treetransformer: transform a treetraversal: traverse a treetrivia: manage trivia on nodescursor: navigate and edit with a movable cursor
Each function and type is marked with its interface group in the documentation.
Trivia
In syntax tree terminology, "trivia" refers to source text that has no semantic meaning to the language but matters to humans: whitespace, comments, blank lines, and sometimes preprocessor directives. A pure AST discards trivia entirely, but a CST must track it.
Greenwood implements a hybrid concrete syntax tree supporting Roslyn-style Trivia annotations (attached trivia) or Rowan-style green tree child tokens (inline trivia), depending on the choices made by the parser.
Attached trivia (Roslyn-style) is where each node carries leading and trailing trivia tokens. A comment above a function "belongs to" that function node. This makes it easy to move a node and have its comments follow. Greenwood supports this with
Trivia(leading, trailing).Inline trivia (Rowan-style) tokens are siblings in the children list, with no special attachment. The tree is uniform but the parser (or a later pass) must decide ownership when moving nodes. Greenwood supports this with
Baretrivia markers.
Cursor (Zipper)
The cursor API implements a Huet zipper (Gérard Huet, "The Zipper", Journal of Functional Programming 7(5):549–554, 1997). It provides a focused view into the tree — you can navigate down into children, edit the focused node, and reconstruct the full tree by moving back up. This avoids rebuilding the entire tree from the root for localized edits.
Core Types
Node(kind, children, trivia)— interior tree nodeToken(kind, text)— leaf carrying literal source textElement— either aNodeElement(Node)orTokenElement(Token)Trivia—Trivia(leading, trailing)orBareZipper— cursor with focus node and breadcrumbsCrumb— context for reconstructing a parent from a focused child
Libraries Using Greenwood
COMING SOON
Roadmap
Future capabilities may include tree diffing (compare two trees and produce a minimal edit script).
Semantic Versioning
greenwood follows Semantic Versioning 2.0.