Parsing.Combinators - purescript-parsing - Pursuit (original) (raw)

Package

purescript-parsing

Repository

purescript-contrib/purescript-parsing

A “parser combinator” is a function which takes some parsers as arguments and returns a new parser.

Combinators in other packages

Many variations of well-known monadic and applicative combinators used for parsing are defined in other PureScript packages. We list some of them here.

If you use a combinator from some other package for parsing, keep in mind this surprising truth about the parsing package: All other combinators used with this package will be stack-safe, but usually the combinators with a MonadRec constraint will run faster. So you should prefer MonadRec versions of combinators, but for reasons of speed, not stack-safety.

Data.Array

The many and many1 combinators in the Parsing.Combinators.Arraymodule are faster.

Data.List

The many and many1 combinators in this package are redeclarations of the manyRec and someRec combinators in Data.List.

Data.List.Lazy

Combinators in this package

the replicateA and replicateM combinators are re-exported from this module. replicateA n p or replicateM n pwill repeat parser p exactly n times. The replicateA combinator can produce either an Array or a List.

#try Source

try :: forall m s a. ParserT s m a -> ParserT s m a

If the parser fails then backtrack the input stream to the unconsumed state.

One use for this combinator is to ensure that the right parser of an alternative will always be tried when the left parser fails.

>>> runParser "ac" ((char 'a' *> char 'b') <|> (char 'a' *> char 'c'))
Left (ParseError "Expected 'b'" (Position { line: 1, column: 2 }))

>>> runParser "ac" (try (char 'a' *> char 'b') <|> (char 'a' *> char 'c'))
Right 'c'

#tryRethrow Source

tryRethrow :: forall m s a. ParserT s m a -> ParserT s m a

If the parser fails then backtrack the input stream to the unconsumed state.

Like try, but will reposition the error to the try point.

>>> runParser "ac" (try (char 'a' *> char 'b'))
Left (ParseError "Expected 'b'" (Position { index: 1, line: 1, column: 2 }))

>>> runParser "ac" (tryRethrow (char 'a' *> char 'b'))
Left (ParseError "Expected 'b'" (Position { index: 0, line: 1, column: 1 }))

#between Source

between :: forall m s a open close. ParserT s m open -> ParserT s m close -> ParserT s m a -> ParserT s m a

Wrap a parser with opening and closing markers.

For example:

parens = between (string "(") (string ")")

#option Source

option :: forall m s a. a -> ParserT s m a -> ParserT s m a

Provide a default result in the case where a parser fails without consuming input.

#optional Source

optional :: forall m s a. ParserT s m a -> ParserT s m Unit

Optionally parse something, failing quietly.

To optionally parse p and never fail: optional (try p).

#many Source

many :: forall s m a. ParserT s m a -> ParserT s m (List a)

Match the phrase p as many times as possible.

If p never consumes input when it fails then many p will always succeed, but may return an empty list.

#manyTill_ Source

manyTill_ :: forall s a m e. ParserT s m a -> ParserT s m e -> ParserT s m (Tuple (List a) e)

Parse many phrases until the terminator phrase matches. Returns the list of phrases and the terminator phrase.

Non-greedy repetition

Use the manyTill_ combinator to do non-greedy repetition of a pattern p, like we would in Regex by writing p*?. To repeat pattern p non-greedily, writemanyTill_ p q where q is the entire rest of the parser.

For example, this parse fails because many repeats the pattern lettergreedily.

runParser "aab" do
  a <- many letter
  b <- char 'b'
  pure (Tuple a b)
(ParseError "Expected 'b'" (Position { line: 1, column: 4 }))

To repeat pattern letter non-greedily, use manyTill_.

runParser "aab" do
  Tuple a b <- manyTill_ letter do
    char 'b'
  pure (Tuple a b)
(Tuple ('a' : 'a' : Nil) 'b')

#manyIndex Source

manyIndex :: forall s m a. Int -> Int -> (Int -> ParserT s m a) -> ParserT s m (Tuple Int (List a))

Parse the phrase as many times as possible, at least N times, but no more than M times. If the phrase can’t parse as least N times then the whole parser fails. If the phrase parses successfully M times then stop. The current phrase index, starting at 0, is passed to the phrase.

Returns the list of parse results and the number of results.

manyIndex n n (\_ -> p) is equivalent to replicateA n p.

#chainl Source

chainl :: forall m s a. ParserT s m a -> ParserT s m (a -> a -> a) -> a -> ParserT s m a

chainl p f parses one or more occurrences of p, separated by operator f.

Returns a value obtained by a left-associative application of the functions returned byf to the values returned by p. This combinator can be used to eliminate left-recursion in expression grammars.

For example:

chainl digit (string "+" $> add) 0

#chainr Source

chainr :: forall m s a. ParserT s m a -> ParserT s m (a -> a -> a) -> a -> ParserT s m a

chainr p f parses one or more occurrences of p, separated by operator f.

Returns a value obtained by a right-associative application of the functions returned byf to the values returned by p. This combinator can be used to eliminate right-recursion in expression grammars.

For example:

chainr digit (string "+" $> add) 0

#advance Source

advance :: forall s m a. ParserT s m a -> ParserT s m a

If the parser succeeds without advancing the input stream position, then force the parser to fail.

This combinator can be used to prevent infinite parser repetition.

Does not depend on or effect the consumed flag which indicates whether we are committed to this parsing branch.

#(<?>) Source

Operator alias for Parsing.Combinators.withErrorMessage (left-associative / precedence 4)

#withLazyErrorMessage Source

withLazyErrorMessage :: forall m s a. ParserT s m a -> (Unit -> String) -> ParserT s m a

Provide an error message in the case of failure, but lazily. This is handy in cases where constructing the error message is expensive, so it's preferable to defer it until an error actually happens.

parseBang :: Parser Char
parseBang = char '!' <~?> \_ -> "a bang"

#(<~?>) Source

Operator alias for Parsing.Combinators.withLazyErrorMessage (left-associative / precedence 4)

#() Source

Operator alias for Parsing.Combinators.asErrorMessage (right-associative / precedence 3)

Re-exports from Control.Plus

#(<|>) Source

Operator alias for Control.Alt.alt (right-associative / precedence 3)

Re-exports from Data.List.Lazy

#replicateM Source

replicateM :: forall m a. Monad m => Int -> m a -> m (List a)

Perform a monadic action n times collecting all of the results.

Re-exports from Data.Unfoldable

Re-exports from Data.Unfoldable1

#replicate1A Source

replicate1A :: forall m f a. Apply m => Unfoldable1 f => Traversable1 f => Int -> m a -> m (f a)

Perform an Apply action n times (at least once, so values n less than 1 will be treated as 1), and accumulate the results.

> replicate1A 2 (randomInt 1 10) :: Effect (NEL.NonEmptyList Int)
(NonEmptyList (NonEmpty 8 (2 : Nil)))
> replicate1A 0 (randomInt 1 10) :: Effect (NEL.NonEmptyList Int)
(NonEmptyList (NonEmpty 4 Nil))