-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathLexer.x
148 lines (136 loc) · 4.84 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
142
143
144
145
146
147
148
{
module Lexer where
}
%wrapper "posn"
$digit = 0-9
$alpha = [a-zA-Z]
tokens :-
"#".* ;
-- Methods
read { \p s -> TokenRead p }
println { \p s -> TokenPrintln p }
-- Attributions
\= { \p s -> TokenAtr p }
-- Expressions
\[ { \p s -> TokenLP p }
\] { \p s -> TokenRP p }
\( { \p s -> TokenLB p }
\) { \p s -> TokenRB p }
[\+\-\*\/\^\%\!\|\&\=\<\>]+ { \p s -> TokenOp p s }
-- Ifs
if { \p s -> TokenIf p }
elseif { \p s -> TokenElseIf p }
else { \p s -> TokenElse p }
-- While
while { \p s -> TokenWhile p }
-- Functions
return { \p s -> TokenReturn p }
function { \p s -> TokenDef p }
-- Types
int { \p s -> TokenTInt p }
float { \p s -> TokenTFloat p }
bool { \p s -> TokenTBool p }
-- Miscelaneous
new { \p s -> TokenNew p }
\, { \p s -> TokenComma p }
end { \p s -> TokenEnd p }
\; { \p s -> TokenSep p }
\n { \p s -> TokenLC p }
-- Types and Variables
$digit+ { \p s -> TokenInt p (read s) }
$digit+\.$digit { \p s -> TokenFloat p (read s) }
true { \p s -> TokenBool p True }
false { \p s -> TokenBool p False }
$alpha [$alpha $digit \_ !]* { \p s -> TokenVar p s }
[\ \t\f\v\r]+ ;
{
data Token = TokenInt AlexPosn Int -- Types and Variables
| TokenFloat AlexPosn Float
| TokenBool AlexPosn Bool
| TokenVar AlexPosn String
-- Arithmetic Expressions
| TokenLP AlexPosn -- [
| TokenRP AlexPosn -- ]
| TokenLB AlexPosn -- (
| TokenRB AlexPosn -- )
| TokenOp AlexPosn String
-- Methods
| TokenRead AlexPosn
| TokenPrintln AlexPosn
-- Attributions
| TokenAtr AlexPosn -- =
-- Ifs
| TokenIf AlexPosn
| TokenElseIf AlexPosn
| TokenElse AlexPosn
-- While
| TokenWhile AlexPosn
-- Functions
| TokenReturn AlexPosn
| TokenDef AlexPosn
-- Types
| TokenTInt AlexPosn
| TokenTFloat AlexPosn
| TokenTBool AlexPosn
-- Miscelaneous
| TokenComma AlexPosn
| TokenNew AlexPosn
| TokenEnd AlexPosn
| TokenSep AlexPosn -- ;
| TokenLC AlexPosn -- \n
deriving (Show)
tokenPosn (TokenInt p _) = p
tokenPosn (TokenFloat p _) = p
tokenPosn (TokenBool p _) = p
tokenPosn (TokenVar p _) = p
-- Arithmetic Expressions
tokenPosn (TokenOp p _) = p
tokenPosn (TokenLP p) = p
tokenPosn (TokenRP p) = p
tokenPosn (TokenLB p) = p
tokenPosn (TokenRB p) = p
-- Methods
tokenPosn (TokenRead p) = p
tokenPosn (TokenPrintln p) = p
-- Attributions
tokenPosn (TokenAtr p) = p
-- Ifs
tokenPosn (TokenIf p) = p
tokenPosn (TokenElseIf p) = p
tokenPosn (TokenElse p) = p
-- While
tokenPosn (TokenWhile p) = p
-- Functions
tokenPosn (TokenReturn p) = p
tokenPosn (TokenDef p) = p
-- Types
tokenPosn (TokenTInt p) = p
tokenPosn (TokenTFloat p) = p
tokenPosn (TokenTBool p) = p
-- Miscelaneous
tokenPosn (TokenComma p) = p
tokenPosn (TokenNew p) = p
tokenPosn (TokenEnd p) = p
tokenPosn (TokenSep p) = p
tokenPosn (TokenLC p) = p
getLineNum :: AlexPosn -> Int
getLineNum (AlexPn offset lineNum colNum) = lineNum
getColumnNum :: AlexPosn -> Int
getColumnNum (AlexPn offset lineNum colNum) = colNum
trim :: [Token] -> [Token]
trim [] = []
trim ((TokenLC p1):(TokenLC p2):ts) = (trim ((TokenLC p1) : ts))
trim (t:ts) = t : (trim ts)
cap :: [Token] -> [Token]
cap [] = []
cap ((TokenLC p1):ts) = ts
cap ts = ts
alexScanTokensWrapper :: String -> [Token]
alexScanTokensWrapper str = cap (trim (go (alexStartPos, '\n', [], str)))
where go inp@(pos, _, _, str) =
case alexScan inp 0 of
AlexEOF -> []
AlexError _ -> error ("lexical error @ line " ++ show (getLineNum(pos)) ++ " and column " ++ show (getColumnNum(pos)))
AlexSkip inp' len -> go inp'
AlexToken inp' len act -> act pos (take len str) : go inp'
}