Commit 88ae18b6 authored by POTTIER Francois's avatar POTTIER Francois

Moved [DependencyGraph] out of [Grammar].

parent e49e84e8
* Look for "artificial dependency" and remove them.
Make sure every module is explicitly called.
* Compute NULLABLE and FIRST prior to inlining, and use it to optimize
$symbolstartpos.
......
open Grammar
let print_dependency_graph() =
(* Allocate. *)
let forward : NonterminalSet.t NonterminalMap.t ref =
ref NonterminalMap.empty
in
let successors nt =
try
NonterminalMap.find nt !forward
with Not_found ->
NonterminalSet.empty
in
(* Populate. *)
Production.iter (fun prod ->
let nt1 = Production.nt prod
and rhs = Production.rhs prod in
Array.iter (function
| Symbol.T _ ->
()
| Symbol.N nt2 ->
forward := NonterminalMap.add
nt1
(NonterminalSet.add nt2 (successors nt1))
!forward
) rhs
);
(* Print. *)
let module P = Dot.Print (struct
type vertex = Nonterminal.t
let name nt =
Printf.sprintf "nt%d" (Nonterminal.n2i nt)
let successors (f : ?style:Dot.style -> label:string -> vertex -> unit) nt =
NonterminalSet.iter (fun successor ->
f ~label:"" successor
) (successors nt)
let iter (f : ?shape:Dot.shape -> ?style:Dot.style -> label:string -> vertex -> unit) =
Nonterminal.iter (fun nt ->
f ~label:(Nonterminal.print false nt) nt
)
end) in
let f = open_out (Settings.base ^ ".dot") in
P.print f;
close_out f
(* Build and print the forward reference graph of the grammar. There is an edge
of a nonterminal symbol [nt1] to every nonterminal symbol [nt2] that occurs
in the definition of [nt1]. *)
val print_dependency_graph: unit -> unit
open Grammar
let () =
if Settings.graph then
DependencyGraph.print_dependency_graph()
(* artificial dependency *)
(* -------------------------------------------------------------------------- *)
(* Our output channel. *)
......
......@@ -140,7 +140,7 @@ module Nonterminal = struct
end
(* Sets and maps over nonterminals, used only below. *)
(* Sets and maps over nonterminals. *)
module NonterminalMap = Patricia.Big
......@@ -807,52 +807,6 @@ module ProductionMap = struct
end
(* ------------------------------------------------------------------------ *)
(* If requested, build and print the forward reference graph of the grammar.
There is an edge of a nonterminal symbol [nt1] to every nonterminal symbol
[nt2] that occurs in the definition of [nt1]. *)
let () =
if Settings.graph then begin
(* Allocate. *)
let forward : NonterminalSet.t array =
Array.make Nonterminal.n NonterminalSet.empty
in
(* Populate. *)
Array.iter (fun (nt1, rhs) ->
Array.iter (function
| Symbol.T _ ->
()
| Symbol.N nt2 ->
forward.(nt1) <- NonterminalSet.add nt2 forward.(nt1)
) rhs
) Production.table;
(* Print. *)
let module P = Dot.Print (struct
type vertex = Nonterminal.t
let name nt =
Printf.sprintf "nt%d" nt
let successors (f : ?style:Dot.style -> label:string -> vertex -> unit) nt =
NonterminalSet.iter (fun successor ->
f ~label:"" successor
) forward.(nt)
let iter (f : ?shape:Dot.shape -> ?style:Dot.style -> label:string -> vertex -> unit) =
Nonterminal.iter (fun nt ->
f ~label:(Nonterminal.print false nt) nt
)
end) in
let f = open_out (Settings.base ^ ".dot") in
P.print f;
close_out f
end
(* ------------------------------------------------------------------------ *)
(* Support for analyses of the grammar, expressed as fixed point computations.
We exploit the generic fixed point algorithm in [Fix]. *)
......
......@@ -85,6 +85,13 @@ module Nonterminal : sig
end
(* ------------------------------------------------------------------------ *)
(* Sets of nonterminals. *)
module NonterminalMap : GMap.S with type key = Nonterminal.t
module NonterminalSet = NonterminalMap.Domain
(* ------------------------------------------------------------------------ *)
(* Terminals. *)
......
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