在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