Parse.hs 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. {-# LANGUAGE OverloadedStrings #-}
  2. module Data.Adnot.Parse (decodeValue) where
  3. import Control.Applicative((<|>))
  4. import Data.Attoparsec.ByteString.Char8
  5. import Data.ByteString (ByteString)
  6. import qualified Data.ByteString.Char8 as BS
  7. import qualified Data.Map as M
  8. import qualified Data.Text as T
  9. import qualified Data.Text.Encoding as T
  10. import qualified Data.Vector as V
  11. import Data.Adnot.Type
  12. decodeValue :: ByteString -> Either String Value
  13. decodeValue = parseOnly pVal
  14. where pVal = ws *> (pSum <|> pProd <|> pList <|> pLit)
  15. pSum = Sum <$> (char '(' *> ws *> (pIdent <|> pString))
  16. <*> (pValueList <* (ws *> char ')'))
  17. pProd = Product . M.fromList
  18. <$> (char '{' *> pProdBody <* ws <* char '}')
  19. pProdBody = many' pPair
  20. pPair = (,) <$> (ws *> (pIdent <|> pString)) <*> pVal
  21. pList = List <$> (char '[' *> pValueList <* ws <* char ']')
  22. pLit = String <$> pIdent
  23. <|> String <$> pString
  24. <|> Double <$> double
  25. <|> Integer <$> decimal
  26. pStr = String <$> (pIdent <|> pString)
  27. pValueList = V.fromList <$> many' pVal
  28. pIdent = T.pack <$>
  29. ((:) <$> (letter_ascii <|> char '_')
  30. <*> many' (letter_ascii <|> digit <|> char '_'))
  31. pString = T.decodeUtf8 . BS.pack <$> (char '"' *> manyTill pStrChar (char '"'))
  32. pStrChar = '\n' <$ string "\\n"
  33. <|> '\t' <$ string "\\t"
  34. <|> '\r' <$ string "\\r"
  35. <|> '\b' <$ string "\\b"
  36. <|> '\f' <$ string "\\f"
  37. <|> '\'' <$ string "\\'"
  38. <|> '\"' <$ string "\\\""
  39. <|> '\\' <$ string "\\\\"
  40. <|> anyChar
  41. ws = skipSpace *> ((comment *> ws) <|> return ())
  42. comment = char '#' *> manyTill anyChar (char '\n')