Source file cmly_api.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
(******************************************************************************)
(*                                                                            *)
(*                                    Menhir                                  *)
(*                                                                            *)
(*   Copyright Inria. All rights reserved. This file is distributed under     *)
(*   the terms of the GNU General Public License version 2, as described in   *)
(*   the file LICENSE.                                                        *)
(*                                                                            *)
(******************************************************************************)

(* The following signatures describe the API offered by the functor
   [Cfmly_read.Read]. This functor reads in a .cmly file and gives
   access to the description of the grammar and automaton contained
   in this file. *)

(* This API is currently entirely self-contained, except for a reference
   to the module [Keyword], which is also part of [MenhirSdk]. *)

(**The module type [INDEXED] describes a type [t] whose elements are
   in a bijection with an integer interval of the form [\[0..count)]. *)
module type INDEXED = sig
  type t
  val count : int
  val of_int : int -> t
  val to_int : t -> int
  (* Hashing, equality and ordering. *)
  val hash : t -> int
  val equal : t -> t -> bool
  val compare : t -> t -> int
  (* Iteration and tabulation. *)
  val iter : (t -> unit) -> unit
  val fold : (t -> 'a -> 'a) -> 'a -> 'a
  val tabulate : (t -> 'a) -> t -> 'a
end

(**The module type [GRAMMAR] describes the grammar and automaton. *)
module type GRAMMAR = sig

  type terminal    = private int
  type nonterminal = private int
  type production  = private int
  type lr0         = private int
  type lr1         = private int
  type item        = production * int
  type ocamltype   = string
  type ocamlexpr   = string

  module Range : sig
    type t
    val startp: t -> Lexing.position
    val endp: t -> Lexing.position
  end

  module Attribute : sig
    type t
    val label        : t -> string
    val has_label    : string -> t -> bool
    val payload      : t -> string
    val position     : t -> Range.t
  end

  module Grammar : sig
    val basename     : string
    val preludes     : string list
    val postludes    : string list
    val parameters   : string list
    val entry_points : (nonterminal * production * lr1) list
    val attributes   : Attribute.t list
  end

  module Terminal : sig
    include INDEXED with type t = terminal
    val name         : t -> string
    val kind         : t -> [`REGULAR | `ERROR | `EOF | `PSEUDO]
    val typ          : t -> ocamltype option
    val attributes   : t -> Attribute.t list
  end

  module Nonterminal : sig
    include INDEXED with type t = nonterminal
    val name         : t -> string
    val mangled_name : t -> string
    val kind         : t -> [`REGULAR | `START]
    val typ          : t -> ocamltype option
    val positions    : t -> Range.t list
    val nullable     : t -> bool
    val first        : t -> terminal list
    val attributes   : t -> Attribute.t list
  end

  module Symbol : sig

    type t =
      | T of terminal
      | N of nonterminal

    val name : ?mangled:bool -> t -> string

    (* Hashing, equality and ordering. *)
    val hash : t -> int
    val equal : t -> t -> bool
    val compare : t -> t -> int

  end

  (**The type [symbol] is a synonym for [Symbol.t]. *)
  type symbol = Symbol.t =
    | T of terminal
    | N of nonterminal

  (**[symbol_name] is a synonym for [Symbol.name]. *)
  val symbol_name : ?mangled:bool -> symbol -> string

  type identifier = string

  module Action : sig
    type t
    val expr         : t -> ocamlexpr
    val keywords     : t -> Keyword.keyword list
  end

  module Production : sig
    include INDEXED with type t = production
    val kind         : t -> [`REGULAR | `START]
    val lhs          : t -> nonterminal
    val rhs          : t -> (symbol * identifier * Attribute.t list) array
    val positions    : t -> Range.t list
    val action       : t -> Action.t option
    val attributes   : t -> Attribute.t list
        (* Before 2023/08/02, these were the attributes of the left-hand
           side of the production. Now, these are the attributes of the
           production itself. *)
  end

  module Lr0 : sig
    include INDEXED with type t = lr0
    val incoming     : t -> symbol option
    val items        : t -> item list
  end

  module Lr1 : sig
    include INDEXED with type t = lr1
    val lr0          : t -> lr0
    val transitions  : t -> (symbol * t) list
    val get_reductions : t -> (terminal * production) list
    val default_reduction : t -> production option

    val reductions   : t -> (terminal * production list) list
    [@@ocaml.deprecated "Please use [get_reductions]"]
  end

  module Print : sig
    open Format
    val terminal            : formatter -> terminal -> unit
    val nonterminal         : formatter -> nonterminal -> unit
    val symbol              : formatter -> symbol -> unit
    val mangled_nonterminal : formatter -> nonterminal -> unit
    val mangled_symbol      : formatter -> symbol -> unit
    val production          : formatter -> production -> unit
    val item                : formatter -> item -> unit
    val itemset             : formatter -> item list -> unit
    val annot_item          : string      list -> formatter -> item      -> unit
    val annot_itemset       : string list list -> formatter -> item list -> unit
  end

end