-
Notifications
You must be signed in to change notification settings - Fork 0
/
Lexer.x
141 lines (121 loc) · 3.7 KB
/
Lexer.x
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
{
module Lexer where
}
%wrapper "monad"
$digit = 0-9
$alpha = [a-zA-Z]
tokens :-
$white+ { skip }
"--".* { skip }
"()" { sAction TkUnit }
"(" { sAction TkLParen }
")" { sAction TkRParen }
";;" { sAction TkDoubleSemi }
$digit+ { strAction $ \s -> TkInt (read s) }
\\ { sAction TkFun }
"->" { sAction TkArrow }
"-U>" { sAction TkArrowU }
"-R>" { sAction TkArrowR }
"-A>" { sAction TkArrowA }
"-L>" { sAction TkArrowL }
"let" { sAction TkLet }
"=" { sAction TkEq }
"in" { sAction TkIn }
"," { sAction TkComma }
"letp" { sAction TkLetp }
"Left" { sAction TkInl }
"Right" { sAction TkInr }
"case" { sAction TkMatch }
"of" { sAction TkWith }
";" { sAction TkSemi }
"[" { sAction TkLBrack }
"]" { sAction TkRBrack }
"fst" { sAction TkFst }
"snd" { sAction TkSnd }
"-" { sAction TkMinus }
"+" { sAction TkPlus }
">" { sAction TkGt }
"<" { sAction TkLt }
"==" { sAction TkEqq }
"or" { sAction TkOr }
"and" { sAction TkAnd }
"fix" { sAction TkFix }
"wnew" { sAction TkWNew }
"snew" { sAction TkSNew }
"release" { sAction TkRelease }
"srelease" { sAction TkSRelease }
"swap" { sAction TkSwap }
"sswap" { sAction TkSSwap }
"@" [$alpha $digit \_ \']* { strAction $ \s -> TkGVar s}
$alpha [$alpha $digit \_ \']* { strAction $ \s -> TkVar s }
{
strAction :: (String -> LToken) -> AlexAction LToken
strAction tfun = token (\(pos,_,_,str) len -> tfun (take len str))
sAction :: LToken -> AlexAction LToken
sAction t = strAction (\_ -> t)
data LToken =
TkLParen
| TkRParen
| TkDoubleSemi
| TkInt Int
| TkUnit
| TkFun
| TkArrow
| TkArrowU
| TkArrowR
| TkArrowA
| TkArrowL
| TkLet
| TkEq
| TkIn
| TkComma
| TkLetp
| TkInl
| TkInr
| TkMatch
| TkWith
| TkSemi
| TkLBrack
| TkRBrack
| TkFst
| TkSnd
| TkMinus
| TkPlus
| TkGt
| TkLt
| TkEqq
| TkOr
| TkAnd
| TkFix
| TkWNew
| TkSNew
| TkRelease
| TkSRelease
| TkSwap
| TkSSwap
| TkVar String
| TkGVar String
| TkEOF
deriving (Show, Eq)
-- Alex calls this function when it reaches EOF
alexEOF = return TkEOF
-- The Alex monad is just like a reader monad, this is used in the parser
-- for errors
getPos :: Alex AlexPosn
getPos = Alex $ \s -> Right (s,alex_pos s)
showPosn (AlexPn _ line col) = show line ++ ":" ++ show col
-- alexMonadScan scans the next token within the reader monad
scanner :: String -> Either String [LToken]
scanner str = runAlex str $ do
loop []
where
loop ts = do
tok <- alexMonadScan
if tok == TkEOF
then return ts
else loop $! (tok:ts)
lexer :: (LToken -> Alex a) -> Alex a
lexer cont = do
t <- alexMonadScan
cont t
}