Skip to content

Alternatives

hyperlark fills a specific niche: it builds LALR(1) and Earley parse tables from a Lark .lark grammar at runtime — no code generation — and exposes that engine natively in Rust, Python, TypeScript/WASM, and C (the C binding is LALR-only today; the others expose both engines). That shapes where it fits well and where it doesn’t, and it differs from every other tool in at least one axis (runtime vs codegen, declarative grammar vs grammar-as-code, LALR vs PEG vs GLR, one language vs four).

Pick your language below — the tabs are sticky, and stay in sync with the code-example tabs elsewhere in the docs, except WASM: what is measured there is the wasm binding rather than a language, so it has no code-example tab to pair with. Each compares hyperlark to the main parsing libraries in that language. Read them as “pick the right tool,” not “hyperlark wins”: a code-generated LR parser or a hand-tuned combinator will out-run runtime tables on a constant factor, and hyperlark’s Earley engine is its general engine, not its fast one.

In Python, hyperlark is a drop-in for lark — the same grammar and API, reimplemented in native Rust. So the honest comparison is against the Python parsing field, where hyperlark’s LALR is the fast option and everyone else (including hyperlark’s own Earley) sits in the pure-Python-speed tier.

ParserApproachProsCons
hyperlarkNative-Rust core with a Lark-compatible APIDrop-in for lark (same grammar + API); the parse runs in native code; LALR and Earley; no runtime lark dependencyYounger; close but not a full-parity guarantee (documented gaps); ships as a compiled wheel
larkPure Python — the reference hyperlark reimplementsVery mature and feature-rich (Earley/LALR/CYK, reconstructor, tree templates); large community; trivial to installPure Python — the slow baseline
PLYPython lex-yacc (LALR)Classic yacc/lex model; stable; well documentedyacc-style (grammars in method docstrings); no tree by default; dated
slyPLY successor (yacc-style LALR)Cleaner than PLY; reduces straight to a value (no tree)Rule-method grammar (no separate grammar file); no general parse tree; less active
pyparsingCombinators (PEG-ish), pure PythonExpressive; hugely popular; no separate grammar fileSlow; grammar-as-Python-code; PEG-style limits
parsimoniousPEG, clean external grammarSimple declarative PEG grammarPure-Python slow; PEG semantics
ANTLR4 (Python target)LL(*) generator (codegen)Powerful; excellent tooling; one grammar → many targetsCodegen via a Java tool; heavy, verbose runtime; LL(*), not LALR

Choose hyperlark when you already use (or would use) lark and want the same trees far faster. Stay on lark if you need a feature hyperlark defers (reconstructor, tree templates, CYK) or want zero compiled dependencies. Choose sly for a yacc-style evaluator with no tree. Choose ANTLR if you need one grammar across many host languages and its tooling.

JSON → value at ~134 KB (Python, lower is better)
hyperlark (LALR) 4.85 ms
sly 43.4 ms
lark (LALR) 52.6 ms
hyperlark (Earley) 66.1 ms
parsimonious 201 ms
Same value from every library (checked; a disagreement is reported). hyperlark's LALR runs the parse in native Rust — ~10.8× lark, and ahead of the yacc-style sly (which builds no tree, as hyperlark's benched path does not either). Its Earley is the general engine — slower than any LALR here — but lark's own Earley (the fair peer) is 1056 ms, so hyperlark-Earley is ~16.0× faster than it.