Skip to content

Parseff is a direct-style parser combinator library for OCaml 5 where parsers are plain functions (unit -> 'a), errors are typed via polymorphic variants, and algebraic effects handle control flow, backtracking, and streaming input. Designed for performance with zero-copy span APIs and fused operations.

Parseff is faster than Angstrom and MParser by a factor of 2 to 4x. In case of equal implementations, Parseff is ~2x faster than Angstrom and MParser. With an optimized version using zero-copy span APIs, that gap widens to ~4x. See the full comparison for details and bench/bench_vs_angstrom.ml for the benchmark.

Terminal window
opam install parseff -y

Add parseff to your dune-project:

(package
(name my_project)
(depends
(ocaml (>= 5.3))
(parseff (>= 0.1))))

Then lock and build:

Terminal window
dune pkg lock
dune build
Terminal window
git clone https://github.com/davesnx/parseff.git
cd parseff
make init
make build
dune install
(executable
(name my_parser)
(libraries parseff))

Here’s a small parser that validates IPv4 addresses 192.168.1.1 or 0.0.0.0. A detailed explanation of the IPv4 addresses parser:

let number () =
let digits = Parseff.many1 Parseff.digit () in
let n = List.fold_left (fun acc d -> (acc * 10) + d) 0 digits in
if n >= 0 && n <= 255 then n
else Parseff.error (`Out_of_range n)
let ip_address () =
let a = number () in
let _ = Parseff.char '.' in
let b = number () in
let _ = Parseff.char '.' in
let c = number () in
let _ = Parseff.char '.' in
let d = number () in
Parseff.end_of_input ();
(a, b, c, d)
let () =
match Parseff.parse "192.168.1.1" ip_address with
| Ok (a, b, c, d) ->
Printf.printf "Parsed: %d.%d.%d.%d\n" a b c d
| Error { pos; error = `Out_of_range n } ->
Printf.printf "Error at %d: %d out of range (0-255)\n" pos n
| Error { pos; error = `Expected msg } ->
Printf.printf "Error at %d: %s\n" pos msg
SectionCombinators
Coreconsume, char, satisfy, take_while, take_while1, skip_while, match_regex, fail, error, end_of_input
Combinatorsor_, one_of, one_of_labeled, optional, look_ahead, expect, rec_
Repetition and separationmany, many1, count, sep_by, sep_by1, between, end_by, end_by1, chainl, chainl1, chainr, chainr1
Conveniencedigit, letter, alphanum, any_char, is_whitespace, whitespace, whitespace1, skip_whitespace
Errorsfail, error, expect
Diagnosticswarn, warn_at, parse_until_end, parse_source_until_end
Zero-copy and fused operationstake_while_span, sep_by_take_span, sep_by_take, fused_sep_take, skip_while_then_char
StreamingSource.of_string, Source.of_channel, Source.of_function, parse_source, parse_source_until_end