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
|
module Grasp.Parser (
GraspProgram(..),
parseGrasp
) where
import Control.Applicative( some )
import Text.ParserCombinators.Parsec
import Data.Graph.Inductive.Graph( Node, LNode, LEdge, (&) )
import Data.Graph.Inductive.Graph as Graph
import Data.Graph.Inductive.Tree
data GraspProgram = Gr String String
parseGrasp :: String -> Either ParseError ([LNode String],[LEdge String])
parseGrasp = parse grasp "error"
--parseGrasp input =
-- let firstPass = parse grasp "error" input
-- in case firstPass of
-- Left e -> Left e
-- Right (n,e) -> validate n e
--validate :: [LNode String] -> [LEdge String] -> Either ParseError GraspProgram
grasp = do
string "digraph {"
whiteSpace
(n,e) <- stmtList ([],[])
string "}"
eol
eof
return (n,e)
stmtList (n,e) =
try (node >>= (\x -> stmtList (x:n,e)) )
<|> try (edge >>= (\x -> stmtList (n,x:e)) )
<|> return (reverse n, reverse e)
node = do
i <- ident
l <- labelAttrib
whiteSpace
return (i,l)
edge = do
a <- ident
directedEdge
b <- ident
l <- labelAttrib
whiteSpace
return (a,b,l)
ident = do
d <- some digit
inLineWhSp
return (read d)
labelAttrib = do
char '['
inLineWhSp
string "label=\""
l <- labelID
char '\"'
inLineWhSp
string "];"
return l
labelID = some (noneOf "\"\r\n\\" <|> escapedChar)
escapedChar = try (string "\\\"" >> return '\"')
<|> try (string "\\\\" >> return '\\')
directedEdge = string "->" >> inLineWhSp
inLineWhSp = many (oneOf "\t ")
whiteSpace = many (oneOf "\n\r\t ")
eol = try (string "\r\n")
<|> try (string "\n\r")
<|> try (string "\n")
<|> try (string "\r")
<?> "end of line"
|