content: {-# LANGUAGE QuasiQuotes, FlexibleContexts #-}
  
  import Control.Monad
  import qualified Data.ByteString as B
  import Data.Char
  import qualified Data.ListLike as LL
  import Numeric
  import Text.Peggy
  
  data JSON
    = JSONString String
    | JSONNumber Double
    | JSONObject [(String, JSON)]
    | JSONArray [JSON]
    | JSONBool Bool
    | JSONNull
    deriving (Show)
  
  [peggy|
  jsons :: [JSON]
    = json* !.
   
  json :: JSON
    = object / array
  
  object :: JSON
    = "{" (pair, ",") "}" { JSONObject $1 }
  
  pair :: (String, JSON)
    = jsstring ":" value
  
  array :: JSON
    = "[" (value, ",") "]" { JSONArray $1 }
  
  value :: JSON
    = jsstring { JSONString $1 }
    / number   { JSONNumber $1 }
    / object
    / array
    / "true"   { JSONBool True }
    / "false"  { JSONBool False }
    / "null"   { JSONNull }
  
  jsstring ::: String
    = '\"' jschar* '\"'
  
  jschar :: Char
    = '\\' escChar / [^\"\\\]
  
  escChar :: Char
    = '\"' { '\"' }
    / '\\' { '\\' }
    / '/' { '/' }
    / 'b' { '\b' }
    / 'f' { '\f' }
    / 'n' { '\n' }
    / 'r' { '\r' }
    / 't' { '\t' }
    / 'u' hex hex hex hex { chr $ fst $ head $ readHex [$1, $2, $3, $4] }
  
  hex :: Char = [0-9a-zA-Z]
  
  number ::: Double
    = [1-9] [0-9]* { read ($1 : $2) }
    / [0]          { 0.0 }
  |]
  
  main :: IO ()
  main =
    forever $ do
      line <- B.getLine
      print . parseString json "<stdin>" $ LL.CS line
  