Skip to content

Commit 5905939

Browse files
newlandsvalleypaf31
authored andcommitted
Add many1Till to Combinators (#30)
* Add many1Till to Combinators * Reimplement manyTill in terms of many1Till
1 parent e5699a9 commit 5905939

File tree

2 files changed

+14
-6
lines changed

2 files changed

+14
-6
lines changed

src/Text/Parsing/StringParser/Combinators.purs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ module Text.Parsing.StringParser.Combinators
2323
, chainr1'
2424
, choice
2525
, manyTill
26+
, many1Till
2627
, module Control.Lazy
2728
) where
2829

@@ -144,8 +145,11 @@ choice = foldl (<|>) (fail "Nothing to parse")
144145

145146
-- | Parse values until a terminator.
146147
manyTill :: forall a end. Parser a -> Parser end -> Parser (List a)
147-
manyTill p end = scan
148-
where
149-
scan = (end *> pure Nil) <|> do x <- p
150-
xs <- scan
151-
pure (Cons x xs)
148+
manyTill p end = (end *> pure Nil) <|> many1Till p end
149+
150+
-- | Parse values until the terminator matches, requiring at least one match.
151+
many1Till :: forall a end. Parser a -> Parser end -> Parser (List a)
152+
many1Till p end = do
153+
x <- p
154+
xs <- manyTill p end
155+
pure (Cons x xs)

test/Main.purs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import Data.Unfoldable (replicate)
1313

1414
import Test.Assert (assert', ASSERT, assert)
1515
import Text.Parsing.StringParser (Parser, runParser, try)
16-
import Text.Parsing.StringParser.Combinators (many1, endBy1, sepBy1, optionMaybe, many, chainl, fix, between)
16+
import Text.Parsing.StringParser.Combinators (many1, endBy1, sepBy1, optionMaybe, many, manyTill, many1Till, chainl, fix, between)
1717
import Text.Parsing.StringParser.Expr (Assoc(..), Operator(..), buildExprParser)
1818
import Text.Parsing.StringParser.String (anyDigit, eof, string, anyChar, regex)
1919

@@ -86,3 +86,7 @@ main = do
8686
assert $ expectResult ('0':'1':'2':'3':'4':Nil) (many1 anyDigit) "01234/"
8787
assert $ expectResult ('5':'6':'7':'8':'9':Nil) (many1 anyDigit) "56789:"
8888
assert $ expectResult "aaaa" (regex "a+") "aaaab"
89+
assert $ expectResult ("a":"a":"a":Nil) (manyTill (string "a") (string "b")) "aaab"
90+
assert $ expectResult Nil (manyTill (string "a") (string "b")) "b"
91+
assert $ expectResult ("a":"a":"a":Nil) (many1Till (string "a") (string "b")) "aaab"
92+
assert $ parseFail (many1Till (string "a") (string "b")) "b"

0 commit comments

Comments
 (0)