From 303cbe57a7f824f2118573b2ec630d9eab65a675 Mon Sep 17 00:00:00 2001 From: James Brock Date: Wed, 7 Oct 2020 01:20:04 +0900 Subject: [PATCH] parsing failure context region --- src/Text/Parsing/Parser.purs | 13 +++++++------ test/Main.purs | 9 +++++---- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/Text/Parsing/Parser.purs b/src/Text/Parsing/Parser.purs index 013df83..32be296 100644 --- a/src/Text/Parsing/Parser.purs +++ b/src/Text/Parsing/Parser.purs @@ -13,7 +13,7 @@ module Text.Parsing.Parser , position , fail , failWithPosition - , label + , region ) where import Prelude @@ -138,8 +138,9 @@ fail message = failWithPosition message =<< position failWithPosition :: forall m s a. Monad m => String -> Position -> ParserT s m a failWithPosition message pos = throwError (ParseError message pos) --- | If parsing fails inside this labelled context, then prepend the `String` --- | to the error `String` in the `ParseError`. -label :: forall m s a. Monad m => String -> ParserT s m a -> ParserT s m a -label messagePrefix p = catchError p $ \ (ParseError message pos) -> - throwError $ ParseError (messagePrefix <> message) pos +-- | Contextualize parsing failures inside a region. If a parsing failure +-- | occurs, then the `ParseError` will be transformed by each containing +-- | `region` as the parser backs out the call stack. +region :: forall m s a. Monad m => (ParseError -> ParseError) -> ParserT s m a -> ParserT s m a +region context p = catchError p $ \err -> throwError $ context err + diff --git a/test/Main.purs b/test/Main.purs index 21c0dd5..b2466a0 100644 --- a/test/Main.purs +++ b/test/Main.purs @@ -13,7 +13,7 @@ import Data.Tuple (Tuple(..)) import Effect (Effect) import Effect.Console (logShow) import Test.Assert (assert') -import Text.Parsing.Parser (Parser, ParserT, ParseError(..), runParser, parseErrorPosition, label) +import Text.Parsing.Parser (Parser, ParserT, ParseError(..), runParser, parseErrorPosition, region) import Text.Parsing.Parser.Combinators (endBy1, sepBy1, optionMaybe, try, chainl, between) import Text.Parsing.Parser.Expr (Assoc(..), Operator(..), buildExprParser) import Text.Parsing.Parser.Language (javaStyle, haskellStyle, haskellDef) @@ -500,11 +500,12 @@ main = do case runParser "aa" p of Right _ -> assert' "error: ParseError expected!" false Left (ParseError message pos) -> do - let messageExpected = "context1context2Expected \"b\"" + let messageExpected = "context1 context2 Expected \"b\"" assert' ("expected message: " <> messageExpected <> ", message: " <> message) (message == messageExpected) logShow messageExpected where - p = label "context1" $ do + prependContext m' (ParseError m pos) = ParseError (m' <> m) pos + p = region (prependContext "context1 ") $ do _ <- string "a" - label "context2" $ do + region (prependContext "context2 ") $ do string "b"