# Parsing.Combinators

- 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.Array**
module 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 p`

will 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 }))
```

### #notFollowedBy Source

`notFollowedBy :: forall s a m. ParserT s m a -> ParserT s m Unit`

Fail if the parser succeeds.

Will never consume input.

### #optionMaybe Source

`optionMaybe :: forall m s a. ParserT s m a -> ParserT s m (Maybe a)`

pure `Nothing`

in the case where a parser fails without consuming input.

### #many1 Source

`many1 :: forall m s a. ParserT s m a -> ParserT s m (NonEmptyList a)`

Match the phrase `p`

as many times as possible, at least once.

### #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, write
`manyTill_ p q`

where `q`

is the entire rest of the parser.

For example, this parse fails because `many`

repeats the pattern `letter`

greedily.

```
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')
```

### #many1Till Source

`many1Till :: forall s a m e. ParserT s m a -> ParserT s m e -> ParserT s m (NonEmptyList a)`

Parse at least one phrase until the terminator phrase matches.

### #many1Till_ Source

`many1Till_ :: forall s a m e. ParserT s m a -> ParserT s m e -> ParserT s m (Tuple (NonEmptyList a) e)`

Parse many phrases until the terminator phrase matches, requiring at least one match. Returns the list of phrases and the terminator phrase.

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

.

### #sepBy1 Source

`sepBy1 :: forall m s a sep. ParserT s m a -> ParserT s m sep -> ParserT s m (NonEmptyList a)`

Parse phrases delimited by a separator, requiring at least one match.

### #sepEndBy1 Source

`sepEndBy1 :: forall m s a sep. ParserT s m a -> ParserT s m sep -> ParserT s m (NonEmptyList a)`

Parse phrases delimited and optionally terminated by a separator, requiring at least one match.

### #endBy1 Source

`endBy1 :: forall m s a sep. ParserT s m a -> ParserT s m sep -> ParserT s m (NonEmptyList a)`

Parse phrases delimited and terminated by a separator, requiring at least one match.

### #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 by
`f`

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 by
`f`

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.

### #withErrorMessage Source

`withErrorMessage :: forall m s a. ParserT s m a -> String -> ParserT s m a`

Provide an error message in the case of failure.

### #(<?>) 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)*

### #asErrorMessage Source

`asErrorMessage :: forall m s a. String -> ParserT s m a -> ParserT s m a`

Flipped `(<?>)`

.

### #(<??>) Source

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

## Re-exports from **Control.**Plus

## 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

### #replicateA Source

`replicateA :: forall m f a. Applicative m => Unfoldable f => Traversable f => Int -> m a -> m (f a)`

Perform an Applicative action `n`

times, and accumulate all the results.

```
> replicateA 5 (randomInt 1 10) :: Effect (Array Int)
[1,3,2,7,5]
```

## 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))
```