[Haskell] Parsec (Haskellのパーサーライブラリー)
さすがに最後のパーサーの部分は難易度が高かったです。 型、クラス、モナドなどの理解が良く出来てないのが露呈し、またその部分を読みながらサンプルコードをなんとか読みきりました。
そこで、Parsecを使って、以下のBNFで表されるような 指数部付き整数 (? なんだそれですが・・・)
<num> ::= <int> | <e_int> <int> ::= <uint> | - <uint> <uint> ::= <digit> | <uint> <digit> <digit> ::= 0 | 1 | ... | 9 <e_int> :: = <int> E <uint>
のパーサーを Parsec を使って書いてみました。
import Text.ParserCombinators.Parsec num :: Parser Int num = do n <- try(e_int) return n <|> do n <- int return n e_int :: Parser Int e_int = do n <- int s <- char 'E' e <- uint return $ n * pow10(read e) int :: Parser Int int = do char '-' n <- uint return $ - read n <|> do n <- uint return $ read n uint :: Parser String uint = do d <- many1 (digit) return d pow10 :: Int -> Int pow10 n = if n == 0 then 1 else 10 * pow10(n - 1) evalNum :: String -> Int evalNum s = case parse num "" s of Right n -> n Left err -> -1
苦節、数時間 やっとできました ^^)!
こんな感じで動きます (gchi上で)
*Main> evalNum "1234" 1234 *Main> evalNum "-1234" -1234 *Main> evalNum "-1234E3" -1234000