# `Ichor.Syntax.Record`
[🔗](https://github.com/joetjen/ichor_runtime/blob/v0.6.0/lib/ichor/syntax/record.ex#L1)

How a lossless parser records which rules matched where, for
`Ichor.Syntax.tree/3` to weave the tokens into.

The records travel **inside the ordinary raw captures**, under one
reserved name (`key/0`), rather than beside them. That is what makes
them correct for free: every backend already discards a failed
alternative's captures and merges a name captured more than once into
one ordered list, so a record of a rule that was tried and abandoned
never survives, and the ones that do stay in source order. The key
can never collide with a grammar's own capture name, since `$` is not
a name character in any grammar notation Ichor reads.

A rule's own captures hold its callees' records; the call site takes
them out before the captures go anywhere else (`called/4`), so
`Ichor.Actions` never sees one, and records the call as one record in
its place.

# `called`

```elixir
@spec called(
  atom(),
  non_neg_integer(),
  non_neg_integer(),
  Ichor.Capture.raw_captures()
) ::
  {Ichor.Capture.raw_captures(), Ichor.Syntax.record()}
```

A call of `rule` that matched the tokens `[from, to)`, whose own
captures were `captures`: the captures without the records, for the
ordinary `{:rule, rule, captures}`, and the call's own record, holding
those records as its children.

# `key`

```elixir
@spec key() :: atom()
```

The reserved capture name records travel under.

# `reduced`

```elixir
@spec reduced(
  Grammar.LRTable.Production.t(),
  [Grammar.LRTable.Captures.entry()],
  tuple()
) ::
  Ichor.Capture.raw_captures()
```

`Grammar.LRTable.Captures.build/3`, recording: the captures for
`production`, holding the records of the rules on its right-hand
side. It takes what `build/3` takes, so a runtime can be handed
either.

A grammar rule on the right-hand side is recorded as one record over
the span it covers. A helper nonterminal LR desugaring made up
(`$star_1`, `$grp_2`, ... -- every name starting with `$`) is not a
rule the grammar's author wrote, so its records are spliced into this
production's own. A helper's span is taken whatever kind of capture
the production makes of it: a `:text` capture drops the helper's
captures but keeps its records, as the PEG backends do.

# `root`

```elixir
@spec root(atom(), non_neg_integer(), Ichor.Capture.raw_captures()) ::
  {Ichor.Capture.raw_captures(), Ichor.Syntax.record()}
```

The root's record of a parse that matched `[0, to)` with `captures`,
and the captures without the records -- for `Ichor.Actions`.

# `take`

```elixir
@spec take(Ichor.Capture.raw_captures()) ::
  {[Ichor.Syntax.record()], Ichor.Capture.raw_captures()}
```

The records `captures` hold, in order, and `captures` without them.

    iex> Ichor.Syntax.Record.take([{:n, {:text, "1"}}])
    {[], [{:n, {:text, "1"}}]}

---

*Consult [api-reference.md](api-reference.md) for complete listing*
