summaryrefslogtreecommitdiff
path: root/src/GF/Visualization/VisualizeGrammar.hs
blob: 5c920e36d155a8ec454fbe212dc53eb22fe625fd (plain)
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
-- Print a graph of module dependencies in Graphviz DOT format
module VisualizeGrammar where

import qualified Modules as M
import GFC
import Ident

import Data.List (intersperse)
import Data.Maybe (maybeToList)

data GrType = GrAbstract | GrConcrete | GrResource
	    deriving Show

data Node = Node { 
		  label :: String,
		  grtype :: GrType,
		  extends :: [String],
		  opens :: [String],
		  implements :: Maybe String
		  }
		  deriving Show


visualizeGrammar :: CanonGrammar -> String
visualizeGrammar gr = prGraph ns
    where
    ns = [ toNode i m | (i,M.ModMod m) <- M.modules gr ]

toNode :: Ident -> M.Module Ident f Info -> Node
toNode i m = Node {
		   label = prIdent i,
		   grtype = t,
		   extends = map prIdent (M.extends m),
		   opens = map openName (M.opens m),
		   implements = is
		  }
    where 
    (t,is) = case M.mtype m of
			  M.MTAbstract -> (GrAbstract, Nothing)
			  M.MTConcrete i -> (GrConcrete, Just (prIdent i))
			  M.MTResource -> (GrResource, Nothing)
			  -- FIXME: transfer and resource
    
openName :: M.OpenSpec Ident -> String
openName (M.OSimple q i) = prIdent i
openName (M.OQualif q i _) = prIdent i

prGraph :: [Node] -> String
prGraph ns = concat $ map (++"\n") $ ["digraph {\n"] ++ map prNode ns ++ ["}"]

prNode :: Node -> String
prNode n = concat (map (++";\n") stmts)
    where 
    l = label n
    stmts = [l ++ " [" ++ prAttributes attrs ++ "]"]
	    ++ map (prExtend l) (extends n)
	    ++ map (prOpen l) (opens n)
	    ++ map (prImplement l) (maybeToList (implements n))
    style = case grtype n of
			  GrAbstract -> "solid"
			  GrConcrete -> "dashed"
			  GrResource -> "dotted"
    attrs = [("style",style)]


prExtend :: String -> String -> String
prExtend f t = prEdge f t []

prOpen :: String -> String -> String
prOpen f t = prEdge f t [("style","dotted")]

prImplement :: String -> String -> String
prImplement f t = prEdge f t [("arrowhead","empty"),("style","dashed")]

prEdge :: String -> String -> [(String,String)] -> String
prEdge f t as = f ++ " -> " ++ t ++ " [" ++ prAttributes as ++ "]"

prAttributes :: [(String,String)] -> String
prAttributes = concat . intersperse ", " . map (\ (n,v) -> n ++ " = " ++ v)