Skip to content
This repository was archived by the owner on Jun 15, 2023. It is now read-only.

Commit 11fed36

Browse files
committed
Add quasar regression test examples, bugfixes
1 parent edb6a20 commit 11fed36

File tree

5 files changed

+993
-295
lines changed

5 files changed

+993
-295
lines changed

src/SqlSquared/Parser.purs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import Data.Either as E
2020
import Data.Foldable as F
2121
import Data.List ((:))
2222
import Data.List as L
23-
import Data.Maybe (Maybe(..), fromMaybe, isJust, maybe)
23+
import Data.Maybe (Maybe(..), fromMaybe, isJust)
2424
import Data.NonEmpty ((:|))
2525
import Data.Json.Extended as EJ
2626
import Data.Tuple (Tuple(..), uncurry)
@@ -88,7 +88,7 @@ prettyParse parser input =
8888
nums = A.mapWithIndex (\n l → padLeft 4 (show (n + pos.line - (A.length pre))) <> " | " <> l) (pre <> line <> post)
8989
pointer = pure $ S.fromCharArray (A.replicate (pos.column - 1 + 7) '-') <> "^ " <> message
9090
in
91-
S.joinWith "\n" $ A.take 3 nums <> pointer <> A.drop 3 nums
91+
S.joinWith "\n" $ A.take (A.length pre + 1) nums <> pointer <> A.drop 3 nums
9292

9393
parse
9494
t
@@ -215,7 +215,7 @@ andExpr = prod cmpExpr (keyword "and") $ _BINOP' Sig.And
215215
cmpExpr m t. SqlParser' m t
216216
cmpExpr = do
217217
e ← defaultExpr
218-
modifiers ← A.many $ negatableSuffix <|> relationalSuffix
218+
modifiers ← A.many $ PC.try negatableSuffix <|> relationalSuffix
219219
pure $ F.foldl (\acc fn → fn acc) e modifiers
220220

221221
defaultExpr m t. SqlParser' m t
@@ -280,7 +280,7 @@ derefExpr = do
280280

281281
fieldDeref = do
282282
operator "."
283-
k ← ident
283+
k ← ident <|> anyKeyword <|> stringLiteral
284284
pure \e → C.binop Sig.FieldDeref e (C.ident k)
285285

286286
fieldDerefExpr = do
@@ -385,7 +385,7 @@ unaryOperator = do
385385

386386
functionExpr m t. SqlParser' m t
387387
functionExpr = PC.try do
388-
name ← ident
388+
name ← ident <|> anyKeyword
389389
args ← parenList
390390
pure $ C.invokeFunction name args
391391

@@ -427,15 +427,20 @@ variableString = asErrorMessage "variable" $ PC.try do
427427
pure s
428428

429429
literal m t. SqlParser' m t
430-
literal = PC.tryRethrow $ token >>= case _ of
430+
literal = withToken "literal" case _ of
431431
Lit (String s) → pure $ embed $ Sig.Literal $ EJ.String s
432432
Lit (Integer i) → pure $ embed $ Sig.Literal $ EJ.Integer i
433433
Lit (Decimal d) → pure $ embed $ Sig.Literal $ EJ.Decimal d
434434
Kw s
435435
| s == "null" → pure $ embed $ Sig.Literal $ EJ.Null
436436
| s == "true" → pure $ embed $ Sig.Literal $ EJ.Boolean true
437437
| s == "false" → pure $ embed $ Sig.Literal $ EJ.Boolean false
438-
_ → P.fail "incorrect literal"
438+
_ → P.fail "not a literal"
439+
440+
stringLiteral m. Monad m P.ParserT TokenStream m String
441+
stringLiteral = withToken "string literal" case _ of
442+
Lit (String s) → pure s
443+
_ → P.fail "not a string"
439444

440445
arrayLiteral m t. SqlParser' m t
441446
arrayLiteral = do
@@ -461,11 +466,10 @@ keyValuePair = do
461466
negatableSuffix m t. SqlParser m t (t t)
462467
negatableSuffix = do
463468
inv ← do
464-
_ ← PC.optionMaybe $ keyword "is"
469+
_ ← PC.optionMaybe (keyword "is")
465470
n ← PC.optionMaybe $ keyword "not"
466471
pure $ isJust n
467-
suffix ← asErrorMessage "`LIKE`, `IN`, or `BETWEEN`" do
468-
betweenSuffix <|> inSuffix <|> likeSuffix
472+
suffix ← betweenSuffix <|> inSuffix <|> likeSuffix
469473
pure \e → (if inv then _NOT else id) $ suffix e
470474

471475
betweenSuffix m t. SqlParser m t (t t)
@@ -563,12 +567,8 @@ tableRelation = do
563567
Pt.parsePath
564568
(const $ P.fail "incorrect path")
565569
(const $ P.fail "incorrect path")
566-
(maybe (P.fail "incorrect path")
567-
(pure ∘ E.Right)
568-
Pt.sandbox Pt.currentDir)
569-
(maybe (P.fail "incorrect path")
570-
(pure ∘ E.Left ∘ (Pt.rootDir Pt.</> _))
571-
Pt.sandbox Pt.rootDir)
570+
(pure ∘ E.Right)
571+
(pure ∘ E.Left)
572572
i
573573
a ← PC.optionMaybe do
574574
_ ← keyword "as"

src/SqlSquared/Parser/Tokenizer.purs

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,16 @@ import Prelude
1212
import Control.Alt ((<|>))
1313
import Control.Monad.State (get)
1414
import Data.Array as A
15+
import Data.Char as Char
1516
import Data.Either (Either)
1617
import Data.HugeInt as HI
1718
import Data.HugeNum as HN
19+
import Data.Int as Int
1820
import Data.Json.Extended.Signature.Parse as EJP
21+
import Data.Maybe (Maybe(..))
1922
import Data.Set as Set
2023
import Data.String as S
24+
import Data.Traversable (sequence)
2125
import SqlSquared.Utils ((∘))
2226
import Text.Parsing.Parser as P
2327
import Text.Parsing.Parser.Pos as PP
@@ -182,7 +186,7 @@ identOrKeyword = PC.try quotedIdent <|> notQuotedIdentOrKeyword
182186

183187
oneLineComment m. Monad m P.ParserT String m Token
184188
oneLineComment =
185-
PC.between (PC.try $ PS.string "--") (PS.string "\n")
189+
PC.between (PS.string "--") (PS.string "\n")
186190
$ map (CommentS.fromCharArray)
187191
$ A.many $ PS.satisfy
188192
$ not ∘ eq '\n'
@@ -234,6 +238,23 @@ numLit = Lit ∘ Decimal <$> EJP.parseDecimalLiteral
234238
intLit m. Monad m P.ParserT String m Token
235239
intLit = LitInteger <$> EJP.parseHugeIntLiteral
236240

241+
charLit m. Monad m P.ParserT String m Token
242+
charLit = PS.char '\'' *> charAtom <* PS.char '\''
243+
where
244+
charAtom = PC.tryRethrow do
245+
ch ← PS.anyChar
246+
LitStringS.singleton <$> case ch of
247+
'\''P.fail "Expected character"
248+
'\\' → charEscape <|> PS.anyChar
249+
_ → pure ch
250+
251+
charEscape = do
252+
_ ← PS.char 'u'
253+
hex ← S.fromCharArray <$> sequence (A.replicate 4 PT.hexDigit)
254+
case Int.fromStringAs Int.hexadecimal hex of
255+
NothingP.fail "Expected character escape sequence"
256+
Just i → pure $ Char.fromCharCode i
257+
237258
positioned m. Monad m P.ParserT String m Token P.ParserT String m PositionedToken
238259
positioned m = do
239260
P.ParseState _ position _ ← get
@@ -247,13 +268,14 @@ tokens = do
247268
, skipped multiLineComment
248269
, skipped op
249270
, skipped identOrKeyword
250-
, skipped numLit
271+
, skipped (PC.try numLit)
251272
, skipped intLit
252273
, skipped stringLit
274+
, skipped charLit
253275
]
254276
where
255-
skipped r = PC.try (r <* PS.skipSpaces)
277+
skipped r = r <* PS.skipSpaces
256278

257279
tokenize String Either P.ParseError TokenStream
258280
tokenize input =
259-
A.filter (not ∘ isComment ∘ _.token) <$> P.runParser input tokens
281+
A.filter (not ∘ isComment ∘ _.token) <$> P.runParser input (tokens <* PS.eof)

0 commit comments

Comments
 (0)