Expand description
The rule machine: it runs the rule table read out of
grammar over the tokens lex produces,
and the grammar-local actions build the AST as it goes.
The canonical TypeScript port and the Go port hand this job to the tabnas
engine. There is no Rust engine, so this module is the one piece of the
port with no line-for-line counterpart — but it is not a new design: it
implements the same rule/alt contract those alts are written against, so
css-grammar.jsonic stays the single source of truth for all three ports.
A rule runs in two phases. In the OPEN phase its open alts are tried in
order; in the CLOSE phase its close alts are. An alt matches when the
next tokens are its s sequence (no s matches unconditionally), and then
- its
aactions run, against this rule’s matched tokens and node; bof the matched tokens are pushed back — matched and recorded, but left in the buffer for whatever reads next;ppushes a child rule (this rule moves to its CLOSE phase and resumes when the child pops),rreplaces this rule with a fresh one, and neither means: open → close, or close → pop.
Tokens are lexed LAZILY — only as many as the alt being tried needs, under
the rule trying it. That is what decides whether a comment becomes a node,
so it is behaviour, not an optimisation: see crate::lex.
§Node ownership
In the canonical ports a child rule inherits its parent’s node BY
REFERENCE, so a selector pushed three rules down lands in the parent’s
node. Rust has no such aliasing without interior mutability, so the node
MOVES down the stack instead: a pushed child takes the node, a constructor
action hands it back before installing its own, and a popping rule either
returns it or delivers its own node to the parent as child. Only the top
frame ever runs, so the node is always where the running rule is.
Structs§
- Options
- Plugin options. Mirrors the TypeScript
CssOptionsand the GoCssOptions, and the defaults matchCss.defaults/Defaults.
Functions§
- parse
- Run the grammar over
src.