pub enum SyntaxKind {
Show 190 variants
WHITESPACE = 0,
NEWLINE,
LINE_COMMENT,
BLOCK_COMMENT,
DOC_COMMENT_OUTER,
DOC_COMMENT_INNER,
KW_PUB,
KW_FLOW,
KW_FN,
KW_VAR,
KW_CONST,
KW_LET,
KW_FLAGS,
KW_STRUCT,
KW_EXTERN,
KW_IMPORT,
KW_USE,
KW_MODULE,
KW_RETURN,
KW_REF,
KW_IF,
KW_MATCH,
KW_ELSE,
KW_WHILE,
KW_FOR,
KW_IN,
KW_UNTIL,
KW_BREAK,
KW_CONTINUE,
KW_AS,
KW_OR,
KW_TRUE,
KW_FALSE,
KW_END,
KW_DONE,
EQ,
PLUS_EQ,
MINUS_EQ,
STAR_EQ,
SLASH_EQ,
EQ_EQ,
BANG_EQ,
LT,
GT,
LT_EQ,
GT_EQ,
AMP,
AMP_AMP,
PLUS,
MINUS,
STAR,
SLASH,
PERCENT,
CARET,
BANG,
QUESTION,
L_PAREN,
R_PAREN,
L_BRACE,
R_BRACE,
L_BRACKET,
R_BRACKET,
PIPE,
COMMA,
DOT,
COLON,
SEMICOLON,
COLON_COLON,
HASH,
TILDE,
BACKSLASH,
AT,
AT_L_BRACKET,
GLUE,
DIVERT,
THREAD,
FAT_ARROW,
INTEGER,
FLOAT,
QUOTE,
STRING_TEXT,
STRING_ESCAPE,
IDENT,
ERROR_TOKEN,
EOF,
DOC_COMMENT,
SOURCE_FILE,
FLOW_DECL,
FN_DECL,
PARAM_LIST,
PARAM,
VAR_DECL,
CONST_DECL,
FLAGS_DECL,
FLAGS_MEMBER_LIST,
FLAGS_MEMBER,
STRUCT_DECL,
STRUCT_FIELD,
EXTERN_DECL,
USE_DECL,
USE_TREE,
USE_TREE_LIST,
IMPORT_DECL,
MODULE_DECL,
BLOCK,
CONTENT_LINE,
LOGIC_LINE,
PROSE_LINE,
TEXT,
INTERPOLATION,
GLUE_NODE,
TAG_LINE,
TAG,
SCENE_STITCH,
SCENE_HEADING,
SCENE_TITLE,
SCENE_SLUG,
SCENE_BODY,
CUE,
CUE_NAME,
COMPACT_CUE,
PARENTHETICAL,
BANG_DISPATCH,
DISPATCH_NAME,
SPAN,
SPAN_NAME,
SPAN_ATTR,
SPAN_ATTR_VALUE,
ESCAPE,
CHOICE_POINT,
CHOICE,
CHOICE_BULLET,
LABEL,
CHOICE_GUARD,
CHOICE_START_CONTENT,
CHOICE_BRACKET_CONTENT,
CHOICE_INNER_CONTENT,
CHOICE_BODY,
ELSE_BRANCH,
SPLICE,
CONDITIONAL_BLOCK,
IF_ARM,
MATCH_ARM,
MATCH_PATTERN,
ALTERNATION_BLOCK,
ALTERNATION_MARKER,
ENTRY,
ANNOTATION_LINE,
ANNOTATION_ARGS,
ANNOTATION_ARG,
DIVERT_STMT,
TUNNEL_CALL,
DIVERT_TARGET,
RETURN_STMT,
RETURN_REDIRECT,
PATH,
PATH_SEGMENT,
INTEGER_LIT,
FLOAT_LIT,
STRING_LIT,
BOOLEAN_LIT,
PATH_EXPR,
PAREN_EXPR,
PREFIX_EXPR,
INFIX_EXPR,
CALL_EXPR,
ARG_LIST,
LAMBDA_EXPR,
LAMBDA_PARAMS,
ARRAY_LITERAL,
CONSTRUCT_LITERAL,
CONSTRUCT_ENTRY,
STMT_BLOCK,
LET_STMT,
ASSIGN_STMT,
EXPR_STMT,
BREAK_STMT,
CONTINUE_STMT,
IF_STMT,
ELSE_CLAUSE,
WHILE_STMT,
FOR_STMT,
UNTIL_STMT,
TYPE_ANNOTATION,
TYPE_EXPR,
TYPE_NAME,
TYPE_GENERIC,
TYPE_FN,
AS_BINDING,
ERROR,
// some variants omitted
}Expand description
All syntactic constructs in the native .brink grammar.
This is a peer enum to brink-syntax’s ink-shaped SyntaxKind — its
own discriminant space, sharing no numbering with the ink frontend (NF-1
ruling, 2026-07-19: a new crate, not a co-located module, because the
only reason to share SyntaxKind space was AstPtr interop, which the
HIR admission contract’s opaque Provenance already removed). Tokens
(lexer output) and nodes (parser output) share one flat enum so rowan
can store them in a single u16 discriminant — see [is_token] /
[is_node].
Scope: B0.5 (docs/b0-sequencing.md §B0.5) — the token set and
error-resilient CST for the ruled native surface subset (NF-2:
writer-sufficient, not the full charter). No HIR lowering happens in
this crate; that is B0.6/B0.7/B0.8.
Variants§
WHITESPACE = 0
Spaces and tabs (NOT newlines). A leading UTF-8 BOM is folded in here too (lossless-roundtrip requirement — see lexer tests).
NEWLINE
\n or \r\n.
LINE_COMMENT
// ... through end-of-line. Also ////+ (four or more slashes) —
Rust precedent: only exactly three slashes is a doc comment (see
Self::DOC_COMMENT_OUTER).
BLOCK_COMMENT
/* ... */ (may span lines; unterminated block comments run to EOF —
recorded as a parse error, never a panic).
DOC_COMMENT_OUTER
/// ... through end-of-line — exactly three slashes (a fourth
keeps it a plain Self::LINE_COMMENT). B0.6b
(docs/decision-log.md 2026-07-20): first-class on the native
surface — not trivia (see Self::is_trivia), since the parser
dispatches on this token to decide whether a contiguous run attaches
as a DOC_COMMENT CST node to the declaration it immediately
precedes (parser::doc_comment).
DOC_COMMENT_INNER
//! ... through end-of-line — the inner form (B0.6b, Rust //!
precedent, ink had no equivalent). A contiguous run at the very
start of a knot/flow/file body documents the enclosing container
rather than a following declaration. Also not trivia.
KW_PUB
pub — the native visibility marker (issue #1582, RULED
2026-08-03, docs/decision-log.md “Native visibility marker: a
pub keyword”). Optionally precedes flow/fn/var/const/
struct/extern/flags (never import/use/module, which
have no [crate::VisibilityMark] slot to carry, and never a
knot/stitch — those are ink-dialect grammar, untouched here).
Produces the same VisibilityMark::Public the brink dialect’s
#@public tag directive already does; absent, a declaration stays
Private (already ratified 2026-07-23, unchanged by this token).
Hard-reserved everywhere, like every other keyword in this section
(Finding #1) — a prose line whose first word is literally “pub”
still falls through to body_line’s generic TEXT fallback
exactly like an unmatched flow/var/… does today, since the
declaration-head lookahead (parser/decl.rs::at_pub_decl) only
commits when a legal declaration shape follows.
KW_FLOW
flow — story-time container (Coloring axis, charter §3).
KW_FN
fn — expression-time container (Coloring axis, charter §3).
KW_VAR
KW_CONST
KW_LET
let — a code-ground statement-position binding (B0.8 Wave A,
docs/decision-log.md 2026-07-23 “Code-ground sitting”). Distinct
from var/const (declaration-layer keywords, B0.5): let
introduces a LET_STMT inside a STMT_BLOCK, terminated by ;
like every other code-ground statement — var/const keep their
existing terminator-free declaration shape (parser/decl.rs’s
var_decl/const_decl doc comments).
KW_FLAGS
flags — renamed LIST (charter §11).
KW_STRUCT
KW_EXTERN
KW_IMPORT
KW_USE
KW_MODULE
KW_RETURN
return — leave this container; also the tunnel-return respelling’s
first half (return -> x, charter §11).
KW_REF
ref — ref-argument marker (kept from ink).
KW_IF
if — word-annotated brace family member (charter §6) AND (Finding
#1) reserved as a code-ground keyword everywhere.
KW_MATCH
match — word-annotated brace family member (charter §6).
KW_ELSE
else — conditional else-arm AND a choice point’s fallback branch
(charter §11: “a choice point’s fallback is its else-branch”).
KW_WHILE
while — code-ground loop statement (B0.8 Wave B,
docs/decision-log.md 2026-07-23 “Code-ground sitting”). Hard-
reserved everywhere, mirroring if/match/else (Finding #1) —
unlike the brink-dialect’s ~ { … } T1b grammar, where while is a
contextual soft keyword (brink-syntax/src/parser/logic.rs), the
native surface reserves its RustScript-shaped statement keywords
globally.
KW_FOR
for — code-ground loop statement (B0.8 Wave B). Hard-reserved,
see Self::KW_WHILE’s doc.
KW_IN
in — the for name in expr { … } loop-head separator (B0.8 Wave
B). Hard-reserved, see Self::KW_WHILE’s doc.
KW_UNTIL
until — the code-ground condition-park statement (B0.8 Wave B,
decision-log 2026-07-23 item 4): until <pure-bool-expr>; parks the
flow until the condition becomes true (reactive), then resumes —
the runtime’s existing FlowSleep reactive-wake mechanism. Native
retires await entirely (its future-resolution mental model is
wrong for a condition-park); until is the only spelling. Lowers to
the exact same AwaitStmt HIR node the brink-dialect’s ~ await cond produces — a spelling change, not a new construct (NF-2
fence). Hard-reserved, see Self::KW_WHILE’s doc.
KW_BREAK
break — code-ground loop-exit statement (B0.8 Wave B tail, issue
#1322, docs/decision-log.md 2026-07-23 “Code-ground sitting”).
Hard-reserved, see Self::KW_WHILE’s doc. No content-ground
counterpart — break only has meaning inside a while/for body.
KW_CONTINUE
continue — code-ground loop-skip statement (B0.8 Wave B tail,
issue #1322). Hard-reserved, see Self::KW_WHILE’s doc. No
content-ground counterpart, same as Self::KW_BREAK.
KW_AS
as — import/use aliasing (use a::b as c).
KW_OR
or — B1 or-coalescing (docs/stdlib-spec.md §1.6a, issue
#1460): x or default. A distinct keyword from || (boolean
disjunction, still two adjacent PIPE tokens — see
ast::InfixExpr::is_double_pipe).
KW_TRUE
KW_FALSE
KW_END
END — divert target sentinel (kept verbatim, charter §11).
KW_DONE
DONE — divert target sentinel (kept verbatim, charter §11).
EQ
=
PLUS_EQ
+=
MINUS_EQ
-=
STAR_EQ
*=
SLASH_EQ
/=
EQ_EQ
==
BANG_EQ
!=
LT
<
GT
>
LT_EQ
<=
GT_EQ
>=
AMP
&
AMP_AMP
&&
PLUS
+
MINUS
-. Also the entry-marker sigil (charter §6) and the choice-list
once-bullet-adjacent dash; the parser, not the lexer, decides which
role a given - plays from structural position.
STAR
*
SLASH
/
PERCENT
%
CARET
^
BANG
!
QUESTION
?. Also half of the {? choice-point opener — the parser
recognizes the adjacent L_BRACE QUESTION pair, no compound token
(mirrors how {if/{match/{~ are recognized: { is always plain
L_BRACE, disambiguation is a parser lookahead, not a lexer job).
L_PAREN
(
R_PAREN
)
L_BRACE
{
R_BRACE
}
L_BRACKET
[
R_BRACKET
]
PIPE
|. Two adjacent PIPEs are NOT compounded into a logical-or token
(mirrors brink-syntax precedent for ||/++/--) — the parser
disambiguates a || b (logical or) from |x| (lambda params) by
expression-vs-lambda-head position, not lexical shape.
COMMA
,
DOT
. — the intra-module separator (containers, fields, variants,
UFCS; charter §13.2).
COLON
:
SEMICOLON
; — use’s optional statement terminator (charter §13.2’s
literal example: use story::market::{barter, haggle};, Finding #6:
no declaration requires one), and the code-ground statement
terminator (B0.8 Wave A, docs/decision-log.md 2026-07-23
“Code-ground sitting”): LET_STMT/ASSIGN_STMT/EXPR_STMT inside a
STMT_BLOCK each require a trailing ; — the one thing that
distinguishes a statement from the block’s unterminated tail
expression (blocks-as-values).
COLON_COLON
:: — the module-wall separator (charter §13.2). Lexed as one
compound token so a bare : (used in inline {if cond: …} bodies)
never gets swallowed by a stray adjacent colon.
HASH
# — tag opener (charter §11: tags kept).
TILDE
~. Also an alternation-family opener ({~ } shuffle, charter §6).
BACKSLASH
\
AT
@. Always its own token (never ERROR_TOKEN), whatever role the
parser gives it from structural position:
- directly against an identifier at body-item position it opens a
Self::CUE/Self::COMPACT_CUE— the ruled block-cue spelling (docs/prose-dialect-spec.md§8b.9, issue #1715); - anywhere else — detached (
@ 5pm), or reached mid-line — it folds into plainTEXT, so prose containing a bare@round-trips losslessly and errorlessly (docs/directive-annotations-spec.md§5b: “a lone@in prose stays plain text”).
The @[ annotation opener is a separate compound token
(Self::AT_L_BRACKET), so the two @ channels never compete.
AT_L_BRACKET
@[ — annotation-line opener (charter §11 / NS-A2 lineage,
docs/directive-annotations-spec.md §5b). Only the adjacent pair
opens an annotation line.
GLUE
<> — glue (kept, charter §11).
DIVERT
-> — divert (kept verbatim, charter §11).
THREAD
<- — splice, valid only inside a choice point (charter §5).
FAT_ARROW
=> — match-arm separator.
INTEGER
Integer literal (digits only; no leading sign — unary - is a
separate PREFIX_EXPR).
FLOAT
Float literal (digits.digits).
QUOTE
" (opening or closing quote).
STRING_TEXT
Run of non-special characters inside a string literal.
STRING_ESCAPE
Escape sequence inside a string (\n, \t, \\, \").
IDENT
Identifier: ASCII [A-Za-z_][A-Za-z0-9_]* (Finding #2: native
identifiers are ASCII-only in this skeleton — the charter’s S4
casing partition (snake_case/UpperCamel) is an ASCII-shaped rule
and the ink Unicode identifier range table is ink-specific baggage
with no native ruling to inherit it from; widening later is
additive, not breaking).
ERROR_TOKEN
Any byte/char the lexer could not classify — unterminated block
comments’ unreachable tail (folded into BLOCK_COMMENT itself, not
this), and raw prose bytes at declaration scope. Does NOT include a
lone @, which lexes as its own AT token (see AT’s doc
comment) — not this.
EOF
End of file (synthetic).
DOC_COMMENT
A contiguous run of Self::DOC_COMMENT_OUTER tokens (the leading
child of the declaration node it documents) or
Self::DOC_COMMENT_INNER tokens (the leading child of the
enclosing knot/flow/file body it documents) — one node shape for
both variants; ast::DocComment::is_inner tells them apart by
inspecting which token kind the node’s children carry
(docs/native-surface-charter.md’s doc-comment section).
SOURCE_FILE
FLOW_DECL
flow name(params) { … } / nested flow = stitch (charter §4).
FN_DECL
fn name(params) { … }.
PARAM_LIST
Shared param-list shape for FLOW_DECL/FN_DECL.
PARAM
One parameter: ref? IDENT (: type)? (NG-A, #1487). Also the
node lambda parameters use under LAMBDA_PARAMS — they used to be
bare IDENT tokens directly there, but now each gets its own
PARAM so a : type annotation attaches to the right one (ref
is still not accepted on a lambda parameter).
VAR_DECL
var name = expr.
CONST_DECL
const name = expr.
FLAGS_DECL
flags Name = (member), member, … (charter §11).
FLAGS_MEMBER_LIST
FLAGS_MEMBER
One flag member; a parenthesized member is the default-on entry.
STRUCT_DECL
struct Name { field: type, … } (charter §13.1’s sibling; concrete
grammar shape here, no field-type semantics checked).
STRUCT_FIELD
EXTERN_DECL
extern name(params).
USE_DECL
use path::{a, b as c}; (Rust use lifted verbatim, charter
§13.2).
USE_TREE
One use tree: a path optionally followed by { … } (nested
group), as alias, or bare.
USE_TREE_LIST
IMPORT_DECL
import name; (Finding #3: the charter doesn’t separately spell an
import grammar distinct from use — b0-sequencing’s token-set
bullet lists import as its own decl keyword alongside use
regardless, so this skeleton gives it the minimal reasonable shape:
a single bare path statement, distinct node from USE_DECL. Real
semantics (whole-module import vs name-import) are B0.6’s call).
MODULE_DECL
module name { … } — a nested module block (charter §13.2: files
hold declared module blocks nesting within them).
BLOCK
A brace-delimited body: { BodyItem* }. Universal body delimiter
(charter §4) for flow/fn/module bodies and nested block content.
CONTENT_LINE
A single line of prose content, generic text interspersed with
interpolation/glue, terminated by NEWLINE or EOF.
LOGIC_LINE
~ stmt — the content-ground line-escape into code (charter §8.2,
RULED 2026-07-23, docs/decision-log.md “Native interleaving &
body-dialect spelling”: ink’s logic line, kept — issue #1991).
Wraps a single Self::LET_STMT/Self::ASSIGN_STMT/
Self::EXPR_STMT/Self::UNTIL_STMT/Self::STMT_BLOCK child,
every node kind reused unmodified from the code-ground statement
layer (parser/stmt.rs) in a different position — the four
line-shaped children (LET_STMT/ASSIGN_STMT/EXPR_STMT/
UNTIL_STMT) parse WITHOUT the code-ground ; terminator, this
escape being one content-ground line, terminated by NEWLINE/EOF
exactly like Self::CONTENT_LINE itself; the STMT_BLOCK child
(a ~{ … } multi-statement logic block, issue #1972) is
self-delimiting via its own matching } instead. Mirrors
Self::RETURN_STMT’s doc precedent (one node shape safely serving
two grammars). Parsed by parser/stmt.rs::logic_line, dispatched
from block::body_line’s (and family::colon_body_line’s) TILDE
arm.
PROSE_LINE
> text — the code-ground line-escape into prose (charter §8.2,
RULED 2026-07-23, docs/decision-log.md “Native interleaving &
body-dialect spelling”: the mirror image of Self::LOGIC_LINE at
the opposite ground — issue #1992). Wraps a single
Self::CONTENT_LINE child, reused unmodified from the
content-ground line layer (parser/content.rs::content_line) in a
different position: same grammar, same terminator discipline
(NEWLINE/EOF, never a bare R_BRACE, which — as for CONTENT_LINE
itself — closes the enclosing body rather than the escape). Mirrors
Self::LOGIC_LINE’s own one-node-two-grammars precedent, just with
the wrapped/wrapper roles swapped: there the escape wraps a
code-ground node inside a content-ground dispatch; here it wraps a
content-ground node inside a code-ground dispatch. Parsed by
parser/stmt.rs::prose_line, dispatched from stmt::statement()’s
GT arm — reachable everywhere a code-ground STMT_BLOCK statement
is parsed (a fn’s default body, a flow’s ~{ } override, and
every nested if/while/for body, which all share that one
dispatch loop).
TEXT
A run of literal text inside a CONTENT_LINE (no escapes, no
interpolation — those break the run).
INTERPOLATION
{expr} — bare-brace interpolation, and nothing else, ever (charter
§6).
GLUE_NODE
<> glue, in content position.
TAG_LINE
# tag text — a tag line (charter §11: tags kept).
TAG
One #-prefixed tag inside a TAG_LINE or a CONTENT_LINE’s
trailing-tags tail. Also the trailing-tag shape a FLOW_DECL
header line and a Self::SCENE_HEADING carry (§8b.4 —
container-level per-flow tags).
SCENE_STITCH
A header-scoped stitch: a Self::SCENE_HEADING plus the
Self::SCENE_BODY it scopes (§8b.2, RULED). Amends charter
§4’s “braces are the universal body delimiter” for preset
heading-elements in prose-ground only — a scene runs to the next
heading or the enclosing close, restoring ink’s own header-scoped
stitch. Heading-stitches are flat siblings: scenes never nest,
as on a real page, and deeper nesting keeps the general
flow x { … } spelling, which stays first-class in prose-ground.
SCENE_HEADING
The heading line itself: INT. MARKET SQUARE - NIGHT [market] #tense #act1. Line order is fixed (§8b.3): pattern, [slug],
tags. Two rejected slug spellings, recorded so they are not
revisited: #x# (clashes with the tag lexer) and {x} (lexes as
interpolation — headings get no carve-out).
SCENE_TITLE
The heading’s title run — everything before the optional
[slug]/tags. The title is the display name (§3.3) and, with no
explicit slug, the address is inferred from it.
SCENE_SLUG
[market] — the explicit address slug on a heading (§8b.3).
SCENE_BODY
The header-scoped body a Self::SCENE_HEADING opens: every item
up to the next heading, the enclosing }, or EOF. Braceless by
construction — that is the whole point of §8b.2 — so it is a
distinct node kind from Self::BLOCK, whose contract is “a
brace-delimited body”.
CUE
@VENDOR — a block character cue (attached-forward, §3.6). Its
trailing tags are the ruled home for cue extensions (§8d.4:
@VENDOR #(v.o.) — no parsed ext capture, no new payload
machinery).
CUE_NAME
The name run inside a Self::CUE/Self::COMPACT_CUE, after
the @ sigil and before :/tags/end of line.
COMPACT_CUE
@KID: Says who? — the compact cue (§8b.9, the Yarn cross): cue
plus a single fused dialogue line, declared as a second pattern
beside the block cue rather than a rewrite of it. Holds a
Self::CUE_NAME and the fused Self::CONTENT_LINE.
PARENTHETICAL
(hushed) — a parenthetical delivery line (attached-forward,
§3.6). Recognized only inside a live cue chain (after a cue, a
parenthetical, or that cue’s dialogue), so the G-1 (label)
content-line spelling is untouched everywhere else.
BANG_DISPATCH
!name rest of the line… — the self-announcing !name
annotation-element dispatch sigil (§3.5b, issue #2004). The ! and
the name must be adjacent, mirroring Self::CUE’s @NAME
discipline (element::at_bang_dispatch) — a bare ! not
immediately followed by an identifier stays ordinary prose. Holds a
Self::DISPATCH_NAME and the remainder as a fused
Self::CONTENT_LINE (the same technique Self::COMPACT_CUE
uses for its dialogue line) — whether a handler by that name
actually exists, and whether its args = "…" pattern matches the
remainder, is hir::lower_native::element::try_dispatch’s
question, not the parser’s.
DISPATCH_NAME
The name run inside a Self::BANG_DISPATCH, after the ! sigil
and before the remainder.
SPAN
One inline span: the open tag (name + attrs), its content (when not
self-closing — recursively any content-item shape, including a
nested SPAN), and the matching close tag. Self-closing spans (no
content, no close tag) are the point-marker shape (§8b.11).
SPAN_NAME
The tag name at a Self::SPAN’s open tag — one IDENT, or an
IDENT (MINUS IDENT)* chain for a hyphenated name (<fade-in>,
issue #1996). Wrapped (rather than a bare token) so lowering can
find this name unambiguously among the attr names and the close
tag’s own (unwrapped) name tokens that also live under SPAN.
SPAN_ATTR
One name="value" attribute inside a Self::SPAN’s open tag.
SPAN_ATTR_VALUE
An attribute’s quoted value. Deliberately not Self::STRING_LIT
— attribute values are static text only (§4.1’s worked examples are
all static: <sfx name="bell"/>, <item id="lantern">); nothing in
the ruling asks for {expr} interpolation inside an attribute, and
reusing STRING_LIT would silently admit it. Uses the same
STRING_TEXT/STRING_ESCAPE token pair as STRING_LIT, just
without the INTERPOLATION child arm.
ESCAPE
One escape sequence: BACKSLASH plus the one escaped token — \<
\{ \# \\, and only those four (§8d.6: “the escape set is
final… do not extend it”). A BACKSLASH before anything else is a
parse error, not this node — see markup::escape.
CHOICE_POINT
{? … } — an explicit choice point.
CHOICE
One */+ choice line inside a CHOICE_POINT.
CHOICE_BULLET
* (once) or + (sticky) bullet token wrapper.
LABEL
(name) — a choice label (kept, charter §11).
CHOICE_GUARD
{if cond} — a choice guard.
CHOICE_START_CONTENT
The text[bracket]inner display-split anatomy of a choice line
(kept as-is, charter §5).
CHOICE_BRACKET_CONTENT
CHOICE_INNER_CONTENT
CHOICE_BODY
A choice’s braced nested-content body (charter §5: “choice bodies take braces when they have nested content”).
ELSE_BRANCH
else { … } — a choice point’s fallback branch (charter §11).
SPLICE
<- flow(args) — a splice inside a choice point (charter §5).
CONDITIONAL_BLOCK
{if cond { … } else { … }} / {if cond: … else: …} (Finding #4:
this skeleton accepts BOTH an inline colon-body form and a braced
multiline-arm form for if/match rather than the entry-marker--
form charter §6 documents for the alternation family — the
charter itself flags entry-marker anatomy as “under-understood even
by the implementer,” and nothing in the charter says - arms apply
to if/match specifically, so branches use the brace delimiter
charter §4 already declares universal, and dashes are reserved for
alternation blocks below. Flagged for the Track-B queue to confirm
or correct.) The colon-body form’s else: boundary is recognized
whether it starts its own physical line or trails other content on
the SAME line (#1254 Gap 1, fixed #1261 — family::colon_body_line).
A flat else if <cond> { … }/else if <cond>: … chain (ruled
2026-07-22, #1258, implemented #1261) lowers to the identical shape
an explicit nested {if …} would.
IF_ARM
MATCH_ARM
MATCH_PATTERN
A match arm’s pattern (kept intentionally shallow — a bare
expression grammar reused, not a real pattern language; exhaustive
pattern matching is out of B0.5’s scope).
ALTERNATION_BLOCK
{~ … } shuffle / {& … } cycle / {! … } once / {| … }
stopping-sequence — one node shape, ALTERNATION_MARKER child
records which. A { led by any of these four marker chars is
ALWAYS claimed by this family ahead of bare {expr} interpolation
(ruled 2026-07-22, “alternation markers win,” #1258/#1261 —
family::at_alternation’s doc comment has the full rationale and
the parens escape hatch); a body with zero branches ({~}, {&\n})
is a parse error (brink-syntax parity), not silently accepted.
ALTERNATION_MARKER
The ~/&/!/| token that opened an ALTERNATION_BLOCK.
ENTRY
One --prefixed entry/arm inside a multiline ALTERNATION_BLOCK
(charter §6). Runs until the next - or the closing }.
ANNOTATION_LINE
{? … }’s sibling annotation-position dispatch already lives under
CHOICE_POINT above; this marker exists only so the family’s
dispatch site has one name to log against in doc comments — not a
real node, never emitted. (Kept out of is_node/is_token via the
__LAST sentinel below being the true boundary; this variant is
unused and reserved as a documentation anchor only.)
@[name(args)] (directive-annotations-spec.md §5b’s paren-clause
grammar, e.g. @[effects(pure, silent, reads(gold, hp))]).
ANNOTATION_ARGS
The parenthesized, comma-separated argument list of an annotation or nested paren-clause.
ANNOTATION_ARG
One argument: a bare IDENT, or IDENT(ANNOTATION_ARGS) (the
nested paren-clause form, e.g. reads(gold, hp) nested inside
effects(…)).
DIVERT_STMT
-> target — kept verbatim.
TUNNEL_CALL
-> place -> — a tunnel call (kept, charter §11): divert, target,
divert, with nothing else before the line ends.
DIVERT_TARGET
A divert target: END / DONE / a PATH.
RETURN_STMT
return / return <expr> — leave this container, optionally with a
value (content-ground, parser/divert.rs::return_stmt; the value
expression is optional — issue #1973 added it, previously always
bare). Also reused, unmodified, as the code-ground return e?;
value-return statement (B0.8 Wave B tail, issue #1322,
docs/decision-log.md 2026-07-23 “Code-ground sitting” item 1) —
parser/stmt.rs::return_stmt parses an optional value expression
and a ; terminator instead. The two grammars never overlap
(dispatched from different parent contexts — content-ground
BLOCK/family.rs vs. code-ground STMT_BLOCK/stmt.rs), so one
node shape serves both, mirroring the brink-dialect’s own
RETURN_STMT (brink-syntax), which likewise serves both its bare
container-exit and its valued ~ { … }-block-return uses.
ast::ReturnStmt::value() is a plain “first child expr, if any”
accessor — Some/None for both grammars now (content-ground: a
bare return is still None, and return -> x is a distinct
RETURN_REDIRECT node below, never this one’s value; code-ground:
the initializer was already optional).
RETURN_REDIRECT
return -> x — the tunnel-return respelling (charter §11):
RETURN_STMT immediately followed by a divert to x. Content-
ground only — code-ground return has no redirect counterpart (a
content-ground/tunnel concept with no code-ground meaning).
PATH
A dotted/::-separated name path. :: crosses module walls, .
walks everything inside.
PATH_SEGMENT
INTEGER_LIT
FLOAT_LIT
STRING_LIT
BOOLEAN_LIT
PATH_EXPR
PAREN_EXPR
PREFIX_EXPR
INFIX_EXPR
CALL_EXPR
ARG_LIST
LAMBDA_EXPR
|x, y| expr — lambda pipes. Tokenized and structurally parsed in
B0.5; lowered since issue #1685 (hir::lower_native::lambda →
hir::Expr::Lambda), per the 2026-07-19 ruling.
LAMBDA_PARAMS
Holds one PARAM child per lambda parameter (NG-A, #1487) — each
parameter used to be a bare IDENT token directly under this node;
promoting them to PARAM lets : type attach to the right one.
ARRAY_LITERAL
[expr, expr, …] — the array/sequence literal (NG-D, issue #1490,
RULED 2026-07-27: “the everyday collection literal deserves the
lightest spelling”). The B5-symmetric Array { … } construction-
registry entry was weighed and rejected in the same ruling —
L_BRACKET/R_BRACKET were already lexed and idle in expression
position, so this is a new atom, not a CONSTRUCT_LITERAL registry
entry. Holds its element expressions as direct children (same shape
as Self::ARG_LIST — no per-element wrapper node, unlike
Self::CONSTRUCT_ENTRY, since an array element is never a pair).
Distinct from the type-annotation grammar’s <T> generic-argument
syntax (NG-D’s sibling ruling, issue #1552): [ ] is for values,
< > is for type arguments — parser/types.rs never touches
L_BRACKET, so the two spellings cannot collide.
CONSTRUCT_LITERAL
TypeName { … } — the one construction-initializer grammar
(docs/decision-log.md 2026-07-23 “Collection/construction
initializer”). The brace tokens are fixed surface grammar this
parser produces; meaning is protocol dispatch, resolved one
layer up by the construct registry
(brink_ir::hir::construct::ConstructTarget) against the leading
Self::PATH, never by this grammar. So Map { "a": 1 },
Flags { Red, Blue }, Weighted { 3: "gold" } and a struct’s
Point { x: 1, y: 2 } are all one node shape here.
CONSTRUCT_ENTRY
One entry of a Self::CONSTRUCT_LITERAL, in whichever of the
three ruled forms the source used: the element form (a single
child expression — Flags { Red }), or the pair/field form
(two child expressions around a COLON — Map { k: v },
Point { x: 1 }). Pair and field are one shape by construction:
they differ only in what the target type makes of the left-hand
expression, which is dispatch, not grammar.
STMT_BLOCK
{ stmt* tail? } — the code-ground body shape. Blocks-as-values
ruled: an unterminated trailing expression, if present, is the
block’s tail — a bare (unwrapped) expression child, the last thing
before R_BRACE. Reached as an expression atom (expr::atom’s
L_BRACE case) — a statement-block is itself an expression
(let x = { … }; is valid), distinct from the content-ground
Self::BLOCK flow/fn/module bodies still use (that seam is
Wave B’s call, not this wave’s).
LET_STMT
let name = expr; (initializer optional). Distinct from
Self::VAR_DECL/Self::CONST_DECL — those are declaration-layer
keywords (B0.5, terminator-free); let is code-ground, inside a
Self::STMT_BLOCK, and always ;-terminated.
ASSIGN_STMT
x = expr; / x.field = expr; — a read-modify-write place path
(charter’s RMW-paths ruling). The place is a dotted Self::PATH
(no :: — an assignable place is always local).
EXPR_STMT
expr; — a bare expression statement, ;-terminated. The one
thing distinguishing this from a Self::STMT_BLOCK’s unterminated
tail expression.
BREAK_STMT
break; — loop-exit statement, ;-terminated like every other
code-ground statement. Legal only inside a while/for body — an
out-of-loop break is brink-analyzer’s job to reject (E057), not
this grammar’s.
CONTINUE_STMT
continue; — loop-skip statement, ;-terminated. See
Self::BREAK_STMT’s doc for the same in-loop caveat.
IF_STMT
if cond { … } (else if cond { … } | else { … })?. No case for a
bare { opener here — that’s Self::CONDITIONAL_BLOCK’s
annotated-brace family, a different (content-ground) construct this
one does not replace.
ELSE_CLAUSE
The else arm of an Self::IF_STMT: either another Self::IF_STMT
(an else if chain) or a plain Self::STMT_BLOCK.
WHILE_STMT
while cond { … }. Always a plain loop on the native surface — no
while await cond { … } persistent-await form (that’s the
brink-dialect T1b grammar’s own concern; native retired await
entirely in favor of Self::UNTIL_STMT, decision-log item 4).
FOR_STMT
for name in expr { … } — single-binding iteration (charter’s
existing ForStmt HIR shape; no destructuring).
UNTIL_STMT
until <pure-bool-expr>; — the condition-park statement
(decision-log 2026-07-23 item 4): native’s sole flow-suspension
spelling, replacing await. Lowers to the same AwaitStmt HIR node
the brink-dialect’s ~ await cond produces.
TYPE_ANNOTATION
: type_expr — the annotation clause itself (the : token plus
exactly one Self::TYPE_EXPR child).
TYPE_EXPR
A type expression: wraps exactly one of Self::TYPE_NAME,
Self::TYPE_GENERIC, or Self::TYPE_FN.
TYPE_NAME
A bare nominal type name — int, string, a struct name. The
grammar accepts any IDENT; recognizing the fixed set is a semantic
check (brink-analyzer), never this parser’s concern.
TYPE_GENERIC
name<arg, …> — List<L>, Map<K, V>, or any unrecognized
generic head.
TYPE_FN
fn(type, …): type — a function type. Parses here; the checker
decides what it means.
AS_BINDING
as NAME — the condition-position Option binding, in BOTH of the
language’s condition positions: the statement forms
(Self::IF_STMT, Self::WHILE_STMT) and the template form
(Self::CONDITIONAL_BLOCK’s {if …: … else: …}). One construct,
one node kind — the ruling explicitly refused a second binding
grammar. Always the LAST child node of the construct it binds in,
following the head expression, so every existing “first child node
that isn’t a body/arm” condition accessor keeps working.
Also parsed and lowered inside a Self::CHOICE_GUARD (issue
#1508): the guard’s binding captures at presentation time, riding
the same OptionBind opcode + frame-slot machinery this construct
already uses in the other two positions — no separate wire-level
capture was needed once traced end to end (the choice’s
thread-fork snapshot, which already restores tunnel/function
temps across a pick, generalizes to the guard’s bound slot for
free). E146 is retired now that this lowers for real.
ERROR
A parse-error wrapper node — swallows one unexpected token so error recovery always makes forward progress.
Implementations§
Source§impl SyntaxKind
impl SyntaxKind
Sourcepub fn is_token(self) -> bool
pub fn is_token(self) -> bool
Returns true for tokens produced by the lexer (leaf nodes in the CST).
Sourcepub fn is_trivia(self) -> bool
pub fn is_trivia(self) -> bool
Returns true for trivia — tokens the parser may skip over.
NEWLINE is not trivia; it terminates lines and delimits blocks.
Sourcepub fn is_keyword(self) -> bool
pub fn is_keyword(self) -> bool
Returns true for keyword tokens.
Trait Implementations§
Source§impl Clone for SyntaxKind
impl Clone for SyntaxKind
Source§fn clone(&self) -> SyntaxKind
fn clone(&self) -> SyntaxKind
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more