Skip to content
PARG: one grammar, every runtime|O(n) Guaranteed

Build Parsers with Confidence

Write a grammar once. Compile it to a verified, checksummed artifact. Get byte-identical trees and IDE-grade error recovery on every engine.

# demo.parg
grammar Demo version "1.0.0" {
  skip = trivia
  trivia = 1*" "

  digit = %x30-39
  number = 1*digit
  publisher = %i"iso" / %i"ieee"

  origin = publisher as publisher
  serial = number as number

  iso_identifier = origin serial
}

bindings iso_identifier {
  publisher -> publisher (string)
  number -> number (integer)
}

entry identifier: iso_identifier
require "parsanol"

document = Parsanol::PARG::Parser.new(File.read("demo.parg")).parse
result   = Parsanol::PARG::Compiler.compile(document)
File.write("demo.artifact.json", JSON.generate(result.envelope))

artifact = Parsanol::PARG::Artifact.load("demo.artifact.json")
artifact.parse_and_bind("identifier", "iso 12345")
# => { publisher: "iso", number: 12345 }
use parsanol::PargArtifact;

// Checksum verified on load — a mismatch is a hard error
let artifact = PargArtifact::from_path("demo.artifact.json")?;
let grammar = artifact.grammar("identifier")?;

// parse `input` with PortableParser::new(&grammar, input, &mut arena)
let bound = artifact.apply_bindings("identifier", &shape)?;
// => { publisher: "iso", number: 12345 }
import init, { PargArtifactJs } from "@parsanol/wasm";

await init();

// Checksum verified on load
const parg = new PargArtifactJs(demoArtifactJson);
const bound = parg.parseAndBind("identifier", "iso 12345");
// => { publisher: "iso", number: 12345 }

parg.runTests(); // replay the artifact's embedded tests

What Parsanol does today

The mission: replace ABNF and ANTLR

Parsanol is the modern grammar language — beyond parslet, beyond SOTA. One grammar replaces ABNF for specification and ANTLR for parser generation: importable from both (:abnf, :antlr), compiled to one checksummed artifact, byte-identical trees on every engine, typed bindings as the listener/visitor replacement, PEG predictability by construction. The parslet wire shape is a migration contract, not the ceiling.

Error recovery, by design

A failed parse returns the deepest real-content position, the expected set, the best partial tree — and when the grammar declares a resync policy, the exact spans consumed so parsing resumed. Deterministic across engines.

One grammar, every runtime

PARG is the grammar language: write once, compile to a checksummed parsanol-tree/v2 artifact; Ruby, Rust, WebAssembly, and the TypeScript runtime consume the same bytes and build the same tree.

Verified identical, every day

A 32-artifact conformance corpus, a nightly five-engine differential fuzz — including a reference walker with every optimization switched off — and shipped-artifact audits keep "identical everywhere" an enforced property.

Fast where it counts

Packrat parsing with O(n) guarantees. On real documents the native engine parses the same grammar roughly 3.6× faster than parslet, with a bytecode VM and incremental sessions for editor-scale reparse.

Real-world grammar features

Skip/trivia injection with comment capture, atomic rules, compile-time left-recursion rewriting with precedence tiers, lookbehind guards, and runtime state atoms — the things real formats actually need.

Tooling that meets you where you are

A language server, a browser playground running the shipped wasm binary, and Ruby-DSL / PARG frontends feeding the same portable core. Next milestone: the compiler itself as wasm — live grammar compilation in the browser (parsanol-rs#298).

Recent News