-
Notifications
You must be signed in to change notification settings - Fork 0
/
Parser.hs
122 lines (103 loc) · 2.52 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
module Parser where
import qualified Data.Functor.Identity
import STLC (Tm (..), Ty (TyArrow, TyNat))
import qualified Text.Parsec as Text.Parsec.Prim
import Text.ParserCombinators.Parsec
( Parser,
alphaNum,
char,
letter,
parse,
string,
(<|>),
)
import Text.ParserCombinators.Parsec.Expr ()
import Text.ParserCombinators.Parsec.Language
( GenLanguageDef,
emptyDef,
)
import qualified Text.ParserCombinators.Parsec.Token as Token
languageDef :: GenLanguageDef String u Data.Functor.Identity.Identity
languageDef =
emptyDef
{ Token.identStart = letter,
Token.identLetter = alphaNum,
Token.reservedNames =
[ "var",
"app",
"abs",
"const",
"var"
],
Token.reservedOpNames =
[ "->",
"=>",
"."
]
}
lexer :: Token.GenTokenParser String u Data.Functor.Identity.Identity
lexer = Token.makeTokenParser languageDef
identifier :: Text.Parsec.Prim.ParsecT String u Data.Functor.Identity.Identity String
identifier = Token.identifier lexer
reserved :: String -> Text.Parsec.Prim.ParsecT String u Data.Functor.Identity.Identity ()
reserved = Token.reserved lexer
reservedOp :: String -> Text.Parsec.Prim.ParsecT String u Data.Functor.Identity.Identity ()
reservedOp = Token.reservedOp lexer
parens :: Text.Parsec.Prim.ParsecT String u Data.Functor.Identity.Identity a -> Text.Parsec.Prim.ParsecT String u Data.Functor.Identity.Identity a
parens = Token.parens lexer
whiteSpace :: Text.Parsec.Prim.ParsecT String u Data.Functor.Identity.Identity ()
whiteSpace = Token.whiteSpace lexer
stlcParser :: Parser Tm
stlcParser = whiteSpace >> statement
tyParser :: Parser Ty
tyParser = parens tyParser_
tyParser_ :: Parser Ty
tyParser_ = arrowTy <|> natTy
natTy :: Parser Ty
natTy =
do
string "Nat"
return TyNat
arrowTy :: Parser Ty
arrowTy =
do
ty1 <- tyParser
reserved "->"
TyArrow ty1 <$> tyParser
statement :: Parser Tm
statement =
parens statement
<|> statement'
statement' :: Parser Tm
statement' =
varTm
<|> constTm
<|> appTm
<|> absTm
varTm :: Parser Tm
varTm =
do
reserved "var"
Var <$> identifier
constTm :: Parser Tm
constTm =
do
reserved "const"
Const <$> identifier
appTm :: Parser Tm
appTm =
do
reserved "app"
app1 <- statement
App app1 <$> statement
absTm :: Parser Tm
absTm =
do
reserved "abs"
char '.'
varName <- identifier
char ':'
tyName <- tyParser
char '='
char '>'
Abs varName tyName <$> statement