Skip to content

Rust: the LALR table and parser state, readable as in Python Lark - #13

Merged
vrenken merged 1 commit into
developfrom
claude/lalr-accessors
Oct 24, 2026
Merged

vrenken merged 1 commit into
developfrom
claude/lalr-accessors

Conversation

@vrenken

@vrenken vrenken commented Oct 24, 2026

Copy link
Copy Markdown
Owner

Requested by Peter · project thread

The Rust crate gets read access to the LALR automaton and the parser state, as Python Lark leaves them public, so that a tool can print the automaton and recover from errors itself. etalii.adp spec 035 needs this (amendment of 2026-10-24, research R9, tasks T164 and T165), to rebuild adp-atd-grammar and adp-atd-syntax on etalii-lark. It's meant for release as 0.4.0. This PR is Rust only; the .NET and TypeScript ports are unchanged.

What

  • Lark::parse_table() -> Option<&ParseTable> gives a LALR parser's table, as Python Lark's parser.parser.parser.parse_table; it is None for Earley and CYK. parsers::lalr_analysis is public, with ParseTable and LalrAction (its Action) re-exported at the root.
  • ParserState (now re-exported at the root) gets three methods:
    • state_stack() and value_stack(), as Python's state_stack and value_stack;
    • truncate(depth), which pops both stacks to depth states and keeps at least the start state. It returns the popped values, as Lark's on_error handlers pop them.
  • InteractiveParser gets two methods:
    • parser_state_mut(), to change the state for recovery;
    • next_token(), which lexes one token for the current parser state without feeding it. With the contextual lexer it matches only what the state accepts.

Tests

rust/etalii-lark/tests/lalr_access.rs covers:

  • the table is the parser's: shifts go to its states, reductions name its rules, and Earley has none;
  • next_token lexes per state: if if reads the keyword, then a name;
  • recovery: read the stacks, pop back to the state that read {, skip what that state does not read, and resume the parse.

On this branch, cargo fmt --check, cargo clippy --all-targets -- -D warnings and cargo test pass, the conformance suite included.

I also used the branch to prototype etalii.adp's table printing. Its normalized table for the ATD grammar equals what Python Lark gives (atd.tables.json) byte for byte.

🤖 Generated with Claude Code

…able

Lark::parse_table() gives a LALR parser's table (ParseTable and its
Action, now public as LalrAction), as Python Lark's
parser.parser.parser.parse_table; ParserState gives its state and value
stacks and pops them with truncate(), as Lark's on_error handlers do
through state_stack and value_stack; InteractiveParser gives
parser_state_mut() and next_token(), which lexes one token for the
current state without feeding it. Tools that print the automaton or
recover from errors themselves (etalii.adp spec 035) need nothing else.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@vrenken vrenken self-assigned this Oct 24, 2026
@vrenken
vrenken merged commit 26bc527 into develop Oct 24, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant