-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathParser.hs
107 lines (73 loc) · 2.25 KB
/
Parser.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
96
97
98
99
100
101
102
103
104
105
106
107
module Parser(term, run, run', tt, tts, tts') where
import Syntax
import Text.ParserCombinators.Parsec
-- Grammar Rules --
term :: Parser [Term]
term = do spaces
terms <- sepEndBy expr (optional (symbol "."))
eof
return terms
atom = identifier `as` Atom <?> "atomic formula"
atomish = atom
<|> unit
<|> parens expr
negation = atomish >>= negs
negs x = do
n <- optionMaybe (symbol "^")
case n of
Just _ -> negs (Not x)
Nothing -> return x
expr = expr1 `chainr1` imp
expr1 = expr2 `chainr1` add
expr2 = expr3 `chainr1` mul
expr3 = expt
mul = tensor <|> par
tensor = symbol "*" `construct` (:*:)
par = symbol "$" `construct` (:$:)
imp = rlolly <|> (symbol "-" >> (lolly <|> arrow))
lolly = symbol "@" `construct` (:-@:)
arrow = symbol "!" `construct` (\l r -> OfCourse (l :-@: r))
rlolly = symbol "@-" `construct` flip (:-@:)
add = with <|> plus
with = symbol "&" `construct` (:&:)
plus = symbol "+" `construct` (:+:)
expt = ofcourse <|> whynot <|> negation
ofcourse = symbol "!" >> expt `as` OfCourse
whynot = symbol "?" >> expt `as` WhyNot
unit = symbol "#" `giving` Top
<|> symbol "%" `giving` Bottom
<|> symbol "1" `giving` One
<|> symbol "0" `giving` Zero
-- Useful Combinators --
despace p = do x <- p
spaces
return x
symbol s = despace (string s)
identifier = despace $
do c <- letter
d <- many (letter <|> digit)
return (c:d)
parens p = do symbol "("
inner <- p
symbol ")"
return inner
-- Utility Functions --
run' :: Parser a -> (a -> IO ()) -> String -> IO ()
run' p f input
= case (parse p "<unknown>" input) of
Left err -> putStr "parse error at " >> print err
Right x -> f x
run p input = run' p print input
tts' :: String -> [Term]
tts' s = case parse term "<inline>" s of
Left err -> error (show err)
Right x -> x
tt :: String -> Term
tt s = head (tts' s)
tts = map tt
as :: Parser a -> (a -> b) -> Parser b
as = flip fmap
giving :: Parser b -> a -> Parser a
giving p x = p >> return x
construct :: Parser b -> (a -> a -> a) -> Parser (a -> a -> a)
construct p c = p >> return c