liquid-fixpoint-0.1.0.0: external/ocamlgraph/src/gml.mll
(**************************************************************************)
(* *)
(* Ocamlgraph: a generic graph library for OCaml *)
(* Copyright (C) 2004-2007 *)
(* Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles *)
(* *)
(* This software is free software; you can redistribute it and/or *)
(* modify it under the terms of the GNU Library General Public *)
(* License version 2, with the special exception on linking *)
(* described in file LICENSE. *)
(* *)
(* This software is distributed in the hope that it will be useful, *)
(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)
(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *)
(* *)
(**************************************************************************)
(* $Id: gml.mll,v 1.3 2005-07-06 13:20:31 conchon Exp $ *)
{
open Lexing
type value =
| Int of int
| Float of float
| String of string
| List of value_list
and value_list = (string * value) list
}
let space = [' ' '\t' '\r' '\n']+
let ident = ['a'-'z' 'A'-'Z'] ['a'-'z' 'A'-'Z' '0'-'9']*
let digit = ['0'-'9']
let sign = '-' | '+'
let integer = sign? digit+
let mantissa = 'E' sign? digit+
let real = sign? digit* '.' digit* mantissa?
let in_string = [^ '"']*
rule file = parse
| space
{ file lexbuf }
| (ident as key) space
{ let v = value lexbuf in
(key, v) :: file lexbuf }
| eof
{ [] }
| _ as c
{ failwith ("Gml: invalid character " ^ String.make 1 c) }
and value_list = parse
| space
{ value_list lexbuf }
| (ident as key) space
{ let v = value lexbuf in
(key, v) :: value_list lexbuf }
| ']'
{ [] }
| _ as c
{ failwith ("Gml: invalid character " ^ String.make 1 c) }
and value = parse
| integer as i
{ Int (int_of_string i) }
| real as r
{ Float (float_of_string r) }
| '"' (in_string as s) '"'
{ String s }
| '['
{ let l = value_list lexbuf in List l }
| _ as c
{ failwith ("Gml: invalid character " ^ String.make 1 c) }
{
let parse f =
let c = open_in f in
let lb = from_channel c in
let v = file lb in
close_in c;
v
module Parse
(B : Builder.S)
(L : sig val node : value_list -> B.G.V.label
val edge : value_list -> B.G.E.label end) =
struct
let create_graph l =
let nodes = Hashtbl.create 97 in
let g = B.empty () in
(* 1st pass: create the nodes *)
let g =
List.fold_left
(fun g v -> match v with
| "node", List l ->
let n = B.G.V.create (L.node l) in
begin
try
let id = List.assoc "id" l in Hashtbl.add nodes id n
with Not_found ->
()
end;
B.add_vertex g n
| _ ->
g)
g l
in
(* 2nd pass: add the edges *)
List.fold_left
(fun g v -> match v with
| "edge", List l ->
begin try
let source = List.assoc "source" l in
let target = List.assoc "target" l in
let nsource = Hashtbl.find nodes source in
let ntarget = Hashtbl.find nodes target in
let e = B.G.E.create nsource (L.edge l) ntarget in
B.add_edge_e g e
with Not_found ->
g
end
| _ ->
g)
g l
let parse f =
match parse f with
| ["graph", List l] -> create_graph l
| _ -> invalid_arg "Gml.Parse.parse: not a graph file"
end
module Print
(G : sig
module V : sig
type t
val hash : t -> int
val equal : t -> t -> bool
type label
val label : t -> label
end
module E : sig
type t
type label
val src : t -> V.t
val dst : t -> V.t
val label : t -> label
end
type t
val iter_vertex : (V.t -> unit) -> t -> unit
val iter_edges_e : (E.t -> unit) -> t -> unit
end)
(L : sig
val node : G.V.label -> value_list
val edge : G.E.label -> value_list
end) =
struct
open Format
module H = Hashtbl.Make(G.V)
let print fmt g =
let nodes = H.create 97 in
let cpt = ref 0 in
let id n =
try H.find nodes n
with Not_found -> incr cpt; let id = !cpt in H.add nodes n id; id
in
fprintf fmt "@[graph [@\n";
let rec value fmt = function
| Int n -> fprintf fmt "%d" n
| Float f -> fprintf fmt "%f" f
| String s -> fprintf fmt "\"%s\"" s
| List l -> fprintf fmt "[@\n @[%a@]@\n]" value_list l
and value_list fmt = function
| [] -> ()
| [s,v] -> fprintf fmt "%s %a" s value v
| (s,v) :: l -> fprintf fmt "%s %a@\n" s value v; value_list fmt l
in
G.iter_vertex
(fun v ->
fprintf fmt " @[node [@\n id %d@\n @[%a@]@\n]@]@\n"
(id v) value_list (L.node (G.V.label v)))
g;
G.iter_edges_e
(fun e ->
fprintf fmt
" @[edge [@\n source %d@\n target %d@\n @[%a@]@\n]@]@\n"
(id (G.E.src e)) (id (G.E.dst e))
value_list (L.edge (G.E.label e)))
g;
fprintf fmt "]@\n"
end
}