Expand description
Typed AST wrappers over the lossless CST.
Phase 3 of #1262. The CST (phase 1-2) preserves every byte of
the source as an untyped tree of SyntaxKind nodes and tokens.
This module adds a thin typed layer on top: newtype wrappers
around SyntaxNode / SyntaxToken with kind()-gated
constructors (cast) and structural accessors (date(),
account(), amount(), etc.).
Two traits anchor the surface:
AstNode: typed wrapper around aSyntaxNode. Each wrapper pins its expectedSyntaxKindviacan_castand offers accessors that walk direct children.AstToken: typed wrapper around aSyntaxToken. Providestext()for the raw bytes; specific token wrappers (Date,Account,Number, …) can layer parsing on top.
The wrappers are zero-cost — they store a SyntaxNode /
SyntaxToken by value and forward to it. Cloning is cheap
(rowan’s nodes/tokens are Arc-backed). All accessors return
Option<_> because the CST is lossless: a malformed input
still produces a tree, just one with missing children.
§Round-trip
Every wrapper exposes syntax() returning the underlying
SyntaxNode/SyntaxToken, whose text() reproduces the
original bytes exactly. Typed-AST consumers that want to
modify the source can therefore navigate via accessors and
splice via raw text ranges.
Structs§
- Account
ACCOUNTtoken (e.g.,Assets:Cash).- Amount
- Units amount:
[sign] (NUMBER | PAREN_EXPR) ([WS] op [WS] [sign] (NUMBER | PAREN_EXPR))* [WS CURRENCY], or a bareCURRENCY. Phase 2.4 extension supports arithmetic. - Balance
Directive DATE balance ACCOUNT AMOUNT_TOKENS. Amount stays flat (phase 2.2c scopes AMOUNT wrapping to POSTING only); walknumber()andcurrency()to read it.- Bool
False BOOL_FALSEtoken literal.- Bool
True BOOL_TRUEtoken literal.- Close
Directive DATE close ACCOUNT.- Commodity
Directive DATE commodity CURRENCY.- Cost
Spec - Bracketed cost annotation:
{...}(per-unit),{#...}(per-unit + total), or{{...}}(total-only). Contents stay flat (phase 2.2c); accessors scan the children. - Currency
Name CURRENCYtoken (e.g.,USD).- Custom
Directive DATE custom "TYPE" values.... Heterogeneous value list stays flat (phase 2.3); walk the raw token sequence viasyntax().children_with_tokens().- Date
DATEtoken (e.g.,2024-01-15).- Document
Directive DATE document ACCOUNT "PATH".- Error
Node - Wrapper for unrecognized / malformed top-level content
(PR 2.4
ERROR_NODE). Typed-AST consumers can use this to surface error regions to users (e.g., LSP diagnostics). - Event
Directive DATE event "TYPE" "VALUE".- Include
Directive include "PATH".- Link
LINKtoken (e.g.,^expense-123).- Meta
Entry - Metadata sub-line:
WS META_KEY ... (NEWLINE | EOF). Key is theMETA_KEYtoken; value is the remaining flat content tokens. Usekey()andvalue_*()accessors. - MetaKey
META_KEYtoken (e.g.,note:). Note the trailing colon is part of the token; usetext_without_colon()to strip it.- Note
Directive DATE note ACCOUNT "TEXT".- Number
NUMBERtoken (e.g.,100.00).- Open
Directive DATE open ACCOUNT [CURRENCY[,CURRENCY]*] ["BOOKING"].- Option
Directive option "KEY" "VALUE".- PadDirective
DATE pad ACCOUNT_TARGET ACCOUNT_SOURCE.- Plugin
Directive plugin "MODULE" ["CONFIG"].- Popmeta
Directive popmeta KEY:.- Poptag
Directive poptag #TAG.- Posting
WS [(FLAG | STAR | PENDING_KW | HASH | single-char CURRENCY) WS] ACCOUNT [AMOUNT] [COST_SPEC] [PRICE_ANNOTATION].- Posting
Flag - Typed wrapper for a posting-line flag token. Same as
TransactionFlagminus theTXN_KWvariant (postings can’t carry thetxnkeyword). UseSelf::classifyfor exhaustivematchergonomics. - Price
Annotation - Price annotation:
AT [WS AMOUNT](per-unit) orAT_AT [WS AMOUNT](total). - Price
Directive DATE price CURRENCY NUMBER CURRENCY.- Pushmeta
Directive pushmeta KEY: VALUE.- Pushtag
Directive pushtag #TAG.- Query
Directive DATE query "NAME" "QUERY".- Sign
- Typed wrapper for an amount sign token (
PLUSorMINUS). - Source
File - Root of a parsed Beancount file.
SourceFile::parse(src)is the typed-AST entry point — it wrapsparse_structured. - String
Lit STRINGliteral (e.g.,"Coffee").text()includes the surrounding quotes; usetext_unquoted()for the content.- Syntax
Text - Re-export of rowan’s
SyntaxText— a rope view over aSyntaxNode’s text without allocation. Returned byErrorNode::textso consumers don’t need a directrowandependency. - Tag
TAGtoken (e.g.,#trip).- Transaction
DATE FLAG ["PAYEE"] "NARRATION" #TAG... ^LINK...followed by indentedPOSTINGlines andMETA_ENTRYsub-lines.- Transaction
Flag - Typed wrapper for the transaction-header flag token.
Enums§
- Directive
- Sum type over every recognized top-level directive wrapper.
- Posting
Flag Kind - Exhaustive classification of a
PostingFlagtoken. Same asTransactionFlagKindminusTxn(postings cannot carry thetxnkeyword). - Transaction
Flag Kind - Exhaustive classification of a
TransactionFlagtoken.