doc for CCParse

close #392
This commit is contained in:
Simon Cruanes 2021-12-16 13:17:09 -05:00
parent 946ac4e05d
commit a127e139ae
No known key found for this signature in database
GPG key ID: EBFFF6F283F3A2B4

View file

@ -362,7 +362,12 @@ val is_white : char -> bool
val suspend : (unit -> 'a t) -> 'a t val suspend : (unit -> 'a t) -> 'a t
(** [suspend f] is the same as [f ()], but evaluates [f ()] only (** [suspend f] is the same as [f ()], but evaluates [f ()] only
when needed. *) when needed.
A practical use case is to implement recursive parsers manually,
as described in {!fix}. The parser is [let rec p () = ],
and [suspend p] can be used in the definition to use [p].
*)
val string : string -> string t val string : string -> string t
(** [string s] parses exactly the string [s], and nothing else. *) (** [string s] parses exactly the string [s], and nothing else. *)
@ -423,12 +428,15 @@ val try_or_l :
'a t 'a t
(** [try_or_l ?else_ l] tries each pair [(test, p)] in order. (** [try_or_l ?else_ l] tries each pair [(test, p)] in order.
If the n-th [test] succeeds, then [try_or_l l] behaves like n-th [p], If the n-th [test] succeeds, then [try_or_l l] behaves like n-th [p],
whether [p] fails or not. whether [p] fails or not. If [test] consumes input, the state is restored
before calling [p].
If they all fail, and [else_] is defined, then it behaves like [else_]. If they all fail, and [else_] is defined, then it behaves like [else_].
If all fail, and [else_] is [None], then it fails as well. If all fail, and [else_] is [None], then it fails as well.
This is a performance optimization compared to {!(<|>)}. We commit to a This is a performance optimization compared to {!(<|>)}. We commit to a
branch if the test succeeds, without backtracking at all. branch if the test succeeds, without backtracking at all.
It can also provide better error messages, because failures in the parser
will not be reported as failures in [try_or_l].
See {!lookahead_ignore} for a convenient way of writing the test conditions. See {!lookahead_ignore} for a convenient way of writing the test conditions.
@ -481,7 +489,17 @@ val lookahead_ignore : 'a t -> unit t
@since 3.6 *) @since 3.6 *)
val fix : ('a t -> 'a t) -> 'a t val fix : ('a t -> 'a t) -> 'a t
(** Fixpoint combinator. *) (** Fixpoint combinator. [fix (fun self -> p)] is the parser [p],
in which [self] refers to the parser [p] itself (which is useful to
parse recursive structures.
An alternative, manual implementation to [let p = fix (fun self -> q)]
is:
{[ let rec p () =
let self = suspend p in
q
]}
*)
val line : slice t val line : slice t
(** Parse a line, ['\n'] excluded, and position the cursor after the ['\n']. (** Parse a line, ['\n'] excluded, and position the cursor after the ['\n'].
@ -634,9 +652,7 @@ module Infix : sig
[a <|> b] tries to parse [a], and if [a] fails without [a <|> b] tries to parse [a], and if [a] fails without
consuming any input, backtracks and tries consuming any input, backtracks and tries
to parse [b], otherwise it fails as [a]. to parse [b], otherwise it fails as [a]. *)
See {!try_} to ensure [a] does not consume anything (but it is best
to avoid wrapping large parsers with {!try_}). *)
val (<?>) : 'a t -> string -> 'a t val (<?>) : 'a t -> string -> 'a t
(** [a <?> msg] behaves like [a], but if [a] fails, (** [a <?> msg] behaves like [a], but if [a] fails,