Module CCParse
Very Simple Parser Combinators
open CCParse;;
type tree = L of int | N of tree * tree;;
let mk_leaf x = L x
let mk_node x y = N(x,y)
let ptree = fix @@ fun self ->
skip_space *>
( (try_ (char '(') *> (pure mk_node <*> self <*> self) <* char ')')
<|>
(U.int >|= mk_leaf) )
;;
parse_string_exn ptree "(1 (2 3))" ;;
parse_string_exn ptree "((1 2) (3 (4 5)))" ;;
Parse a list of words
open Containers.Parse;;
let p = U.list ~sep:"," U.word;;
parse_string_exn p "[abc , de, hello ,world ]";;
Stress Test
This makes a list of 100_000 integers, prints it and parses it back.
let p = CCParse.(U.list ~sep:"," U.int);;
let l = CCList.(1 -- 100_000);;
let l_printed =
CCFormat.(to_string (within "[" "]" (list ~sep:(return ",@,") int))) l;;
let l' = CCParse.parse_string_exn p l_printed;;
assert (l=l');;
val string_of_branch : parse_branch -> string
exception
ParseError of parse_branch * unit -> string
parsing branch * message.
Input
val state_of_string : string -> state
Combinators
type 'a t
= state -> ok:('a -> unit) -> err:(exn -> unit) -> unit
Takes the input and two continuations:
ok
to call with the result when it's doneerr
to call when the parser met an error
- raises ParseError
in case of failure.
val return : 'a -> 'a t
Always succeeds, without consuming its input.
val map : ('a -> 'b) -> 'a t -> 'b t
val map2 : ('a -> 'b -> 'c) -> 'a t -> 'b t -> 'c t
val map3 : ('a -> 'b -> 'c -> 'd) -> 'a t -> 'b t -> 'c t -> 'd t
val (>>=) : 'a t -> ('a -> 'b t) -> 'b t
Monadic bind.
p >>= f
results in a new parser which behaves asp
then, in case of success, appliesf
to the result.
val (<*) : 'a t -> _ t -> 'a t
a <* b
parsesa
intox
, parsesb
and ignores its result, and returnsx
.
val (*>) : _ t -> 'a t -> 'a t
a *> b
parsesa
, then parsesb
intox
, and returnsx
. The results ofa
is ignored.
val fail : string -> 'a t
fail msg
fails with the given message. It can trigger a backtrack.
val parsing : string -> 'a t -> 'a t
parsing s p
behaves the same asp
, with the information that we are parsings
, ifp
fails.
val eoi : unit t
Expect the end of input, fails otherwise.
val nop : unit t
Succeed with
()
.
val char : char -> char t
char c
parses the characterc
and nothing else.
val char_if : (char -> bool) -> char t
char_if f
parses a characterc
iff c = true
.
val chars_if : (char -> bool) -> string t
chars_if f
parses a string of chars that satisfyf
.
val endline : char t
Parse '\n'.
val space : char t
Tab or space.
val white : char t
Tab or space or newline.
val skip_chars : (char -> bool) -> unit t
Skip 0 or more chars satisfying the predicate.
val skip_space : unit t
Skip ' ' and '\t'.
val skip_white : unit t
Skip ' ' and '\t' and '\n'.
val (<|>) : 'a t -> 'a t -> 'a t
a <|> b
tries to parsea
, and ifa
fails without consuming any input, backtracks and tries to parseb
, otherwise it fails asa
. Seetry_
to ensurea
does not consume anything (but it is best to avoid wrapping large parsers withtry_
).
val (<?>) : 'a t -> string -> 'a t
a <?> msg
behaves likea
, but ifa
fails without consuming any input, it fails withmsg
instead. Useful as the last choice in a series of<|>
:a <|> b <|> c <?> "expected a|b|c"
.
val try_ : 'a t -> 'a t
try_ p
tries to parse likep
, but backtracks ifp
fails. Useful in combination with<|>
.
val suspend : (unit -> 'a t) -> 'a t
suspend f
is the same asf ()
, but evaluatesf ()
only when needed.
val string : string -> string t
string s
parses exactly the strings
, and nothing else.
val memo : 'a t -> 'a t
Memoize the parser.
memo p
will behave likep
, but when called in a state (read: position in input) it has already processed,memo p
returns a result directly. The implementation uses an underlying hashtable. This can be costly in memory, but improve the run time a lot if there is a lot of backtracking involvingp
.This function is not thread-safe.
val get_lnum : int t
Reflect the current line number.
val get_cnum : int t
Reflect the current column number.
val get_pos : (int * int) t
Reflect the current (line, column) numbers.
Parse
Those functions have a label ~p
on the parser, since 0.14.
val parse : 'a t -> state -> 'a or_error
parse p st
appliesp
on the input, and returnsOk x
ifp
succeeds withx
, orError s
otherwise.
val parse_string_exn : 'a t -> string -> 'a
- raises ParseError
if it fails.
val parse_file : 'a t -> string -> 'a or_error
parse_file p file
parsesfile
withp
by opening the file and reading it whole.
val parse_file_exn : 'a t -> string -> 'a
- raises ParseError
if it fails.
Infix
module Infix : sig ... end
Utils
This is useful to parse OCaml-like values in a simple way.
module U : sig ... end
Let operators on OCaml >= 4.08.0, nothing otherwise
- since
- 2.8