Skip to content

Instantly share code, notes, and snippets.

@naoto-ogawa
Last active May 6, 2018 04:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save naoto-ogawa/85b75fe1693258ec0303f080a641fe7e to your computer and use it in GitHub Desktop.
Save naoto-ogawa/85b75fe1693258ec0303f080a641fe7e to your computer and use it in GitHub Desktop.
Regrex {min, max} for Attoparsec
import Control.Applicative
import Data.Attoparsec.ByteString.Char8
import qualified Data.Attoparsec.Internal.Types as T
-- | an equivalence of regrex {min, max}
-- see http://d.hatena.ne.jp/kazu-yamamoto/20100104/1262588929
range :: Int -> Int -> T.Parser i a -> T.Parser i [a]
range n m p = (++)
<$> count n p -- mimimam
<*> upto (m - n) p -- rest
-- | until n times.
upto :: Int -> T.Parser i a -> T.Parser i [a]
upto 0 _ = return []
upto n p = (:) <$>
p -- at least once
<*> upto (n - 1) p -- repeat
<|> return [] -- in case of faliure
{-# LANGUAGE
OverloadedStrings
#-}
import Test.Tasty
import Test.Tasty.Hspec
--
import Data.Attoparsec.ByteString.Char8
import qualified Data.Attoparsec.Internal.Types as T
--
getContext = return "dummy"
spec_range = do
before getContext $ do
describe "test description" $ its
where
its = foldl1 (>>) $ fmap it_ testRange
it_ (casedesc, myparser, input , expected)
= it casedesc $ \ctc -> testparser myparser input
`shouldBe`
expected
testRange = [
("2-3", (range 2 3 (char '*')), "**", "**")
, ("2-3", (range 2 3 (char '*')), "**A", "**")
, ("2-3", (range 2 3 (char '*')), "****", "***")
, ("2-3", (range 2 3 (char '*')), "***A", "***")
, ("2-3", (range 2 3 (char '*')), "*****", "***")
, ("2-3", (range 2 3 (char '*')), "****A", "***")
, ("2-3", (range 2 3 (char '*')), "*", "error")
, ("2-3", (range 2 3 (char '*')), "A", "error")
]
testparser p inp = either (\x -> "error") id (parseOnly p inp)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment