Skip to content

Commit 7120bae

Browse files
committed
Drop stacks of source positions
1 parent cdbbe5c commit 7120bae

File tree

10 files changed

+86
-138
lines changed

10 files changed

+86
-138
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,14 @@
3030
makes sense because the collection of expected items cannot depend on what
3131
we see in the input stream.
3232

33+
* Dropped stacks of source positions. Thus the field `statePos` in `State`
34+
has the type `SourcePos` instead of `NonEmpty SourcePos`. Accordingly, the
35+
functions `pushPosition` and `popPosition` from `Text.Megaparsec` and
36+
`sourcePosStackPretty` from `Text.Megaparsec.Error` were removed.
37+
38+
The reason for this simplification is that I could not find any code that
39+
uses the feature and it makes manipulation of source positions hairy.
40+
3341
* The debugging function `dbg` has been moved from `Text.Megaparsec` to its
3442
own module `Text.Megaparsec.Debug`.
3543

Text/Megaparsec.hs

Lines changed: 6 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,6 @@ module Text.Megaparsec
108108
, getPosition
109109
, getNextTokenPosition
110110
, setPosition
111-
, pushPosition
112-
, popPosition
113111
, getTokensProcessed
114112
, setTokensProcessed
115113
, getTabWidth
@@ -129,8 +127,7 @@ import Text.Megaparsec.Internal
129127
import Text.Megaparsec.Pos
130128
import Text.Megaparsec.State
131129
import Text.Megaparsec.Stream
132-
import qualified Data.List.NonEmpty as NE
133-
import qualified Data.Set as E
130+
import qualified Data.Set as E
134131

135132
-- $reexports
136133
--
@@ -292,7 +289,7 @@ runParserT' p s = do
292289
initialState :: String -> s -> State s
293290
initialState name s = State
294291
{ stateInput = s
295-
, statePos = initialPos name :| []
292+
, statePos = initialPos name
296293
, stateTokensProcessed = 0
297294
, stateTabWidth = defaultTabWidth }
298295

@@ -540,7 +537,7 @@ setInput s = updateParserState (\(State _ pos tp w) -> State s pos tp w)
540537
-- See also: 'getNextTokenPosition'.
541538

542539
getPosition :: MonadParsec e s m => m SourcePos
543-
getPosition = NE.head . statePos <$> getParserState
540+
getPosition = statePos <$> getParserState
544541

545542
-- | Get the position where the next token in the stream begins. If the
546543
-- stream is empty, return 'Nothing'.
@@ -552,7 +549,7 @@ getPosition = NE.head . statePos <$> getParserState
552549
getNextTokenPosition :: forall e s m. MonadParsec e s m => m (Maybe SourcePos)
553550
getNextTokenPosition = do
554551
State {..} <- getParserState
555-
let f = positionAt1 (Proxy :: Proxy s) (NE.head statePos)
552+
let f = positionAt1 (Proxy :: Proxy s) statePos
556553
return (f . fst <$> take1_ stateInput)
557554
{-# INLINEABLE getNextTokenPosition #-}
558555

@@ -561,33 +558,8 @@ getNextTokenPosition = do
561558
-- See also: 'getPosition', 'pushPosition', 'popPosition', and 'SourcePos'.
562559

563560
setPosition :: MonadParsec e s m => SourcePos -> m ()
564-
setPosition pos = updateParserState $ \(State s (_:|z) tp w) ->
565-
State s (pos:|z) tp w
566-
567-
-- | Push a position to the stack of positions and continue parsing working
568-
-- with this position. Useful for working with include files and the like.
569-
--
570-
-- See also: 'popPosition'.
571-
--
572-
-- @since 5.0.0
573-
574-
pushPosition :: MonadParsec e s m => SourcePos -> m ()
575-
pushPosition pos = updateParserState $ \(State s z tp w) ->
576-
State s (NE.cons pos z) tp w
577-
578-
-- | Pop a position from the stack of positions unless it only contains one
579-
-- element (in that case the stack of positions remains the same). This is
580-
-- how to return to previous source file after 'pushPosition'.
581-
--
582-
-- See also: 'pushPosition'.
583-
--
584-
-- @since 5.0.0
585-
586-
popPosition :: MonadParsec e s m => m ()
587-
popPosition = updateParserState $ \(State s z tp w) ->
588-
case snd (NE.uncons z) of
589-
Nothing -> State s z tp w
590-
Just z' -> State s z' tp w
561+
setPosition pos = updateParserState $ \(State s _ tp w) ->
562+
State s pos tp w
591563

592564
-- | Get the number of tokens processed so far.
593565
--

Text/Megaparsec/Error.hs

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ module Text.Megaparsec.Error
3636
, parseErrorPretty
3737
, parseErrorPretty'
3838
, parseErrorPretty_
39-
, sourcePosStackPretty
4039
, parseErrorTextPretty )
4140
where
4241

@@ -115,12 +114,16 @@ instance NFData a => NFData (ErrorFancy a) where
115114
-- @since 6.0.0
116115

117116
data ParseError t e
118-
= TrivialError (NonEmpty SourcePos) (Maybe (ErrorItem t)) (Set (ErrorItem t))
117+
= TrivialError SourcePos (Maybe (ErrorItem t)) (Set (ErrorItem t))
119118
-- ^ Trivial errors, generated by Megaparsec's machinery. The data
120-
-- constructor includes the stack of source positions, unexpected token
119+
-- constructor includes the source position of error, unexpected token
121120
-- (if any), and expected tokens.
122-
| FancyError (NonEmpty SourcePos) (Set (ErrorFancy e))
121+
--
122+
-- Type of the first argument was changed in the version /7.0.0/.
123+
| FancyError SourcePos (Set (ErrorFancy e))
123124
-- ^ Fancy, custom errors.
125+
--
126+
-- Type of the first argument was changed in the version /7.0.0/.
124127
deriving (Show, Read, Eq, Data, Typeable, Generic)
125128

126129
instance (NFData t, NFData e) => NFData (ParseError t e)
@@ -130,7 +133,7 @@ instance (Ord t, Ord e) => Semigroup (ParseError t e) where
130133
{-# INLINE (<>) #-}
131134

132135
instance (Ord t, Ord e) => Monoid (ParseError t e) where
133-
mempty = TrivialError (initialPos "" :| []) Nothing E.empty
136+
mempty = TrivialError (initialPos "") Nothing E.empty
134137
mappend = (<>)
135138
{-# INLINE mappend #-}
136139

@@ -148,7 +151,7 @@ instance ( Show t
148151
--
149152
-- @since 6.0.0
150153

151-
errorPos :: ParseError t e -> NonEmpty SourcePos
154+
errorPos :: ParseError t e -> SourcePos
152155
errorPos (TrivialError p _ _) = p
153156
errorPos (FancyError p _) = p
154157

@@ -278,7 +281,7 @@ parseErrorPretty
278281
=> ParseError t e -- ^ Parse error to render
279282
-> String -- ^ Result of rendering
280283
parseErrorPretty e =
281-
sourcePosStackPretty (errorPos e) <> ":\n" <> parseErrorTextPretty e
284+
sourcePosPretty (errorPos e) <> ":\n" <> parseErrorTextPretty e
282285

283286
-- | Pretty-print a 'ParseError' and display the line on which the parse
284287
-- error occurred. The rendered 'String' always ends with a newline.
@@ -319,13 +322,13 @@ parseErrorPretty_
319322
-> ParseError (Token s) e -- ^ Parse error to render
320323
-> String -- ^ Result of rendering
321324
parseErrorPretty_ w s e =
322-
sourcePosStackPretty (errorPos e) <> ":\n" <>
325+
sourcePosPretty (errorPos e) <> ":\n" <>
323326
padding <> "|\n" <>
324327
lineNumber <> " | " <> rline <> "\n" <>
325328
padding <> "| " <> rpadding <> "^\n" <>
326329
parseErrorTextPretty e
327330
where
328-
epos = NE.last (errorPos e)
331+
epos = errorPos e
329332
lineNumber = (show . unPos . sourceLine) epos
330333
padding = replicate (length lineNumber + 1) ' '
331334
rpadding = replicate (unPos (sourceColumn epos) - 1) ' '
@@ -336,17 +339,6 @@ parseErrorPretty_ w s e =
336339
rline' = fmap tokenAsChar . chunkToTokens (Proxy :: Proxy s) $
337340
selectLine (sourceLine epos) s
338341

339-
-- | Pretty-print a stack of source positions.
340-
--
341-
-- @since 5.0.0
342-
343-
sourcePosStackPretty :: NonEmpty SourcePos -> String
344-
sourcePosStackPretty ms = mconcat (f <$> rest) <> sourcePosPretty pos
345-
where
346-
(pos :| rest') = ms
347-
rest = reverse rest'
348-
f p = "in file included from " <> sourcePosPretty p <> ",\n"
349-
350342
-- | Pretty-print a textual part of a 'ParseError', that is, everything
351343
-- except stack of source positions. The rendered staring always ends with a
352344
-- new line.

Text/Megaparsec/Error/Builder.hs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -97,15 +97,15 @@ instance Ord e => Monoid (EF e) where
9797
-- provided by this module, see below.
9898

9999
err
100-
:: NonEmpty SourcePos -- ^ 'ParseError' position
100+
:: SourcePos -- ^ 'ParseError' position
101101
-> ET t -- ^ Error components
102102
-> ParseError t e -- ^ Resulting 'ParseError'
103103
err pos (ET us ps) = TrivialError pos us ps
104104

105105
-- | Like 'err', but constructs a “fancy” 'ParseError'.
106106

107107
errFancy
108-
:: NonEmpty SourcePos -- ^ 'ParseError' position
108+
:: SourcePos -- ^ 'ParseError' position
109109
-> EF e -- ^ Error components
110110
-> ParseError t e -- ^ Resulting 'ParseError'
111111
errFancy pos (EF xs) = FancyError pos xs
@@ -115,21 +115,21 @@ errFancy pos (EF xs) = FancyError pos xs
115115

116116
-- | Initial source position with empty file name.
117117

118-
posI :: NonEmpty SourcePos
119-
posI = initialPos "" :| []
118+
posI :: SourcePos
119+
posI = initialPos ""
120120

121121
-- | @'posN' n s@ returns source position achieved by applying 'advanceN'
122122
-- method corresponding to the type of stream @s@.
123123

124124
posN :: forall s. Stream s
125125
=> Int
126126
-> s
127-
-> NonEmpty SourcePos
127+
-> SourcePos
128128
posN n s =
129129
case takeN_ n s of
130130
Nothing -> posI
131131
Just (ts, _) ->
132-
advanceN (Proxy :: Proxy s) defaultTabWidth (initialPos "") ts :| []
132+
advanceN (Proxy :: Proxy s) defaultTabWidth (initialPos "") ts
133133

134134
----------------------------------------------------------------------------
135135
-- Error components

Text/Megaparsec/Internal.hs

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -409,44 +409,44 @@ pObserving p = ParsecT $ \s cok _ eok _ ->
409409
{-# INLINE pObserving #-}
410410

411411
pEof :: forall e s m. Stream s => ParsecT e s m ()
412-
pEof = ParsecT $ \s@(State input (pos:|z) tp w) _ _ eok eerr ->
412+
pEof = ParsecT $ \s@(State input pos tp w) _ _ eok eerr ->
413413
case take1_ input of
414414
Nothing -> eok () s mempty
415415
Just (x,_) ->
416416
let !apos = positionAt1 (Proxy :: Proxy s) pos x
417417
us = (pure . Tokens . nes) x
418418
ps = E.singleton EndOfInput
419-
in eerr (TrivialError (apos:|z) us ps)
420-
(State input (apos:|z) tp w)
419+
in eerr (TrivialError apos us ps)
420+
(State input apos tp w)
421421
{-# INLINE pEof #-}
422422

423423
pToken :: forall e s m a. Stream s
424424
=> (Token s -> Maybe a)
425425
-> Set (ErrorItem (Token s))
426426
-> ParsecT e s m a
427-
pToken test ps = ParsecT $ \s@(State input (pos:|z) tp w) cok _ _ eerr ->
427+
pToken test ps = ParsecT $ \s@(State input pos tp w) cok _ _ eerr ->
428428
case take1_ input of
429429
Nothing ->
430430
let us = pure EndOfInput
431-
in eerr (TrivialError (pos:|z) us ps) s
431+
in eerr (TrivialError pos us ps) s
432432
Just (c,cs) ->
433433
case test c of
434434
Nothing ->
435435
let !apos = positionAt1 (Proxy :: Proxy s) pos c
436436
us = (Just . Tokens . nes) c
437-
in eerr (TrivialError (apos:|z) us ps)
438-
(State input (apos:|z) tp w)
437+
in eerr (TrivialError apos us ps)
438+
(State input apos tp w)
439439
Just x ->
440440
let !npos = advance1 (Proxy :: Proxy s) w pos c
441-
newstate = State cs (npos:|z) (tp + 1) w
441+
newstate = State cs npos (tp + 1) w
442442
in cok x newstate mempty
443443
{-# INLINE pToken #-}
444444

445445
pTokens :: forall e s m. Stream s
446446
=> (Tokens s -> Tokens s -> Bool)
447447
-> Tokens s
448448
-> ParsecT e s m (Tokens s)
449-
pTokens f tts = ParsecT $ \s@(State input (pos:|z) tp w) cok _ eok eerr ->
449+
pTokens f tts = ParsecT $ \s@(State input pos tp w) cok _ eok eerr ->
450450
let pxy = Proxy :: Proxy s
451451
unexpect pos' u =
452452
let us = pure u
@@ -455,24 +455,24 @@ pTokens f tts = ParsecT $ \s@(State input (pos:|z) tp w) cok _ eok eerr ->
455455
len = chunkLength pxy tts
456456
in case takeN_ len input of
457457
Nothing ->
458-
eerr (unexpect (pos:|z) EndOfInput) s
458+
eerr (unexpect pos EndOfInput) s
459459
Just (tts', input') ->
460460
if f tts tts'
461461
then let !npos = advanceN pxy w pos tts'
462-
st = State input' (npos:|z) (tp + len) w
462+
st = State input' npos (tp + len) w
463463
in if chunkEmpty pxy tts
464464
then eok tts' st mempty
465465
else cok tts' st mempty
466466
else let !apos = positionAtN pxy pos tts'
467467
ps = (Tokens . NE.fromList . chunkToTokens pxy) tts'
468-
in eerr (unexpect (apos:|z) ps) (State input (apos:|z) tp w)
468+
in eerr (unexpect apos ps) (State input apos tp w)
469469
{-# INLINE pTokens #-}
470470

471471
pTakeWhileP :: forall e s m. Stream s
472472
=> Maybe String
473473
-> (Token s -> Bool)
474474
-> ParsecT e s m (Tokens s)
475-
pTakeWhileP ml f = ParsecT $ \(State input (pos:|z) tp w) cok _ eok _ ->
475+
pTakeWhileP ml f = ParsecT $ \(State input pos tp w) cok _ eok _ ->
476476
let pxy = Proxy :: Proxy s
477477
(ts, input') = takeWhile_ f input
478478
!npos = advanceN pxy w pos ts
@@ -482,15 +482,15 @@ pTakeWhileP ml f = ParsecT $ \(State input (pos:|z) tp w) cok _ eok _ ->
482482
Nothing -> mempty
483483
Just l -> (Hints . pure . E.singleton . Label) l
484484
in if chunkEmpty pxy ts
485-
then eok ts (State input' (npos:|z) (tp + len) w) hs
486-
else cok ts (State input' (npos:|z) (tp + len) w) hs
485+
then eok ts (State input' npos (tp + len) w) hs
486+
else cok ts (State input' npos (tp + len) w) hs
487487
{-# INLINE pTakeWhileP #-}
488488

489489
pTakeWhile1P :: forall e s m. Stream s
490490
=> Maybe String
491491
-> (Token s -> Bool)
492492
-> ParsecT e s m (Tokens s)
493-
pTakeWhile1P ml f = ParsecT $ \(State input (pos:|z) tp w) cok _ _ eerr ->
493+
pTakeWhile1P ml f = ParsecT $ \(State input pos tp w) cok _ _ eerr ->
494494
let pxy = Proxy :: Proxy s
495495
(ts, input') = takeWhile_ f input
496496
len = chunkLength pxy ts
@@ -506,31 +506,31 @@ pTakeWhile1P ml f = ParsecT $ \(State input (pos:|z) tp w) cok _ _ eerr ->
506506
Nothing -> EndOfInput
507507
Just (t,_) -> Tokens (nes t)
508508
ps = maybe E.empty E.singleton el
509-
in eerr (TrivialError (apos:|z) us ps)
510-
(State input (apos:|z) tp w)
509+
in eerr (TrivialError apos us ps)
510+
(State input apos tp w)
511511
else let !npos = advanceN pxy w pos ts
512-
in cok ts (State input' (npos:|z) (tp + len) w) hs
512+
in cok ts (State input' npos (tp + len) w) hs
513513
{-# INLINE pTakeWhile1P #-}
514514

515515
pTakeP :: forall e s m. Stream s
516516
=> Maybe String
517517
-> Int
518518
-> ParsecT e s m (Tokens s)
519-
pTakeP ml n = ParsecT $ \s@(State input (pos:|z) tp w) cok _ _ eerr ->
519+
pTakeP ml n = ParsecT $ \s@(State input pos tp w) cok _ _ eerr ->
520520
let pxy = Proxy :: Proxy s
521521
el = Label <$> (ml >>= NE.nonEmpty)
522522
ps = maybe E.empty E.singleton el
523523
in case takeN_ n input of
524524
Nothing ->
525-
eerr (TrivialError (pos:|z) (pure EndOfInput) ps) s
525+
eerr (TrivialError pos (pure EndOfInput) ps) s
526526
Just (ts, input') ->
527527
let len = chunkLength pxy ts
528528
!apos = positionAtN pxy pos ts
529529
!npos = advanceN pxy w pos ts
530530
in if len /= n
531-
then eerr (TrivialError (npos:|z) (pure EndOfInput) ps)
532-
(State input (apos:|z) tp w)
533-
else cok ts (State input' (npos:|z) (tp + len) w) mempty
531+
then eerr (TrivialError npos (pure EndOfInput) ps)
532+
(State input apos tp w)
533+
else cok ts (State input' npos (tp + len) w) mempty
534534
{-# INLINE pTakeP #-}
535535

536536
pGetParserState :: ParsecT e s m (State s)
@@ -551,8 +551,8 @@ nes x = x :| []
551551
-- | Convert 'ParseError' record into 'Hints'.
552552

553553
toHints
554-
:: NonEmpty SourcePos -- ^ Current position in input stream
555-
-> ParseError t e -- ^ Parse error to convert
554+
:: SourcePos -- ^ Current position in input stream
555+
-> ParseError t e -- ^ Parse error to convert
556556
-> Hints t
557557
toHints streamPos = \case
558558
TrivialError errPos _ ps ->

0 commit comments

Comments
 (0)