Created
September 29, 2013 11:59
-
-
Save mjhoy/6751909 to your computer and use it in GitHub Desktop.
parsing ipv4, not allowing leading 0s
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Text.ParserCombinators.Parsec | |
import Control.Monad (liftM2) | |
-- helper function | |
manyNtoM :: Int -> Int -> GenParser a b c -> GenParser a b [c] | |
manyNtoM n m p | |
| n < 0 = return [] | |
| n > m = return [] | |
| n == m = count n p | |
| n == 0 = foldr (<|>) (return []) (map (\x -> try $ count x p) (reverse [1..m])) | |
| otherwise = liftM2 (++) (count n p) (manyNtoM 0 (m-n) p) | |
part = do | |
r <- choice [ zero, nonzero ] | |
return r | |
where | |
zero = string "0" | |
nonzero = do | |
a <- oneOf ['1'..'9'] <?> "non-zero digit with non-zero part" | |
rest <- manyNtoM 0 2 digit | |
if (read (a:rest) :: Int) > 255 | |
then fail "IP address parts must be 0 <= x <= 255" | |
else return (a:rest) | |
ipv4 = do | |
p1 <- part | |
char '.' | |
p2 <- part | |
char '.' | |
p3 <- part | |
char '.' | |
p4 <- part | |
notFollowedBy digit | |
return [p1,p2,p3,p4] | |
-- ghci> parse ipv4 "" "1.0.0.1" | |
-- Right ["1","0","0","1"] | |
-- ghci> parse ipv4 "" "192.168.01.0" | |
-- Left (line 1, column 10): | |
-- unexpected "1" | |
-- expecting "." | |
-- ghci> parse ipv4 "" "0.368.0.1" | |
-- Left (line 1, column 6): | |
-- IP address parts must be 0 <= x <= 255 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment