Parse.hs 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142
  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.Map as M
  7. import qualified Data.Text as T
  8. import qualified Data.Vector as V
  9. import Data.Adnot.Type
  10. decodeValue :: ByteString -> Either String Value
  11. decodeValue = parseOnly pVal
  12. where pVal = ws *> (pSum <|> pProd <|> pList <|> pLit)
  13. pSum = Sum <$> (char '(' *> ws *> pIdent)
  14. <*> (pValueList <* char ')')
  15. pProd = Product . M.fromList
  16. <$> (char '{' *> pProdBody <* ws <* char '}')
  17. pProdBody = many' pPair
  18. pPair = (,) <$> (ws *> pIdent) <*> pVal
  19. pList = List <$> (char '[' *> pValueList <* ws <* char ']')
  20. pLit = Symbol <$> pIdent
  21. <|> String <$> pString
  22. <|> Integer <$> decimal
  23. pValueList = V.fromList <$> many' pVal
  24. pIdent = T.pack <$>
  25. ((:) <$> (letter_ascii <|> char '_')
  26. <*> many' (letter_ascii <|> digit <|> char '_'))
  27. pString = T.pack <$> (char '"' *> manyTill pStrChar (char '"'))
  28. pStrChar = '\n' <$ string "\\n"
  29. <|> '\t' <$ string "\\t"
  30. <|> '\r' <$ string "\\r"
  31. <|> '\b' <$ string "\\b"
  32. <|> '\f' <$ string "\\f"
  33. <|> '\'' <$ string "\\'"
  34. <|> '\"' <$ string "\\\""
  35. <|> '\\' <$ string "\\\\"
  36. <|> anyChar
  37. ws = skipSpace *> ((comment *> ws) <|> return ())
  38. comment = char '#' *> manyTill anyChar (char '\n')