Text.Parser.Combinators

parsers-0.12.12: Parsing combinators

Copyright | (c) Edward Kmett 2011-2012
License | BSD3
Maintainer | ekmett@gmail.com
Stability | experimental
Portability | non-portable
Safe Haskell | None
Language | Haskell2010

Text.Parser.Combinators

Contents

- Parsing Combinators
- Parsing Class

Description

Alternative parser combinators

Synopsis

- choice :: Alternative m => [m a] -> m a
- option :: Alternative m => a -> m a -> m a
- optional :: Alternative f => f a -> f (Maybe a)
- skipOptional :: Alternative m => m a -> m ()
- between :: Applicative m => m bra -> m ket -> m a -> m a
- surroundedBy :: Applicative m => m a -> m sur -> m a
- some :: Alternative f => f a -> f [a]
- many :: Alternative f => f a -> f [a]
- sepBy :: Alternative m => m a -> m sep -> m [a]
- sepBy1 :: Alternative m => m a -> m sep -> m [a]
- sepByNonEmpty :: Alternative m => m a -> m sep -> m (NonEmpty a)
- sepEndBy1 :: Alternative m => m a -> m sep -> m [a]
- sepEndByNonEmpty :: Alternative m => m a -> m sep -> m (NonEmpty a)
- sepEndBy :: Alternative m => m a -> m sep -> m [a]
- endBy1 :: Alternative m => m a -> m sep -> m [a]
- endByNonEmpty :: Alternative m => m a -> m sep -> m (NonEmpty a)
- endBy :: Alternative m => m a -> m sep -> m [a]
- count :: Applicative m => Int -> m a -> m [a]
- chainl :: Alternative m => m a -> m (a -> a -> a) -> a -> m a
- chainr :: Alternative m => m a -> m (a -> a -> a) -> a -> m a
- chainl1 :: Alternative m => m a -> m (a -> a -> a) -> m a
- chainr1 :: Alternative m => m a -> m (a -> a -> a) -> m a
- manyTill :: Alternative m => m a -> m end -> m [a]
- class Alternative m => Parsing (m :: Type -> Type) where
  - try :: m a -> m a
  - (<?>) :: m a -> String -> m a
  - skipMany :: m a -> m ()
  - skipSome :: m a -> m ()
  - unexpected :: String -> m a
  - eof :: m ()
  - notFollowedBy :: Show a => m a -> m ()

# Parsing Combinators

choice :: Alternative m => [m a] -> m a #

`choice ps` tries to apply the parsers in the list `ps` in order, until one of them succeeds. Returns the value of the succeeding parser.

option :: Alternative m => a -> m a -> m a #

`option x p` tries to apply parser `p`. If `p` fails without consuming input, it returns the value `x`, otherwise the value returned by `p`.

     priority = option 0 (digitToInt <$> digit)

optional :: Alternative f => f a -> f (Maybe a) #

One or none.

It is useful for modelling any computation that is allowed to fail.

#### Examples

Expand

Using the `Alternative` instance of Control.Monad.Except, the following functions:

    >>> import Control.Monad.Except

    >>> canFail = throwError "it failed" :: Except String Int
    >>> final = return 42                :: Except String Int

Can be combined by allowing the first function to fail:

    >>> runExcept $ canFail *> final
    Left "it failed"

    >>> runExcept $ optional canFail *> final
    Right 42

skipOptional :: Alternative m => m a -> m () #

`skipOptional p` tries to apply parser `p`. It will parse `p` or nothing. It only fails if `p` fails after consuming input. It discards the result of `p`. (Plays the role of parsec's optional, which conflicts with Applicative's optional)

between :: Applicative m => m bra -> m ket -> m a -> m a #

`between open close p` parses `open`, followed by `p` and `close`. Returns the value returned by `p`.

     braces  = between (symbol "{") (symbol "}")

surroundedBy :: Applicative m => m a -> m sur -> m a #

`p `surroundedBy` f` is `p` surrounded by `f`. Shortcut for `between f f p`. As in `between`, returns the value returned by `p`.

some :: Alternative f => f a -> f [a] #

One or more.

#### Examples

Expand

    >>> some (putStr "la")
    lalalalalalalalala... * goes on forever *

    >>> some Nothing
    nothing

    >>> take 5 <$> some (Just 1)
    * hangs forever *

Note that this function can be used with Parsers based on Applicatives. In that case `some parser` will attempt to parse `parser` one or more times until it fails.

many :: Alternative f => f a -> f [a] #

Zero or more.

#### Examples

Expand

    >>> many (putStr "la")
    lalalalalalalalala... * goes on forever *

    >>> many Nothing
    Just []

    >>> take 5 <$> many (Just 1)
    * hangs forever *

Note that this function can be used with Parsers based on Applicatives. In that case `many parser` will attempt to parse `parser` zero or more times until it fails.

sepBy :: Alternative m => m a -> m sep -> m [a] #

`sepBy p sep` parses zero or more occurrences of `p`, separated by `sep`. Returns a list of values returned by `p`.

     commaSep p  = p `sepBy` (symbol ",")

sepBy1 :: Alternative m => m a -> m sep -> m [a] #

`sepBy1 p sep` parses one or more occurrences of `p`, separated by `sep`. Returns a list of values returned by `p`.

sepByNonEmpty :: Alternative m => m a -> m sep -> m (NonEmpty a) #

`sepByNonEmpty p sep` parses one or more occurrences of `p`, separated by `sep`. Returns a non-empty list of values returned by `p`.

sepEndBy1 :: Alternative m => m a -> m sep -> m [a] #

`sepEndBy1 p sep` parses one or more occurrences of `p`, separated and optionally ended by `sep`. Returns a list of values returned by `p`.

sepEndByNonEmpty :: Alternative m => m a -> m sep -> m (NonEmpty a) #

`sepEndByNonEmpty p sep` parses one or more occurrences of `p`, separated and optionally ended by `sep`. Returns a non-empty list of values returned by `p`.

sepEndBy :: Alternative m => m a -> m sep -> m [a] #

`sepEndBy p sep` parses zero or more occurrences of `p`, separated and optionally ended by `sep`, ie. haskell style statements. Returns a list of values returned by `p`.

     haskellStatements  = haskellStatement `sepEndBy` semi

endBy1 :: Alternative m => m a -> m sep -> m [a] #

`endBy1 p sep` parses one or more occurrences of `p`, separated and ended by `sep`. Returns a list of values returned by `p`.

endByNonEmpty :: Alternative m => m a -> m sep -> m (NonEmpty a) #

`endByNonEmpty p sep` parses one or more occurrences of `p`, separated and ended by `sep`. Returns a non-empty list of values returned by `p`.

endBy :: Alternative m => m a -> m sep -> m [a] #

`endBy p sep` parses zero or more occurrences of `p`, separated and ended by `sep`. Returns a list of values returned by `p`.

      cStatements  = cStatement `endBy` semi

count :: Applicative m => Int -> m a -> m [a] #

`count n p` parses `n` occurrences of `p`. If `n` is smaller or equal to zero, the parser equals to `return []`. Returns a list of `n` values returned by `p`.

chainl :: Alternative m => m a -> m (a -> a -> a) -> a -> m a #

`chainl p op x` parses zero or more occurrences of `p`, separated by `op`. Returns a value obtained by a left associative application of all functions returned by `op` to the values returned by `p`. If there are zero occurrences of `p`, the value `x` is returned.

chainr :: Alternative m => m a -> m (a -> a -> a) -> a -> m a #

`chainr p op x` parses zero or more occurrences of `p`, separated by `op` Returns a value obtained by a right associative application of all functions returned by `op` to the values returned by `p`. If there are no occurrences of `p`, the value `x` is returned.

chainl1 :: Alternative m => m a -> m (a -> a -> a) -> m a #

`chainl1 p op x` parses one or more occurrences of `p`, separated by `op` Returns a value obtained by a left associative application of all functions returned by `op` to the values returned by `p`. . This parser can for example be used to eliminate left recursion which typically occurs in expression grammars.

     expr   = term   `chainl1` addop
     term   = factor `chainl1` mulop
     factor = parens expr <|> integer

     mulop  = (*) <$ symbol "*"
          <|> div <$ symbol "/"

     addop  = (+) <$ symbol "+"
          <|> (-) <$ symbol "-"

chainr1 :: Alternative m => m a -> m (a -> a -> a) -> m a #

`chainr1 p op x` parses one or more occurrences of `p`, separated by `op` Returns a value obtained by a right associative application of all functions returned by `op` to the values returned by `p`.

manyTill :: Alternative m => m a -> m end -> m [a] #

`manyTill p end` applies parser `p` zero or more times until parser `end` succeeds. Returns the list of values returned by `p`. This parser can be used to scan comments:

     simpleComment   = do{ string "<!--"
                         ; manyTill anyChar (try (string "-->"))
                         }

Note the overlapping parsers `anyChar` and `string "-->"`, and therefore the use of the `try` combinator.

# Parsing Class

class Alternative m => Parsing (m :: Type -> Type) where #

Additional functionality needed to describe parsers independent of input type.

Minimal complete definition

try, (<?>), notFollowedBy

Methods

try :: m a -> m a #

Take a parser that may consume input, and on failure, go back to where we started and fail as if we didn't consume input.

(<?>) :: m a -> String -> m a infixr 0 #

Give a parser a name

skipMany :: m a -> m () #

A version of many that discards its input. Specialized because it can often be implemented more cheaply.

skipSome :: m a -> m () #

`skipSome p` applies the parser `p` one or more times, skipping its result. (aka skipMany1 in parsec)

unexpected :: String -> m a #

Used to emit an error on an unexpected token

default unexpected :: forall (t :: (Type -> Type) -> Type -> Type) (n :: Type -> Type) a. (MonadTrans t, Monad n, Parsing n, m ~ t n) => String -> m a #

eof :: m () #

This parser only succeeds at the end of the input. This is not a primitive parser but it is defined using `notFollowedBy`.

     eof  = notFollowedBy anyChar <?> "end of input"

default eof :: forall (t :: (Type -> Type) -> Type -> Type) (n :: Type -> Type). (MonadTrans t, Monad n, Parsing n, m ~ t n) => m () #

notFollowedBy :: Show a => m a -> m () #

`notFollowedBy p` only succeeds when parser `p` fails. This parser does not consume any input. This parser can be used to implement the 'longest match' rule. For example, when recognizing keywords (for example `let`), we want to make sure that a keyword is not followed by a legal identifier character, in which case the keyword is actually an identifier (for example `lets`). We can program this behaviour as follows:

     keywordLet  = try $ string "let" <* notFollowedBy alphaNum

#### Instances

Instances details

Parsing Get # |
Instance details Defined in Text.Parser.Combinators Methods try :: Get a -> Get a # (<?>) :: Get a -> String -> Get a # skipMany :: Get a -> Get () # skipSome :: Get a -> Get () # unexpected :: String -> Get a # eof :: Get () # notFollowedBy :: Show a => Get a -> Get () #
Parsing ReadP # |
Instance details Defined in Text.Parser.Combinators Methods try :: ReadP a -> ReadP a # (<?>) :: ReadP a -> String -> ReadP a # skipMany :: ReadP a -> ReadP () # skipSome :: ReadP a -> ReadP () # unexpected :: String -> ReadP a # eof :: ReadP () # notFollowedBy :: Show a => ReadP a -> ReadP () #
Chunk t => Parsing (Parser t) # |
Instance details Defined in Text.Parser.Combinators Methods try :: Parser t a -> Parser t a # (<?>) :: Parser t a -> String -> Parser t a # skipMany :: Parser t a -> Parser t () # skipSome :: Parser t a -> Parser t () # unexpected :: String -> Parser t a # eof :: Parser t () # notFollowedBy :: Show a => Parser t a -> Parser t () #
Parsing m => Parsing (Unhighlighted m) # |
Instance details Defined in Text.Parser.Token Methods try :: Unhighlighted m a -> Unhighlighted m a # (<?>) :: Unhighlighted m a -> String -> Unhighlighted m a # skipMany :: Unhighlighted m a -> Unhighlighted m () # skipSome :: Unhighlighted m a -> Unhighlighted m () # unexpected :: String -> Unhighlighted m a # eof :: Unhighlighted m () # notFollowedBy :: Show a => Unhighlighted m a -> Unhighlighted m () #
Parsing m => Parsing (Unlined m) # |
Instance details Defined in Text.Parser.Token Methods try :: Unlined m a -> Unlined m a # (<?>) :: Unlined m a -> String -> Unlined m a # skipMany :: Unlined m a -> Unlined m () # skipSome :: Unlined m a -> Unlined m () # unexpected :: String -> Unlined m a # eof :: Unlined m () # notFollowedBy :: Show a => Unlined m a -> Unlined m () #
Parsing m => Parsing (Unspaced m) # |
Instance details Defined in Text.Parser.Token Methods try :: Unspaced m a -> Unspaced m a # (<?>) :: Unspaced m a -> String -> Unspaced m a # skipMany :: Unspaced m a -> Unspaced m () # skipSome :: Unspaced m a -> Unspaced m () # unexpected :: String -> Unspaced m a # eof :: Unspaced m () # notFollowedBy :: Show a => Unspaced m a -> Unspaced m () #
(Parsing m, Monad m) => Parsing (IdentityT m) # |
Instance details Defined in Text.Parser.Combinators Methods try :: IdentityT m a -> IdentityT m a # (<?>) :: IdentityT m a -> String -> IdentityT m a # skipMany :: IdentityT m a -> IdentityT m () # skipSome :: IdentityT m a -> IdentityT m () # unexpected :: String -> IdentityT m a # eof :: IdentityT m () # notFollowedBy :: Show a => IdentityT m a -> IdentityT m () #
(Parsing m, MonadPlus m) => Parsing (ReaderT e m) # |
Instance details Defined in Text.Parser.Combinators Methods try :: ReaderT e m a -> ReaderT e m a # (<?>) :: ReaderT e m a -> String -> ReaderT e m a # skipMany :: ReaderT e m a -> ReaderT e m () # skipSome :: ReaderT e m a -> ReaderT e m () # unexpected :: String -> ReaderT e m a # eof :: ReaderT e m () # notFollowedBy :: Show a => ReaderT e m a -> ReaderT e m () #
(Parsing m, MonadPlus m) => Parsing (StateT s m) # |
Instance details Defined in Text.Parser.Combinators Methods try :: StateT s m a -> StateT s m a # (<?>) :: StateT s m a -> String -> StateT s m a # skipMany :: StateT s m a -> StateT s m () # skipSome :: StateT s m a -> StateT s m () # unexpected :: String -> StateT s m a # eof :: StateT s m () # notFollowedBy :: Show a => StateT s m a -> StateT s m () #
(Parsing m, MonadPlus m) => Parsing (StateT s m) # |
Instance details Defined in Text.Parser.Combinators Methods try :: StateT s m a -> StateT s m a # (<?>) :: StateT s m a -> String -> StateT s m a # skipMany :: StateT s m a -> StateT s m () # skipSome :: StateT s m a -> StateT s m () # unexpected :: String -> StateT s m a # eof :: StateT s m () # notFollowedBy :: Show a => StateT s m a -> StateT s m () #
(Parsing m, MonadPlus m, Monoid w) => Parsing (WriterT w m) # |
Instance details Defined in Text.Parser.Combinators Methods try :: WriterT w m a -> WriterT w m a # (<?>) :: WriterT w m a -> String -> WriterT w m a # skipMany :: WriterT w m a -> WriterT w m () # skipSome :: WriterT w m a -> WriterT w m () # unexpected :: String -> WriterT w m a # eof :: WriterT w m () # notFollowedBy :: Show a => WriterT w m a -> WriterT w m () #
(Parsing m, MonadPlus m, Monoid w) => Parsing (WriterT w m) # |
Instance details Defined in Text.Parser.Combinators Methods try :: WriterT w m a -> WriterT w m a # (<?>) :: WriterT w m a -> String -> WriterT w m a # skipMany :: WriterT w m a -> WriterT w m () # skipSome :: WriterT w m a -> WriterT w m () # unexpected :: String -> WriterT w m a # eof :: WriterT w m () # notFollowedBy :: Show a => WriterT w m a -> WriterT w m () #
(Stream s m t, Show t) => Parsing (ParsecT s u m) # |
Instance details Defined in Text.Parser.Combinators Methods try :: ParsecT s u m a -> ParsecT s u m a # (<?>) :: ParsecT s u m a -> String -> ParsecT s u m a # skipMany :: ParsecT s u m a -> ParsecT s u m () # skipSome :: ParsecT s u m a -> ParsecT s u m () # unexpected :: String -> ParsecT s u m a # eof :: ParsecT s u m () # notFollowedBy :: Show a => ParsecT s u m a -> ParsecT s u m () #
(Parsing m, MonadPlus m, Monoid w) => Parsing (RWST r w s m) # |
Instance details Defined in Text.Parser.Combinators Methods try :: RWST r w s m a -> RWST r w s m a # (<?>) :: RWST r w s m a -> String -> RWST r w s m a # skipMany :: RWST r w s m a -> RWST r w s m () # skipSome :: RWST r w s m a -> RWST r w s m () # unexpected :: String -> RWST r w s m a # eof :: RWST r w s m () # notFollowedBy :: Show a => RWST r w s m a -> RWST r w s m () #
(Parsing m, MonadPlus m, Monoid w) => Parsing (RWST r w s m) # |
Instance details Defined in Text.Parser.Combinators Methods try :: RWST r w s m a -> RWST r w s m a # (<?>) :: RWST r w s m a -> String -> RWST r w s m a # skipMany :: RWST r w s m a -> RWST r w s m () # skipSome :: RWST r w s m a -> RWST r w s m () # unexpected :: String -> RWST r w s m a # eof :: RWST r w s m () # notFollowedBy :: Show a => RWST r w s m a -> RWST r w s m () #