14
14
-- | ### Data.List
15
15
-- | * [Data.List.many](https://pursuit.purescript.org/packages/purescript-lists/docs/Data.List#v:many)
16
16
-- | * [Data.List.some](https://pursuit.purescript.org/packages/purescript-lists/docs/Data.List#v:some)
17
- -- | * [Data.List.someRec](https://pursuit.purescript.org/packages/purescript-lists/docs/Data.List#v:someRec)
18
- -- | * [Data.List.manyRec](https://pursuit.purescript.org/packages/purescript-lists/docs/Data.List#v:manyRec)
19
17
-- |
20
18
-- | ### Data.List.NonEmpty
21
19
-- | * See the __many1__ combinator below.
40
38
-- | return a parser `replicateA n p :: Parser s (Array a)` which will
41
39
-- | repeat parser `p` exactly `n` times. `replicateA n p` will only succeed
42
40
-- | if it can match parser `p` exactly `n` consecutive times.
41
+ -- |
42
+ -- | ## Stack-safety
43
+ -- |
44
+ -- | The `ParserT` monad is always stack-safe, so `MonadRec` combinators are
45
+ -- | not necessary.
43
46
module Parsing.Combinators
44
47
( (<?>)
45
48
, (<??>)
@@ -48,27 +51,16 @@ module Parsing.Combinators
48
51
, between
49
52
, chainl
50
53
, chainl1
51
- , chainl1Rec
52
- , chainlRec
53
54
, chainr
54
55
, chainr1
55
- , chainr1Rec
56
- , chainrRec
57
56
, choice
58
57
, endBy
59
58
, endBy1
60
- , endBy1Rec
61
- , endByRec
62
59
, lookAhead
63
60
, many1
64
- , many1Rec
65
61
, many1Till
66
- , many1TillRec
67
- , many1TillRec_
68
62
, many1Till_
69
63
, manyTill
70
- , manyTillRec
71
- , manyTillRec_
72
64
, manyTill_
73
65
, module Control.Plus
74
66
, module Data.Unfoldable
@@ -79,16 +71,10 @@ module Parsing.Combinators
79
71
, optional
80
72
, sepBy
81
73
, sepBy1
82
- , sepBy1Rec
83
- , sepByRec
84
74
, sepEndBy
85
75
, sepEndBy1
86
- , sepEndBy1Rec
87
- , sepEndByRec
88
76
, skipMany
89
77
, skipMany1
90
- , skipMany1Rec
91
- , skipManyRec
92
78
, try
93
79
, tryRethrow
94
80
, withErrorMessage
@@ -98,16 +84,14 @@ module Parsing.Combinators
98
84
import Prelude
99
85
100
86
import Control.Lazy (defer )
101
- import Control.Monad.Rec.Class (Step (..), tailRecM )
102
87
import Control.Plus (empty , (<|>), alt )
103
- import Data.Foldable (class Foldable , foldl , foldr )
88
+ import Data.Foldable (class Foldable , foldr )
104
89
import Data.Function.Uncurried (mkFn2 , mkFn5 , runFn2 , runFn5 )
105
- import Data.List (List (..), many , manyRec , reverse , (:))
90
+ import Data.List (List (..), many , (:))
106
91
import Data.List.NonEmpty (NonEmptyList , cons' )
107
92
import Data.List.NonEmpty as NEL
108
93
import Data.Maybe (Maybe (..), fromMaybe )
109
94
import Data.Tuple (Tuple (..))
110
- import Data.Tuple.Nested (type (/\), (/\))
111
95
import Data.Unfoldable (replicateA )
112
96
import Data.Unfoldable1 (replicate1A )
113
97
import Parsing (ParseError (..), ParseState (..), ParserT (..), fail )
@@ -223,12 +207,6 @@ lookAhead (ParserT k1) = ParserT
223
207
many1 :: forall m s a . ParserT s m a -> ParserT s m (NonEmptyList a )
224
208
many1 p = NEL .cons' <$> p <*> many p
225
209
226
- -- | Match one or more times.
227
- -- |
228
- -- | Stack-safe version of `many1` at the expense of a `MonadRec` constraint.
229
- many1Rec :: forall m s a . ParserT s m a -> ParserT s m (NonEmptyList a )
230
- many1Rec p = NEL .cons' <$> p <*> manyRec p
231
-
232
210
-- | Parse phrases delimited by a separator.
233
211
-- |
234
212
-- | For example:
@@ -239,38 +217,17 @@ many1Rec p = NEL.cons' <$> p <*> manyRec p
239
217
sepBy :: forall m s a sep . ParserT s m a -> ParserT s m sep -> ParserT s m (List a )
240
218
sepBy p sep = map NEL .toList (sepBy1 p sep) <|> pure Nil
241
219
242
- -- | Parse phrases delimited by a separator.
243
- -- |
244
- -- | Stack-safe version of `sepBy` at the expense of a `MonadRec` constraint.
245
- sepByRec :: forall m s a sep . ParserT s m a -> ParserT s m sep -> ParserT s m (List a )
246
- sepByRec p sep = map NEL .toList (sepBy1Rec p sep) <|> pure Nil
247
-
248
220
-- | Parse phrases delimited by a separator, requiring at least one match.
249
221
sepBy1 :: forall m s a sep . ParserT s m a -> ParserT s m sep -> ParserT s m (NonEmptyList a )
250
222
sepBy1 p sep = do
251
223
a <- p
252
224
as <- many $ sep *> p
253
225
pure (NEL .cons' a as)
254
226
255
- -- | Parse phrases delimited by a separator, requiring at least one match.
256
- -- |
257
- -- | Stack-safe version of `sepBy1` at the expense of a `MonadRec` constraint.
258
- sepBy1Rec :: forall m s a sep . ParserT s m a -> ParserT s m sep -> ParserT s m (NonEmptyList a )
259
- sepBy1Rec p sep = do
260
- a <- p
261
- as <- manyRec $ sep *> p
262
- pure (NEL .cons' a as)
263
-
264
227
-- | Parse phrases delimited and optionally terminated by a separator.
265
228
sepEndBy :: forall m s a sep . ParserT s m a -> ParserT s m sep -> ParserT s m (List a )
266
229
sepEndBy p sep = map NEL .toList (sepEndBy1 p sep) <|> pure Nil
267
230
268
- -- | Parse phrases delimited and optionally terminated by a separator.
269
- -- |
270
- -- | Stack-safe version of `sepEndBy` at the expense of a `MonadRec` constraint.
271
- sepEndByRec :: forall m s a sep . ParserT s m a -> ParserT s m sep -> ParserT s m (List a )
272
- sepEndByRec p sep = map NEL .toList (sepEndBy1Rec p sep) <|> pure Nil
273
-
274
231
-- | Parse phrases delimited and optionally terminated by a separator, requiring at least one match.
275
232
sepEndBy1 :: forall m s a sep . ParserT s m a -> ParserT s m sep -> ParserT s m (NonEmptyList a )
276
233
sepEndBy1 p sep = do
@@ -281,45 +238,14 @@ sepEndBy1 p sep = do
281
238
pure (NEL .cons' a as)
282
239
) <|> pure (NEL .singleton a)
283
240
284
- -- | Parse phrases delimited and optionally terminated by a separator, requiring at least one match.
285
- -- |
286
- -- | Stack-safe version of `sepEndBy1` at the expense of a `MonadRec` constraint.
287
- sepEndBy1Rec :: forall m s a sep . ParserT s m a -> ParserT s m sep -> ParserT s m (NonEmptyList a )
288
- sepEndBy1Rec p sep = do
289
- a <- p
290
- (NEL .cons' a <$> tailRecM go Nil ) <|> pure (NEL .singleton a)
291
- where
292
- go :: List a -> ParserT s m (Step (List a ) (List a ))
293
- go acc = nextOne <|> done
294
- where
295
- nextOne = do
296
- -- First make sure there's a separator.
297
- _ <- sep
298
- -- Then try the phrase and loop if it's there, or bail if it's not there.
299
- (p <#> \a -> Loop $ a : acc) <|> done
300
-
301
- done = defer \_ -> pure $ Done $ reverse acc
302
-
303
241
-- | Parse phrases delimited and terminated by a separator, requiring at least one match.
304
242
endBy1 :: forall m s a sep . ParserT s m a -> ParserT s m sep -> ParserT s m (NonEmptyList a )
305
243
endBy1 p sep = many1 $ p <* sep
306
244
307
- -- | Parse phrases delimited and terminated by a separator, requiring at least one match.
308
- -- |
309
- -- | Stack-safe version of `endBy1` at the expense of a `MonadRec` constraint.
310
- endBy1Rec :: forall m s a sep . ParserT s m a -> ParserT s m sep -> ParserT s m (NonEmptyList a )
311
- endBy1Rec p sep = many1Rec $ p <* sep
312
-
313
245
-- | Parse phrases delimited and terminated by a separator.
314
246
endBy :: forall m s a sep . ParserT s m a -> ParserT s m sep -> ParserT s m (List a )
315
247
endBy p sep = many $ p <* sep
316
248
317
- -- | Parse phrases delimited and terminated by a separator.
318
- -- |
319
- -- | Stack-safe version of `endBy` at the expense of a `MonadRec` constraint.
320
- endByRec :: forall m s a sep . ParserT s m a -> ParserT s m sep -> ParserT s m (List a )
321
- endByRec p sep = manyRec $ p <* sep
322
-
323
249
-- | Parse phrases delimited by a right-associative operator.
324
250
-- |
325
251
-- | For example:
@@ -330,12 +256,6 @@ endByRec p sep = manyRec $ p <* sep
330
256
chainr :: forall m s a . ParserT s m a -> ParserT s m (a -> a -> a ) -> a -> ParserT s m a
331
257
chainr p f a = chainr1 p f <|> pure a
332
258
333
- -- | Parse phrases delimited by a right-associative operator.
334
- -- |
335
- -- | Stack-safe version of `chainr` at the expense of a `MonadRec` constraint.
336
- chainrRec :: forall m s a . ParserT s m a -> ParserT s m (a -> a -> a ) -> a -> ParserT s m a
337
- chainrRec p f a = chainr1Rec p f <|> pure a
338
-
339
259
-- | Parse phrases delimited by a left-associative operator.
340
260
-- |
341
261
-- | For example:
@@ -346,12 +266,6 @@ chainrRec p f a = chainr1Rec p f <|> pure a
346
266
chainl :: forall m s a . ParserT s m a -> ParserT s m (a -> a -> a ) -> a -> ParserT s m a
347
267
chainl p f a = chainl1 p f <|> pure a
348
268
349
- -- | Parse phrases delimited by a left-associative operator.
350
- -- |
351
- -- | Stack-safe version of `chainl` at the expense of a `MonadRec` constraint.
352
- chainlRec :: forall m s a . ParserT s m a -> ParserT s m (a -> a -> a ) -> a -> ParserT s m a
353
- chainlRec p f a = chainl1Rec p f <|> pure a
354
-
355
269
-- | Parse phrases delimited by a left-associative operator, requiring at least one match.
356
270
chainl1 :: forall m s a . ParserT s m a -> ParserT s m (a -> a -> a ) -> ParserT s m a
357
271
chainl1 p f = do
@@ -365,23 +279,6 @@ chainl1 p f = do
365
279
chainl1' (f' a a')
366
280
) <|> pure a
367
281
368
- -- | Parse phrases delimited by a left-associative operator, requiring at least one match.
369
- -- |
370
- -- | Stack-safe version of `chainl1` at the expense of a `MonadRec` constraint.
371
- chainl1Rec :: forall m s a . ParserT s m a -> ParserT s m (a -> a -> a ) -> ParserT s m a
372
- chainl1Rec p f = do
373
- a <- p
374
- tailRecM go a
375
- where
376
- go :: a -> ParserT s m (Step a a )
377
- go a =
378
- ( do
379
- op <- f
380
- a' <- p
381
- pure $ Loop $ op a a'
382
- )
383
- <|> pure (Done a)
384
-
385
282
-- | Parse phrases delimited by a right-associative operator, requiring at least one match.
386
283
chainr1 :: forall m s a . ParserT s m a -> ParserT s m (a -> a -> a ) -> ParserT s m a
387
284
chainr1 p f = do
@@ -395,51 +292,6 @@ chainr1 p f = do
395
292
pure $ f' a a'
396
293
) <|> pure a
397
294
398
- -- | Parse phrases delimited by a right-associative operator, requiring at least one match.
399
- -- |
400
- -- | Stack-safe version of `chainr1` at the expense of a `MonadRec` constraint.
401
- chainr1Rec :: forall m s a . ParserT s m a -> ParserT s m (a -> a -> a ) -> ParserT s m a
402
- chainr1Rec p f = do
403
- a <- p
404
- tailRecM go { last: a, init: Nil }
405
- where
406
- -- This looks scary at first glance, so I'm leaving a comment in a vain
407
- -- attempt to explain how it works.
408
- --
409
- -- The loop state is a record {init, last}, where `last` is the last (i.e.
410
- -- rightmost) `a` value that has been parsed so far, and `init` is a list of
411
- -- (value + operator) pairs that have been parsed before that.
412
- --
413
- -- The very first value is parsed at top level, and it becomes the initial
414
- -- value of `last`, while the initial value of `init` is just `Nil`,
415
- -- indicating that no pairs of (value + operator) have been parsed yet.
416
- --
417
- -- At every step, we parse an operator and a value, and then the newly parsed
418
- -- value becomes `last` (because, well, it's been parsed last), and the pair
419
- -- of (previous last + operator) is prepended to `init`.
420
- --
421
- -- After we can no longer parse a pair of (value + operation), we're done. At
422
- -- that point, we have a list of (value + operation) pairs in reverse order
423
- -- (since we prepend each pair as we go) and the very last value. All that's
424
- -- left is combine them all via `foldl`.
425
- go
426
- :: { init :: List (a /\ (a -> a -> a )), last :: a }
427
- -> ParserT s m
428
- ( Step
429
- { init :: List (a /\ (a -> a -> a )), last :: a }
430
- a
431
- )
432
- go { last, init } =
433
- ( do
434
- op <- f
435
- a <- p
436
- pure $ Loop { last: a, init: (last /\ op) : init }
437
- )
438
- <|> pure (Done $ foldl apply last init)
439
-
440
- apply :: a -> (a /\ (a -> a -> a )) -> a
441
- apply y (x /\ op) = x `op` y
442
-
443
295
-- | Parse one of a set of alternatives.
444
296
choice :: forall f m s a . Foldable f => f (ParserT s m a ) -> ParserT s m a
445
297
choice = fromMaybe empty <<< foldr go Nothing
@@ -452,27 +304,13 @@ choice = fromMaybe empty <<< foldr go Nothing
452
304
skipMany :: forall s a m . ParserT s m a -> ParserT s m Unit
453
305
skipMany p = skipMany1 p <|> pure unit
454
306
455
- -- | Skip many instances of a phrase.
456
- -- |
457
- -- | Stack-safe version of `skipMany` at the expense of a `MonadRec` constraint.
458
- skipManyRec :: forall s a m . ParserT s m a -> ParserT s m Unit
459
- skipManyRec p = skipMany1Rec p <|> pure unit
460
-
461
307
-- | Skip at least one instance of a phrase.
462
308
skipMany1 :: forall s a m . ParserT s m a -> ParserT s m Unit
463
309
skipMany1 p = do
464
310
_ <- p
465
311
_ <- skipMany p
466
312
pure unit
467
313
468
- -- | Skip at least one instance of a phrase.
469
- -- |
470
- -- | Stack-safe version of `skipMany1` at the expense of a `MonadRec` constraint.
471
- skipMany1Rec :: forall s a m . ParserT s m a -> ParserT s m Unit
472
- skipMany1Rec p = p *> tailRecM go unit
473
- where
474
- go _ = (p $> Loop unit) <|> pure (Done unit)
475
-
476
314
-- | Fail if the parser succeeds.
477
315
-- |
478
316
-- | Will never consume input.
@@ -488,30 +326,13 @@ manyTill p end = scan
488
326
xs <- scan
489
327
pure (x : xs)
490
328
491
- -- | Parse many phrases until the terminator phrase matches.
492
- -- |
493
- -- | Stack-safe version of `manyTill` at the expense of a `MonadRec` constraint.
494
- manyTillRec :: forall s a m e . ParserT s m a -> ParserT s m e -> ParserT s m (List a )
495
- manyTillRec p end = tailRecM go Nil
496
- where
497
- go :: List a -> ParserT s m (Step (List a ) (List a ))
498
- go acc =
499
- (end <#> \_ -> Done $ reverse acc)
500
- <|> (p <#> \x -> Loop $ x : acc)
501
-
502
329
-- | Parse at least one phrase until the terminator phrase matches.
503
330
many1Till :: forall s a m e . ParserT s m a -> ParserT s m e -> ParserT s m (NonEmptyList a )
504
331
many1Till p end = do
505
332
x <- p
506
333
xs <- manyTill p end
507
334
pure (NEL .cons' x xs)
508
335
509
- -- | Parse at least one phrase until the terminator phrase matches.
510
- -- |
511
- -- | Stack-safe version of `many1Till` at the expense of a `MonadRec` constraint.
512
- many1TillRec :: forall s a m e . ParserT s m a -> ParserT s m e -> ParserT s m (NonEmptyList a )
513
- many1TillRec p end = NEL .cons' <$> p <*> manyTillRec p end
514
-
515
336
-- | Parse many phrases until the terminator phrase matches.
516
337
-- | Returns the list of phrases and the terminator phrase.
517
338
-- |
@@ -567,30 +388,3 @@ many1Till_ p end = do
567
388
x <- p
568
389
Tuple xs t <- manyTill_ p end
569
390
pure $ Tuple (cons' x xs) t
570
-
571
- -- | Parse many phrases until the terminator phrase matches.
572
- -- | Returns the list of phrases and the terminator phrase.
573
- -- |
574
- -- | Stack-safe version of `manyTill_` at the expense of a `MonadRec` constraint.
575
- manyTillRec_ :: forall s a m e . ParserT s m a -> ParserT s m e -> ParserT s m (Tuple (List a ) e )
576
- manyTillRec_ p end = tailRecM go Nil
577
- where
578
- go :: List a -> ParserT s m (Step (List a ) (Tuple (List a ) e ))
579
- go xs =
580
- do
581
- t <- end
582
- pure (Done (Tuple (reverse xs) t))
583
- <|>
584
- do
585
- x <- p
586
- pure (Loop (x : xs))
587
-
588
- -- | Parse many phrases until the terminator phrase matches, requiring at least one match.
589
- -- | Returns the list of phrases and the terminator phrase.
590
- -- |
591
- -- | Stack-safe version of `many1Till_` at the expense of a `MonadRec` constraint.
592
- many1TillRec_ :: forall s a m e . ParserT s m a -> ParserT s m e -> ParserT s m (Tuple (NonEmptyList a ) e )
593
- many1TillRec_ p end = do
594
- x <- p
595
- Tuple xs t <- manyTillRec_ p end
596
- pure $ Tuple (cons' x xs) t
0 commit comments