Commit 6bb62a8d authored by POTTIER Francois's avatar POTTIER Francois

Isolated the signature [SYMBOLS] (in [IncrementalEngine])

and the functor [Symbols] (in [InspectionTableInterpreter]).
This removes the need for generating the types [symbol] and [xsymbol].
The module [SymbolType] in the table back-end disappears.
parent a04e6224
......@@ -90,11 +90,45 @@ module type INCREMENTAL_ENGINE = sig
end
(* This signature is a fragment of the inspection API that is made available
to the user when [--inspection] is used. This fragment contains type
definitions for symbols. *)
module type SYMBOLS = sig
(* The type ['a terminal] represents a terminal symbol. The type ['a
nonterminal] represents a nonterminal symbol. In both cases, the index
['a] represents the type of the semantic values associated with this
symbol. The concrete definitions of these types are generated. *)
type 'a terminal
type 'a nonterminal
(* The type ['a symbol] represents a terminal or nonterminal symbol. It is
the disjoint union of the types ['a terminal] and ['a nonterminal]. *)
type 'a symbol =
| T : 'a terminal -> 'a symbol
| N : 'a nonterminal -> 'a symbol
(* The type [xsymbol] is an existentially quantified version of the type
['a symbol]. This type is useful in situations where the index ['a]
is not statically known. *)
type xsymbol =
| X : 'a symbol -> xsymbol
end
(* This signature describes the inspection API that is made available to the
user when [--inspection] is used. *)
module type INSPECTION = sig
(* The types of symbols are described above. *)
include SYMBOLS
(* The type ['a lr1state] is meant to be the same as in [INCREMENTAL_ENGINE]. *)
type 'a lr1state
......@@ -112,23 +146,6 @@ module type INSPECTION = sig
type item =
production * int
(* The type ['a symbol] represents a (terminal or nonterminal) symbol of the
grammar. It is generated. The index ['a] represents the type of the
semantic values associated with this symbol. *)
type 'a terminal
type 'a nonterminal
type 'a symbol =
| T : 'a terminal -> 'a symbol
| N : 'a nonterminal -> 'a symbol
(* The type [xsymbol] is an existentially quantified version of the type
['a symbol]. *)
type xsymbol =
| X : 'a symbol -> xsymbol
(* [incoming_symbol s] is the incoming symbol of the state [s], that is,
the symbol that the parser must recognize before (has recognized when)
it enters the state [s]. This function gives access to the semantic
......
......@@ -5,22 +5,14 @@
module type TABLES = sig
(* The type ['a lr1state] describes an LR(1) state and will be defined
internally as [int]. The types ['a symbol] and [xsymbol] are (generated)
algebraic data types. These types must appear here because they serve to
describe the argument and/or result of [InspectionTableInterpreter.Make]. *)
(* The types of symbols. *)
type 'a lr1state
type 'a terminal
type 'a nonterminal
include IncrementalEngine.SYMBOLS
type 'a symbol =
| T : 'a terminal -> 'a symbol
| N : 'a nonterminal -> 'a symbol
(* The type ['a lr1state] describes an LR(1) state. The generated parser defines
it internally as [int]. *)
type xsymbol =
| X : 'a symbol -> xsymbol
type 'a lr1state
(* Some of the tables that follow use encodings of (terminal and
nonterminal) symbols as integers. So, we need functions that
......
(* -------------------------------------------------------------------------- *)
(* The type functor. *)
module Symbols (T : sig
type 'a terminal
type 'a nonterminal
end) = struct
open T
type 'a symbol =
| T : 'a terminal -> 'a symbol
| N : 'a nonterminal -> 'a symbol
type xsymbol =
| X : 'a symbol -> xsymbol
end
(* -------------------------------------------------------------------------- *)
(* The code functor. *)
module Make (
T : InspectionTableFormat.TABLES
with type 'a lr1state = int
......
(* This functor is invoked inside the generated parser, in [--table] mode. It
produces no code! It simply constructs the types [symbol] and [xsymbol] on
top of the generated types [terminal] and [nonterminal]. *)
module Symbols (T : sig
type 'a terminal
type 'a nonterminal
end)
: IncrementalEngine.SYMBOLS
with type 'a terminal := 'a T.terminal
and type 'a nonterminal := 'a T.nonterminal
(* This functor is invoked inside the generated parser, in [--table] mode. It
constructs the inspection API on top of the inspection tables described in
[InspectionTableFormat]. *)
......@@ -6,8 +21,8 @@ module Make (T : InspectionTableFormat.TABLES
with type 'a lr1state = int)
: IncrementalEngine.INSPECTION
with type 'a lr1state := 'a T.lr1state
and type 'a terminal := 'a T.terminal
with type 'a terminal := 'a T.terminal
and type 'a nonterminal := 'a T.nonterminal
and type 'a lr1state := 'a T.lr1state
and type production := int
open IL
(* -------------------------------------------------------------------------- *)
(* The symbol GADT is the union of the terminal and nonterminal GADTs. *)
(* The conventional name of the symbol GADT. *)
let tcsymbolgadt =
"symbol"
let tsymbolgadt a =
TypApp (tcsymbolgadt, [ a ])
(* The conventional names of the data constructors. *)
let dataT =
"T"
let dataN =
"N"
(* The definition of the symbol GADT. *)
let symbolgadtdef () =
assert Settings.inspection;
let a = "a" in
let datadefs =
{
dataname = dataT;
datavalparams = [ TokenType.ttokengadt (TypVar a) ];
datatypeparams = Some [ TypVar a ]
} ::
{
dataname = dataN;
datavalparams = [ NonterminalType.tnonterminalgadt (TypVar a) ];
datatypeparams = Some [ TypVar a ]
} ::
[]
in
[ IIComment "The indexed type of terminal and nonterminal symbols.";
IITypeDecls [{
typename = tcsymbolgadt;
typeparams = [ a ];
typerhs = TDefSum datadefs;
typeconstraint = None
}]
]
(* -------------------------------------------------------------------------- *)
(* We also need an existentially quantified version of the type ['a symbol].
This type is not parameterized. *)
let tcxsymbol =
"xsymbol"
let txsymbol =
TypApp (tcxsymbol, [])
let dataX =
"X"
let xsymboldef () =
assert Settings.inspection;
let a = "a" in
let datadefs =
{
dataname = dataX;
datavalparams = [ tsymbolgadt (TypVar a) ];
datatypeparams = Some []
} ::
[]
in
[ IIComment "The (non-indexed) type of terminal and nonterminal symbols.";
IITypeDecls [{
typename = tcxsymbol;
typeparams = [];
typerhs = TDefSum datadefs;
typeconstraint = None
}]
]
(* The symbol GADT is the union of the terminal and nonterminal GADTs. *)
val tcsymbolgadt: string
val tsymbolgadt: IL.typ -> IL.typ
(* The conventional names of the data constructors. *)
val dataT: string
val dataN: string
(* The definition of the symbol GADT. This definition can be produced only if
we are successfully able to construct the nonterminal GADT first. *)
val symbolgadtdef: unit -> IL.interface
(* The type [xsymbol] is an existentially quantified version of the symbol
GADT above. Thus, it is not parameterized. *)
val dataX: string
val tcxsymbol: string
val txsymbol: IL.typ
val xsymboldef: unit -> IL.interface
......@@ -5,7 +5,6 @@ open Interface
open Printf
open TokenType
open NonterminalType
open SymbolType
open CodePieces
module Run (T : sig end) = struct
......@@ -23,6 +22,9 @@ let tableInterpreter =
let make =
tableInterpreter ^ ".Make"
let make_symbol =
menhirlib ^ ".InspectionTableInterpreter.Symbols"
let make_inspection =
menhirlib ^ ".InspectionTableInterpreter.Make"
......@@ -764,6 +766,12 @@ let enonterminal (nt : Nonterminal.t) : expr =
that encodes the symbol [symbol]. It is built by applying the
injection [T] or [N] to the terminal or nonterminal encoding. *)
let dataT =
"T"
let dataN =
"N"
let esymbol (symbol : Symbol.t) : expr =
match symbol with
| Symbol.T t ->
......@@ -775,6 +783,9 @@ let esymbol (symbol : Symbol.t) : expr =
symbol [symbol]. It is built by applying the injection [X] (an
existential quantifier) to [esymbol symbol]. *)
let dataX =
"X"
let xsymbol (symbol : Symbol.t) : expr =
EData (dataX, [ esymbol symbol ])
......@@ -789,22 +800,19 @@ let terminal () =
let t = "t" in
define (
"terminal",
EAnnot (
EFun ([ PVar t ],
EMatch (EVar t,
Terminal.mapx (fun tok ->
{ branchpat = pint (Terminal.t2i tok);
branchbody = xsymbol (Symbol.T tok) }
) @ [
{ branchpat = PWildcard;
branchbody =
EComment ("This terminal symbol does not exist.",
EApp (EVar "assert", [ efalse ])
) }
]
)
),
type2scheme (arrow tint txsymbol)
EFun ([ PVar t ],
EMatch (EVar t,
Terminal.mapx (fun tok ->
{ branchpat = pint (Terminal.t2i tok);
branchbody = xsymbol (Symbol.T tok) }
) @ [
{ branchpat = PWildcard;
branchbody =
EComment ("This terminal symbol does not exist.",
EApp (EVar "assert", [ efalse ])
) }
]
)
)
)
......@@ -818,22 +826,19 @@ let nonterminal () =
let nt = "nt" in
define (
"nonterminal",
EAnnot (
EFun ([ PVar nt ],
EMatch (EVar nt,
Nonterminal.foldx (fun nt branches ->
{ branchpat = pint (Nonterminal.n2i nt);
branchbody = xsymbol (Symbol.N nt) } :: branches
) [
{ branchpat = PWildcard;
branchbody =
EComment ("This nonterminal symbol does not exist.",
EApp (EVar "assert", [ efalse ])
) }
]
)
),
type2scheme (arrow tint txsymbol)
EFun ([ PVar nt ],
EMatch (EVar nt,
Nonterminal.foldx (fun nt branches ->
{ branchpat = pint (Nonterminal.n2i nt);
branchbody = xsymbol (Symbol.N nt) } :: branches
) [
{ branchpat = PWildcard;
branchbody =
EComment ("This nonterminal symbol does not exist.",
EApp (EVar "assert", [ efalse ])
) }
]
)
)
)
......@@ -996,11 +1001,10 @@ let program =
] @
(* [terminal], [nonterminal]. *)
SIInclude (MVar more) ::
(* [symbol], [xsymbol]. *)
interface_to_structure (
symbolgadtdef() @
xsymboldef()
) @
(* This functor application builds the types [symbol] and [xsymbol]
in terms of the types [terminal] and [nonterminal]. This saves
us the trouble of generating these definitions. *)
SIInclude (MApp (MVar make_symbol, MVar more)) ::
(* [lhs] *)
SIInclude (MVar tables) ::
SIValDefs (false,
......
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