@@ -2,12 +2,12 @@
22-----------------------------------------------------------------------------
33-- |
44-- Module : Data.Attoparsec.Combinator
5−-- Copyright : Bryan O'Sullivan 2009
5+-- Copyright : Daan Leijen 1999-2001, Bryan O'Sullivan 2009
66-- License : BSD3
77--
88-- Maintainer : bos@serpentine.com
99-- Stability : experimental
10−-- Portability : unknown
10+-- Portability : portable
1111--
1212-- Useful parser combinators, similar to Parsec.
1313--
@@ -16,29 +16,62 @@ module Data.Attoparsec.Combinator
1616 (
1717 choice
1818 , count
19− , many
19+ , option
2020 , many1
2121 , manyTill
2222 , sepBy
2323 , sepBy1
2424 , skipMany
2525 , skipMany1
26+ , module Control.Applicative
2627 ) where
2728
2829import Control.Applicative
2930
31+-- | @choice ps@ tries to apply the parsers in the list @ps@ in order,
32+-- until one of them succeeds. Returns the value of the succeeding
33+-- parser.
3034choice :: Alternative f => [f a] -> f a
3135choice = foldr (<|>) empty
3236
37+-- | @option x p@ tries to apply parser @p@. If @p@ fails without
38+-- consuming input, it returns the value @x@, otherwise the value
39+-- returned by @p@.
40+--
41+-- > priority = option 0 (digitToInt <$> digit)
42+option :: Alternative f => a -> f a -> f a
43+option x p = p <|> pure x
44+
45+-- | @many1 p@ applies the parser @p@ /one/ or more times. Returns a
46+-- list of the returned values of @p@.
47+--
48+-- > word = many1 letter
3349many1 :: Alternative f => f a -> f [a]
3450many1 p = liftA2 (:) p (many p)
3551
52+-- | @sepBy p sep@ parses /zero/ or more occurrences of @p@, separated
53+-- by @sep@. Returns a list of values returned by @p@.
54+--
55+-- > commaSep p = p `sepBy` (symbol ",")
3656sepBy :: Alternative f => f a -> f s -> f [a]
3757sepBy p s = liftA2 (:) p ((s *> sepBy1 p s) <|> pure []) <|> pure []
3858
59+-- | @sepBy1 p sep@ parses /one/ or more occurrences of @p@, separated
60+-- by @sep@. Returns a list of values returned by @p@.
61+--
62+-- > commaSep p = p `sepBy` (symbol ",")
3963sepBy1 :: Alternative f => f a -> f s -> f [a]
40−sepBy1 p s = liftA2 (:) p ((s *> sepBy1 p s) <|> pure [])
64+sepBy1 p s = scan
65+ where scan = liftA2 (:) p ((s *> scan) <|> pure [])
4166
67+-- | @manyTill p end@ applies parser @p@ /zero/ or more times until
68+-- parser @end@ succeeds. Returns the list of values returned by @p@.
69+-- This parser can be used to scan comments:
70+--
71+-- > simpleComment = string "<!--" *> manyTill anyChar (try (string "-->"))
72+--
73+-- Note the overlapping parsers @anyChar@ and @string \"<!--\"@, and
74+-- therefore the use of the 'try' combinator.
4275manyTill :: Alternative f => f a -> f b -> f [a]
4376manyTill p end = scan
4477 where scan = (end *> pure []) <|> liftA2 (:) p scan