Commit 535cee59 authored by POTTIER Francois's avatar POTTIER Francois

Merge branch 'master' into merr

Conflicts:
	CHANGES
	TODO
parents f5dae789 942ce961
......@@ -20,6 +20,21 @@ New option --interpret-error, which confirms that one particular input
sentence ends in a syntax error, and prints the number of the state in
which this error occurs.
2015/10/16:
Additions to the incremental API.
A [supplier] is a function that produces tokens on demand.
[lexer_lexbuf_to_supplier] turns a lexer and a lexbuf into a supplier.
[loop] is a ready-made made main parsing loop.
[loop_handle] is a variant of [loop] that lets the user do her own error handling.
2015/10/16:
Incompatible change of the incremental API: renamed the type ['a result]
to ['a checkpoint]. This is a better name anyway, and should help avoid
confusion with the type ['a result] introduced in OCaml 4.03.
2015/10/12:
Avoid using $(shell pwd) in Makefile, for better Windows compatibility.
2015/10/05:
Fixed a bug where inconsistent OCaml code was generated when --table
and --external-tokens were used together. (Reported by Darin Morrison.)
......
......@@ -35,6 +35,9 @@
Idea: investigate the use of placeholders (in the message)
that could be filled with dynamic information!
* Clear up the Windows path confusion. Can we use "/" in Menhir's
source code and in the Makefiles? Does OPAM work on Windows?
* Dans les avantages de Menhir versus ocamlyacc (dans la doc et
sur la page Web), ajouter le back-end Coq, l'API incrémentale
et l'API d'inspection, les règles anonymes, la gestion fine des
......
......@@ -3,27 +3,28 @@
module I =
Parser.MenhirInterpreter
(* The loop which drives the parser. At each iteration, we analyze a
result produced by the parser, and act in an appropriate manner. *)
(* -------------------------------------------------------------------------- *)
(* [lexbuf] is the lexing buffer. [result] is the last result produced
(* The loop which drives the parser. At each iteration, we analyze a
checkpoint produced by the parser, and act in an appropriate manner.
[lexbuf] is the lexing buffer. [checkpoint] is the last checkpoint produced
by the parser. *)
let rec loop lexbuf (result : int I.result) =
match result with
let rec loop lexbuf (checkpoint : int I.checkpoint) =
match checkpoint with
| I.InputNeeded env ->
(* The parser needs a token. Request one from the lexer,
and offer it to the parser, which will produce a new
result. Then, repeat. *)
checkpoint. Then, repeat. *)
let token = Lexer.token lexbuf in
let startp = lexbuf.Lexing.lex_start_p
and endp = lexbuf.Lexing.lex_curr_p in
let result = I.offer result (token, startp, endp) in
loop lexbuf result
let checkpoint = I.offer checkpoint (token, startp, endp) in
loop lexbuf checkpoint
| I.Shifting _
| I.AboutToReduce _ ->
let result = I.resume result in
loop lexbuf result
let checkpoint = I.resume checkpoint in
loop lexbuf checkpoint
| I.HandlingError env ->
(* The parser has suspended itself because of a syntax error. Stop. *)
Printf.fprintf stderr
......@@ -37,6 +38,28 @@ let rec loop lexbuf (result : int I.result) =
we stop as soon as the parser reports [HandlingError]. *)
assert false
(* -------------------------------------------------------------------------- *)
(* The above loop is shown for explanatory purposes, but can in fact be
replaced with the following code, which exploits the functions
[lexer_lexbuf_to_supplier] and [loop_handle] offered by Menhir. *)
let succeed (v : int) =
(* The parser has succeeded and produced a semantic value. Print it. *)
Printf.printf "%d\n%!" v
let fail lexbuf (_ : int I.checkpoint) =
(* The parser has suspended itself because of a syntax error. Stop. *)
Printf.fprintf stderr
"At offset %d: syntax error.\n%!"
(Lexing.lexeme_start lexbuf)
let loop lexbuf result =
let supplier = I.lexer_lexbuf_to_supplier Lexer.token lexbuf in
I.loop_handle succeed (fail lexbuf) supplier result
(* -------------------------------------------------------------------------- *)
(* Initialize the lexer, and catch any exception raised by the lexer. *)
let process (line : string) =
......@@ -47,6 +70,8 @@ let process (line : string) =
| Lexer.Error msg ->
Printf.fprintf stderr "%s%!" msg
(* -------------------------------------------------------------------------- *)
(* The rest of the code is as in the [calc] demo. *)
let process (optional_line : string option) =
......
......@@ -1941,7 +1941,7 @@ the name of the start symbol.) The generated file \texttt{parser.mli} contains
the following declaration:
\begin{verbatim}
module Incremental : sig
val main: unit -> thing MenhirInterpreter.result
val main: unit -> thing MenhirInterpreter.checkpoint
end
\end{verbatim}
We emphasize that the function \verb+Incremental.main+ does not parse
......@@ -1959,9 +1959,9 @@ follows:
The signature \verb+INCREMENTAL_ENGINE+, defined in the module
\menhirlibincrementalengine, contains the following elements.
Please keep in mind that, from the outside, these elements should be referred
to with an appropriate prefix: e.g., the type \verb+result+ should be referred
to as \verb+MenhirInterpreter.result+, or
\verb+Parser.MenhirInterpreter.result+, depending on which modules the user
to with an appropriate prefix: e.g., the type \verb+checkpoint+ should be referred
to as \verb+MenhirInterpreter.checkpoint+, or
\verb+Parser.MenhirInterpreter.checkpoint+, depending on which modules the user
chooses to open.
%% type token
......@@ -1987,10 +1987,10 @@ data structure: it can be stored and used multiple times, if desired.
The abstract type \verb+production+ represents a production of the grammar.
%% type 'a result
%% type 'a checkpoint
\begin{verbatim}
type 'a result = private
type 'a checkpoint = private
| InputNeeded of env
| Shifting of env * env * bool
| AboutToReduce of env * production
......@@ -1999,29 +1999,29 @@ The abstract type \verb+production+ represents a production of the grammar.
| Rejected
\end{verbatim}
The type \verb+'a result+ represents an intermediate or
final result of the parser. An intermediate result is a suspension: it records
The type \verb+'a checkpoint+ represents an intermediate or
final state of the parser. An intermediate checkpoint is a suspension: it records
the parser's current state, and allows parsing to be resumed. The parameter
\verb+'a+ is the type of the semantic value that will eventually be produced
if the parser succeeds.
\verb+Accepted+ and \verb+Rejected+ are final results. \verb+Accepted+ carries
\verb+Accepted+ and \verb+Rejected+ are final checkpoints. \verb+Accepted+ carries
a semantic value.
\verb+InputNeeded+ is an intermediate result. It means that the parser wishes
\verb+InputNeeded+ is an intermediate checkpoint. It means that the parser wishes
to read one token before continuing.
\verb+Shifting+ is an intermediate result. It means that the parser is taking
\verb+Shifting+ is an intermediate checkpoint. It means that the parser is taking
a shift transition. It exposes the state of the parser before and after the
transition. The Boolean parameter tells whether the parser intends to request
a new token after this transition. (It always does, except when it is about to
accept.)
\verb+AboutToReduce+ is an intermediate result: it means that the parser is
\verb+AboutToReduce+ is an intermediate checkpoint: it means that the parser is
about to perform a reduction step. \verb+HandlingError+ is also an
intermediate result: it means that the parser has detected an error and is
intermediate checkpoint: it means that the parser has detected an error and is
about to handle it. (Error handling is typically performed in several steps,
so the next result is likely to be \verb+HandlingError+ again.) In these two
so the next checkpoint is likely to be \verb+HandlingError+ again.) In these two
cases, the parser does not need more input. The parser suspends itself at this
point only in order to give the user an opportunity to observe the parser's
transitions and possibly handle errors in a different manner, if desired.
......@@ -2030,16 +2030,16 @@ transitions and possibly handle errors in a different manner, if desired.
\begin{verbatim}
val offer:
'a result ->
'a checkpoint ->
token * Lexing.position * Lexing.position ->
'a result
'a checkpoint
\end{verbatim}
The function \verb+offer+ allows the user to resume the parser after the
parser has suspended itself with a result of the form \verb+InputNeeded env+.
This function expects the previous result \verb+result+ as well as a new token
parser has suspended itself with a checkpoint of the form \verb+InputNeeded env+.
This function expects the previous checkpoint \verb+checkpoint+ as well as a new token
(together with the start and end positions of this token). It produces a new
result, which again can be an intermediate result or a final result. It does
checkpoint, which again can be an intermediate checkpoint or a final checkpoint. It does
not raise any exception. (The exception \texttt{Error} is used only in the
monolithic API.)
......@@ -2047,25 +2047,90 @@ monolithic API.)
\begin{verbatim}
val resume:
'a result ->
'a result
'a checkpoint ->
'a checkpoint
\end{verbatim}
The function \verb+resume+ allows the user to resume the parser after the
parser has suspended itself with a result of the form
parser has suspended itself with a checkpoint of the form
\verb+AboutToReduce (env, prod)+ or \verb+HandlingError env+.
This function expects just the previous result \verb+result+. It produces a new
result. It does not raise any exception.
This function expects just the previous checkpoint \verb+checkpoint+. It produces a new
checkpoint. It does not raise any exception.
The incremental API subsumes the monolithic API. Indeed, \verb+main+ can be
(and is in fact) implemented by first using
\verb+Incremental.main+, then calling \verb+offer+ and
\verb+resume+ in a loop, until a final result is obtained.
\verb+resume+ in a loop, until a final checkpoint is obtained.
Although the type \verb+env+ is opaque, a parser state can be inspected via a
few accessor functions, which we are about to describe. Before we do so, we
give a few more type definitions.
%% type supplier
\begin{verbatim}
type supplier =
unit -> token * Lexing.position * Lexing.position
\end{verbatim}
A token supplier is a function of no arguments which delivers a new token
(together with its start and end positions) every time it is called. The
function \verb+loop+ and its variants, described below, expect a supplier
as an argument.
%% val lexer_lexbuf_to_supplier
\begin{verbatim}
val lexer_lexbuf_to_supplier:
(Lexing.lexbuf -> token) ->
Lexing.lexbuf ->
supplier
\end{verbatim}
The function \verb+lexer_lexbuf_to_supplier+, applied to a lexer and to a
lexing buffer, produces a fresh supplier.
%% (remark about the loop* functions)
The functions \verb+offer+ and \verb+resume+, documented above, are sufficient
to write a parser loop. One can imagine many variations of such a loop, which
is why we expose \verb+offer+ and \verb+resume+ in the first place!.
Nevertheless, some variations are so common that it is worth providing them,
ready for use.
%% val loop
\begin{verbatim}
val loop: supplier -> 'a checkpoint -> 'a
\end{verbatim}
\verb+loop supplier checkpoint+ begins parsing from \verb+checkpoint+, reading
tokens from \verb+supplier+. It continues parsing until it reaches a
checkpoint of the form \verb+Accepted v+ or \verb+Rejected+. In the former
case, it returns \verb+v+. In the latter case, it raises the
exception \verb+Error+. (By the way, this is how we implement the monolithic
API on top of the incremental API.)
\begin{verbatim}
val loop_handle:
('a -> 'answer) ->
('a checkpoint -> 'answer) ->
supplier -> 'a checkpoint -> 'answer
\end{verbatim}
\verb+loop_handle succeed fail supplier checkpoint+ begins parsing from
\verb+checkpoint+, reading tokens from \verb+supplier+. It continues parsing until
it reaches a checkpoint of the form \verb+Accepted v+ or \verb+HandlingError env+
(or \verb+Rejected+, but that should not happen, as \verb+HandlingError _+
will be observed first). In the former case, it calls \verb+succeed v+. In
the latter case, it calls \verb+fail+ with this checkpoint. It cannot
raise \verb+Error+.
This means that Menhir's traditional error-handling procedure (which pops the
stack until a state that can act on the \error token is found) does not get a
chance to run. Instead, the user can implement her own error handling code, in
the \verb+fail+ continuation.
%% type 'a lr1state
\begin{verbatim}
......
......@@ -99,7 +99,7 @@ module Make
| _ :: _, lazy Nil ->
assert false
(* [investigate t result] assumes that [result] has been obtained by
(* [investigate t checkpoint] assumes that [checkpoint] has been obtained by
offering the terminal symbol [t] to the parser. It runs the parser,
through an arbitrary number of reductions, until the parser either
accepts this token (i.e., shifts) or rejects it (i.e., signals an
......@@ -109,8 +109,8 @@ module Make
(* It is desirable that the semantic actions be side-effect free, or
that their side-effects be harmless (replayable). *)
let rec investigate (t : _ terminal) (result : _ result) explanations =
match result with
let rec investigate (t : _ terminal) (checkpoint : _ checkpoint) explanations =
match checkpoint with
| Shifting (env, _, _) ->
(* The parser is about to shift, which means it is willing to
consume the terminal symbol [t]. In the state before the
......@@ -132,7 +132,7 @@ module Make
(* TEMPORARY [env] may be an initial state! violating [item_current]'s precondition *)
| AboutToReduce _ ->
(* The parser wishes to reduce. Just follow. *)
investigate t (resume result) explanations
investigate t (resume checkpoint) explanations
| HandlingError _ ->
(* The parser fails, which means the terminal symbol [t] does
not make sense at this point. Thus, no new explanations of
......@@ -146,7 +146,7 @@ module Make
it can request another token or terminate. *)
assert false
(* [investigate pos result] assumes that [result] is of the form
(* [investigate pos checkpoint] assumes that [checkpoint] is of the form
[InputNeeded _]. For every terminal symbol [t], it investigates
how the parser reacts when fed the symbol [t], and returns a list
of explanations. The position [pos] is where a syntax error was
......@@ -154,7 +154,7 @@ module Make
important because the position of the dummy token may end up in
the explanations that we produce. *)
let investigate pos (result : _ result) : explanation list =
let investigate pos (checkpoint : _ checkpoint) : explanation list =
weed compare_explanations (
foreach_terminal_but_error (fun symbol explanations ->
match symbol with
......@@ -163,7 +163,7 @@ 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. *)
investigate t (offer result token) explanations
investigate t (offer checkpoint token) explanations
) []
)
......@@ -180,38 +180,38 @@ module Make
token, startp, endp
(* The following is a custom version of the loop found in [Engine]. It
drives the parser in the usual way, but keeps a checkpoint, which is the
last [InputNeeded] result. If a syntax error is detected, it goes back to
this state and analyzes it in order to produce a meaningful
drives the parser in the usual way, but records the last [InputNeeded]
checkpoint. If a syntax error is detected, it goes back to this
checkpoint and analyzes it in order to produce a meaningful
diagnostic. *)
exception Error of (Lexing.position * Lexing.position) * explanation list
(* TEMPORARY why loop-style? we should offer a simplified incremental API *)
type 'a result = {
checkpoint: 'a I.result;
current: 'a I.result
type 'a checkpoint = {
inputneeded: 'a I.checkpoint;
current: 'a I.checkpoint
}
let rec loop (read : reader) ({ checkpoint; current } : 'a result) : 'a =
let rec loop (read : reader) ({ inputneeded; current } : 'a checkpoint) : 'a =
match current with
| InputNeeded _ ->
(* Update the checkpoint. *)
let checkpoint = current in
(* Update the last recorded [InputNeeded] checkpoint. *)
let inputneeded = current in
let triple = read() in
let current = offer current triple in
loop read { checkpoint; current }
loop read { inputneeded; current }
| Shifting _
| AboutToReduce _ ->
let current = resume current in
loop read { checkpoint; current }
loop read { inputneeded; current }
| HandlingError env ->
(* The parser signals a syntax error. Note the position of the
problematic token, which is useful. Then, go back to the
checkpoint and investigate. *)
let (startp, _) as positions = positions env in
raise (Error (positions, investigate startp checkpoint))
raise (Error (positions, investigate startp inputneeded))
| Accepted v ->
v
| Rejected ->
......@@ -219,13 +219,13 @@ module Make
we stop as soon as the parser reports [HandlingError]. *)
assert false
let entry (start : 'a I.result) lexer lexbuf =
let entry (start : 'a I.checkpoint) lexer lexbuf =
(* The parser cannot accept or reject before it asks for the very first
character of input. (Indeed, we statically reject a symbol that
generates the empty language or the singleton language {epsilon}.)
So, [start] must be [InputNeeded _]. *)
assert (match start with InputNeeded _ -> true | _ -> false);
loop (wrap lexer lexbuf) { checkpoint = start; current = start }
loop (wrap lexer lexbuf) { inputneeded = start; current = start }
(* TEMPORARY could also publish a list of the terminal symbols that
do not cause an error *)
......
......@@ -75,6 +75,6 @@ module Make
type reader =
unit -> token * Lexing.position * Lexing.position
val entry: 'a I.result -> (Lexing.lexbuf -> token) -> Lexing.lexbuf -> 'a
val entry: 'a I.checkpoint -> (Lexing.lexbuf -> token) -> Lexing.lexbuf -> 'a
end
......@@ -9,36 +9,36 @@ module type INCREMENTAL_ENGINE = sig
type token
(* The type ['a result] represents an intermediate or final result of the
parser. An intermediate result is a suspension: it records the parser's
(* The type ['a checkpoint] represents an intermediate or final state of the
parser. An intermediate checkpoint is a suspension: it records the parser's
current state, and allows parsing to be resumed. The parameter ['a] is
the type of the semantic value that will eventually be produced if the
parser succeeds. *)
(* [Accepted] and [Rejected] are final results. [Accepted] carries a
(* [Accepted] and [Rejected] are final checkpoints. [Accepted] carries a
semantic value. *)
(* [InputNeeded] is an intermediate result. It means that the parser wishes
(* [InputNeeded] is an intermediate checkpoint. It means that the parser wishes
to read one token before continuing. *)
(* [Shifting] is an intermediate result. It means that the parser is taking
(* [Shifting] is an intermediate checkpoint. It means that the parser is taking
a shift transition. It exposes the state of the parser before and after
the transition. The Boolean parameter tells whether the parser intends to
request a new token after this transition. (It always does, except when
it is about to accept.) *)
(* [AboutToReduce] is an intermediate result. It means that the parser is
(* [AboutToReduce] is an intermediate checkpoint. It means that the parser is
about to perform a reduction step. It exposes the parser's current
state as well as the production that is about to be reduced. *)
(* [HandlingError] is an intermediate result. It means that the parser has
(* [HandlingError] is an intermediate checkpoint. It means that the parser has
detected an error and is currently handling it, in several steps. *)
type env
type production
type 'a result = private
type 'a checkpoint = private
| InputNeeded of env
| Shifting of env * env * bool
| AboutToReduce of env * production
......@@ -47,23 +47,65 @@ module type INCREMENTAL_ENGINE = sig
| Rejected
(* [offer] allows the user to resume the parser after it has suspended
itself with a result of the form [InputNeeded env]. [offer] expects the
old result as well as a new token and produces a new result. It does not
itself with a checkpoint of the form [InputNeeded env]. [offer] expects the
old checkpoint as well as a new token and produces a new checkpoint. It does not
raise any exception. *)
val offer:
'a result ->
'a checkpoint ->
token * Lexing.position * Lexing.position ->
'a result
'a checkpoint
(* [resume] allows the user to resume the parser after it has suspended
itself with a result of the form [AboutToReduce (env, prod)] or
[HandlingError env]. [resume] expects the old result and produces a new
result. It does not raise any exception. *)
itself with a checkpoint of the form [AboutToReduce (env, prod)] or
[HandlingError env]. [resume] expects the old checkpoint and produces a new
checkpoint. It does not raise any exception. *)
val resume:
'a result ->
'a result
'a checkpoint ->
'a checkpoint
(* A token supplier is a function of no arguments which delivers a new token
(together with its start and end positions) every time it is called. *)
type supplier =
unit -> token * Lexing.position * Lexing.position
(* A pair of a lexer and a lexing buffer can be easily turned into a supplier. *)
val lexer_lexbuf_to_supplier:
(Lexing.lexbuf -> token) ->
Lexing.lexbuf ->
supplier
(* The functions [offer] and [resume] are sufficient to write a parser loop.
One can imagine many variations (which is why we expose these functions
in the first place!). Here, we expose a few variations of the main loop,
ready for use. *)
(* [loop supplier checkpoint] begins parsing from [checkpoint], reading
tokens from [supplier]. It continues parsing until it reaches a
checkpoint of the form [Accepted v] or [Rejected]. In the former case, it
returns [v]. In the latter case, it raises the exception [Error]. *)
val loop: supplier -> 'a checkpoint -> 'a
(* [loop_handle succeed fail supplier checkpoint] begins parsing from
[checkpoint], reading tokens from [supplier]. It continues parsing until
it reaches a checkpoint of the form [Accepted v] or [HandlingError env]
(or [Rejected], but that should not happen, as [HandlingError _] will be
observed first). In the former case, it calls [succeed v]. In the latter
case, it calls [fail] with this checkpoint. It cannot raise [Error].
This means that Menhir's traditional error-handling procedure (which pops
the stack until a state that can act on the [error] token is found) does
not get a chance to run. Instead, the user can implement her own error
handling code, in the [fail] continuation. *)
val loop_handle:
('a -> 'answer) ->
('a checkpoint -> 'answer) ->
supplier -> 'a checkpoint -> 'answer
(* The abstract type ['a lr1state] describes the non-initial states of the
LR(1) automaton. The index ['a] represents the type of the semantic value
......
......@@ -61,7 +61,11 @@ stage1:
# Do not use . to refer to the current directory, because ocamlbuild
# descends into another directory when executing commands.
SRC := $(shell pwd)
# Do not use $(shell pwd) either, because this assumes we are running
# on a Unix platform, and can fail on Windows.
# So, use .., which works fine if ocamlbuild has effectively descended
# into a subdirectory.
SRC := ..
FLAGS := -v -lg 1 -la 1 -lc 1 --table --infer --stdlib $(SRC) --strict --fixed-exception --canonical
......
This diff is collapsed.
......@@ -312,24 +312,24 @@ end
module type INCREMENTAL_ENGINE_START = sig
(* [start] is an entry point. It requires just a start state, and begins
the parsing process. It produces a result, which usually will be an
[InputNeeded] result. (It could be [Accepted] if this starting state
(* [start] is an entry point. It requires just a start state, and begins the
parsing process. It produces a checkpoint, which usually will be an
[InputNeeded] checkpoint. (It could be [Accepted] if this starting state
accepts only the empty word. It could be [Rejected] if this starting
state accepts no word at all.) It does not raise any exception. *)
(* [start s] should really produce a result of type ['a result], for a
fixed ['a] that depends on the state [s]. We cannot express this, so
we use [semantic_value result], which is safe. The table back-end
uses [Obj.magic] to produce safe specialized versions of [start]. *)
(* [start s] should really produce a checkpoint of type ['a checkpoint], for
a fixed ['a] that depends on the state [s]. We cannot express this, so we
use [semantic_value checkpoint], which is safe. The table back-end uses
[Obj.magic] to produce safe specialized versions of [start]. *)
type state
type semantic_value
type 'a result
type 'a checkpoint
val start:
state ->
semantic_value result
semantic_value checkpoint
end
......@@ -349,7 +349,7 @@ module type ENGINE = sig
include INCREMENTAL_ENGINE_START
with type state := state
and type semantic_value := semantic_value
and type 'a result := 'a result
and type 'a checkpoint := 'a checkpoint
end
......@@ -11,24 +11,24 @@ open MenhirLib.General (* streams: Nil, Cons *)
open Parser.MenhirInterpreter (* incremental API to our parser *)
(* The loop which drives the parser. At each iteration, we analyze a
result produced by the parser, and act in an appropriate manner.
checkpoint produced by the parser, and act in an appropriate manner.
We have to do this in order to get ahold of the current state when
a syntax error is encountered. *)
let rec loop lexer lexbuf (result : 'a result) : 'a =
let rec loop lexer lexbuf (checkpoint : 'a checkpoint) : 'a =
let open Lexing in
match result with
match checkpoint with
| InputNeeded _ ->
(* The parser needs a token. Request one from the lexer,
and offer it to the parser, which will produce a new
result. Then, repeat. *)
checkpoint. Then, repeat. *)
let token = lexer lexbuf in
let result = offer result (token, lexbuf.lex_start_p, lexbuf.lex_curr_p) in
loop lexer lexbuf result
let checkpoint = offer checkpoint (token, lexbuf.lex_start_p, lexbuf.lex_curr_p) in
loop lexer lexbuf checkpoint
| Shifting _
| AboutToReduce _ ->
let result = resume result in
loop lexer lexbuf result
let checkpoint = resume checkpoint in
loop lexer lexbuf checkpoint
| HandlingError env ->
(* The parser has suspended itself because of a syntax error. Stop.
Find out which state the parser is currently in. *)
......
......@@ -31,8 +31,8 @@ let entrytypescheme grammar symbol =
let interpreter =
"MenhirInterpreter"
let result t =
TypApp (interpreter ^ ".result", [ t ])
let checkpoint t =
TypApp (interpreter ^ ".checkpoint", [ t ])
let lr1state =
"lr1state"
......@@ -51,7 +51,7 @@ let incremental =
let entrytypescheme_incremental grammar symbol =
let t = TypTextual (ocamltype_of_start_symbol grammar symbol) in
type2scheme (marrow [ tunit ] (result t))
type2scheme (marrow [ tunit ] (checkpoint t))
(* -------------------------------------------------------------------------- *)
......@@ -148,7 +148,7 @@ let incremental_api grammar () : interface =
) ::
(* The entry points must come after the incremental API, because
their type refers to the type [result]. *)
their type refers to the type [checkpoint]. *)
incremental_entry_points grammar
(* -------------------------------------------------------------------------- *)
......
......@@ -14,9 +14,9 @@ val entrytypescheme: UnparameterizedSyntax.grammar -> string -> IL.typescheme
val interpreter: string
(* The type ['a result], defined in the interpreter sub-module. *)
(* The type ['a checkpoint], defined in the interpreter sub-module. *)
val result: IL.typ -> IL.typ
val checkpoint: IL.typ -> IL.typ
(* The name of the sub-module that contains the incremental entry points. *)
......
......@@ -310,18 +310,18 @@ let check_error_path nt input =
spurious reductions. We accumulate these reductions in [spurious], a
(reversed) list of productions. *)
let rec loop (result : cst E.result) (spurious : spurious_reduction list) =
match result with
let rec loop (checkpoint : cst E.checkpoint) (spurious : spurious_reduction list) =
match checkpoint with
| E.InputNeeded _ ->
begin match next() with
| None ->
OInputReadPastEnd
| Some t ->
let dummy = Lexing.dummy_pos in
loop (E.offer result (t, dummy, dummy)) spurious
loop (E.offer checkpoint (t, dummy, dummy)) spurious
end
| E.Shifting _ ->
loop (E.resume result) spurious
loop (E.resume checkpoint) spurious
| E.AboutToReduce (env, prod) ->
(* If we have requested the last input token and if this is not
a default reduction, then this is a spurious reduction.
......@@ -335,7 +335,7 @@ let check_error_path nt input =
else
spurious
in
loop (E.resume result) spurious
loop (E.resume checkpoint) spurious
| E.HandlingError env ->
(* Check that all of the input has been read. Otherwise, the error
has occurred sooner than expected. *)
......
......@@ -730,7 +730,7 @@ let incremental_entry_point state nt t =
]
)
),
type2scheme (result (TypTextual t))
type2scheme (checkpoint (TypTextual t))
)
)
)
......
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