The LR shift-reduce loop for a lossless parse: the same moves as
Grammar.LR's and Grammar.Native.LR's, building captures with
Ichor.Syntax.Record.reduced/3, so the rules' records travel with them.
Table-driven on purpose, for both backends. The generated LR parser
compiles every state into its own function, which calls the ordinary
Grammar.LR.Stack.reduce/4 inline. A lossless variant of those would
be a second copy of every state function. Instead, a parser generated
with lossless: true embeds its table as data and hands it to this
loop through action_fn/goto_fn -- the shape Grammar.GLR.Runtime
already takes -- so the fast path's functions stay exactly as they
are, and the lossless path pays for lookups rather than for code.
Summary
Functions
Runs the loop over stream from start_state. action_fn answers a
state and a lookahead with the table's list of actions -- one, since an
LR table has no conflicts -- and goto_fn a state and a nonterminal
with the state to go to.
Functions
@spec run( (Grammar.LRTable.state_id(), atom() -> [Grammar.LRTable.action()]), (Grammar.LRTable.state_id(), atom() -> Grammar.LRTable.state_id() | nil), %{required(non_neg_integer()) => Grammar.LRTable.Production.t()}, Grammar.LRTable.state_id(), atom(), tuple() ) :: {:ok, non_neg_integer(), Ichor.Capture.raw_captures()} | {:error, Ichor.Error.t()}
Runs the loop over stream from start_state. action_fn answers a
state and a lookahead with the table's list of actions -- one, since an
LR table has no conflicts -- and goto_fn a state and a nonterminal
with the state to go to.