Commit 9a027761 by POTTIER Francois

Renamed [loop_test] to [shifts] and simplified its type.

It now simply returns an option.
parent 5cf9df2c
......@@ -142,8 +142,11 @@ module Make
(* Build a dummy token for the terminal symbol [t]. *)
let token = (terminal2token t, pos, pos) in
(* Submit it to the parser. Accumulate explanations. *)
let checkpoint = offer checkpoint token in
I.loop_test (accumulate t) checkpoint explanations
match shifts (offer checkpoint token) with
| None ->
explanations
| Some env ->
accumulate t env explanations
) []
)
......
......@@ -593,31 +593,20 @@ module Make (T : TABLE) = struct
(* ------------------------------------------------------------------------ *)
(* [loop_test f checkpoint accu] assumes that [checkpoint] has been obtained
by submitting a token to the parser. It runs the parser from [checkpoint],
through an arbitrary number of reductions, until the parser either accepts
this token (i.e., shifts) or rejects it (i.e., signals an error). If the
parser decides to shift, then the accumulator is updated by applying the
user function [f] to the [env] just before shifting and to the old [accu].
Otherwise, the accumulator is not updated, i.e., [accu] is returned. *)
(* This test causes some semantic actions to be run! The semantic actions
should be side-effect free, or their side-effects should be harmless. *)
let rec loop_test f checkpoint accu =
let rec shifts checkpoint =
match checkpoint with
| Shifting (env, _, _) ->
(* The parser is about to shift, which means it is willing to
consume the terminal symbol that we have fed it. Update the
accumulator with the state just before this transition. *)
f env accu
consume the terminal symbol that we have fed it. Return the
state just before this transition. *)
Some env
| AboutToReduce _ ->
(* The parser wishes to reduce. Just follow. *)
loop_test f (resume checkpoint) accu
shifts (resume checkpoint)
| HandlingError _ ->
(* The parser fails, which means it rejects the terminal symbol
that we have fed it. Do not update the accumulator. *)
accu
None
| InputNeeded _
| Accepted _
| Rejected ->
......@@ -626,27 +615,12 @@ module Make (T : TABLE) = struct
it can request another token or terminate. *)
assert false
(* ------------------------------------------------------------------------ *)
(* The function [loop_test] can be used, after an error has been detected, to
dynamically test which tokens would have been accepted at this point. We
provide this test, ready for use. *)
(* For completeness, one must undo any spurious reductions before carrying out
this test -- that is, one must apply [acceptable] to the FIRST checkpoint
that is passed by [loop_handle_undo] to its failure continuation. *)
(* This test causes some semantic actions to be run! The semantic actions
should be side-effect free, or their side-effects should be harmless. *)
(* The position [pos] is used as the start and end positions of the
hypothetical token, and may be picked up by the semantic actions. We
suggest using the position where the error was detected. *)
let acceptable checkpoint token pos =
let triple = (token, pos, pos) in
let checkpoint = offer checkpoint triple in
loop_test (fun _env _accu -> true) checkpoint false
match shifts checkpoint with
| None -> false
| Some _env -> true
(* ------------------------------------------------------------------------ *)
......
......@@ -152,24 +152,22 @@ module type INCREMENTAL_ENGINE = sig
('a checkpoint -> 'a checkpoint -> 'answer) ->
supplier -> 'a checkpoint -> 'answer
(* [loop_test f checkpoint accu] assumes that [checkpoint] has been obtained
by submitting a token to the parser. It runs the parser from [checkpoint],
through an arbitrary number of reductions, until the parser either accepts
this token (i.e., shifts) or rejects it (i.e., signals an error). If the
parser decides to shift, then the accumulator is updated by applying the
user function [f] to the [env] just before shifting and to the old [accu].
Otherwise, the accumulator is not updated, i.e., [accu] is returned. *)
(* [shifts checkpoint] assumes that [checkpoint] has been obtained by
submitting a token to the parser. It runs the parser from [checkpoint],
through an arbitrary number of reductions, until the parser either
accepts this token (i.e., shifts) or rejects it (i.e., signals an error).
If the parser decides to shift, then [Some env] is returned, where [env]
is the parser's state just before shifting. Otherwise, [None] is
returned. *)
(* It is desirable that the semantic actions be side-effect free, or that
their side-effects be harmless (replayable). *)
val loop_test:
('a env -> 'accu -> 'accu) ->
'a checkpoint -> 'accu -> 'accu
val shifts: 'a checkpoint -> 'a env option
(* The function [loop_test] can be used, after an error has been detected, to
dynamically test which tokens would have been accepted at this point. We
provide this test, ready for use. *)
(* The function [acceptable] allows testing, after an error has been
detected, which tokens would have been accepted at this point. It is
implemented using [shifts]. *)
(* For completeness, one must undo any spurious reductions before carrying out
this test -- that is, one must apply [acceptable] to the FIRST checkpoint
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment