{-# LANGUAGE LambdaCase #-}
import System.Random
import Text.ParserCombinators.ReadP hiding (option)
data Entity
| Any
| Option [CountedEntity]
data CountedEntity
= One Entity
| OneOrMore Entity
| Many Entity
type Regex = [CountedEntity]
main = do
g <- getStdGen
gens :: RandomGen g => g -> [g]
gens g = let ~(g0, g1) = split g in g0 : gens g1
parseRegex
= fst . head . readP
_to
_S regex
regex :: ReadP Regex
regex = manyTill countedEntity eof
countedEntity :: ReadP CountedEntity
countedEntity = do
e <- entity
choice
[ OneOrMore e <$ char '+'
, Many e <$ char '*'
]
entity :: ReadP Entity
entity
= choice
[option
, range
, any, single
]
option :: ReadP Entity
option = Option <$> between (char '[') (char ']') (many countedEntity)
range :: ReadP Entity
range = do
a <- simpleChar
char '-'
b <- simpleChar
single :: ReadP Entity
single = Single <$> simpleChar
simpleChar = choice
[ char '\\' *> get
]
genRegex
:: RandomGen g
=> g
-> Regex
-> String
genCountedEntity
:: RandomGen g
=> g
-> CountedEntity
-> StringgenCountedEntity g = \case
One e -> genEntity g e
OneOrMore e -> more (n + 1) e
Many e -> more n e
where
(n, g') = randomR (0, 10) g -- arbitrary limit of 10
more x = concat
. zipWith genEntity (gens g')
. replicate x
genEntity
:: RandomGen g
=> g
-> Entity
-> StringgenEntity g = \case
Single c -> [c]
Range a b
-> [fst $ randomR
(a
, b
) g
] Option es ->
let (n, g') = randomR (0, length es - 1) g
in genCountedEntity g' (es !! n)
ey0jIExBTkdVQUdFIExhbWJkYUNhc2UgIy19CgppbXBvcnQgICAgICAgICAgIFByZWx1ZGUgICAgICAgICAgICAgICAgICAgICAgaGlkaW5nIChhbnkpCmltcG9ydCAgICAgICAgICAgU3lzdGVtLlJhbmRvbQppbXBvcnQgICAgICAgICAgIFRleHQuUGFyc2VyQ29tYmluYXRvcnMuUmVhZFAgaGlkaW5nIChvcHRpb24pCgpkYXRhIEVudGl0eQogID0gU2luZ2xlIENoYXIKICB8IEFueQogIHwgUmFuZ2UgQ2hhciBDaGFyCiAgfCBPcHRpb24gW0NvdW50ZWRFbnRpdHldCiAgZGVyaXZpbmcgU2hvdwoKZGF0YSBDb3VudGVkRW50aXR5CiAgPSBPbmUgRW50aXR5CiAgfCBPbmVPck1vcmUgRW50aXR5CiAgfCBNYW55IEVudGl0eQogIGRlcml2aW5nIFNob3cKCnR5cGUgUmVnZXggPSBbQ291bnRlZEVudGl0eV0KCm1haW4gOjogSU8gKCkKbWFpbiA9IGRvCiAgZyA8LSBnZXRTdGRHZW4KICBpbnRlcmFjdAogICAgJCB1bmxpbmVzCiAgICAuIHppcFdpdGggZ2VuUmVnZXggKGdlbnMgZykKICAgIC4gbWFwIHBhcnNlUmVnZXgKICAgIC4gbGluZXMKCmdlbnMgOjogUmFuZG9tR2VuIGcgPT4gZyAtPiBbZ10KZ2VucyBnID0gbGV0IH4oZzAsIGcxKSA9IHNwbGl0IGcgaW4gZzAgOiBnZW5zIGcxCgpwYXJzZVJlZ2V4IDo6IFN0cmluZyAtPiBSZWdleApwYXJzZVJlZ2V4ID0gZnN0IC4gaGVhZCAuIHJlYWRQX3RvX1MgcmVnZXgKCnJlZ2V4IDo6IFJlYWRQIFJlZ2V4CnJlZ2V4ID0gbWFueVRpbGwgY291bnRlZEVudGl0eSBlb2YKCmNvdW50ZWRFbnRpdHkgOjogUmVhZFAgQ291bnRlZEVudGl0eQpjb3VudGVkRW50aXR5ID0gZG8KICBlIDwtIGVudGl0eQogIGNob2ljZQogICAgWyBPbmVPck1vcmUgZSA8JCBjaGFyICcrJwogICAgLCBNYW55IGUgPCQgY2hhciAnKicKICAgICwgcmV0dXJuICQgT25lIGUKICAgIF0KCmVudGl0eSA6OiBSZWFkUCBFbnRpdHkKZW50aXR5ID0gY2hvaWNlIFtvcHRpb24sIHJhbmdlLCBhbnksIHNpbmdsZV0KCm9wdGlvbiA6OiBSZWFkUCBFbnRpdHkKb3B0aW9uID0gT3B0aW9uIDwkPiBiZXR3ZWVuIChjaGFyICdbJykgKGNoYXIgJ10nKSAobWFueSBjb3VudGVkRW50aXR5KQoKcmFuZ2UgOjogUmVhZFAgRW50aXR5CnJhbmdlID0gZG8KICBhIDwtIHNpbXBsZUNoYXIKICBjaGFyICctJwogIGIgPC0gc2ltcGxlQ2hhcgogIHJldHVybiAkIFJhbmdlIGEgYgoKYW55IDo6IFJlYWRQIEVudGl0eQphbnkgPSBBbnkgPCQgY2hhciAnLicKCnNpbmdsZSA6OiBSZWFkUCBFbnRpdHkKc2luZ2xlID0gU2luZ2xlIDwkPiBzaW1wbGVDaGFyCgpzaW1wbGVDaGFyIDo6IFJlYWRQIENoYXIKc2ltcGxlQ2hhciA9IGNob2ljZQogIFsgY2hhciAnXFwnICo+IGdldAogICwgc2F0aXNmeSAoYG5vdEVsZW1gICIuKypbXS0iKQogIF0KCmdlblJlZ2V4IDo6IFJhbmRvbUdlbiBnID0+IGcgLT4gUmVnZXggLT4gU3RyaW5nCmdlblJlZ2V4IGcgPSBjb25jYXQgLiB6aXBXaXRoIGdlbkNvdW50ZWRFbnRpdHkgKGdlbnMgZykKCmdlbkNvdW50ZWRFbnRpdHkgOjogUmFuZG9tR2VuIGcgPT4gZyAtPiBDb3VudGVkRW50aXR5IC0+IFN0cmluZwpnZW5Db3VudGVkRW50aXR5IGcgPSBcY2FzZQogIE9uZSBlICAgICAgIC0+IGdlbkVudGl0eSBnIGUKICBPbmVPck1vcmUgZSAtPiBtb3JlIChuICsgMSkgZQogIE1hbnkgZSAgICAgIC0+IG1vcmUgbiBlCiAgd2hlcmUKICAgIChuLCBnJykgPSByYW5kb21SICgwLCAxMCkgZyAtLSBhcmJpdHJhcnkgbGltaXQgb2YgMTAKICAgIG1vcmUgeCAgPSBjb25jYXQKICAgICAgICAgICAgLiB6aXBXaXRoIGdlbkVudGl0eSAoZ2VucyBnJykKICAgICAgICAgICAgLiByZXBsaWNhdGUgeAoKZ2VuRW50aXR5IDo6IFJhbmRvbUdlbiBnID0+IGcgLT4gRW50aXR5IC0+IFN0cmluZwpnZW5FbnRpdHkgZyA9IFxjYXNlCiAgU2luZ2xlIGMgIC0+IFtjXQogIEFueSAgICAgICAtPiBbZnN0ICQgcmFuZG9tIGddCiAgUmFuZ2UgYSBiIC0+IFtmc3QgJCByYW5kb21SIChhLCBiKSBnXQogIE9wdGlvbiBlcyAtPgogICAgbGV0IChuLCBnJykgPSByYW5kb21SICgwLCBsZW5ndGggZXMgLSAxKSBnCiAgICBpbiAgZ2VuQ291bnRlZEVudGl0eSBnJyAoZXMgISEgbik=
YStiCmFiYypkCltBLVphLXowLTkkLishKicoKXt9LH46Oz1AIyVfXC1dKgphYltjLWxdK2prbTkqMTArCmlxYltiZW9xb2ItcV04NzIrMHFicSo=
a+b
abc*d
[A-Za-z0-9$.+!*'(){},~:;=@#%_\-]*
ab[c-l]+jkm9*10+
iqb[beoqob-q]872+0qbq*