Commit ed8b8965 by POTTIER Francois

Extended [IncrementalEngine] with definitions of the types

[lr1state], [element], [stream] and of the function [view].
parent 084c4cd7
......@@ -6,6 +6,8 @@
points. Move also the types terminal, nonterminal, symbol
to a sub-module, to avoid any name clashes.
* IncrementalEngine: document [lr1state], [element], [view].
* document that --depend may produce inaccurate dependencies
for parser.cmi and that it is recommended to use --raw-depend
--ocamldep "ocamldep -modules" and work from there (which is
......
......@@ -60,4 +60,32 @@ module type INCREMENTAL_ENGINE = sig
('a, handling_error) env ->
'a result
(* 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
associated with this state's incoming symbol. *)
type 'a lr1state
(* An element is a pair of a non-initial state [s] and a semantic value [v]
associated with the incoming symbol of this state. The idea is, the value
[v] was pushed onto the stack just before the state [s] was entered. Thus,
for some type ['a], the type [s] has type ['a lr1state] and the value [v]
has type ['a]. In other words, the type [element] is an existential type. *)
type element =
| Element: 'a lr1state * 'a * Lexing.position * Lexing.position -> element
(* A stream is a list whose elements are produced on demand. *)
type 'a stream =
'a head Lazy.t
and 'a head =
| Nil
| Cons of 'a * 'a stream
(* We offer a read-only view of the parser's state as a stream of elements. *)
val view: (_, _) env -> element stream
end
......@@ -456,14 +456,41 @@ module Make (T : TABLE) = struct
(* --------------------------------------------------------------------------- *)
(* The type ['a lr1state] describes the (non-initial) states of the LR(1)
automaton. The index ['a] represents the type of the semantic value
associated with the state's incoming symbol. *)
(* The type ['a lr1state] is defined as an alias for [state], which itself
is usually defined as [int] (see [TableInterpreter]). So, ['a lr1state]
is technically a phantom type, but should really be thought of as a GADT
whose data constructors happen to be represented as integers. It is
presented to the user as an abstract type (see [IncrementalEngine]). *)
type 'a lr1state =
state
(* --------------------------------------------------------------------------- *)
(* Stack inspection. *)
(* This code offers a (read-only) view of the stack as a stream of elements.
Each element contains a pair of a (non-initial) state and a semantic value
associated with (the incoming symbol of) this state. *)
(* We offer a read-only view of the parser's state as a stream of elements.
Each element contains a pair of a (non-initial) state and a semantic
value associated with (the incoming symbol of) this state. Note that the
type [element] is an existential type. *)
type 'a stream =
'a head Lazy.t
and 'a head =
| Nil
| Cons of 'a * 'a stream
type element =
state * semantic_value * Lexing.position * Lexing.position
| Element: 'a lr1state * 'a * Lexing.position * Lexing.position -> element
(* If [current] is the current state and [cell] is the top stack cell,
then [view cell current] is a view of the parser's state as a stream
of elements. *)
let rec view cell current : element stream =
lazy (
......@@ -478,10 +505,12 @@ module Make (T : TABLE) = struct
(* Construct an element containing the current state [current] as well
as the semantic value contained in the top stack cell. This semantic
value is associated with the incoming symbol of this state, so it
makes sense to pair them together. In the typed API, this state will
have type ['a state] and the semantic value will have type ['a], for
some type ['a]. *)
let element = (
makes sense to pair them together. The state has type ['a state] and
the semantic value has type ['a], for some type ['a]. Here, the OCaml
type-checker thinks ['a] is [semantic_value] and considers this code
well-typed. Outside, we will use magic to provide the user with a way
of inspecting states and recovering the value of ['a]. *)
let element = Element (
current,
cell.semv,
cell.startp,
......
......@@ -3,17 +3,6 @@
(* --------------------------------------------------------------------------- *)
(* A vanilla type of streams (lazy lists). *)
type 'a stream =
'a head Lazy.t
and 'a head =
| Nil
| Cons of 'a * 'a stream
(* --------------------------------------------------------------------------- *)
(* It would be nice if we could keep the structure of stacks and environments
hidden. However, stacks and environments must be accessible to semantic
actions, so the following data structure definitions must be public. *)
......@@ -366,12 +355,5 @@ module type ENGINE = sig
and type semantic_value := semantic_value
and type 'a result := 'a result
(* TEMPORARY move/comment *)
type element =
state * semantic_value * Lexing.position * Lexing.position
val view: ('a, 'pc) env -> element stream
end
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