2020-05-18 15:59:07 +03:00
|
|
|
module Language.JSON.Parser
|
|
|
|
|
|
|
|
import Language.JSON.Data
|
|
|
|
import Text.Parser
|
|
|
|
import Text.Token
|
|
|
|
import Data.List
|
|
|
|
|
|
|
|
import public Language.JSON.Tokens
|
|
|
|
|
2020-05-21 18:03:00 +03:00
|
|
|
%default total
|
2020-05-18 15:59:07 +03:00
|
|
|
|
|
|
|
private
|
|
|
|
punct : Punctuation -> Grammar JSONToken True ()
|
|
|
|
punct p = match $ JTPunct p
|
|
|
|
|
|
|
|
private
|
|
|
|
rawString : Grammar JSONToken True String
|
|
|
|
rawString = do mstr <- match JTString
|
|
|
|
the (Grammar _ False _) $
|
|
|
|
case mstr of
|
|
|
|
Just str => pure str
|
|
|
|
Nothing => fail "invalid string"
|
|
|
|
|
|
|
|
mutual
|
|
|
|
private
|
|
|
|
json : Grammar JSONToken True JSON
|
|
|
|
json = object
|
|
|
|
<|> array
|
|
|
|
<|> string
|
|
|
|
<|> boolean
|
|
|
|
<|> number
|
|
|
|
<|> null
|
|
|
|
|
|
|
|
private
|
|
|
|
object : Grammar JSONToken True JSON
|
|
|
|
object = do punct $ Curly Open
|
|
|
|
commit
|
|
|
|
props <- properties
|
|
|
|
punct $ Curly Close
|
|
|
|
pure $ JObject props
|
|
|
|
where
|
|
|
|
properties : Grammar JSONToken False (List (String, JSON))
|
|
|
|
properties = sepBy (punct Comma) $
|
|
|
|
do key <- rawString
|
|
|
|
punct Colon
|
|
|
|
value <- json
|
|
|
|
pure (key, value)
|
|
|
|
|
|
|
|
private
|
|
|
|
array : Grammar JSONToken True JSON
|
|
|
|
array = do punct (Square Open)
|
|
|
|
commit
|
|
|
|
vals <- values
|
|
|
|
punct (Square Close)
|
|
|
|
pure (JArray vals)
|
|
|
|
where
|
|
|
|
values : Grammar JSONToken False (List JSON)
|
|
|
|
values = sepBy (punct Comma) json
|
|
|
|
|
|
|
|
private
|
|
|
|
string : Grammar JSONToken True JSON
|
|
|
|
string = map JString rawString
|
|
|
|
|
|
|
|
private
|
|
|
|
boolean : Grammar JSONToken True JSON
|
|
|
|
boolean = map JBoolean $ match JTBoolean
|
|
|
|
|
|
|
|
private
|
|
|
|
number : Grammar JSONToken True JSON
|
|
|
|
number = map JNumber $ match JTNumber
|
|
|
|
|
|
|
|
private
|
|
|
|
null : Grammar JSONToken True JSON
|
|
|
|
null = map (const JNull) $ match JTNull
|
|
|
|
|
|
|
|
export
|
|
|
|
parseJSON : List JSONToken -> Maybe JSON
|
|
|
|
parseJSON toks = case parse json $ filter (not . ignored) toks of
|
|
|
|
Right (j, []) => Just j
|
|
|
|
_ => Nothing
|