Grammar.LRTable.Captures (IchorRuntime v0.2.0)

Copy Markdown View Source

Builds the raw-capture list Ichor.Actions expects ({:token,...}/ {:rule,...}/{:text,...}, see Ichor.Capture.raw_captures/0) from one reduced production's own RHS entries -- shared by Grammar.LR (a single linear stack) and Grammar.GLR (a graph-structured one): both reduce the same kind of production, against the same kind of token stream, needing the exact same per-position classification (see Grammar.LRTable.Production's own moduledoc for what each capture kind means), so this logic has exactly one place to live rather than two copies drifting apart.

Built as a list, in production.captures' own RHS-position order, rather than a map -- a name's position (first occurrence, for one captured more than once) is real information Ichor.Actions relies on (Ichor.Capture.position/0) to evaluate sibling captures in true source order, which a plain map's own iteration order can't be trusted to reconstruct (it isn't guaranteed to match insertion order, and has been observed to differ across Erlang/OTP versions).

Summary

Types

One popped RHS position: value is the shifted %Token{} (a terminal position) or the already-built raw-captures list of a reduced nonterminal; start_pos/end_pos are the token-stream span it covers, needed for a :text-kind capture regardless of which RHS position it sits at (not just the whole production's own span).

Functions

Builds the raw-captures list for production, given its popped RHS entries in order.

The first/second/third+ list-promotion rule every raw-capture builder in Ichor uses (Grammar.Native.Runtime.Parser.merge_captures/2, mirrored here for the LR/GLR side): a name captured more than once naturally becomes a list without knowing the eventual count in advance. A new name is appended at the end, landing at its first-occurrence RHS position relative to whatever's already there (build/3 calls this in RHS order); a repeat name updates its existing entry in place, not moving it.

Types

entry()

@type entry() ::
  {value :: Grammar.VM.Token.t() | Ichor.Capture.raw_captures(),
   start_pos :: non_neg_integer(), end_pos :: non_neg_integer()}

One popped RHS position: value is the shifted %Token{} (a terminal position) or the already-built raw-captures list of a reduced nonterminal; start_pos/end_pos are the token-stream span it covers, needed for a :text-kind capture regardless of which RHS position it sits at (not just the whole production's own span).

Functions

build(production, entries, stream)

Builds the raw-captures list for production, given its popped RHS entries in order.

merge(captures, name, value)

The first/second/third+ list-promotion rule every raw-capture builder in Ichor uses (Grammar.Native.Runtime.Parser.merge_captures/2, mirrored here for the LR/GLR side): a name captured more than once naturally becomes a list without knowing the eventual count in advance. A new name is appended at the end, landing at its first-occurrence RHS position relative to whatever's already there (build/3 calls this in RHS order); a repeat name updates its existing entry in place, not moving it.