Parser โ
Simple explanation โ
The parser reads the source left to right and progressively builds a structured tree. At each step it asks one question: given everything parsed so far (summarized as a state) and the next token (lookahead), should it shift the token onto its stack, reduce the stack top into a syntax node, accept the finished tree, or recover from an error?
Technical explanation โ
parser/parser.zig implements a table-driven LR loop over language/tables.zig data:
- Lookahead (
parser/lookahead.zig): longest-match tokenization with extras skipped, one token of lookahead held inParseState. - Shift: create a token subtree, push
(target_state, node). - Reduce: pop N values, drain any pending error nodes inside the span, build the interior node, push the goto target.
- Accept: the end token in an accept state finishes the parse; leftover error nodes attach to the root positionally.
- Recovery (
parser/recover.zig): skip bad input intoERRORspans, insertMISSINGtokens at end of input, or unwind to a final error-marked root โ always terminating via bounded budgets.
Reductions record each node's LR start state (reuse_state), which is what later makes incremental reuse sound.
