-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathKif.hs
95 lines (72 loc) · 2.38 KB
/
Kif.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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
{- |
Module : $Header$
Description : Parsing lists of lists with SUMO .kif files
Copyright : (c) T.Mossakowski, C.Maeder and Uni Bremen 2006
License : GPLv2 or higher, see LICENSE.txt
Maintainer : Christian.Maeder@dfki.de
Stability : provisional
Portability : portable
Parsing lists of lists with SUMO (suggested upper merged ontology) .kif files
-}
module CASL.Kif where
import Common.Parsec
import Text.ParserCombinators.Parsec
import qualified Text.PrettyPrint.HughesPJ as Doc
import Data.Char
data StringKind = Quoted | KToken | QWord | AtWord deriving (Eq, Show)
data ListOfList = Literal StringKind String | List [RangedLL]
deriving Show
data RangedLL = RangedLL SourcePos ListOfList SourcePos deriving Show
-- | skip white spaces and comments for the lexer
dq :: Char
dq = '"'
scanString :: CharParser st String
scanString = enclosedBy
(flat $ many $ fmap (: []) (satisfy (/= dq)) <|> tryString "\\\"")
$ char dq
isKTokenChar :: Char -> Bool
isKTokenChar c = isPrint c && not (elem c "()\";" || isSpace c)
scanLiteral :: CharParser st ListOfList
scanLiteral = do
s@(c : _) <- many1 (satisfy isKTokenChar)
return $ Literal (if c == '?' then QWord else
if c == '@' then AtWord else KToken) s
eolOrEof :: GenParser Char st ()
eolOrEof = forget (oneOf "\n\r") <|> eof
commentOut :: CharParser st ()
commentOut = forget $ char ';' >> manyTill anyChar eolOrEof
skip :: CharParser st [()]
skip = many $ forget (satisfy isSpace) <|> commentOut
lexem :: CharParser st a -> CharParser st a
lexem = (<< skip)
rangedLL :: CharParser st RangedLL
rangedLL = do
p <- getPosition
l <- nestedList
q <- getPosition
skip
return $ RangedLL p l q
nestedList :: CharParser st ListOfList
nestedList = do
lexem $ char '('
l <- many rangedLL
char ')'
return $ List l
<|> fmap (Literal Quoted) scanString
<|> scanLiteral
kifProg :: CharParser st [RangedLL]
kifProg = kifBasic << eof
kifBasic :: CharParser st [RangedLL]
kifBasic = skip >> many1 rangedLL
ppRangedLL :: RangedLL -> Doc.Doc
ppRangedLL (RangedLL _ l _) = ppListOfList l
ppListOfList :: ListOfList -> Doc.Doc
ppListOfList e = case e of
Literal _ s -> Doc.text s
List l -> Doc.parens $ Doc.fsep $ map ppRangedLL l
kifParse :: String -> IO ()
kifParse s = do
e <- parseFromFile kifProg s
case e of
Left err -> print err
Right l -> print $ Doc.vcat $ map ppRangedLL l