Skip to content

Commit 5426932

Browse files
committed
Better errors for manyIndex
Return the parse error message of the phrase parser which failed instead of “Expected more phrases.” Also how many phrases were expected. #210
1 parent 4056d08 commit 5426932

File tree

4 files changed

+23
-9
lines changed

4 files changed

+23
-9
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ New features:
1515

1616
Other improvements:
1717

18+
- Better error messages for `manyIndex` (#211 by @jamesbrock)
19+
1820
## [v10.0.0](https://github.com/purescript-contrib/purescript-parsing/releases/tag/v9.1.0) - 2022-07-18
1921

2022
Bugfixes:

src/Parsing/Combinators.purs

+8-4
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ module Parsing.Combinators
8484
import Prelude
8585

8686
import Control.Lazy (defer)
87+
import Control.Monad.Error.Class (catchError, throwError)
8788
import Control.Monad.Rec.Class (Step(..), tailRecM)
8889
import Control.Plus (empty, (<|>), alt)
8990
import Data.Foldable (class Foldable, foldl, foldr)
@@ -98,7 +99,7 @@ import Data.Tuple (Tuple(..))
9899
import Data.Tuple.Nested (type (/\), (/\))
99100
import Data.Unfoldable (replicateA)
100101
import Data.Unfoldable1 (replicate1A)
101-
import Parsing (ParseError(..), ParseState(..), ParserT(..), Position(..), fail, position)
102+
import Parsing (ParseError(..), ParseState(..), ParserT(..), Position(..), fail, parseErrorMessage, parseErrorPosition, position)
102103

103104
-- | Provide an error message in the case of failure.
104105
withErrorMessage :: forall m s a. ParserT s m a -> String -> ParserT s m a
@@ -461,15 +462,18 @@ manyIndex from to p =
461462
go (Tuple i xs) =
462463
if i >= to then
463464
pure (Done (Tuple i (reverse xs)))
464-
else alt
465+
else catchError
465466
do
466467
x <- p i
467468
pure (Loop (Tuple (i + 1) (x : xs)))
468-
do
469+
\e -> do
469470
if i >= from then
470471
pure (Done (Tuple i (reverse xs)))
471472
else
472-
fail "Expected more phrases"
473+
throwError $ ParseError
474+
(parseErrorMessage e <> " (at least " <> show from <> ", but only parsed " <> show i <> ")")
475+
(parseErrorPosition e)
476+
473477

474478
-- | If the parser succeeds without advancing the input stream position,
475479
-- | then force the parser to fail.

src/Parsing/Combinators/Array.purs

+7-4
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,15 @@ module Parsing.Combinators.Array
1919
import Prelude
2020

2121
import Control.Alt (alt)
22+
import Control.Monad.Error.Class (catchError, throwError)
2223
import Control.Monad.Rec.Class (Step(..), tailRecM)
2324
import Data.Array as Array
2425
import Data.Array.NonEmpty (NonEmptyArray)
2526
import Data.Array.NonEmpty as Array.NonEmpty
2627
import Data.List (List(..), (:))
2728
import Data.Maybe (Maybe(..))
2829
import Data.Tuple (Tuple(..))
29-
import Parsing (ParserT, fail)
30+
import Parsing (ParseError(..), ParserT, fail, parseErrorMessage, parseErrorPosition)
3031
import Parsing.Combinators (try)
3132

3233
-- | Match the phrase `p` as many times as possible.
@@ -85,12 +86,14 @@ manyIndex from to p =
8586
go (Tuple i xs) =
8687
if i >= to then
8788
pure (Done (Tuple i xs))
88-
else alt
89+
else catchError
8990
do
9091
x <- p i
9192
pure (Loop (Tuple (i + 1) (x : xs)))
92-
do
93+
\e -> do
9394
if i >= from then
9495
pure (Done (Tuple i xs))
9596
else
96-
fail "Expected more phrases"
97+
throwError $ ParseError
98+
(parseErrorMessage e <> " (at least " <> show from <> ", but only parsed " <> show i <> ")")
99+
(parseErrorPosition e)

test/Main.purs

+6-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import Data.String.CodePoints as SCP
2727
import Data.String.CodeUnits (fromCharArray, singleton)
2828
import Data.String.CodeUnits as SCU
2929
import Data.String.Regex.Flags (RegexFlags, ignoreCase, noFlags)
30-
import Data.Tuple (Tuple(..), fst)
30+
import Data.Tuple (Tuple(..), fst, snd)
3131
import Data.Tuple.Nested (get2, (/\))
3232
import Effect (Effect)
3333
import Effect.Console (log, logShow)
@@ -1060,6 +1060,10 @@ main = do
10601060
{ actual: runParser "aaa" $ manyIndex (-2) (1) (\_ -> char 'a')
10611061
, expected: Right (Tuple 0 (Nil))
10621062
}
1063+
assertEqual' "manyIndex 6 errors"
1064+
{ actual: lmap parseErrorPosition $ runParser "aab" $ map snd $ manyIndex 3 3 (\_ -> char 'a')
1065+
, expected: lmap parseErrorPosition $ runParser "aab" $ (replicateA 3 (char 'a') :: Parser String (List Char))
1066+
}
10631067

10641068
log "\nTESTS advance\n"
10651069

@@ -1106,3 +1110,4 @@ main = do
11061110
$ string "aaaa\r\n" *> (replicateA 5 letter :: Parser String (List Char))
11071111
, expected: [ "Expected letter at position index:6 (line:2, column:1)", "", "🍷bbbb" ]
11081112
}
1113+

0 commit comments

Comments
 (0)