megaparsec-5.3.1: Monadic parser combinators

Copyright | © 2015–2017 Megaparsec contributors © 2007 Paolo Martini © 1999–2001 Daan Leijen
License | FreeBSD
Maintainer | Mark Karpov <markkarpov92@gmail.com>
Stability | experimental
Portability | portable
Safe Haskell | None
Language | Haskell2010

Text.Megaparsec

Contents

- Running parser
- Combinators
- Character parsing
- Textual source position
- Error messages
- Debugging
- Low-level operations

Description

This module includes everything you need to get started writing a parser. If you are new to Megaparsec and don't know where to begin, take a look at the tutorials https://markkarpov.com/learn-haskell.html#megaparsec-tutorials.

By default this module is set up to parse character data. If you'd like to parse the result of your own tokenizer you should start with the following imports:

    import Text.Megaparsec.Prim
    import Text.Megaparsec.Combinator

Then you can implement your own version of `satisfy` on top of the `token` primitive, etc.

The typical import section looks like this:

    import Text.Megaparsec
    import Text.Megaparsec.String
    -- import Text.Megaparsec.ByteString
    -- import Text.Megaparsec.ByteString.Lazy
    -- import Text.Megaparsec.Text
    -- import Text.Megaparsec.Text.Lazy

As you can see the second import depends on the data type you want to use as input stream. It just defines the useful type-synonym `Parser`.

Megaparsec 5 uses some type-level machinery to provide flexibility without compromising on type safety. Thus type signatures are sometimes necessary to avoid ambiguous types. If you're seeing a error message that reads like “Ambiguous type variable `e0` arising from … prevents the constraint `(ErrorComponent e0)` from being resolved”, you need to give an explicit signature to your parser to resolve the ambiguity. It's a good idea to provide type signatures for all top-level definitions.

Megaparsec is capable of a lot. Apart from this standard functionality you can parse permutation phrases with Text.Megaparsec.Perm, expressions with Text.Megaparsec.Expr, and even entire languages with Text.Megaparsec.Lexer. These modules should be imported explicitly along with the two modules mentioned above.

Synopsis

- type Parsec e s = ParsecT e s Identity
- data ParsecT e s m a
- parse :: Parsec e s a -> String -> s -> Either (ParseError (Token s) e) a
- parseMaybe :: (ErrorComponent e, Stream s) => Parsec e s a -> s -> Maybe a
- parseTest :: (ShowErrorComponent e, Ord (Token s), ShowToken (Token s), Show a) => Parsec e s a -> s -> IO ()
- runParser :: Parsec e s a -> String -> s -> Either (ParseError (Token s) e) a
- runParser' :: Parsec e s a -> State s -> (State s, Either (ParseError (Token s) e) a)
- runParserT :: Monad m => ParsecT e s m a -> String -> s -> m (Either (ParseError (Token s) e) a)
- runParserT' :: Monad m => ParsecT e s m a -> State s -> m (State s, Either (ParseError (Token s) e) a)
- (<|>) :: Alternative f => forall a. f a -> f a -> f a
- many :: Alternative f => forall a. f a -> f [a]
- some :: Alternative f => forall a. f a -> f [a]
- optional :: Alternative f => f a -> f (Maybe a)
- unexpected :: MonadParsec e s m => ErrorItem (Token s) -> m a
- match :: MonadParsec e s m => m a -> m ([Token s], a)
- region :: MonadParsec e s m => (ParseError (Token s) e -> ParseError (Token s) e) -> m a -> m a
- failure :: MonadParsec e s m => Set (ErrorItem (Token s)) -> Set (ErrorItem (Token s)) -> Set e -> m a
- (<?>) :: MonadParsec e s m => m a -> String -> m a
- label :: MonadParsec e s m => String -> m a -> m a
- hidden :: MonadParsec e s m => m a -> m a
- try :: MonadParsec e s m => m a -> m a
- lookAhead :: MonadParsec e s m => m a -> m a
- notFollowedBy :: MonadParsec e s m => m a -> m ()
- withRecovery :: MonadParsec e s m => (ParseError (Token s) e -> m a) -> m a -> m a
- observing :: MonadParsec e s m => m a -> m (Either (ParseError (Token s) e) a)
- eof :: MonadParsec e s m => m ()
- token :: MonadParsec e s m => (Token s -> Either (Set (ErrorItem (Token s)), Set (ErrorItem (Token s)), Set e) a) -> Maybe (Token s) -> m a
- tokens :: MonadParsec e s m => (Token s -> Token s -> Bool) -> [Token s] -> m [Token s]
- between :: Applicative m => m open -> m close -> m a -> m a
- choice :: (Foldable f, Alternative m) => f (m a) -> m a
- count :: Applicative m => Int -> m a -> m [a]
- count' :: Alternative m => Int -> Int -> m a -> m [a]
- eitherP :: Alternative m => m a -> m b -> m (Either a b)
- endBy :: Alternative m => m a -> m sep -> m [a]
- endBy1 :: Alternative m => m a -> m sep -> m [a]
- manyTill :: Alternative m => m a -> m end -> m [a]
- someTill :: Alternative m => m a -> m end -> m [a]
- option :: Alternative m => a -> m a -> m a
- sepBy :: Alternative m => m a -> m sep -> m [a]
- sepBy1 :: Alternative m => m a -> m sep -> m [a]
- sepEndBy :: Alternative m => m a -> m sep -> m [a]
- sepEndBy1 :: Alternative m => m a -> m sep -> m [a]
- skipMany :: Alternative m => m a -> m ()
- skipSome :: Alternative m => m a -> m ()
- newline :: (MonadParsec e s m, Token s ~ Char) => m Char
- crlf :: (MonadParsec e s m, Token s ~ Char) => m String
- eol :: (MonadParsec e s m, Token s ~ Char) => m String
- tab :: (MonadParsec e s m, Token s ~ Char) => m Char
- space :: (MonadParsec e s m, Token s ~ Char) => m ()
- controlChar :: (MonadParsec e s m, Token s ~ Char) => m Char
- spaceChar :: (MonadParsec e s m, Token s ~ Char) => m Char
- upperChar :: (MonadParsec e s m, Token s ~ Char) => m Char
- lowerChar :: (MonadParsec e s m, Token s ~ Char) => m Char
- letterChar :: (MonadParsec e s m, Token s ~ Char) => m Char
- alphaNumChar :: (MonadParsec e s m, Token s ~ Char) => m Char
- printChar :: (MonadParsec e s m, Token s ~ Char) => m Char
- digitChar :: (MonadParsec e s m, Token s ~ Char) => m Char
- octDigitChar :: (MonadParsec e s m, Token s ~ Char) => m Char
- hexDigitChar :: (MonadParsec e s m, Token s ~ Char) => m Char
- markChar :: (MonadParsec e s m, Token s ~ Char) => m Char
- numberChar :: (MonadParsec e s m, Token s ~ Char) => m Char
- punctuationChar :: (MonadParsec e s m, Token s ~ Char) => m Char
- symbolChar :: (MonadParsec e s m, Token s ~ Char) => m Char
- separatorChar :: (MonadParsec e s m, Token s ~ Char) => m Char
- asciiChar :: (MonadParsec e s m, Token s ~ Char) => m Char
- latin1Char :: (MonadParsec e s m, Token s ~ Char) => m Char
- charCategory :: (MonadParsec e s m, Token s ~ Char) => GeneralCategory -> m Char
- char :: (MonadParsec e s m, Token s ~ Char) => Char -> m Char
- char' :: (MonadParsec e s m, Token s ~ Char) => Char -> m Char
- anyChar :: (MonadParsec e s m, Token s ~ Char) => m Char
- oneOf :: (Foldable f, MonadParsec e s m, Token s ~ Char) => f Char -> m Char
- oneOf' :: (Foldable f, MonadParsec e s m, Token s ~ Char) => f Char -> m Char
- noneOf :: (Foldable f, MonadParsec e s m, Token s ~ Char) => f Char -> m Char
- noneOf' :: (Foldable f, MonadParsec e s m, Token s ~ Char) => f Char -> m Char
- satisfy :: (MonadParsec e s m, Token s ~ Char) => (Char -> Bool) -> m Char
- string :: (MonadParsec e s m, Token s ~ Char) => String -> m String
- string' :: (MonadParsec e s m, Token s ~ Char) => String -> m String
- data Pos
- mkPos :: (Integral a, MonadThrow m) => a -> m Pos
- unPos :: Pos -> Word
- unsafePos :: Word -> Pos
- data InvalidPosException = InvalidPosException
- data SourcePos = SourcePos {
  - sourceName :: FilePath
  - sourceLine :: !Pos
  - sourceColumn :: !Pos
  }
- initialPos :: String -> SourcePos
- sourcePosPretty :: SourcePos -> String
- data ErrorItem t
  - = Tokens (NonEmpty t)
  - | Label (NonEmpty Char)
  - | EndOfInput
- class Ord e => ErrorComponent e where
- data Dec
  - = DecFail String
  - | DecIndentation Ordering Pos Pos
- data ParseError t e = ParseError {
  - errorPos :: NonEmpty SourcePos
  - errorUnexpected :: Set (ErrorItem t)
  - errorExpected :: Set (ErrorItem t)
  - errorCustom :: Set e
  }
- class ShowToken a where
- class Ord a => ShowErrorComponent a where
- parseErrorPretty :: (Ord t, ShowToken t, ShowErrorComponent e) => ParseError t e -> String
- dbg :: forall e s m a. (Stream s, ShowToken (Token s), ShowErrorComponent e, Show a) => String -> ParsecT e s m a -> ParsecT e s m a
- class Ord (Token s) => Stream s where
  - type Token s :: *
- data State s = State {
  - stateInput :: s
  - statePos :: NonEmpty SourcePos
  - stateTokensProcessed :: !Word
  - stateTabWidth :: Pos
  }
- getInput :: MonadParsec e s m => m s
- setInput :: MonadParsec e s m => s -> m ()
- getPosition :: MonadParsec e s m => m SourcePos
- getNextTokenPosition :: forall e s m. MonadParsec e s m => m (Maybe SourcePos)
- setPosition :: MonadParsec e s m => SourcePos -> m ()
- pushPosition :: MonadParsec e s m => SourcePos -> m ()
- popPosition :: MonadParsec e s m => m ()
- getTokensProcessed :: MonadParsec e s m => m Word
- setTokensProcessed :: MonadParsec e s m => Word -> m ()
- getTabWidth :: MonadParsec e s m => m Pos
- setTabWidth :: MonadParsec e s m => Pos -> m ()
- getParserState :: MonadParsec e s m => m (State s)
- setParserState :: MonadParsec e s m => State s -> m ()
- updateParserState :: MonadParsec e s m => (State s -> State s) -> m ()

# Running parser

type Parsec e s = ParsecT e s Identity #

`Parsec` is a non-transformer variant of the more general `ParsecT` monad transformer.

data ParsecT e s m a #

`ParsecT e s m a` is a parser with custom data component of error `e`, stream type `s`, underlying monad `m` and return type `a`.

Instances

(ErrorComponent e, Stream s) => MonadParsec e s (ParsecT e s m) # |
Methods failure :: Set (ErrorItem (Token s)) -> Set (ErrorItem (Token s)) -> Set e -> ParsecT e s m a # label :: String -> ParsecT e s m a -> ParsecT e s m a # hidden :: ParsecT e s m a -> ParsecT e s m a # try :: ParsecT e s m a -> ParsecT e s m a # lookAhead :: ParsecT e s m a -> ParsecT e s m a # notFollowedBy :: ParsecT e s m a -> ParsecT e s m () # withRecovery :: (ParseError (Token s) e -> ParsecT e s m a) -> ParsecT e s m a -> ParsecT e s m a # observing :: ParsecT e s m a -> ParsecT e s m (Either (ParseError (Token s) e) a) # eof :: ParsecT e s m () # token :: (Token s -> Either (Set (ErrorItem (Token s)), Set (ErrorItem (Token s)), Set e) a) -> Maybe (Token s) -> ParsecT e s m a # tokens :: (Token s -> Token s -> Bool) -> [Token s] -> ParsecT e s m [Token s] # getParserState :: ParsecT e s m (State s) # updateParserState :: (State s -> State s) -> ParsecT e s m () #
(ErrorComponent e, Stream s, MonadError e' m) => MonadError e' (ParsecT e s m) # |
Methods throwError :: e' -> ParsecT e s m a # catchError :: ParsecT e s m a -> (e' -> ParsecT e s m a) -> ParsecT e s m a #
(ErrorComponent e, Stream s, MonadReader r m) => MonadReader r (ParsecT e s m) # |
Methods ask :: ParsecT e s m r # local :: (r -> r) -> ParsecT e s m a -> ParsecT e s m a # reader :: (r -> a) -> ParsecT e s m a #
(ErrorComponent e, Stream s, MonadState st m) => MonadState st (ParsecT e s m) # |
Methods get :: ParsecT e s m st # put :: st -> ParsecT e s m () # state :: (st -> (a, st)) -> ParsecT e s m a #
MonadTrans (ParsecT e s) # |
Methods lift :: Monad m => m a -> ParsecT e s m a #
(ErrorComponent e, Stream s) => Monad (ParsecT e s m) # |
Methods (>>=) :: ParsecT e s m a -> (a -> ParsecT e s m b) -> ParsecT e s m b # (>>) :: ParsecT e s m a -> ParsecT e s m b -> ParsecT e s m b # return :: a -> ParsecT e s m a # fail :: String -> ParsecT e s m a #
Functor (ParsecT e s m) # |
Methods fmap :: (a -> b) -> ParsecT e s m a -> ParsecT e s m b # (<$) :: a -> ParsecT e s m b -> ParsecT e s m a #
(ErrorComponent e, Stream s) => MonadFail (ParsecT e s m) # |
Methods fail :: String -> ParsecT e s m a #
(ErrorComponent e, Stream s) => Applicative (ParsecT e s m) # |
Methods pure :: a -> ParsecT e s m a # (<*>) :: ParsecT e s m (a -> b) -> ParsecT e s m a -> ParsecT e s m b # (*>) :: ParsecT e s m a -> ParsecT e s m b -> ParsecT e s m b # (<*) :: ParsecT e s m a -> ParsecT e s m b -> ParsecT e s m a #
(ErrorComponent e, Stream s, MonadIO m) => MonadIO (ParsecT e s m) # |
Methods liftIO :: IO a -> ParsecT e s m a #
(ErrorComponent e, Stream s) => Alternative (ParsecT e s m) # |
Methods empty :: ParsecT e s m a # (<|>) :: ParsecT e s m a -> ParsecT e s m a -> ParsecT e s m a # some :: ParsecT e s m a -> ParsecT e s m [a] # many :: ParsecT e s m a -> ParsecT e s m [a] #
(ErrorComponent e, Stream s) => MonadPlus (ParsecT e s m) # |
Methods mzero :: ParsecT e s m a # mplus :: ParsecT e s m a -> ParsecT e s m a -> ParsecT e s m a #
(ErrorComponent e, Stream s, MonadCont m) => MonadCont (ParsecT e s m) # |
Methods callCC :: ((a -> ParsecT e s m b) -> ParsecT e s m a) -> ParsecT e s m a #
(ErrorComponent e, Stream s, Semigroup a) => Semigroup (ParsecT e s m a) # |
Methods (<>) :: ParsecT e s m a -> ParsecT e s m a -> ParsecT e s m a # sconcat :: NonEmpty (ParsecT e s m a) -> ParsecT e s m a # stimes :: Integral b => b -> ParsecT e s m a -> ParsecT e s m a #
(ErrorComponent e, Stream s, Monoid a) => Monoid (ParsecT e s m a) # |
Methods mempty :: ParsecT e s m a # mappend :: ParsecT e s m a -> ParsecT e s m a -> ParsecT e s m a # mconcat :: [ParsecT e s m a] -> ParsecT e s m a #

parse #

Arguments

:: Parsec e s a | Parser to run
-> String | Name of source file
-> s | Input for parser
-> Either (ParseError (Token s) e) a |

`parse p file input` runs parser `p` over `Identity` (see `runParserT` if you're using the `ParsecT` monad transformer; `parse` itself is just a synonym for `runParser`). It returns either a `ParseError` (`Left`) or a value of type `a` (`Right`). `parseErrorPretty` can be used to turn `ParseError` into the string representation of the error message. See Text.Megaparsec.Error if you need to do more advanced error analysis.

    main = case (parse numbers "" "11,2,43") of
             Left err -> putStr (parseErrorPretty err)
             Right xs -> print (sum xs)

    numbers = integer `sepBy` char ','

parseMaybe :: (ErrorComponent e, Stream s) => Parsec e s a -> s -> Maybe a #

`parseMaybe p input` runs the parser `p` on `input` and returns the result inside `Just` on success and `Nothing` on failure. This function also parses `eof`, so if the parser doesn't consume all of its input, it will fail.

The function is supposed to be useful for lightweight parsing, where error messages (and thus file name) are not important and entire input should be parsed. For example it can be used when parsing of a single number according to specification of its format is desired.

parseTest #

Arguments

:: (ShowErrorComponent e, Ord (Token s), ShowToken (Token s), Show a) |
=> Parsec e s a | Parser to run
-> s | Input for parser
-> IO () |

The expression `parseTest p input` applies the parser `p` against input `input` and prints the result to stdout. Useful for testing.

runParser #

Arguments

:: Parsec e s a | Parser to run
-> String | Name of source file
-> s | Input for parser
-> Either (ParseError (Token s) e) a |

`runParser p file input` runs parser `p` on the input stream of tokens `input`, obtained from source `file`. The `file` is only used in error messages and may be the empty string. Returns either a `ParseError` (`Left`) or a value of type `a` (`Right`).

    parseFromFile p file = runParser p file <$> readFile file

runParser' #

Arguments

:: Parsec e s a | Parser to run
-> State s | Initial state
-> (State s, Either (ParseError (Token s) e) a) |

The function is similar to `runParser` with the difference that it accepts and returns parser state. This allows to specify arbitrary textual position at the beginning of parsing, for example. This is the most general way to run a parser over the `Identity` monad.

Since: 4.2.0

runParserT #

Arguments

:: Monad m |
=> ParsecT e s m a | Parser to run
-> String | Name of source file
-> s | Input for parser
-> m (Either (ParseError (Token s) e) a) |

`runParserT p file input` runs parser `p` on the input list of tokens `input`, obtained from source `file`. The `file` is only used in error messages and may be the empty string. Returns a computation in the underlying monad `m` that returns either a `ParseError` (`Left`) or a value of type `a` (`Right`).

runParserT' #

Arguments

:: Monad m |
=> ParsecT e s m a | Parser to run
-> State s | Initial state
-> m (State s, Either (ParseError (Token s) e) a) |

This function is similar to `runParserT`, but like `runParser'` it accepts and returns parser state. This is thus the most general way to run a parser.

Since: 4.2.0

# Combinators

(<|>) :: Alternative f => forall a. f a -> f a -> f a #

An associative binary operation

This combinator implements choice. The parser `p <|> q` first applies `p`. If it succeeds, the value of `p` is returned. If `p` fails without consuming any input, parser `q` is tried.

The parser is called predictive since `q` is only tried when parser `p` didn't consume any input (i.e. the look ahead is 1). This non-backtracking behaviour allows for both an efficient implementation of the parser combinators and the generation of good error messages.

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

Zero or more.

`many p` applies the parser `p` zero or more times and returns a list of the returned values of `p`. Note that if the `p` parser fails consuming input, then the entire `many p` parser fails with the error message `p` produced instead of just stopping iterating. In these cases wrapping `p` with `try` may be desirable.

    identifier = (:) <$> letter <*> many (alphaNumChar <|> char '_')

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

One or more.

`some p` applies the parser `p` one or more times and returns a list of the returned values of `p`. The note about behavior of the combinator in the case when `p` fails consuming input (see `many`) applies to `some` as well.

    word = some letter

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

One or none.

`optional p` tries to apply the parser `p`. It will parse `p` or nothing. It only fails if `p` fails after consuming input. On success result of `p` is returned inside of `Just`, on failure `Nothing` is returned.

unexpected :: MonadParsec e s m => ErrorItem (Token s) -> m a #

The parser `unexpected item` fails with an error message telling about unexpected item `item` without consuming any input.

match :: MonadParsec e s m => m a -> m ([Token s], a) #

Return both the result of a parse and the list of tokens that were consumed during parsing. This relies on the change of the `stateTokensProcessed` value to evaluate how many tokens were consumed.

Since: 5.3.0

region #

Arguments

:: MonadParsec e s m |
=> (ParseError (Token s) e -> ParseError (Token s) e) | How to process `ParseError`s
-> m a | The “region” that processing applies to
-> m a |

Specify how to process `ParseError`s that happen inside of this wrapper. As a side effect of the current implementation changing `errorPos` with this combinator will also change the final `statePos` in the parser state.

Since: 5.3.0

failure :: MonadParsec e s m => Set (ErrorItem (Token s)) -> Set (ErrorItem (Token s)) -> Set e -> m a #

The most general way to stop parsing and report a `ParseError`.

`unexpected` is defined in terms of this function:

    unexpected item = failure (Set.singleton item) Set.empty Set.empty

Since: 4.2.0

(<?>) :: MonadParsec e s m => m a -> String -> m a infix 0 #

A synonym for `label` in the form of an operator.

label :: MonadParsec e s m => String -> m a -> m a #

The parser `label name p` behaves as parser `p`, but whenever the parser `p` fails without consuming any input, it replaces names of “expected” tokens with the name `name`.

hidden :: MonadParsec e s m => m a -> m a #

`hidden p` behaves just like parser `p`, but it doesn't show any “expected” tokens in error message when `p` fails.

try :: MonadParsec e s m => m a -> m a #

The parser `try p` behaves like parser `p`, except that it backtracks the parser state when `p` fails (either consuming input or not).

This combinator is used whenever arbitrary look ahead is needed. Since it pretends that it hasn't consumed any input when `p` fails, the (`<|>`) combinator will try its second alternative even when the first parser failed while consuming input.

For example, here is a parser that is supposed to parse the word “let” or the word “lexical”:

    >>> parseTest (string "let" <|> string "lexical") "lexical"
    1:1:
    unexpected "lex"
    expecting "let"

What happens here? The first parser consumes “le” and fails (because it doesn't see a “t”). The second parser, however, isn't tried, since the first parser has already consumed some input! `try` fixes this behavior and allows backtracking to work:

    >>> parseTest (try (string "let") <|> string "lexical") "lexical"
    "lexical"

`try` also improves error messages in case of overlapping alternatives, because Megaparsec's hint system can be used:

    >>> parseTest (try (string "let") <|> string "lexical") "le"
    1:1:
    unexpected "le"
    expecting "let" or "lexical"

Please note that as of Megaparsec 4.4.0, `string` backtracks automatically (see `tokens`), so it does not need `try`. However, the examples above demonstrate the idea behind `try` so well that it was decided to keep them. You still need to use `try` when your alternatives are complex, composite parsers.

lookAhead :: MonadParsec e s m => m a -> m a #

If `p` in `lookAhead p` succeeds (either consuming input or not) the whole parser behaves like `p` succeeded without consuming anything (parser state is not updated as well). If `p` fails, `lookAhead` has no effect, i.e. it will fail consuming input if `p` fails consuming input. Combine with `try` if this is undesirable.

notFollowedBy :: MonadParsec e s m => m a -> m () #

`notFollowedBy p` only succeeds when the parser `p` fails. This parser never consumes any input and never modifies parser state. It can be used to implement the “longest match” rule.

withRecovery :: MonadParsec e s m => (ParseError (Token s) e -> m a) -> m a -> m a #

`withRecovery r p` allows continue parsing even if parser `p` fails. In this case `r` is called with the actual `ParseError` as its argument. Typical usage is to return a value signifying failure to parse this particular object and to consume some part of the input up to the point where the next object starts.

Note that if `r` fails, original error message is reported as if without `withRecovery`. In no way recovering parser `r` can influence error messages.

Since: 4.4.0

observing :: MonadParsec e s m => m a -> m (Either (ParseError (Token s) e) a) #

`observing p` allows to “observe” failure of the `p` parser, should it happen, without actually ending parsing, but instead getting the `ParseError` in `Left`. On success parsed value is returned in `Right` as usual. Note that this primitive just allows you to observe parse errors as they happen, it does not backtrack or change how the `p` parser works in any way.

Since: 5.1.0

eof :: MonadParsec e s m => m () #

This parser only succeeds at the end of the input.

token :: MonadParsec e s m => (Token s -> Either (Set (ErrorItem (Token s)), Set (ErrorItem (Token s)), Set e) a) -> Maybe (Token s) -> m a #

The parser `token test mrep` accepts a token `t` with result `x` when the function `test t` returns ``Right` x`. `mrep` may provide representation of the token to report in error messages when input stream in empty.

This is the most primitive combinator for accepting tokens. For example, the `satisfy` parser is implemented as:

    satisfy f = token testChar Nothing
      where
        testChar x =
          if f x
            then Right x
            else Left (Set.singleton (Tokens (x:|[])), Set.empty, Set.empty)

tokens :: MonadParsec e s m => (Token s -> Token s -> Bool) -> [Token s] -> m [Token s] #

The parser `tokens test` parses a list of tokens and returns it. Supplied predicate `test` is used to check equality of given and parsed tokens.

This can be used for example to write `string`:

    string = tokens (==)

Note that beginning from Megaparsec 4.4.0, this is an auto-backtracking primitive, which means that if it fails, it never consumes any input. This is done to make its consumption model match how error messages for this primitive are reported (which becomes an important thing as user gets more control with primitives like `withRecovery`):

    >>> parseTest (string "abc") "abd"
    1:1:
    unexpected "abd"
    expecting "abc"

This means, in particular, that it's no longer necessary to use `try` with `tokens`-based parsers, such as `string` and `string'`. This feature does not affect performance in any way.

between :: Applicative m => m open -> m close -> 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 "}")

choice :: (Foldable f, Alternative m) => f (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.

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.

count' :: Alternative m => Int -> Int -> m a -> m [a] #

`count' m n p` parses from `m` to `n` occurrences of `p`. If `n` is not positive or `m > n`, the parser equals to `return []`. Returns a list of parsed values.

Please note that `m` may be negative, in this case effect is the same as if it were equal to zero.

eitherP :: Alternative m => m a -> m b -> m (Either a b) #

Combine two alternatives.

Since: 4.4.0

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` semicolon

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`.

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 = string "<!--" >> manyTill anyChar (string "-->")

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

`someTill p end` works similarly to `manyTill p end`, but `p` should succeed at least once.

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

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

    priority = option 0 (digitToInt <$> digitChar)

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` comma

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`.

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`. Returns a 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`.

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

`skipMany p` applies the parser `p` zero or more times, skipping its result.

    space = skipMany spaceChar

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

`skipSome p` applies the parser `p` one or more times, skipping its result.

# Character parsing

newline :: (MonadParsec e s m, Token s ~ Char) => m Char #

Parse a newline character.

crlf :: (MonadParsec e s m, Token s ~ Char) => m String #

Parse a carriage return character followed by a newline character. Return the sequence of characters parsed.

eol :: (MonadParsec e s m, Token s ~ Char) => m String #

Parse a CRLF (see `crlf`) or LF (see `newline`) end of line. Return the sequence of characters parsed.

    eol = (pure <$> newline) <|> crlf <?> "end of line"

tab :: (MonadParsec e s m, Token s ~ Char) => m Char #

Parse a tab character.

space :: (MonadParsec e s m, Token s ~ Char) => m () #

Skip zero or more white space characters.

See also: `skipMany` and `spaceChar`.

controlChar :: (MonadParsec e s m, Token s ~ Char) => m Char #

Parse a control character (a non-printing character of the Latin-1 subset of Unicode).

spaceChar :: (MonadParsec e s m, Token s ~ Char) => m Char #

Parse a Unicode space character, and the control characters: tab, newline, carriage return, form feed, and vertical tab.

upperChar :: (MonadParsec e s m, Token s ~ Char) => m Char #

Parse an upper-case or title-case alphabetic Unicode character. Title case is used by a small number of letter ligatures like the single-character form of Lj.

lowerChar :: (MonadParsec e s m, Token s ~ Char) => m Char #

Parse a lower-case alphabetic Unicode character.

letterChar :: (MonadParsec e s m, Token s ~ Char) => m Char #

Parse an alphabetic Unicode character: lower-case, upper-case, or title-case letter, or a letter of case-less scripts/modifier letter.

alphaNumChar :: (MonadParsec e s m, Token s ~ Char) => m Char #

Parse an alphabetic or numeric digit Unicode characters.

Note that the numeric digits outside the ASCII range are parsed by this parser but not by `digitChar`. Such digits may be part of identifiers but are not used by the printer and reader to represent numbers.

printChar :: (MonadParsec e s m, Token s ~ Char) => m Char #

Parse a printable Unicode character: letter, number, mark, punctuation, symbol or space.

digitChar :: (MonadParsec e s m, Token s ~ Char) => m Char #

Parse an ASCII digit, i.e between “0” and “9”.

octDigitChar :: (MonadParsec e s m, Token s ~ Char) => m Char #

Parse an octal digit, i.e. between “0” and “7”.

hexDigitChar :: (MonadParsec e s m, Token s ~ Char) => m Char #

Parse a hexadecimal digit, i.e. between “0” and “9”, or “a” and “f”, or “A” and “F”.

markChar :: (MonadParsec e s m, Token s ~ Char) => m Char #

Parse a Unicode mark character (accents and the like), which combines with preceding characters.

numberChar :: (MonadParsec e s m, Token s ~ Char) => m Char #

Parse a Unicode numeric character, including digits from various scripts, Roman numerals, etc.

punctuationChar :: (MonadParsec e s m, Token s ~ Char) => m Char #

Parse a Unicode punctuation character, including various kinds of connectors, brackets and quotes.

symbolChar :: (MonadParsec e s m, Token s ~ Char) => m Char #

Parse a Unicode symbol characters, including mathematical and currency symbols.

separatorChar :: (MonadParsec e s m, Token s ~ Char) => m Char #

Parse a Unicode space and separator characters.

asciiChar :: (MonadParsec e s m, Token s ~ Char) => m Char #

Parse a character from the first 128 characters of the Unicode character set, corresponding to the ASCII character set.

latin1Char :: (MonadParsec e s m, Token s ~ Char) => m Char #

Parse a character from the first 256 characters of the Unicode character set, corresponding to the ISO 8859-1 (Latin-1) character set.

charCategory :: (MonadParsec e s m, Token s ~ Char) => GeneralCategory -> m Char #

`charCategory cat` parses character in Unicode General Category `cat`, see `GeneralCategory`.

char :: (MonadParsec e s m, Token s ~ Char) => Char -> m Char #

`char c` parses a single character `c`.

    semicolon = char ';'

char' :: (MonadParsec e s m, Token s ~ Char) => Char -> m Char #

The same as `char` but case-insensitive. This parser returns the actually parsed character preserving its case.

    >>> parseTest (char' 'e') "E"
    'E'
    >>> parseTest (char' 'e') "G"
    1:1:
    unexpected 'G'
    expecting 'E' or 'e'

anyChar :: (MonadParsec e s m, Token s ~ Char) => m Char #

This parser succeeds for any character. Returns the parsed character.

oneOf :: (Foldable f, MonadParsec e s m, Token s ~ Char) => f Char -> m Char #

`oneOf cs` succeeds if the current character is in the supplied collection of characters `cs`. Returns the parsed character. Note that this parser cannot automatically generate the “expected” component of error message, so usually you should label it manually with `label` or (`<?>`).

See also: `satisfy`.

    digit = oneOf ['0'..'9'] <?> "digit"

oneOf' :: (Foldable f, MonadParsec e s m, Token s ~ Char) => f Char -> m Char #

The same as `oneOf`, but case-insensitive. Returns the parsed character preserving its case.

    vowel = oneOf' "aeiou" <?> "vowel"

noneOf :: (Foldable f, MonadParsec e s m, Token s ~ Char) => f Char -> m Char #

As the dual of `oneOf`, `noneOf cs` succeeds if the current character not in the supplied list of characters `cs`. Returns the parsed character.

noneOf' :: (Foldable f, MonadParsec e s m, Token s ~ Char) => f Char -> m Char #

The same as `noneOf`, but case-insensitive.

    consonant = noneOf' "aeiou" <?> "consonant"

satisfy :: (MonadParsec e s m, Token s ~ Char) => (Char -> Bool) -> m Char #

The parser `satisfy f` succeeds for any character for which the supplied function `f` returns `True`. Returns the character that is actually parsed.

    digitChar = satisfy isDigit <?> "digit"
    oneOf cs  = satisfy (`elem` cs)

string :: (MonadParsec e s m, Token s ~ Char) => String -> m String #

`string s` parses a sequence of characters given by `s`. Returns the parsed string (i.e. `s`).

    divOrMod = string "div" <|> string "mod"

string' :: (MonadParsec e s m, Token s ~ Char) => String -> m String #

The same as `string`, but case-insensitive. On success returns string cased as actually parsed input.

    >>> parseTest (string' "foobar") "foObAr"
    "foObAr"

# Textual source position

data Pos #

Positive integer that is used to represent line number, column number, and similar things like indentation level. `Semigroup` instance can be used to safely and purely add `Pos`es together.

Since: 5.0.0

Instances

Eq Pos # |
Methods (==) :: Pos -> Pos -> Bool # (/=) :: Pos -> Pos -> Bool #
Data Pos # |
Methods gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> Pos -> c Pos # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c Pos # toConstr :: Pos -> Constr # dataTypeOf :: Pos -> DataType # dataCast1 :: Typeable (* -> *) t => (forall d. Data d => c (t d)) -> Maybe (c Pos) # dataCast2 :: Typeable (* -> * -> *) t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Pos) # gmapT :: (forall b. Data b => b -> b) -> Pos -> Pos # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Pos -> r # gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Pos -> r # gmapQ :: (forall d. Data d => d -> u) -> Pos -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> Pos -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> Pos -> m Pos # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> Pos -> m Pos # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> Pos -> m Pos #
Ord Pos # |
Methods compare :: Pos -> Pos -> Ordering # (<) :: Pos -> Pos -> Bool # (<=) :: Pos -> Pos -> Bool # (>) :: Pos -> Pos -> Bool # (>=) :: Pos -> Pos -> Bool # max :: Pos -> Pos -> Pos # min :: Pos -> Pos -> Pos #
Read Pos # |
Methods readsPrec :: Int -> ReadS Pos # readList :: ReadS [Pos] # readPrec :: ReadPrec Pos # readListPrec :: ReadPrec [Pos] #
Show Pos # |
Methods showsPrec :: Int -> Pos -> ShowS # show :: Pos -> String # showList :: [Pos] -> ShowS #
Semigroup Pos # |
Methods (<>) :: Pos -> Pos -> Pos # sconcat :: NonEmpty Pos -> Pos # stimes :: Integral b => b -> Pos -> Pos #
Arbitrary Pos # |
Methods arbitrary :: Gen Pos # shrink :: Pos -> [Pos] #
NFData Pos # |
Methods rnf :: Pos -> () #

mkPos :: (Integral a, MonadThrow m) => a -> m Pos #

Construction of `Pos` from an instance of `Integral`. The function throws `InvalidPosException` when given non-positive argument. Note that the function is polymorphic with respect to `MonadThrow` `m`, so you can get result inside of `Maybe`, for example.

Since: 5.0.0

unPos :: Pos -> Word #

Extract `Word` from `Pos`.

Since: 5.0.0

unsafePos :: Word -> Pos #

Dangerous construction of `Pos`. Use when you know for sure that argument is positive.

Since: 5.0.0

data InvalidPosException #

The exception is thrown by `mkPos` when its argument is not a positive number.

Since: 5.0.0

Constructors

InvalidPosException |

Instances

Eq InvalidPosException # |
Methods (==) :: InvalidPosException -> InvalidPosException -> Bool # (/=) :: InvalidPosException -> InvalidPosException -> Bool #
Data InvalidPosException # |
Methods gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> InvalidPosException -> c InvalidPosException # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c InvalidPosException # toConstr :: InvalidPosException -> Constr # dataTypeOf :: InvalidPosException -> DataType # dataCast1 :: Typeable (* -> *) t => (forall d. Data d => c (t d)) -> Maybe (c InvalidPosException) # dataCast2 :: Typeable (* -> * -> *) t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c InvalidPosException) # gmapT :: (forall b. Data b => b -> b) -> InvalidPosException -> InvalidPosException # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> InvalidPosException -> r # gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> InvalidPosException -> r # gmapQ :: (forall d. Data d => d -> u) -> InvalidPosException -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> InvalidPosException -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> InvalidPosException -> m InvalidPosException # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> InvalidPosException -> m InvalidPosException # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> InvalidPosException -> m InvalidPosException #
Show InvalidPosException # |
Methods showsPrec :: Int -> InvalidPosException -> ShowS # show :: InvalidPosException -> String # showList :: [InvalidPosException] -> ShowS #
Generic InvalidPosException # |
Associated Types type Rep InvalidPosException :: * -> * # Methods from :: InvalidPosException -> Rep InvalidPosException x # to :: Rep InvalidPosException x -> InvalidPosException #
Exception InvalidPosException # |
Methods toException :: InvalidPosException -> SomeException # fromException :: SomeException -> Maybe InvalidPosException # displayException :: InvalidPosException -> String #
NFData InvalidPosException # |
Methods rnf :: InvalidPosException -> () #
type Rep InvalidPosException # |
type Rep InvalidPosException = D1 (MetaData "InvalidPosException" "Text.Megaparsec.Pos" "megaparsec-5.3.1-GxZCUFyxxwCHfCqiAPkdT1" False) (C1 (MetaCons "InvalidPosException" PrefixI False) U1)

data SourcePos #

The data type `SourcePos` represents source positions. It contains the name of the source file, a line number, and a column number. Source line and column positions change intensively during parsing, so we need to make them strict to avoid memory leaks.

Constructors

SourcePos |
Fields sourceName :: FilePath Name of source file sourceLine :: !Pos Line number sourceColumn :: !Pos Column number

Instances

Eq SourcePos # |
Methods (==) :: SourcePos -> SourcePos -> Bool # (/=) :: SourcePos -> SourcePos -> Bool #
Data SourcePos # |
Methods gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> SourcePos -> c SourcePos # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c SourcePos # toConstr :: SourcePos -> Constr # dataTypeOf :: SourcePos -> DataType # dataCast1 :: Typeable (* -> *) t => (forall d. Data d => c (t d)) -> Maybe (c SourcePos) # dataCast2 :: Typeable (* -> * -> *) t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c SourcePos) # gmapT :: (forall b. Data b => b -> b) -> SourcePos -> SourcePos # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> SourcePos -> r # gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> SourcePos -> r # gmapQ :: (forall d. Data d => d -> u) -> SourcePos -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> SourcePos -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> SourcePos -> m SourcePos # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> SourcePos -> m SourcePos # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> SourcePos -> m SourcePos #
Ord SourcePos # |
Methods compare :: SourcePos -> SourcePos -> Ordering # (<) :: SourcePos -> SourcePos -> Bool # (<=) :: SourcePos -> SourcePos -> Bool # (>) :: SourcePos -> SourcePos -> Bool # (>=) :: SourcePos -> SourcePos -> Bool # max :: SourcePos -> SourcePos -> SourcePos # min :: SourcePos -> SourcePos -> SourcePos #
Read SourcePos # |
Methods readsPrec :: Int -> ReadS SourcePos # readList :: ReadS [SourcePos] # readPrec :: ReadPrec SourcePos # readListPrec :: ReadPrec [SourcePos] #
Show SourcePos # |
Methods showsPrec :: Int -> SourcePos -> ShowS # show :: SourcePos -> String # showList :: [SourcePos] -> ShowS #
Generic SourcePos # |
Associated Types type Rep SourcePos :: * -> * # Methods from :: SourcePos -> Rep SourcePos x # to :: Rep SourcePos x -> SourcePos #
Arbitrary SourcePos # |
Methods arbitrary :: Gen SourcePos # shrink :: SourcePos -> [SourcePos] #
NFData SourcePos # |
Methods rnf :: SourcePos -> () #
type Rep SourcePos # |
type Rep SourcePos = D1 (MetaData "SourcePos" "Text.Megaparsec.Pos" "megaparsec-5.3.1-GxZCUFyxxwCHfCqiAPkdT1" False) (C1 (MetaCons "SourcePos" PrefixI True) ((:*:) (S1 (MetaSel (Just Symbol "sourceName") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 FilePath)) ((:*:) (S1 (MetaSel (Just Symbol "sourceLine") NoSourceUnpackedness SourceStrict DecidedUnpack) (Rec0 Pos)) (S1 (MetaSel (Just Symbol "sourceColumn") NoSourceUnpackedness SourceStrict DecidedUnpack) (Rec0 Pos)))))

initialPos :: String -> SourcePos #

Construct initial position (line 1, column 1) given name of source file.

sourcePosPretty :: SourcePos -> String #

Pretty-print a `SourcePos`.

Since: 5.0.0

# Error messages

data ErrorItem t #

Data type that is used to represent “unexpected/expected” items in `ParseError`. The data type is parametrized over the token type `t`.

Since: 5.0.0

Constructors

Tokens (NonEmpty t) | Non-empty stream of tokens
Label (NonEmpty Char) | Label (cannot be empty)
EndOfInput | End of input

Instances

Eq t => Eq (ErrorItem t) # |
Methods (==) :: ErrorItem t -> ErrorItem t -> Bool # (/=) :: ErrorItem t -> ErrorItem t -> Bool #
Data t => Data (ErrorItem t) # |
Methods gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> ErrorItem t -> c (ErrorItem t) # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c (ErrorItem t) # toConstr :: ErrorItem t -> Constr # dataTypeOf :: ErrorItem t -> DataType # dataCast1 :: Typeable (* -> *) t => (forall d. Data d => c (t d)) -> Maybe (c (ErrorItem t)) # dataCast2 :: Typeable (* -> * -> *) t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (ErrorItem t)) # gmapT :: (forall b. Data b => b -> b) -> ErrorItem t -> ErrorItem t # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> ErrorItem t -> r # gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> ErrorItem t -> r # gmapQ :: (forall d. Data d => d -> u) -> ErrorItem t -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> ErrorItem t -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> ErrorItem t -> m (ErrorItem t) # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> ErrorItem t -> m (ErrorItem t) # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> ErrorItem t -> m (ErrorItem t) #
Ord t => Ord (ErrorItem t) # |
Methods compare :: ErrorItem t -> ErrorItem t -> Ordering # (<) :: ErrorItem t -> ErrorItem t -> Bool # (<=) :: ErrorItem t -> ErrorItem t -> Bool # (>) :: ErrorItem t -> ErrorItem t -> Bool # (>=) :: ErrorItem t -> ErrorItem t -> Bool # max :: ErrorItem t -> ErrorItem t -> ErrorItem t # min :: ErrorItem t -> ErrorItem t -> ErrorItem t #
Read t => Read (ErrorItem t) # |
Methods readsPrec :: Int -> ReadS (ErrorItem t) # readList :: ReadS [ErrorItem t] # readPrec :: ReadPrec (ErrorItem t) # readListPrec :: ReadPrec [ErrorItem t] #
Show t => Show (ErrorItem t) # |
Methods showsPrec :: Int -> ErrorItem t -> ShowS # show :: ErrorItem t -> String # showList :: [ErrorItem t] -> ShowS #
Generic (ErrorItem t) # |
Associated Types type Rep (ErrorItem t) :: * -> * # Methods from :: ErrorItem t -> Rep (ErrorItem t) x # to :: Rep (ErrorItem t) x -> ErrorItem t #
Arbitrary t => Arbitrary (ErrorItem t) # |
Methods arbitrary :: Gen (ErrorItem t) # shrink :: ErrorItem t -> [ErrorItem t] #
NFData t => NFData (ErrorItem t) # |
Methods rnf :: ErrorItem t -> () #
(Ord t, ShowToken t) => ShowErrorComponent (ErrorItem t) # |
Methods showErrorComponent :: ErrorItem t -> String #
type Rep (ErrorItem t) # |
type Rep (ErrorItem t) = D1 (MetaData "ErrorItem" "Text.Megaparsec.Error" "megaparsec-5.3.1-GxZCUFyxxwCHfCqiAPkdT1" False) ((:+:) (C1 (MetaCons "Tokens" PrefixI False) (S1 (MetaSel (Nothing Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 (NonEmpty t)))) ((:+:) (C1 (MetaCons "Label" PrefixI False) (S1 (MetaSel (Nothing Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 (NonEmpty Char)))) (C1 (MetaCons "EndOfInput" PrefixI False) U1)))

class Ord e => ErrorComponent e where #

The type class defines how to represent information about various exceptional situations. Data types that are used as custom data component in `ParseError` must be instances of this type class.

Since: 5.0.0

Minimal complete definition

representFail, representIndentation

Methods

representFail :: String -> e #

Represent the message passed to `fail` in parser monad.

Since: 5.0.0

representIndentation :: Ordering -> Pos -> Pos -> e #

Represent information about incorrect indentation.

Since: 5.0.0

Instances

ErrorComponent () # |
Methods representFail :: String -> () # representIndentation :: Ordering -> Pos -> Pos -> () #
ErrorComponent Dec # |
Methods representFail :: String -> Dec # representIndentation :: Ordering -> Pos -> Pos -> Dec #

data Dec #

“Default error component”. This is our instance of `ErrorComponent` provided out-of-box.

Since: 5.0.0

Constructors

DecFail String | `fail` has been used in parser monad
DecIndentation Ordering Pos Pos | Incorrect indentation error: desired ordering between reference level and actual level, reference indentation level, actual indentation level

Instances

Eq Dec # |
Methods (==) :: Dec -> Dec -> Bool # (/=) :: Dec -> Dec -> Bool #
Data Dec # |
Methods gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> Dec -> c Dec # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c Dec # toConstr :: Dec -> Constr # dataTypeOf :: Dec -> DataType # dataCast1 :: Typeable (* -> *) t => (forall d. Data d => c (t d)) -> Maybe (c Dec) # dataCast2 :: Typeable (* -> * -> *) t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Dec) # gmapT :: (forall b. Data b => b -> b) -> Dec -> Dec # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Dec -> r # gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Dec -> r # gmapQ :: (forall d. Data d => d -> u) -> Dec -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> Dec -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> Dec -> m Dec # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> Dec -> m Dec # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> Dec -> m Dec #
Ord Dec # |
Methods compare :: Dec -> Dec -> Ordering # (<) :: Dec -> Dec -> Bool # (<=) :: Dec -> Dec -> Bool # (>) :: Dec -> Dec -> Bool # (>=) :: Dec -> Dec -> Bool # max :: Dec -> Dec -> Dec # min :: Dec -> Dec -> Dec #
Read Dec # |
Methods readsPrec :: Int -> ReadS Dec # readList :: ReadS [Dec] # readPrec :: ReadPrec Dec # readListPrec :: ReadPrec [Dec] #
Show Dec # |
Methods showsPrec :: Int -> Dec -> ShowS # show :: Dec -> String # showList :: [Dec] -> ShowS #
Arbitrary Dec # |
Methods arbitrary :: Gen Dec # shrink :: Dec -> [Dec] #
NFData Dec # |
Methods rnf :: Dec -> () #
ShowErrorComponent Dec # |
Methods showErrorComponent :: Dec -> String #
ErrorComponent Dec # |
Methods representFail :: String -> Dec # representIndentation :: Ordering -> Pos -> Pos -> Dec #

data ParseError t e #

`ParseError` represents… parse errors. It provides the stack of source positions, a set of expected and unexpected tokens as well as a set of custom associated data. The data type is parametrized over the token type `t` and the custom data `e`.

Note that the stack of source positions contains current position as its head, and the rest of positions allows to track full sequence of include files with topmost source file at the end of the list.

`Semigroup` (and `Monoid`) instance of the data type allows to merge parse errors from different branches of parsing. When merging two `ParseError`s, the longest match is preferred; if positions are the same, custom data sets and collections of message items are combined.

Constructors

ParseError |
Fields errorPos :: NonEmpty SourcePos Stack of source positions errorUnexpected :: Set (ErrorItem t) Unexpected items errorExpected :: Set (ErrorItem t) Expected items errorCustom :: Set e Associated data, if any

Instances

(Eq e, Eq t) => Eq (ParseError t e) # |
Methods (==) :: ParseError t e -> ParseError t e -> Bool # (/=) :: ParseError t e -> ParseError t e -> Bool #
(Ord e, Ord t, Data e, Data t) => Data (ParseError t e) # |
Methods gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> ParseError t e -> c (ParseError t e) # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c (ParseError t e) # toConstr :: ParseError t e -> Constr # dataTypeOf :: ParseError t e -> DataType # dataCast1 :: Typeable (* -> *) t => (forall d. Data d => c (t d)) -> Maybe (c (ParseError t e)) # dataCast2 :: Typeable (* -> * -> *) t => (forall d a. (Data d, Data a) => c (t d a)) -> Maybe (c (ParseError t e)) # gmapT :: (forall b. Data b => b -> b) -> ParseError t e -> ParseError t e # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> ParseError t e -> r # gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> ParseError t e -> r # gmapQ :: (forall d. Data d => d -> u) -> ParseError t e -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> ParseError t e -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> ParseError t e -> m (ParseError t e) # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> ParseError t e -> m (ParseError t e) # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> ParseError t e -> m (ParseError t e) #
(Ord e, Ord t, Read e, Read t) => Read (ParseError t e) # |
Methods readsPrec :: Int -> ReadS (ParseError t e) # readList :: ReadS [ParseError t e] # readPrec :: ReadPrec (ParseError t e) # readListPrec :: ReadPrec [ParseError t e] #
(Show e, Show t) => Show (ParseError t e) # |
Methods showsPrec :: Int -> ParseError t e -> ShowS # show :: ParseError t e -> String # showList :: [ParseError t e] -> ShowS #
Generic (ParseError t e) # |
Associated Types type Rep (ParseError t e) :: * -> * # Methods from :: ParseError t e -> Rep (ParseError t e) x # to :: Rep (ParseError t e) x -> ParseError t e #
(Ord t, Ord e) => Semigroup (ParseError t e) # |
Methods (<>) :: ParseError t e -> ParseError t e -> ParseError t e # sconcat :: NonEmpty (ParseError t e) -> ParseError t e # stimes :: Integral b => b -> ParseError t e -> ParseError t e #
(Ord t, Ord e) => Monoid (ParseError t e) # |
Methods mempty :: ParseError t e # mappend :: ParseError t e -> ParseError t e -> ParseError t e # mconcat :: [ParseError t e] -> ParseError t e #
(Arbitrary t, Ord t, Arbitrary e, Ord e) => Arbitrary (ParseError t e) # |
Methods arbitrary :: Gen (ParseError t e) # shrink :: ParseError t e -> [ParseError t e] #
(Show t, Typeable * t, Ord t, ShowToken t, Show e, Typeable * e, ShowErrorComponent e) => Exception (ParseError t e) # |
Methods toException :: ParseError t e -> SomeException # fromException :: SomeException -> Maybe (ParseError t e) # displayException :: ParseError t e -> String #
(NFData t, NFData e) => NFData (ParseError t e) # |
Methods rnf :: ParseError t e -> () #
type Rep (ParseError t e) # |
type Rep (ParseError t e) = D1 (MetaData "ParseError" "Text.Megaparsec.Error" "megaparsec-5.3.1-GxZCUFyxxwCHfCqiAPkdT1" False) (C1 (MetaCons "ParseError" PrefixI True) ((:*:) ((:*:) (S1 (MetaSel (Just Symbol "errorPos") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 (NonEmpty SourcePos))) (S1 (MetaSel (Just Symbol "errorUnexpected") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 (Set (ErrorItem t))))) ((:*:) (S1 (MetaSel (Just Symbol "errorExpected") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 (Set (ErrorItem t)))) (S1 (MetaSel (Just Symbol "errorCustom") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 (Set e))))))

class ShowToken a where #

Type class `ShowToken` includes methods that allow to pretty-print single token as well as stream of tokens. This is used for rendering of error messages.

Minimal complete definition

showTokens

Methods

showTokens :: NonEmpty a -> String #

Pretty-print non-empty stream of tokens. This function is also used to print single tokens (represented as singleton lists).

Since: 5.0.0

Instances

ShowToken Char # |
Methods showTokens :: NonEmpty Char -> String #

class Ord a => ShowErrorComponent a where #

The type class defines how to print custom data component of `ParseError`.

Since: 5.0.0

Minimal complete definition

showErrorComponent

Methods

showErrorComponent :: a -> String #

Pretty-print custom data component of `ParseError`.

Instances

ShowErrorComponent Dec # |
Methods showErrorComponent :: Dec -> String #
(Ord t, ShowToken t) => ShowErrorComponent (ErrorItem t) # |
Methods showErrorComponent :: ErrorItem t -> String #

parseErrorPretty #

Arguments

:: (Ord t, ShowToken t, ShowErrorComponent e) |
=> ParseError t e | Parse error to render
-> String | Result of rendering

Pretty-print a `ParseError`. The rendered `String` always ends with a newline.

The function is defined as:

    parseErrorPretty e =
      sourcePosStackPretty (errorPos e) ++ ":\n" ++ parseErrorTextPretty e

Since: 5.0.0

# Debugging

dbg #

Arguments

:: (Stream s, ShowToken (Token s), ShowErrorComponent e, Show a) |
=> String | Debugging label
-> ParsecT e s m a | Parser to debug
-> ParsecT e s m a | Parser that prints debugging messages

`dbg label p` parser works exactly like `p`, but when it's evaluated it also prints information useful for debugging. The `label` is only used to refer to this parser in the debugging output. This combinator uses the `trace` function from Debug.Trace under the hood.

Typical usage is to wrap every sub-parser in misbehaving parser with `dbg` assigning meaningful labels. Then give it a shot and go through the print-out. As of current version, this combinator prints all available information except for hints, which are probably only interesting to the maintainer of Megaparsec itself and may be quite verbose to output in general. Let me know if you would like to be able to see hints in the debugging output.

The output itself is pretty self-explanatory, although the following abbreviations should be clarified (they are derived from the low-level source code):

- `COK`—“consumed OK”. The parser consumed input and succeeded.
- `CERR`—“consumed error”. The parser consumed input and failed.
- `EOK`—“empty OK”. The parser succeeded without consuming input.
- `EERR`—“empty error”. The parser failed without consuming input.

Finally, it's not possible to lift this function into some monad transformers without introducing surprising behavior (e.g. unexpected state backtracking) or adding otherwise redundant constraints (e.g. `Show` instance for state), so this helper is only available for `ParsecT` monad, not `MonadParsec` in general.

Since: 5.1.0

# Low-level operations

class Ord (Token s) => Stream s where #

An instance of `Stream s` has stream type `s`. Token type is determined by the stream and can be found via `Token` type function.

Minimal complete definition

uncons, updatePos

Associated Types

type Token s :: * #

Type of token in stream.

Since: 5.0.0

Methods

uncons :: s -> Maybe (Token s, s) #

Get next token from the stream. If the stream is empty, return `Nothing`.

updatePos :: Proxy s -> Pos -> SourcePos -> Token s -> (SourcePos, SourcePos) #

Update position in stream given tab width, current position, and current token. The result is a tuple where the first element will be used to report parse errors for current token, while the second element is the incremented position that will be stored in the parser's state. The stored (incremented) position is used whenever position can't be/shouldn't be updated by consuming a token. For example, when using `failure`, we don't grab a new token (we need to fail right were we are now), so error position will be taken from parser's state.

When you work with streams where elements do not contain information about their position in input, the result is usually consists of the third argument unchanged and incremented position calculated with respect to current token. This is how default instances of `Stream` work (they use `defaultUpdatePos`, which may be a good starting point for your own position-advancing function).

When you wish to deal with a stream of tokens where every token “knows” its start and end position in input (for example, you have produced the stream with Happy/Alex), then the best strategy is to use the start position as the actual element position and provide the end position of the token as the incremented one.

Since: 5.0.0

Instances

Stream String # |
Associated Types type Token String :: * # Methods uncons :: String -> Maybe (Token String, String) # updatePos :: Proxy * String -> Pos -> SourcePos -> Token String -> (SourcePos, SourcePos) #
Stream ByteString # |
Associated Types type Token ByteString :: * # Methods uncons :: ByteString -> Maybe (Token ByteString, ByteString) # updatePos :: Proxy * ByteString -> Pos -> SourcePos -> Token ByteString -> (SourcePos, SourcePos) #
Stream ByteString # |
Associated Types type Token ByteString :: * # Methods uncons :: ByteString -> Maybe (Token ByteString, ByteString) # updatePos :: Proxy * ByteString -> Pos -> SourcePos -> Token ByteString -> (SourcePos, SourcePos) #
Stream Text # |
Associated Types type Token Text :: * # Methods uncons :: Text -> Maybe (Token Text, Text) # updatePos :: Proxy * Text -> Pos -> SourcePos -> Token Text -> (SourcePos, SourcePos) #
Stream Text # |
Associated Types type Token Text :: * # Methods uncons :: Text -> Maybe (Token Text, Text) # updatePos :: Proxy * Text -> Pos -> SourcePos -> Token Text -> (SourcePos, SourcePos) #

data State s #

This is the Megaparsec's state, it's parametrized over stream type `s`.

Constructors

State |
Fields stateInput :: s Current input (already processed input is removed from the stream) statePos :: NonEmpty SourcePos Current position (column + line number) with support for include files stateTokensProcessed :: !Word Number of processed tokens so far Since: 5.2.0 stateTabWidth :: Pos Tab width to use

Instances

Eq s => Eq (State s) # |
Methods (==) :: State s -> State s -> Bool # (/=) :: State s -> State s -> Bool #
Data s => Data (State s) # |
Methods gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> State s -> c (State s) # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c (State s) # toConstr :: State s -> Constr # dataTypeOf :: State s -> DataType # dataCast1 :: Typeable (* -> *) t => (forall d. Data d => c (t d)) -> Maybe (c (State s)) # dataCast2 :: Typeable (* -> * -> *) t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (State s)) # gmapT :: (forall b. Data b => b -> b) -> State s -> State s # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> State s -> r # gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> State s -> r # gmapQ :: (forall d. Data d => d -> u) -> State s -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> State s -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> State s -> m (State s) # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> State s -> m (State s) # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> State s -> m (State s) #
Show s => Show (State s) # |
Methods showsPrec :: Int -> State s -> ShowS # show :: State s -> String # showList :: [State s] -> ShowS #
Generic (State s) # |
Associated Types type Rep (State s) :: * -> * # Methods from :: State s -> Rep (State s) x # to :: Rep (State s) x -> State s #
Arbitrary a => Arbitrary (State a) # |
Methods arbitrary :: Gen (State a) # shrink :: State a -> [State a] #
NFData s => NFData (State s) # |
Methods rnf :: State s -> () #
type Rep (State s) # |
type Rep (State s) = D1 (MetaData "State" "Text.Megaparsec.Prim" "megaparsec-5.3.1-GxZCUFyxxwCHfCqiAPkdT1" False) (C1 (MetaCons "State" PrefixI True) ((:*:) ((:*:) (S1 (MetaSel (Just Symbol "stateInput") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 s)) (S1 (MetaSel (Just Symbol "statePos") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 (NonEmpty SourcePos)))) ((:*:) (S1 (MetaSel (Just Symbol "stateTokensProcessed") SourceUnpack SourceStrict DecidedUnpack) (Rec0 Word)) (S1 (MetaSel (Just Symbol "stateTabWidth") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 Pos)))))

getInput :: MonadParsec e s m => m s #

Return the current input.

setInput :: MonadParsec e s m => s -> m () #

`setInput input` continues parsing with `input`. The `getInput` and `setInput` functions can for example be used to deal with include files.

getPosition :: MonadParsec e s m => m SourcePos #

Return the current source position.

See also: `setPosition`, `pushPosition`, `popPosition`, and `SourcePos`.

getNextTokenPosition :: forall e s m. MonadParsec e s m => m (Maybe SourcePos) #

Get the position where the next token in the stream begins. If the stream is empty, return `Nothing`.

Since: 5.3.0

setPosition :: MonadParsec e s m => SourcePos -> m () #

`setPosition pos` sets the current source position to `pos`.

See also: `getPosition`, `pushPosition`, `popPosition`, and `SourcePos`.

pushPosition :: MonadParsec e s m => SourcePos -> m () #

Push a position into stack of positions and continue parsing working with this position. Useful for working with include files and the like.

See also: `getPosition`, `setPosition`, `popPosition`, and `SourcePos`.

Since: 5.0.0

popPosition :: MonadParsec e s m => m () #

Pop a position from the stack of positions unless it only contains one element (in that case the stack of positions remains the same). This is how to return to previous source file after `pushPosition`.

See also: `getPosition`, `setPosition`, `pushPosition`, and `SourcePos`.

Since: 5.0.0

getTokensProcessed :: MonadParsec e s m => m Word #

Get the number of tokens processed so far.

Since: 5.2.0

setTokensProcessed :: MonadParsec e s m => Word -> m () #

Set the number of tokens processed so far.

Since: 5.2.0

getTabWidth :: MonadParsec e s m => m Pos #

Return the tab width. The default tab width is equal to `defaultTabWidth`. You can set a different tab width with the help of `setTabWidth`.

setTabWidth :: MonadParsec e s m => Pos -> m () #

Set tab width. If the argument of the function is not a positive number, `defaultTabWidth` will be used.

getParserState :: MonadParsec e s m => m (State s) #

Return the full parser state as a `State` record.

setParserState :: MonadParsec e s m => State s -> m () #

`setParserState st` sets the parser state to `st`.

updateParserState :: MonadParsec e s m => (State s -> State s) -> m () #

`updateParserState f` applies the function `f` to the parser state.