List的なものをパースしたい
まぁ全く必要に迫られている訳では無いのですが、日々JavaでかつAndroidアプリ開発をしていると、精神衛生上いろいろとあるので、少し触って放置していたParsecで遊んでみることに。
前回四則計算をやったような気がするので、今回もこじんまりとリストのパースを試してみました。思いっきり我流なのでまぁあれかとは思うけれども、一応メモ的な感じで。
import Text.ParserCombinators.Parsec data Item = List [Item] | Prim Prim deriving Show data Prim = String String | Num Int deriving Show main = do cs <- getContents case parse list "" cs of Right result -> putStrLn $ "Result:" ++ show result Left err -> putStrLn $ "Error:" ++ show err list :: Parser Item list = do char '[' x <- item xs <- many item2 char ']' return $ List $ x:xs item :: Parser Item item = prim <|> list item2 :: Parser Item item2 = char ',' >> item >>= \x -> return x prim :: Parser Item prim = do x <- str <|> num return $ Prim x str :: Parser Prim str = do char '\"' s <- many $ noneOf "\"" char '\"' return $ String s num :: Parser Prim num = many1 digit >>= \s -> return $ Num (read s::Int)
で、これを実行させてみると
komamitsu@carrot:~/lab/haskell$ runghc ListParser.hs [123,["abc",4,[[5,6,"def"],["g","h"],7,8],"ijk"],"lm",9]
こんな結果がでて良かったですねぇという。
Result:List [Prim (Num 123),List [Prim (String "abc"),Prim (Num 4),List [ List [Prim (Num 5),Prim (Num 6),Prim (String "def")],List [Prim (String "g"),Prim (String "h")], Prim (Num 7),Prim (Num 8)],Prim (String "ijk")],Prim (String "lm"),Prim (Num 9)]
まぁParsecがモナド的にどうなっているのかは全然わかってないのですが、すごい綺麗に書けてすごい嬉しいですねぇ。