Skip to content

Commit bfb7abd

Browse files
committed
region docs, inContext example
1 parent 2a49674 commit bfb7abd

File tree

2 files changed

+43
-0
lines changed

2 files changed

+43
-0
lines changed

src/Parsing.purs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,32 @@ failWithPosition message pos = throwError (ParseError message pos)
411411
-- | Contextualize parsing failures inside a region. If a parsing failure
412412
-- | occurs, then the `ParseError` will be transformed by each containing
413413
-- | `region` as the parser backs out the call stack.
414+
-- |
415+
-- | For example, here’s a helper function `inContext` which uses `region` to
416+
-- | add some string context to the error messages.
417+
-- |
418+
-- | ```
419+
-- | let
420+
-- | inContext :: forall s m a. (String -> String) -> ParserT s m a -> ParserT s m a
421+
-- | inContext context = region \(ParseError message pos) ->
422+
-- | ParseError (context message) pos
423+
-- |
424+
-- | input = "Tokyo thirty-nine million"
425+
-- |
426+
-- | lmap (parseErrorHuman input 30) $ runParser input do
427+
-- | inContext ("Megacity list: " <> _) do
428+
-- | cityname <- inContext ("city name: " <> _) do
429+
-- | fst <$> match (skipMany letter)
430+
-- | skipSpaces
431+
-- | population <- inContext ("population: " <> _) intDecimal
432+
-- | pure $ Tuple cityname population
433+
-- | ```
434+
-- | ---
435+
-- | ```
436+
-- | Megacity list: population: Expected Int at position index:6 (line:1, column:7)
437+
-- | ▼
438+
-- | Tokyo thirty-nine million
439+
-- | ```
414440
region :: forall m s a. (ParseError -> ParseError) -> ParserT s m a -> ParserT s m a
415441
region context p = catchError p $ \err -> throwError $ context err
416442

test/Main.purs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import Effect.Unsafe (unsafePerformEffect)
3535
import Node.Process (lookupEnv)
3636
import Parsing (ParseError(..), ParseState(..), Parser, ParserT, Position(..), consume, fail, getParserT, initialPos, parseErrorMessage, parseErrorPosition, position, region, runParser)
3737
import Parsing.Combinators (advance, between, chainl, chainl1, chainr, chainr1, choice, empty, endBy, endBy1, lookAhead, many, many1, many1Till, many1Till_, manyIndex, manyTill, manyTill_, notFollowedBy, optionMaybe, replicateA, sepBy, sepBy1, sepEndBy, sepEndBy1, skipMany, skipMany1, try, (<?>), (<??>), (<~?>))
38+
import Parsing.Combinators as Combinators
3839
import Parsing.Combinators.Array as Combinators.Array
3940
import Parsing.Expr (Assoc(..), Operator(..), buildExprParser)
4041
import Parsing.Language (haskellDef, haskellStyle, javaStyle)
@@ -702,6 +703,22 @@ main = do
702703
, expected: Right false
703704
}
704705

706+
do
707+
let
708+
inContext :: forall s m a. (String -> String) -> ParserT s m a -> ParserT s m a
709+
inContext context = region \(ParseError message pos) -> ParseError (context message) pos
710+
input = "Tokyo thirty-nine million"
711+
assertEqual' "region 1"
712+
{ actual: runParser input do
713+
inContext ("Megacity list: " <> _) do
714+
cityname <- inContext ("city name: " <> _) do
715+
fst <$> match (Combinators.skipMany letter)
716+
skipSpaces
717+
population <- inContext ("population: " <> _) intDecimal
718+
pure $ Tuple cityname population
719+
, expected: (Left (ParseError "Megacity list: population: Expected Int" (Position { column: 7, index: 6, line: 1 })))
720+
}
721+
705722
log "\nTESTS number\n"
706723

707724
-- assert' "Number.fromString" $ Just infinity == Data.Number.fromString "Infinity"

0 commit comments

Comments
 (0)