Skip to content

Instantly share code, notes, and snippets.

@opyapeus
Created October 8, 2018 16:08
Show Gist options
  • Save opyapeus/8297cdb5cf2a7fcfd12aa41260efe395 to your computer and use it in GitHub Desktop.
Save opyapeus/8297cdb5cf2a7fcfd12aa41260efe395 to your computer and use it in GitHub Desktop.
corner-cutting json parser
module Main where
import Data.Functor ( ($>) )
import Text.ParserCombinators.Parsec
data JValue
= JNull
| JString String
| JBool Bool
| JNumber Int
| JArray [JValue]
| JObject [(String, JValue)]
deriving (Show, Eq)
main :: IO ()
main = do
json <- readFile "test.json"
let cjson = compress json
-- NOTE: ignore rows and lines
parseTest jsonParser cjson
compress :: String -> String
compress s = s >>= \c -> if elem c ignores then [] else [c]
where ignores = [' ', '\n', '\t']
jsonParser :: Parser JValue
jsonParser =
(const JNull <$> nullParser)
<|> (JString <$> stringParser)
<|> (JBool <$> boolParser)
<|> (JNumber <$> numberParser)
<|> (JArray <$> arrayParser)
<|> (JObject <$> objectParser)
nullParser :: Parser String
nullParser = string "null"
stringParser :: Parser String
stringParser = between (char '"') (char '"') $ many c where c = noneOf ['"']
boolParser :: Parser Bool
boolParser = (string "true" $> True) <|> (string "false" $> False)
numberParser :: Parser Int
numberParser = read <$> many1 digit
arrayParser :: Parser [JValue]
arrayParser = between (char '[') (char ']') $ sepBy jsonParser (char ',')
objectParser :: Parser [(String, JValue)]
objectParser = between (char '{') (char '}') $ sepBy pair (char ',')
where pair = (,) <$> stringParser <* char ':' <*> jsonParser
{
"glossary": {
"title": "example glossary",
"GlossDiv": {
"title": "S",
"GlossList": {
"GlossEntry": {
"ID": "SGML",
"SortAs": "SGML",
"GlossTerm": "Standard Generalized Markup Language",
"Acronym": "SGML",
"Abbrev": "ISO 8879:1986",
"GlossDef": {
"para": "A meta-markup language, used to create markup languages such as DocBook.",
"GlossSeeAlso": ["GML", "XML"]
},
"GlossSee": "markup"
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment