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