-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathParseLambda.hs
83 lines (64 loc) · 1.4 KB
/
ParseLambda.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
module ParseLambda where
import Lambda
import Nat
import Control.Applicative ((<$>))
import Text.Parsec
import Text.Parsec.String
import Text.Parsec.Char
import Text.Parsec.Combinator
-- import Text.Parsec.Token
-- import Text.ParserCombinators.Parsec
parseExpr str =
case parse pExpr "" str of
Left err -> error $ show err
Right e -> e
pExpr :: Parser LambdaExpr
pExpr = do
e <- pExpr1
eof
return e
pExpr1, pExpr3, pExpr6, pExpr9, pExpr10, pAtom :: Parser LambdaExpr
pExpr1 =
do
asg <- try $ pAsg
asg <$> pExpr1
<|>
do
string "\\"
xs <- pName `sepBy` spaces
string "."
-- Abst x <$> pExpr1
flip (foldr Abst) xs <$> pExpr1
<|>
pExpr3
pAsg :: Parser (LambdaExpr -> LambdaExpr)
pAsg = do
string "("
loc <- pName
string ":="
n <- pNat
string ");"
return $ Asg loc n
pExpr3 = chainr1 pExpr6 (string "|_|" >> return Oplus)
pExpr6 = try pSum <|> pExpr9
pSum = do
x <- pName
string "+"
y <- pName
return $ Sum x y
pExpr9 =
do
string "!"
loc <- pName
return $ Drf loc
<|>
pExpr10
pExpr10 = chainl1 pAtom (spaces >> return Apply)
pAtom = between (string "(") (string ")") pExpr1 <|> (Variable <$> pName) <|> (ConstN <$> pNat)
pNat :: Parser Nat
pNat = do
ds <- many1 $ oneOf ['0'..'9']
return $ fromInteger $ read ds
pName :: Parser String
pName = many1 $ oneOf (['a'..'z']++['A'..'Z'])
-- spaces = many $ oneOf [' ','\t','\n']