Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Text.Megaparsec.Error.errorBundlePrettyForGhcPreProcessors #573

Merged
merged 1 commit into from
Nov 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
* `many` and `some` of the `Alternative` instance of `ParsecT` are now more
efficient, since they use the monadic implementations under the hood.
[Issue 567](https://github.com/mrkkrp/megaparsec/issues/567).
* Add `Text.Megaparsec.Error.errorBundlePrettyForGhcPreProcessors`. [PR
573](https://github.com/mrkkrp/megaparsec/pull/573).

## Megaparsec 9.6.1

Expand Down
83 changes: 74 additions & 9 deletions Text/Megaparsec/Error.hs
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,15 @@ module Text.Megaparsec.Error
-- * Pretty-printing
ShowErrorComponent (..),
errorBundlePretty,
errorBundlePrettyForGhcPreProcessors,
errorBundlePrettyWith,
parseErrorPretty,
parseErrorTextPretty,
showErrorItem,
)
where

import Control.Arrow ((>>>))
import Control.DeepSeq
import Control.Exception
import Control.Monad.State.Strict
Expand Down Expand Up @@ -349,24 +352,24 @@ instance ShowErrorComponent Void where
showErrorComponent = absurd

-- | Pretty-print a 'ParseErrorBundle'. All 'ParseError's in the bundle will
-- be pretty-printed in order together with the corresponding offending
-- lines by doing a single pass over the input stream. The rendered 'String'
-- always ends with a newline.
-- be pretty-printed in order, by applying a provided format function, with
-- a single pass over the input stream.
--
-- @since 7.0.0
errorBundlePretty ::
-- @since 9.7.0
errorBundlePrettyWith ::
forall s e.
( VisualStream s,
TraversableStream s,
ShowErrorComponent e
TraversableStream s
) =>
-- | Format function for a single 'ParseError'
(Maybe String -> SourcePos -> ParseError s e -> String) ->
-- | Parse error bundle to display
ParseErrorBundle s e ->
-- | Textual rendition of the bundle
String
errorBundlePretty ParseErrorBundle {..} =
errorBundlePrettyWith format ParseErrorBundle {..} =
let (r, _) = foldl f (id, bundlePosState) bundleErrors
in drop 1 (r "")
in r ""
where
f ::
(ShowS, PosState s) ->
Expand All @@ -376,6 +379,33 @@ errorBundlePretty ParseErrorBundle {..} =
where
(msline, pst') = reachOffset (errorOffset e) pst
epos = pstateSourcePos pst'
outChunk = format msline epos e

-- | Pretty-print a 'ParseErrorBundle'. All 'ParseError's in the bundle will
-- be pretty-printed in order together with the corresponding offending
-- lines by doing a single pass over the input stream. The rendered 'String'
-- always ends with a newline.
--
-- @since 7.0.0
errorBundlePretty ::
forall s e.
( VisualStream s,
TraversableStream s,
ShowErrorComponent e
) =>
-- | Parse error bundle to display
ParseErrorBundle s e ->
-- | Textual rendition of the bundle
String
errorBundlePretty = drop 1 . errorBundlePrettyWith format
where
format ::
Maybe String ->
SourcePos ->
ParseError s e ->
String
format msline epos e = outChunk
where
outChunk =
"\n"
<> sourcePosPretty epos
Expand Down Expand Up @@ -418,6 +448,41 @@ errorBundlePretty ParseErrorBundle {..} =
FancyError _ xs ->
E.foldl' (\a b -> max a (errorFancyLength b)) 1 xs

-- | Pretty-print a 'ParseErrorBundle'. All 'ParseError's in the bundle will
-- be pretty-printed in order by doing a single pass over the input stream.
--
-- The rendered format is suitable for custom GHC pre-processors (as can be
-- specified with -F -pgmF).
--
-- @since 9.7.0
errorBundlePrettyForGhcPreProcessors ::
forall s e.
( VisualStream s,
TraversableStream s,
ShowErrorComponent e
) =>
-- | Parse error bundle to display
ParseErrorBundle s e ->
-- | Textual rendition of the bundle
String
errorBundlePrettyForGhcPreProcessors = errorBundlePrettyWith format
where
format ::
Maybe String ->
SourcePos ->
ParseError s e ->
String
format _msline epos e =
sourcePosPretty epos
<> ":"
<> indent (parseErrorTextPretty e)

indent :: String -> String
indent =
lines >>> \case
[err] -> err
err -> intercalate "\n" $ map (" " <>) err

-- | Pretty-print a 'ParseError'. The rendered 'String' always ends with a
-- newline.
--
Expand Down