5 import Text.Parsec.String ( Parser )
7 newtype IPv4Octet = IPv4Octet Int
10 data IPv4SequenceMember =
11 IPv4SequenceMemberOctet IPv4Octet
12 | IPv4SequenceMemberOctetRange IPv4Octet IPv4Octet
16 IPv4SequenceSingleMember IPv4SequenceMember
17 | IPv4SequenceOptions IPv4SequenceMember IPv4Sequence
20 data IPv4Field = IPv4FieldOctet IPv4Octet | IPv4FieldSequence IPv4Sequence
24 IPv4Pattern IPv4Field IPv4Field IPv4Field IPv4Field
27 -- An IPv4 address pattern has four fields separated by ".". Each
28 -- field is either a decimal number, or a sequence inside "[]" that
29 -- contains one or more ";"-separated decimal numbers or number..number
32 -- Thus, any pattern field can be a sequence inside "[]", but a "[]"
33 -- sequence cannot span multiple address fields, and a pattern field
34 -- cannot contain both a number and a "[]" sequence at the same time.
36 -- This means that the pattern 1.2.[3.4] is not valid (the sequence
37 -- [3.4] cannot span two address fields) and the pattern 1.2.3.3[6..9]
38 -- is also not valid (the last field cannot be both number 3 and
39 -- sequence [6..9] at the same time).
41 -- The syntax for IPv4 patterns is as follows:
43 -- v4pattern = v4field "." v4field "." v4field "." v4field
44 -- v4field = v4octet | "[" v4sequence "]"
45 -- v4octet = any decimal number in the range 0 through 255
46 -- v4sequence = v4seq_member | v4sequence ";" v4seq_member
47 -- v4seq_member = v4octet | v4octet ".." v4octet
49 v4seq_member :: Parser IPv4SequenceMember
50 v4seq_member = try both <|> just_one
56 return $ IPv4SequenceMemberOctetRange oct1 oct2
58 just_one = fmap IPv4SequenceMemberOctet v4octet
61 v4sequence :: Parser IPv4Sequence
62 v4sequence = try both <|> just_one
68 return $ IPv4SequenceOptions sm s
70 just_one = fmap IPv4SequenceSingleMember v4seq_member
73 v4field :: Parser IPv4Field
74 v4field = just_octet <|> brackets
76 just_octet = fmap IPv4FieldOctet v4octet
82 return $ IPv4FieldSequence s
84 v4octet :: Parser IPv4Octet
85 v4octet = fmap (IPv4Octet . read) $ many1 digit
87 v4pattern :: Parser IPv4Pattern
96 return $ IPv4Pattern field1 field2 field3 field4
99 sequence_members :: IPv4SequenceMember -> [String]
100 sequence_members (IPv4SequenceMemberOctet (IPv4Octet i)) = [show i]
101 sequence_members (IPv4SequenceMemberOctetRange (IPv4Octet start) (IPv4Octet end)) =
102 [show x | x <- [start..end]]
104 sequences :: IPv4Sequence -> [String]
105 sequences (IPv4SequenceSingleMember sm) = sequence_members sm
106 sequences (IPv4SequenceOptions sm s) =
107 (sequence_members sm) ++ (sequences s)
110 fields :: IPv4Field -> [String]
111 fields (IPv4FieldOctet (IPv4Octet i)) = [show i]
112 fields (IPv4FieldSequence s) = sequences s
115 addresses :: IPv4Pattern -> [String]
116 addresses (IPv4Pattern field1 field2 field3 field4) = do
121 return $ f1 ++ "." ++ f2 ++ "." ++ f3 ++ "." ++ f4
125 putStrLn "Hello, world!"