https://www.fpcomplete.com/school/starting-with-haskell/libraries-and-frameworks/text-manipulation/attoparsec给出的解析器似乎可以工作,但它有一个问题。
代码(这里重复)是:
{-# LANGUAGE OverloadedStrings #-}
-- This attoparsec module is intended for parsing text that is
-- represented using an 8-bit character set, e.g. ASCII or ISO-8859-15.
import Data.Attoparsec.Char8
import Data.Word
-- | Type for IP's.
data IP = IP Word8 Word8 Word8 Word8 deriving Show
parseIP :: Parser IP
parseIP = do
d1 <- decimal
char '.'
d2 <- decimal
char '.'
d3 <- decimal
char '.'
d4 <- decimal
return $ IP d1 d2 d3 d4
main :: IO ()
main = print $ parseOnly parseIP "131.45.68.123"
如果解析器输入了一个无效的 IP 地址,例如“1000.1000.1000.1000”,它不会失败,并且由于强制数字转换而返回垃圾结果。
有没有简单的方法来解决这个问题?一种方法是使用较大的Word
类型Word32
并检查数字是否小于 256。但是,如果输入是病态的(例如溢出Word32
),即使这样也可能返回垃圾。转换为Integer
似乎是一种选择,因为它是无界的,但同样,对抗性输入可能会使程序耗尽内存。
那么避免这些问题的(希望是优雅的)解析器会是什么样子呢?