Guest User

Untitled

a guest
Jul 18th, 2018
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.56 KB | None | 0 0
  1. import Text.ParserCombinators.Parsec
  2. import Data.List (intersperse)
  3. import Control.Monad (liftM)
  4. import System.Environment (getArgs)
  5.  
  6. main = do args <- getArgs
  7. parseTest parseExpr (args !! 0)
  8.  
  9. symbol :: Parser Char
  10. symbol = oneOf "$"
  11.  
  12. data JsonVal = Atom String
  13. | Number Integer
  14. | String String
  15. | Bool Bool
  16. | List [JsonVal]
  17. | Hash [(String, JsonVal)]
  18.  
  19. parseExpr :: Parser JsonVal
  20. parseExpr = parseAtom
  21. <|> parseNumber
  22. <|> parseString '\''
  23. <|> parseString '"'
  24. <|> do char '['
  25. x <- parseList
  26. char ']'
  27. return x
  28. <|> do char '{'
  29. x <- parseHash
  30. char '}'
  31. return x
  32.  
  33. parseAtom :: Parser JsonVal
  34. parseAtom = do first <- letter <|> symbol
  35. rest <- many (letter <|> digit <|> symbol)
  36. let atom = first : rest
  37. return $ case atom of
  38. "true" -> Bool True
  39. "false" -> Bool False
  40. otherwise -> Atom atom
  41.  
  42. parseNumber :: Parser JsonVal
  43. parseNumber = liftM (Number . read) $ many1 digit
  44.  
  45. parseString :: Char -> Parser JsonVal
  46. parseString quote = do char quote
  47. x <- many (noneOf [quote])
  48. char quote
  49. return $ String x
  50.  
  51. parseList :: Parser JsonVal
  52. parseList = liftM List $ sepBy parseExpr (spaces >> char ',' >> spaces)
  53.  
  54. parseHash :: Parser JsonVal
  55. parseHash = liftM Hash $ sepBy (parsePair) (spaces >> char ',' >> spaces)
  56. where parsePair = do name <- (parseString '\'' <|> parseString '"' <|> parseAtom)
  57. spaces
  58. char ':'
  59. spaces
  60. val <- parseExpr
  61. let n = case name of
  62. String contents -> contents
  63. Atom atom -> atom
  64. in return (n, val)
  65.  
  66. instance Show JsonVal where
  67. show = showVal
  68.  
  69. showVal :: JsonVal -> String
  70. showVal (Atom name) = name
  71. showVal (String contents) = "\"" ++ contents ++ "\""
  72. showVal (Number contents) = show contents
  73. showVal (Bool True) = "true"
  74. showVal (Bool False) = "false"
  75. showVal (List contents) = "[" ++ unwordsList contents ++ "]"
  76. showVal (Hash pairs) = "{" ++ joinList (map makePair pairs) ++ "}"
  77. where makePair (name, val) = "\"" ++ name ++ "\"" ++ ": " ++ showVal val
  78.  
  79. unwordsList :: [JsonVal] -> String
  80. unwordsList = joinList . map showVal
  81.  
  82. joinList :: [String] -> String
  83. joinList = concat . intersperse ", "
Add Comment
Please, Sign In to add comment