Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import Text.ParserCombinators.Parsec
- import Data.List (intersperse)
- import Control.Monad (liftM)
- import System.Environment (getArgs)
- main = do args <- getArgs
- parseTest parseExpr (args !! 0)
- symbol :: Parser Char
- symbol = oneOf "$"
- data JsonVal = Atom String
- | Number Integer
- | String String
- | Bool Bool
- | List [JsonVal]
- | Hash [(String, JsonVal)]
- parseExpr :: Parser JsonVal
- parseExpr = parseAtom
- <|> parseNumber
- <|> parseString '\''
- <|> parseString '"'
- <|> do char '['
- x <- parseList
- char ']'
- return x
- <|> do char '{'
- x <- parseHash
- char '}'
- return x
- parseAtom :: Parser JsonVal
- parseAtom = do first <- letter <|> symbol
- rest <- many (letter <|> digit <|> symbol)
- let atom = first : rest
- return $ case atom of
- "true" -> Bool True
- "false" -> Bool False
- otherwise -> Atom atom
- parseNumber :: Parser JsonVal
- parseNumber = liftM (Number . read) $ many1 digit
- parseString :: Char -> Parser JsonVal
- parseString quote = do char quote
- x <- many (noneOf [quote])
- char quote
- return $ String x
- parseList :: Parser JsonVal
- parseList = liftM List $ sepBy parseExpr (spaces >> char ',' >> spaces)
- parseHash :: Parser JsonVal
- parseHash = liftM Hash $ sepBy (parsePair) (spaces >> char ',' >> spaces)
- where parsePair = do name <- (parseString '\'' <|> parseString '"' <|> parseAtom)
- spaces
- char ':'
- spaces
- val <- parseExpr
- let n = case name of
- String contents -> contents
- Atom atom -> atom
- in return (n, val)
- instance Show JsonVal where
- show = showVal
- showVal :: JsonVal -> String
- showVal (Atom name) = name
- showVal (String contents) = "\"" ++ contents ++ "\""
- showVal (Number contents) = show contents
- showVal (Bool True) = "true"
- showVal (Bool False) = "false"
- showVal (List contents) = "[" ++ unwordsList contents ++ "]"
- showVal (Hash pairs) = "{" ++ joinList (map makePair pairs) ++ "}"
- where makePair (name, val) = "\"" ++ name ++ "\"" ++ ": " ++ showVal val
- unwordsList :: [JsonVal] -> String
- unwordsList = joinList . map showVal
- joinList :: [String] -> String
- joinList = concat . intersperse ", "
Add Comment
Please, Sign In to add comment