-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathParse.hs
64 lines (49 loc) · 1.85 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
-- Parsers for producing named and nameless untyped LC terms
module Parse where
import Data.Maybe (fromJust)
import Text.ParserCombinators.Parsec
import qualified Text.ParserCombinators.Parsec.Token as T
import qualified Text.ParserCombinators.Parsec.Language as L
import Term
trim = unwords . words -- WTF why doesn't this exist already?
-- Parsing functions
parseUntypedNameless :: String -> Maybe NamelessTerm
parseUntypedNameless input =
case parse untypedNLTermSeqToApp "" $ trim input of
Left err -> Nothing
Right t -> Just t
parseUntypedNameless' :: String -> NamelessTerm
parseUntypedNameless' = fromJust . parseUntypedNameless
parseUntyped :: String -> Maybe Term
parseUntyped input =
case parse untypedTermSeqToApp "" $ trim input of
Left err -> Nothing
Right t -> Just t
parseUntyped' :: String -> Term
parseUntyped' = fromJust . parseUntyped
-- Parsers
seqJoiner :: Parser a -> (a -> a -> a) -> Parser a
seqJoiner p j = do {terms@(t:ts) <- sepBy1 p spaces;
return $ foldl j t ts}
untypedNLTerm :: Parser NamelessTerm
untypedNLTerm =
do { char '('; t <- untypedNLTermSeqToApp; char ')'; return t}
<|> do {n <- number; return $ NLVar n}
<|> do {string "\\."; spaces;
t <- untypedNLTermSeqToApp;
return $ NLAbs t}
where number = T.decimal L.haskell
untypedNLTermSeqToApp :: Parser NamelessTerm
untypedNLTermSeqToApp = seqJoiner untypedNLTerm NLApp
untypedTerm :: Parser Term
untypedTerm =
do { char '('; t <- untypedTermSeqToApp; char ')'; return t}
<|> do { v <- varName; return $ Var v}
<|> do {string "\\";
v <- varName;
string "."; spaces;
body <- untypedTermSeqToApp;
return $ Abs v body}
where varName = T.identifier L.haskell
untypedTermSeqToApp :: Parser Term
untypedTermSeqToApp = seqJoiner untypedTerm App