-
Notifications
You must be signed in to change notification settings - Fork 1
/
Parse.hs
74 lines (60 loc) · 1.76 KB
/
Parse.hs
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
module Parse where
import Text.ParserCombinators.Parsec
import Text.Parsec.Token
import Text.Parsec.Language (haskellDef)
import Data.Char
type Key = String
type Field = (String,String)
-- data Field = Field Key Value
-- type Entry = (String,[Field])
data Entry = Entry Key [Field]
simpleComment = do
string "<!--"
manyTill anyChar (try (string "-->"))
word :: Parser String
word = many1 alphaNum <?> "word"
lexer = makeTokenParser haskellDef
quo p = do {char '"'; res <- p; char '"'; return res}
white :: Parser ()
white = skipMany (space <|> newline);
fval :: String -> Parser String
fval s = do
c <- noneOf s
case c of
'{' -> do co <- fval "}"
char '}'
cs <- fval s
return $ co++cs
'"' -> do co <- fval "\""
char '"'
cs <- fval s
return $ co++cs
'\\' -> do { try $ char '"'; cs <- fval s; return ('"':cs)}
<|> do {cs <- fval s; return (c:cs)}
_ -> do {cs <- fval s; return (c:cs)}
<|> return ""
field :: Parser (String,String)
field = do
key <- many1 (alphaNum <|> oneOf "/+_:-?")
skipMany space
char '='; skipMany space
val <- fval ",}"
return (map toLower key,val)
fields :: Parser (String,[Field])
fields = do
key <- many1 (alphaNum <|> oneOf "/+_:.?-")
white; char ','; white
rest <- sepEndBy field (do white; string ","; white)
return (key,rest)
entry :: Parser Entry
entry = do
char '@'; title <- word; white
(key,cont) <- braces lexer fields
return $ Entry key (("doctype",title):cont)
bibfile = do {white; sepBy1 entry white}
parseIt :: String -> IO [Entry]
parseIt file = do
parsed <- parseFromFile bibfile file
case parsed of
Left err -> print err >> return []
Right table -> return table