RosettaCodeData/Task/S-Expressions/Haskell/s-expressions.hs

41 lines
1.3 KiB
Haskell
Raw Permalink Normal View History

2020-02-17 23:21:07 -08:00
import qualified Data.Functor.Identity as F
import qualified Text.Parsec.Prim as Prim
import Text.Parsec
((<|>), (<?>), many, many1, char, try, parse, sepBy, choice,
between)
import Text.Parsec.Token
(integer, float, whiteSpace, stringLiteral, makeTokenParser)
2016-12-05 22:15:40 +01:00
import Text.Parsec.Char (noneOf)
import Text.Parsec.Language (haskell)
2013-04-10 23:57:08 -07:00
2020-02-17 23:21:07 -08:00
data Val
= Int Integer
| Float Double
| String String
| Symbol String
| List [Val]
deriving (Eq, Show)
2013-04-10 23:57:08 -07:00
2020-02-17 23:21:07 -08:00
tProg :: Prim.ParsecT String a F.Identity [Val]
2013-04-10 23:57:08 -07:00
tProg = many tExpr <?> "program"
2020-02-17 23:21:07 -08:00
where
tExpr = between ws ws (tList <|> tAtom) <?> "expression"
ws = whiteSpace haskell
tAtom =
(try (Float <$> float haskell) <?> "floating point number") <|>
(try (Int <$> integer haskell) <?> "integer") <|>
(String <$> stringLiteral haskell <?> "string") <|>
(Symbol <$> many1 (noneOf "()\"\t\n\r ") <?> "symbol") <?>
"atomic expression"
tList = List <$> between (char '(') (char ')') (many tExpr) <?> "list"
2013-04-10 23:57:08 -07:00
2020-02-17 23:21:07 -08:00
p :: String -> IO ()
2016-12-05 22:15:40 +01:00
p = either print (putStrLn . unwords . map show) . parse tProg ""
2013-04-10 23:57:08 -07:00
2020-02-17 23:21:07 -08:00
main :: IO ()
2013-04-10 23:57:08 -07:00
main = do
2020-02-17 23:21:07 -08:00
let expr =
"((data \"quoted data\" 123 4.5)\n (data (!@# (4.5) \"(more\" \"data)\")))"
putStrLn ("The input:\n" ++ expr ++ "\n\nParsed as:")
p expr