package lrgrep

  1. Overview
  2. Docs
Analyse the stack of a Menhir-generated LR parser using regular expressions

Install

dune-project
 Dependency

Authors

Maintainers

Sources

lrgrep-0.3.tbz
sha256=84a1874d0c063da371e19c84243aac7c40bfcb9aaf204251e0eb0d1f077f2cde
sha512=5a16ff42a196fd741bc64a1bdd45b4dca0098633e73aa665829a44625ec15382891c3643fa210dbe3704336eab095d4024e093e37ae5313810f6754de6119d55

doc/src/valmari/valmari.ml.html

Source file valmari.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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
open Fix.Indexing

module type DFA = sig
  type states
  val states : states cardinal
  type transitions
  val transitions : transitions cardinal

  type label
  val label  : transitions index -> label
  val source : transitions index -> states index
  val target : transitions index -> states index

end

module type INPUT = sig
  include DFA

  val initials : (states index -> unit) -> unit
  val finals : (states index -> unit) -> unit
  val refinements : ((add:(states index -> unit) -> unit) -> unit) -> unit
end

let index_transitions (type state) (type transition)
    (states : state cardinal)
    (transitions : transition cardinal)
    (target : transition index -> state index)
  : state index -> (transition index -> unit) -> unit
  =
  if cardinal transitions = 0 then
    (fun _ _ -> ())
  else
    let f = Array.make (cardinal states + 1) 0 in
    Index.iter transitions (fun t ->
        let state = (target t :> int) in
        f.(state) <- f.(state) + 1
      );
    for i = 0 to cardinal states - 1 do
      f.(i + 1) <- f.(i + 1) + f.(i)
    done;
    let a = Array.make (cardinal transitions) (Index.of_int transitions 0) in
    Index.rev_iter transitions (fun t ->
        let state = (target t :> int) in
        let index = f.(state) - 1 in
        f.(state) <- index;
        a.(index) <- t
      );
    (fun st fn ->
       let st = (st : state index :> int) in
       for i = f.(st) to f.(st + 1) - 1 do fn a.(i) done
    )

let discard_unreachable
    (type state) (type transition)
    (blocks : state Partition.t)
    (transitions_of : state index -> (transition index -> unit) -> unit)
    (target : transition index -> state index)
  =
  Partition.iter_marked_elements blocks 0 (fun state ->
      transitions_of state
        (fun transition -> Partition.mark blocks (target transition))
    );
  Partition.discard_unmarked blocks

module Do_minimize (In: INPUT) (P : sig
    val blocks : In.states Partition.t
    val cords : In.transitions Partition.t
    val transitions_targeting : In.states index -> (In.transitions index -> unit) -> unit
  end):
sig
  include DFA with type label = In.label

  val initials : states index array
  val finals : states index array

  val transport_state :
    In.states index -> states index option
  val transport_transition :
    In.transitions index -> transitions index option

  val represent_state :
    states index -> In.states index
  val represent_transition :
    transitions index -> In.transitions index
end = struct
  open P

  let () =
    Partition.discard cords (fun t ->
        Partition.set_of blocks (In.source t) = -1 ||
        Partition.set_of blocks (In.target t) = -1
      )

  (* Main loop, split the sets *)
  let () =
    let block_set = ref 1 in
    let cord_set = ref 0 in
    while !cord_set < Partition.set_count cords do
      Partition.iter_elements cords !cord_set
        (fun transition -> Partition.mark blocks (In.source transition));
      Partition.split blocks;
      while !block_set < Partition.set_count blocks do
        Partition.iter_elements blocks !block_set (fun state ->
            transitions_targeting state (Partition.mark cords)
          );
        Partition.split cords;
        incr block_set;
      done;
      incr cord_set;
    done

  module States = Const(struct let cardinal = Partition.set_count blocks end)
  type states = States.n
  let states = States.n

  module Transitions = Vector.Of_array(struct
      type a = In.transitions index
      let array =
        let count = ref 0 in
        Index.iter In.transitions (fun tr ->
            if Partition.is_first blocks (In.source tr) &&
               Partition.set_of blocks (In.target tr) > -1
            then incr count
          );
        match !count with
        | 0 -> [||]
        | n -> Array.make n (Index.of_int In.transitions 0)

      let () =
        let count = ref 0 in
        Index.iter In.transitions (fun tr ->
            if Partition.is_first blocks (In.source tr) &&
               Partition.set_of blocks (In.target tr) > -1
            then (
              let index = !count in
              incr count;
              array.(index) <- tr
            )
          );
    end)
  type transitions = Transitions.n
  let transitions = Vector.length Transitions.vector

  type label = In.label

  let transport_state_unsafe =
    let table =
      Vector.init In.states (Partition.set_of blocks)
    in
    Vector.get table

  let represent_state =
    let table =
      Vector.init states
        (fun st -> Partition.choose blocks (st : states index :> int))
    in
    Vector.get table

  let represent_transition transition =
    (Vector.get Transitions.vector transition)

  let label transition : label =
    In.label (represent_transition transition)

  let source transition =
    Index.of_int states
      (transport_state_unsafe (In.source (represent_transition transition)))

  let target transition =
    Index.of_int states
      (transport_state_unsafe (In.target (represent_transition transition)))

  let initials =
    In.initials (Partition.mark blocks);
    let sets = Partition.marked_sets blocks in
    Partition.clear_marks blocks;
    Array.map (Index.of_int states) (Array.of_list sets)

  let finals =
    In.finals (Partition.mark blocks);
    let sets = Partition.marked_sets blocks in
    Partition.clear_marks blocks;
    Array.map (Index.of_int states) (Array.of_list sets)

  let transport_state state =
    match transport_state_unsafe state with
    | -1 -> None
    | n -> Some (Index.of_int states n)

  let transport_transition =
    let table = Vector.make In.transitions None in
    Vector.iteri (fun tr trin ->
        assert (Vector.get table trin = None);
        Vector.set table trin (Some tr);
      ) Transitions.vector;
    Vector.get table
end

module Minimize
    (Label : Map.OrderedType)
    (In: INPUT with type label := Label.t) :
sig
  include DFA with type label = Label.t

  val initials : states index array
  val finals : states index array

  val transport_state :
    In.states index -> states index option
  val transport_transition :
    In.transitions index -> transitions index option

  val represent_state :
    states index -> In.states index
  val represent_transition :
    transitions index -> In.transitions index
end = Do_minimize
    (struct include In type label = Label.t end)
    (struct
      (* State partition *)
      let blocks = Partition.create In.states

      (* Remove states unreachable from initial state *)
      let () =
        In.initials (Partition.mark blocks);
        let transitions_source =
          index_transitions In.states In.transitions In.source in
        discard_unreachable blocks transitions_source In.target

      (* Index the set of transitions targeting a state *)
      let transitions_targeting =
        index_transitions In.states In.transitions In.target

      (* Remove states which cannot reach any final state *)
      let () =
        In.finals (Partition.mark blocks);
        discard_unreachable blocks transitions_targeting In.source

      (* Split final states *)
      let () =
        In.finals (Partition.mark blocks);
        Partition.split blocks

      (* Split explicitely refined states *)
      let () =
        let refine f =
          f ~add:(Partition.mark blocks);
          Partition.split blocks
        in
        In.refinements refine

      (* Transition partition *)
      let cords =
        let partition t1 t2 = Label.compare (In.label t1) (In.label t2) in
        Partition.create In.transitions ~partition
    end
    )

module Minimize_with_custom_decomposition
    (In: sig
       include INPUT
       val decomposition : ((add:(transitions index -> unit) -> unit) -> unit) -> unit
     end) :
sig
  include DFA with type label = In.label

  val initials : states index array
  val finals : states index array

  val transport_state :
    In.states index -> states index option
  val transport_transition :
    In.transitions index -> transitions index option

  val represent_state :
    states index -> In.states index
  val represent_transition :
    transitions index -> In.transitions index
end = Do_minimize
    (In)
    (struct
      (* State partition *)
      let blocks = Partition.create In.states

      (* Remove states unreachable from initial state *)
      let () =
        In.initials (Partition.mark blocks);
        let transitions_source =
          index_transitions In.states In.transitions In.source in
        discard_unreachable blocks transitions_source In.target

      (* Index the set of transitions targeting a state *)
      let transitions_targeting =
        index_transitions In.states In.transitions In.target

      (* Remove states which cannot reach any final state *)
      let () =
        In.finals (Partition.mark blocks);
        discard_unreachable blocks transitions_targeting In.source

      (* Split final states *)
      let () =
        In.finals (Partition.mark blocks);
        Partition.split blocks

      (* Split explicitely refined states *)
      let () =
        let refine f =
          f ~add:(Partition.mark blocks);
          Partition.split blocks
        in
        In.refinements refine

      (* Transition partition *)
      let cords = Partition.create In.transitions

      let () =
        let refine f =
          f ~add:(Partition.mark cords);
          Partition.split cords
        in
        In.decomposition refine
    end
    )