@@ -8,12 +8,11 @@ import Prelude
8
8
9
9
import Control.Alt ((<|>))
10
10
import Data.Array as A
11
- import Data.Char as Ch
12
11
import Data.Either (Either )
13
12
import Data.HugeInt as HI
14
13
import Data.HugeNum as HN
15
14
import Data.Json.Extended.Signature.Parse as EJP
16
- import Data.Maybe ( isJust )
15
+ import Data.Set as Set
17
16
import Data.String as S
18
17
import SqlSquared.Utils ((∘))
19
18
import Text.Parsing.Parser as P
@@ -94,8 +93,8 @@ op = map Op $ PC.choice
94
93
, PS .string " %"
95
94
]
96
95
97
- keywords ∷ Array String
98
- keywords =
96
+ keywords ∷ Set.Set String
97
+ keywords = Set .fromFoldable
99
98
[ " where"
100
99
, " when"
101
100
, " values"
@@ -152,8 +151,8 @@ keywords =
152
151
digits ∷ Array Char
153
152
digits = [' 0' ,' 1' ,' 2' ,' 3' ,' 4' ,' 5' ,' 6' ,' 7' ,' 8' ,' 9' ]
154
153
155
- ident ∷ ∀ m . Monad m ⇒ P.ParserT String m Token
156
- ident = map Identifier $ PC .try quotedIdent <|> PC .try notQuotedIdent
154
+ identOrKeyword ∷ ∀ m . Monad m ⇒ P.ParserT String m Token
155
+ identOrKeyword = PC .try quotedIdent <|> notQuotedIdentOrKeyword
157
156
158
157
oneLineComment ∷ ∀ m . Monad m ⇒ P.ParserT String m Token
159
158
oneLineComment =
@@ -178,25 +177,27 @@ multiLineComment = do
178
177
_ →
179
178
collectBeforeComment $ acc <> S .fromCharArray [ c ]
180
179
181
- quotedIdent ∷ ∀ m . Monad m ⇒ P.ParserT String m String
180
+ quotedIdent ∷ ∀ m . Monad m ⇒ P.ParserT String m Token
182
181
quotedIdent =
183
- PC .between (PS .string " `" ) (PS .string " `" )
184
- $ map S .fromCharArray
185
- $ A .some identChar
182
+ map Identifier
183
+ $ PC .between (PS .string " `" ) (PS .string " `" )
184
+ $ map S .fromCharArray
185
+ $ A .some identChar
186
186
where
187
187
identChar = PC .try identEscape <|> identLetter
188
188
identLetter = PS .satisfy (not ∘ eq ' `' )
189
189
identEscape = PS .string " \\ `" $> ' `'
190
190
191
- notQuotedIdent ∷ ∀ m . Monad m ⇒ P.ParserT String m String
192
- notQuotedIdent = do
191
+ notQuotedIdentOrKeyword ∷ ∀ m . Monad m ⇒ P.ParserT String m Token
192
+ notQuotedIdentOrKeyword = do
193
193
first ← PT .letter
194
194
other ← A .many (PT .alphaNum <|> PS .char ' _' )
195
195
let
196
196
str = S .fromCharArray $ A .cons first other
197
- if isJust $ A .elemIndex (S .toLower str) keywords
198
- then P .fail " unexpected keyword"
199
- else pure str
197
+ low = S .toLower str
198
+ pure if Set .member low keywords
199
+ then Kw low
200
+ else Identifier str
200
201
201
202
stringLit ∷ ∀ m . Monad m ⇒ P.ParserT String m Token
202
203
stringLit = Lit ∘ String <$> EJP .parseStringLiteral
@@ -207,26 +208,14 @@ numLit = Lit ∘ Decimal <$> EJP.parseDecimalLiteral
207
208
intLit ∷ ∀ m . Monad m ⇒ P.ParserT String m Token
208
209
intLit = Lit ∘ Integer <$> EJP .parseHugeIntLiteral
209
210
210
- keyword ∷ ∀ m . Monad m ⇒ P.ParserT String m Token
211
- keyword = map Kw $ PC .choice $ map (PC .try ∘ parseKeyWord) keywords
212
-
213
- parseKeyWord ∷ ∀ m . Monad m ⇒ String → P.ParserT String m String
214
- parseKeyWord s =
215
- map S .fromCharArray $ A .foldM foldFn [ ] $ S .toCharArray s
216
- where
217
- foldFn acc ch = do
218
- c ← PC .try $ PS .oneOf [ Ch .toUpper ch, Ch .toLower ch ]
219
- pure $ A .snoc acc c
220
-
221
211
tokens ∷ ∀ m . Monad m ⇒ P.ParserT String m (Array Token )
222
212
tokens = do
223
213
PS .skipSpaces
224
214
A .some $ PC .choice
225
215
[ skipped oneLineComment
226
216
, skipped multiLineComment
227
217
, skipped op
228
- , skipped keyword
229
- , skipped ident
218
+ , skipped identOrKeyword
230
219
, skipped numLit
231
220
, skipped intLit
232
221
, skipped stringLit
0 commit comments