-
Notifications
You must be signed in to change notification settings - Fork 0
/
Parser.hs
127 lines (105 loc) · 2.86 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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
module Parser (parseCore) where
-- Use http://hackage.haskell.org/package/haskell-src/ to parse full
-- haskell
import Language
import Lexer
import Text.Parsec
import Text.Parsec.String -- has a parseFromFile
import qualified Text.Parsec.Token as P
--import Text.Parsec.Language (haskell)
import Control.Monad
identifier = P.identifier haskell
reserved = P.reserved haskell
whiteSpace = P.whiteSpace haskell
parens = P.parens haskell
integer = P.integer haskell
reservedOp = P.reservedOp haskell
semi = P.semi haskell
comma = P.comma haskell
int :: Parser Int
int = liftM fromInteger integer
parseCore :: String -> Either ParseError CoreProgram
parseCore = runParser pProgram () "filename.nice"
pProgram :: Parser CoreProgram
pProgram = do whiteSpace
scs <- sepBy1 pSc semi
eof
return scs
<?> "Program"
pSc :: Parser CoreScDef
pSc = do name <- identifier
args <- many identifier
reservedOp "="
exp <- pExp
return (name, args, exp)
<?> "Supercombinator"
pExp :: Parser CoreExp
pExp = pApp
-- <|> pBinApp
<|> pLet
<|> pCase
<|> pLam
<|> pAExp
<?> "Expression"
pAExp :: Parser CoreExp
pAExp = pVar
<|> pNum
<|> pConstr
<|> parens pExp
<?> "(A)Expression"
pApp :: Parser CoreExp
pApp = liftM (foldl1 EAp) (many1 pAExp)
<?> "Application"
pVar :: Parser CoreExp
pVar = liftM EVar identifier
<?> "Variabel"
pNum :: Parser CoreExp
pNum = liftM ENum int
<?> "Number"
pLet :: Parser CoreExp
pLet = do reserved "let"
isRec <- (reserved "rec" >> return True) <|> return False
defs <- pDefs
reserved "in"
exp <- pExp
return $ ELet isRec defs exp
<?> "Let(rec) expression"
pDefs :: Parser [(Name, CoreExp)]
pDefs = sepBy1 pDef semi
<?> "List of bindings"
pDef :: Parser (Name, CoreExp)
pDef = do var <- identifier
reservedOp "="
exp <- pExp
return (var, exp)
<?> "Let(rec) binding"
pCase :: Parser CoreExp
pCase = do reserved "case"
exp <- pExp
reserved "of"
reservedOp "{"
alts <- pAlts
reservedOp "}"
return $ ECase exp alts
<?> "Case expression"
pAlts :: Parser [CoreAlt]
pAlts = sepBy1 pAlt semi
pAlt :: Parser CoreAlt
pAlt = do reservedOp "<"
num <- int
reservedOp ">"
ids <- many identifier
reservedOp "->"
exp <- pExp
return (num, ids, exp)
<?> "Case alternative"
pLam :: Parser CoreExp
pLam = do reserved "\\"
args <- sepBy1 identifier comma
reserved "->"
body <- pExp
return $ ELam args body
<?> "Lambda expression"
pConstr :: Parser CoreExp
pConstr = (reserved "@" >> liftM2 EConstr int int)
<?> "Constructor expression"