Ichor.Syntax.Record (IchorRuntime v0.5.0)

Copy Markdown View Source

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.

Summary

Functions

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.

The reserved capture name records travel under.

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.

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

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

Functions

called(rule, from, to, captures)

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()

@spec key() :: atom()

The reserved capture name records travel under.

reduced(production, entries, stream)

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(rule, to, captures)

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

take(captures)

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

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