File tree Expand file tree Collapse file tree 2 files changed +17
-3
lines changed
src/Text/Parsing/StringParser Expand file tree Collapse file tree 2 files changed +17
-3
lines changed Original file line number Diff line number Diff line change @@ -31,10 +31,11 @@ import Prelude
31
31
32
32
import Control.Alt ((<|>))
33
33
import Control.Lazy (fix)
34
+ import Control.Monad.Rec.Class (Step(..), tailRecM)
34
35
35
36
import Data.Either (Either(..))
36
37
import Data.Foldable (class Foldable, foldl)
37
- import Data.List (List(..), singleton, manyRec)
38
+ import Data.List (List(..), singleton, manyRec, reverse )
38
39
import Data.Maybe (Maybe(..))
39
40
40
41
import Text.Parsing.StringParser (Parser(..), fail)
@@ -151,5 +152,12 @@ manyTill p end = (end *> pure Nil) <|> many1Till p end
151
152
many1Till :: forall a end. Parser a -> Parser end -> Parser (List a)
152
153
many1Till p end = do
153
154
x <- p
154
- xs <- manyTill p end
155
- pure (Cons x xs)
155
+ tailRecM inner (pure x)
156
+ where
157
+ ending acc = do
158
+ _ <- end
159
+ pure $ Done (reverse acc)
160
+ continue acc = do
161
+ c <- p
162
+ pure $ Loop (Cons c acc)
163
+ inner acc = ending acc <|> continue acc
Original file line number Diff line number Diff line change @@ -7,7 +7,9 @@ import Control.Monad.Eff (Eff)
7
7
import Control.Monad.Eff.Console (CONSOLE)
8
8
9
9
import Data.Either (isLeft, isRight, Either(..))
10
+ import Data.Foldable (fold)
10
11
import Data.List (List(Nil), (:))
12
+ import Data.List.Lazy (take, repeat)
11
13
import Data.String (joinWith, singleton)
12
14
import Data.Unfoldable (replicate)
13
15
@@ -90,3 +92,7 @@ main = do
90
92
assert $ expectResult Nil (manyTill (string "a") (string "b")) "b"
91
93
assert $ expectResult ("a":"a":"a":Nil) (many1Till (string "a") (string "b")) "aaab"
92
94
assert $ parseFail (many1Till (string "a") (string "b")) "b"
95
+ -- check against overflow
96
+ assert $ canParse (many1Till (string "a") (string "and")) $ (fold <<< take 10000 $ repeat "a") <> "and"
97
+ -- check correct order
98
+ assert $ expectResult ('a':'b':'c':Nil) (many1Till anyChar (string "d")) "abcd"
You can’t perform that action at this time.
0 commit comments