Grammar.LR.Stack (IchorRuntime v0.1.0)

Copy Markdown View Source

The linear LR stack's shift/reduce mechanics -- shared by the interpreted Grammar.LR and Grammar.Native.LR's per-state generated code, since a stack push/pop is exactly the same operation regardless of whether the state driving it came from a Map.get or a compiled case.

A stack entry is {state, start_pos, end_pos, value}: state is needed after a reduce to know which GOTO to consult -- the state a pop exposes isn't knowable until then, even when which production reduced is already compile-time-known (the same production can be reduced from more than one calling context, exposing a different state each time). start_pos/end_pos are token-stream indices, needed for a :text-kind capture's span regardless of which RHS position it sits at (Grammar.LRTable.Captures). value is the shifted %Grammar.VM.Token{} itself, or a reduced nonterminal's own already-built captures map.

Summary

Functions

Pushes a reduced nonterminal's captures onto rest_stack (as returned by reduce/4), landing in target_state.

Pushes a freshly-shifted token onto stack, landing in state.

Pops production's own RHS length off stack, builds its captures via Grammar.LRTable.Captures.build/3, and returns {exposed_state, rest_stack, start_pos, end_pos, captures} -- exposed_state is whatever's now on top (the caller's own job to look up GOTO for), start_pos/end_pos the span the whole reduced production covers (both pos, for a zero-width/epsilon production).

Types

entry()

@type entry() :: {state :: term(), non_neg_integer(), non_neg_integer(), term()}

Functions

push_reduced(rest_stack, target_state, start_pos, end_pos, captures)

@spec push_reduced([entry()], term(), non_neg_integer(), non_neg_integer(), map()) ::
  [entry()]

Pushes a reduced nonterminal's captures onto rest_stack (as returned by reduce/4), landing in target_state.

push_token(stack, state, token, pos, new_pos)

@spec push_token(
  [entry()],
  term(),
  Grammar.VM.Token.t(),
  non_neg_integer(),
  non_neg_integer()
) :: [
  entry()
]

Pushes a freshly-shifted token onto stack, landing in state.

reduce(stack, production, stream, pos)

Pops production's own RHS length off stack, builds its captures via Grammar.LRTable.Captures.build/3, and returns {exposed_state, rest_stack, start_pos, end_pos, captures} -- exposed_state is whatever's now on top (the caller's own job to look up GOTO for), start_pos/end_pos the span the whole reduced production covers (both pos, for a zero-width/epsilon production).