From fc007f9ed14226e486216210cb38799a4e5e7593 Mon Sep 17 00:00:00 2001 From: Spiros Eliopoulos Date: Sun, 15 Apr 2018 21:21:56 +0000 Subject: [PATCH] choice-error: add an optional `failure_msg` argument to `choice` This can be used to quickly identify which choice resulted in the failure of the parser. In the absence of `commit`, it's always the first choice encountered, but it gets trickier when a parser does use choice. In that case it's the first choice encountered after the last `commit`. --- lib/angstrom.ml | 4 ++-- lib/angstrom.mli | 8 +++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/angstrom.ml b/lib/angstrom.ml index 7ee9700..4ec7dda 100644 --- a/lib/angstrom.ml +++ b/lib/angstrom.ml @@ -425,8 +425,8 @@ let take_while1 f = let take_till f = take_while (fun c -> not (f c)) -let choice ps = - List.fold_right (<|>) ps (fail "empty") +let choice ?(failure_msg="no more choices") ps = + List.fold_right (<|>) ps (fail failure_msg) let fix f = let rec p = lazy (f r) diff --git a/lib/angstrom.mli b/lib/angstrom.mli index 7c3e131..e946797 100644 --- a/lib/angstrom.mli +++ b/lib/angstrom.mli @@ -338,9 +338,11 @@ val (<|>) : 'a t -> 'a t -> 'a t (** [p <|> q] runs [p] and returns the result if succeeds. If [p] fails, then the input will be reset and [q] will run instead. *) -val choice : 'a t list -> 'a t -(** [choice ts] runs each parser in [ts] in order until one succeeds and - returns that result. *) +val choice : ?failure_msg:string -> 'a t list -> 'a t +(** [choice ?message ts] runs each parser in [ts] in order until one succeeds + and returns that result. In the case that none of the parser succeeds, then + the parser will fail with the message [failure_msg], if provided, or a + much less informative message otherwise. *) val () : 'a t -> string -> 'a t (** [p name] associates [name] with the parser [p], which will be reported