Skip to content

spike: evaluate 4 Rust SQL parser toolchains against SQLite 3.53.4 grammar - #3

Merged
iheitlager merged 2 commits into
mainfrom
spike/001_parser-eval
Aug 13, 2026
Merged

spike: evaluate 4 Rust SQL parser toolchains against SQLite 3.53.4 grammar#3
iheitlager merged 2 commits into
mainfrom
spike/001_parser-eval

Conversation

@iheitlager

Copy link
Copy Markdown
Member

Summary

  • Implements the same SQL subset (CREATE TABLE, INSERT, SELECT, UPDATE, DELETE + shared expr grammar) in 4 Rust parser toolchains — lemon-rs, pomelo, lalrpop, pest — each as a standalone crate under tests/spike/001_parser/.
  • Every variant is verified against the same fixture corpus (fixtures/valid.sql — 30 statements, fixtures/invalid.sql — 20 statements): all four pass 30/30 and 20/20, no panics.
  • Written comparison and recommendation at tests/spike/001_parser/comparison.md.

Changes

Added

  • tests/spike/001_parser/001_lemon-rs/ — Lemon grammar (parse.y), build.rs compiling vendored lemon.c as a build-time tool against the lempar.rs template, hand-rolled tokenizer, minimal AST.
  • tests/spike/001_parser/002_pomelo/pomelo! proc-macro grammar, tokenizer, minimal AST.
  • tests/spike/001_parser/003_lalrpop/.lalrpop grammar, build.rs codegen, minimal AST.
  • tests/spike/001_parser/004_pest/.pest PEG grammar (no separate lexer), minimal AST.
  • tests/spike/001_parser/comparison.md — full comparison (ergonomics, error messages, performance, licensing, maintainability) with a recommendation.
  • CLAUDE.md — project instructions (token spend policy).

Results

lemon-rs pomelo lalrpop pest
Conflicts 0 0 0 n/a (PEG)
µs/statement (release) ~1.3–1.4 ~1.8–2.2 ~9.3 ~4.1
Runtime deps 0 (vendors lemon.c) 0 2 ~10 (all permissive)
License Unlicense/public domain MIT/Apache-2.0 MIT/Apache-2.0 MIT/Apache-2.0

Recommendation: carry pomelo forward. Nearly all of lemon-rs's parse.y fidelity, without its maintenance cost (vendored C tool, undocumented template internals, runtime panics on semantic-type mismatches). lalrpop is the strongest runner-up if compile-time diagnostics matter more than parse.y fidelity. pest isn't recommended for the main grammar (its ordered-choice model makes reproducing SQLite's %fallback ID keyword-as-identifier behavior structurally harder), though it could suit a narrower PEG-shaped problem later.

Two cross-cutting issues surfaced that need tracking separately:

  • The shared EBNF's comparison-precedence text and its %left-mirroring comment disagree on whether chained comparisons (1 = 2 = 3) should be legal.
  • None of the 4 variants attempted SQLite's %fallback ID (keywords double as identifiers) — out of scope for the spike, but a real differentiator going forward.

Testing

  • cargo test passes in all 4 variants (verified individually, not as a workspace — each is a standalone crate)
  • All 30 valid fixtures parse and all 20 invalid fixtures are rejected, in every variant
  • No panics on any fixture, including degenerate/truncated input

Related Issues

Closes #1


🤖 Generated with Claude Code

iheitlager and others added 2 commits August 13, 2026 20:37
…ammar

Implements the same SQL subset (CREATE TABLE, INSERT, SELECT, UPDATE,
DELETE + shared expr grammar) in lemon-rs, pomelo, lalrpop, and pest,
each verified against a shared valid/invalid SQL fixture corpus.
Recommends carrying pomelo forward: closest to lemon-rs's parse.y
fidelity without its vendored-C-tool maintenance burden. Full
comparison in tests/spike/001_parser/comparison.md.

Closes #1

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Layered Makefiles (root delegates to tests/spike/001_parser/Makefile)
with a self-documenting help target, modeled on mvl-lang/mvl's Makefile.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
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.

spike: evaluate Rust SQL parser approaches against SQLite 3.53.4 grammar

1 participant