mirror of
https://github.com/c-cube/iter.git
synced 2025-12-06 11:15:32 -05:00
ability to parse a sequence of values from a Sexpr
This commit is contained in:
parent
cce20838c4
commit
6322884f2f
2 changed files with 22 additions and 6 deletions
23
sexpr.ml
23
sexpr.ml
|
|
@ -224,10 +224,11 @@ type 'a state =
|
||||||
| Bottom : 'a state
|
| Bottom : 'a state
|
||||||
| Push : ('b parser * ('b -> 'a state)) -> 'a state
|
| Push : ('b parser * ('b -> 'a state)) -> 'a state
|
||||||
|
|
||||||
(** Actually parse the sequence of tokens *)
|
(** Actually parse the sequence of tokens, with a callback to be called
|
||||||
let parse p tokens =
|
on every parsed value. The callback decides whether to push another
|
||||||
let res = ref None in
|
state or whether to continue. *)
|
||||||
let state = Push(p, fun x -> (res := Some x; Bottom)) in
|
let parse_k p tokens k =
|
||||||
|
let rec state = Push(p, fun x -> match k x with `Stop -> Bottom | `Continue -> state) in
|
||||||
(* Token handler. It also takes the current parser. *)
|
(* Token handler. It also takes the current parser. *)
|
||||||
let rec one_step state token =
|
let rec one_step state token =
|
||||||
match state with
|
match state with
|
||||||
|
|
@ -255,9 +256,21 @@ let parse p tokens =
|
||||||
| Push (Fail reason, _) -> raise (ParseFailure reason)
|
| Push (Fail reason, _) -> raise (ParseFailure reason)
|
||||||
in
|
in
|
||||||
(* iterate on the tokens *)
|
(* iterate on the tokens *)
|
||||||
ignore (Sequence.fold one_step state tokens);
|
ignore (Sequence.fold one_step state tokens)
|
||||||
|
|
||||||
|
(** Parse one value *)
|
||||||
|
let parse p tokens =
|
||||||
|
let res = ref None in
|
||||||
|
parse_k p tokens (fun x -> res := Some x; `Stop);
|
||||||
(* return result *)
|
(* return result *)
|
||||||
match !res with
|
match !res with
|
||||||
| None -> raise (ParseFailure "incomplete input")
|
| None -> raise (ParseFailure "incomplete input")
|
||||||
| Some x -> x
|
| Some x -> x
|
||||||
|
|
||||||
|
(** Parse a sequence of values *)
|
||||||
|
let parse_seq p tokens =
|
||||||
|
let seq_fun k =
|
||||||
|
parse_k p tokens (fun x -> k x; `Continue)
|
||||||
|
in
|
||||||
|
Sequence.from_iter seq_fun
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -110,5 +110,8 @@ val many : 'a parser -> 'a list parser
|
||||||
val many1 : 'a parser -> 'a list parser
|
val many1 : 'a parser -> 'a list parser
|
||||||
|
|
||||||
val parse : 'a parser -> token Sequence.t -> 'a
|
val parse : 'a parser -> token Sequence.t -> 'a
|
||||||
(** Actually parse the sequence of tokens. Raises
|
(** Parses exactly one value from the sequence of tokens. Raises
|
||||||
ParseFailure if anything goes wrong. *)
|
ParseFailure if anything goes wrong. *)
|
||||||
|
|
||||||
|
val parse_seq : 'a parser -> token Sequence.t -> 'a Sequence.t
|
||||||
|
(** Parses a sequence of values *)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue