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

Parsers#3

Merged
cryogenian merged 10 commits into
slamdata:masterfrom
cryogenian:parsers
Apr 19, 2017
Merged

Parsers#3
cryogenian merged 10 commits into
slamdata:masterfrom
cryogenian:parsers

Conversation

@cryogenian
Copy link
Copy Markdown
Member

@cryogenian cryogenian commented Apr 12, 2017

@garyb @natefaubion Please review

This depends on slamdata/purescript-ejson#17

Initially I tried to reuse ejson parsing coalgebra, but it seems that such parser isn't parser in parsec meaning. But something different. So, I've ported quasar sql^2 parser with part of scala's stdparsers.
Also it has Gen coalgebra that uses ejson's one.

Search example removed. I can add link to SD sources if you guy think that it's for the best.

Couple things that can be improved

  • Parsing algorithm recursion points differ with ast recursion points. That's not so bad, but I think there should be a couple more types, like Expr a for anything that could be ranged/summed/etc.
  • Sql isn't safe by construction.
  • I didn't implement instance for arbitrary parseable sql. That's bad but it could take a long especially with two previous points.

@cryogenian cryogenian requested review from garyb and natefaubion April 12, 2017 22:48
Comment thread test/src/Gen.purs Outdated
test ∷ ∀ r. Eff (TestEffects r) Unit
test = do
Console.printLabel "\n\n:::::::::: TESTING Argonaut codecs ::::::::::\n\n"
testJsonSerialization
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's because of stack overflow in Gen

Comment thread src/SqlSquare/Parser.purs Outdated
>=> flip P.runParser do
res ← expr
eof
pure res
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

expr <* eof?

Comment thread src/SqlSquare/Parser.purs Outdated
eof = do
input ← gets \(P.ParseState input _ _) → input
unless (A.null input) $ P.fail "Expected EOF"
pure unit
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary pure unit.

Comment thread src/SqlSquare/Parser.purs Outdated
p ← A.many do
o ← pb
r ← pa
pure $ o × r
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(×) <$> pb <*> pa

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like this notation for binary operators. Why do you prefer it?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tuple <$> pb <*> pa? 😆

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep ^_^

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, my point is just that if it's trivial applicative usage, it should be favored.

Comment thread src/SqlSquare/Parser.purs Outdated
a ← token
case a of
Identifier s → pure s
_ → P.fail "Token is not an identifier"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PC.try $ token >>= case _ of

Should we be putting try in top-level parsers or deferring to use site?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍
I tried to wrap parsers with wrap because it seemed a bit more convenient to me. Is there any best practices for parsing stuff?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you put try at the root of your parsers, you have no option to use it without try. I don't know if this flexibility is important, which is why I posed it as a question. I haven't written enough complex parsers to have a strong opinion. But it seems like you mostly want it in alternatives, and being able to tell in the alternative structure which is backtracking or not is helpful.

Comment thread src/SqlSquare/Parser.purs Outdated
derefExpr = PC.try do
e ← primaryExpression
modifiers ← A.many modifier
(mbWildcard ∷ Maybe t) ← PC.optionMaybe do
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary parens. Why is the type annotation necessary?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Next expression is dropped. It has constrained type. Ps can't say what's that.

Comment thread src/SqlSquare/Parser.purs Outdated
operator "."
wildcard
let
modified = F.foldl (\a f → f a) e modifiers
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

foldl (#)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought this syntax is deprecated. Cool!

Comment thread src/SqlSquare/Parser.purs Outdated
pure \e → embed $ Sig.Binop { op: Sig.IndexDeref, lhs: e, rhs })

wildcard ∷ ∀ m t. (Corecursive t (Sig.SqlF EJ.EJsonF), Monad m) ⇒ P.ParserT (Array Token) m t
wildcard = operator "*" $> (embed $ Sig.Splice Nothing)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

embed (Sig.Splice Nothing)

Must...use...$

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:P

Comment thread src/SqlSquare/Parser.purs Outdated
pure $ isNothing n
let inv = fromMaybe true mbInv
suffix ← betweenSuffix <|> inSuffix <|> likeSuffix
pure $ \e → (if inv then _NOT else id) $ suffix e
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These $s are unnecessary when the rhs is a lambda.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Comment thread src/SqlSquare/Parser.purs Outdated
mbV ←
PC.optionMaybe definedExpr
sortStr ←
map (fromMaybe "asc") $ PC.optionMaybe (keyword "asc" <|> keyword "desc")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fromMaybe "asc" <$> ...

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One reason me preferring map is that I know precedence of $. E.g.

map (fromMaybe "asc") $ PC.optionMaybe  $ foo <|> bar

Comment thread src/SqlSquare/Parser/Tokenizer.purs Outdated
skipped r = PC.try do
res ← r
PS.skipSpaces
pure res
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

r <* skipSpaces

@cryogenian
Copy link
Copy Markdown
Member Author

  • Addressed comments except PC.try. I personally think that this is ok to use that stuff in declaration, not in use case, because we don't want to use them w/o PC.try
  • Added comments handling in tokenizer (Ooops, forgot about this)
  • foreachE in gen tests

@cryogenian
Copy link
Copy Markdown
Member Author

  • Updated purescript-ejson dep.
  • Added Enhancements #4 to handle issues found in this pr.

@natefaubion @garyb good to go?

@cryogenian cryogenian merged commit aef9ce4 into slamdata:master Apr 19, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants