在https://www.fpcomplete.com/school/starting-with-haskell/libraries-and-frameworks/text-manipulation/attoparsec处给出的解析器似乎可行,但存在问题。使用attoparsec解析IP地址
的代码(这里不再重复)是:
{-# 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
似乎是一种选择,因为它是无限的,但同样,对抗性输入可能会导致程序内存不足。
那么避免这些问题的(希望优雅的)解析器会是什么样子?
你试过像'除非(0 <= D1 && D 1 <= 255)$失败“D1不是[0,255] “'Parser'是一个monad,所以失败了,'unless除了'会起作用 – epsilonhalbe
这是行不通的,因为库已经将字符串转换成了一个'Word8',并且会通过这个条件。 – donatello