Skip to content

Convenience combinators provide ready-to-use parsers for common patterns like digits, letters, and whitespace.

Parseff.digit parses a decimal digit (0-9) and returns its integer value.

val digit : unit -> int
(* Parse two-digit number *)
let two_digits () =
let a = Parseff.digit () in
let b = Parseff.digit () in
a * 10 + b
(* Matches "42" -> 42 *)

Parseff.letter parses an ASCII letter (a-z or A-Z).

val letter : unit -> char
let initial () = Parseff.letter ()
(* Matches "A" -> 'A' *)
(* Matches "z" -> 'z' *)
(* Fails on "1" *)

Parseff.alphanum parses an alphanumeric character (letter or digit).

val alphanum : unit -> char
let username () =
let first = Parseff.letter () in
let rest = Parseff.many Parseff.alphanum () in
String.make 1 first ^ String.of_seq (List.to_seq rest)
(* Matches "user123" -> "user123" *)
(* Fails on "123user" (must start with letter) *)

Parseff.any_char parses any character. Fails only at end of input.

val any_char : unit -> char
(* Skip past a single unknown character *)
let skip_one () =
let _ = Parseff.any_char () in
()
(* Peek at the next character without consuming it *)
let peek () = Parseff.look_ahead Parseff.any_char

Parseff.is_whitespace returns true for whitespace characters (space, tab, newline, carriage return). This is a predicate, not a parser.

val is_whitespace : char -> bool
let trim_parser () =
Parseff.skip_while Parseff.is_whitespace;
let value =
Parseff.take_while1
(fun c -> not (Parseff.is_whitespace c))
~label:"value"
in
Parseff.skip_while Parseff.is_whitespace;
value
(* Matches " hello " -> "hello" *)

Parseff.whitespace parses zero or more whitespace characters. Returns the matched string. Always succeeds (returns empty string if no whitespace).

val whitespace : unit -> string
let spaced_values () =
let a = Parseff.digit () in
let _ = Parseff.whitespace () in
let b = Parseff.digit () in
(a, b)
(* Matches "1 2" -> (1, 2) *)
(* Matches "1 2" -> (1, 2) *)
(* Matches "12" -> (1, 2) *)

Parseff.whitespace1 parses one or more whitespace characters. Fails if no whitespace found.

val whitespace1 : unit -> string
let words () =
Parseff.sep_by1
(fun () ->
Parseff.take_while1
(fun c -> not (Parseff.is_whitespace c))
~label:"word")
(fun () -> Parseff.whitespace1 ())
()
(* Matches "hello world" -> ["hello"; "world"] *)
(* Fails on "helloworld" (no whitespace separator) *)

Parseff.skip_whitespace skips zero or more whitespace characters (returns unit). More efficient than Parseff.whitespace when you don’t need the matched string.

val skip_whitespace : unit -> unit
(* Parse comma-separated list with flexible spacing *)
let flexible_list () =
let _ = Parseff.char '[' in
Parseff.skip_whitespace ();
let values =
Parseff.sep_by
(fun () ->
Parseff.skip_whitespace ();
let n = Parseff.digit () in
Parseff.skip_whitespace ();
n)
(fun () -> Parseff.char ',')
()
in
Parseff.skip_whitespace ();
let _ = Parseff.char ']' in
values
(* All of these parse to [1; 2; 3]: *)
(* "[1,2,3]" *)
(* "[ 1 , 2 , 3 ]" *)
(* "[ 1 , 2 , 3 ]" *)
(* allocates a string you don't need *)
let _ = Parseff.whitespace () in
parse_value ()
(* skips without allocating *)
Parseff.skip_whitespace ();
parse_value ()