megaparsec 9.7.1 → 9.8.1
raw patch · 8 files changed
Files
- CHANGELOG.md +20/−0
- Text/Megaparsec/Byte/Lexer.hs +6/−6
- Text/Megaparsec/Char/Lexer.hs +6/−6
- Text/Megaparsec/Error.hs +1/−1
- Text/Megaparsec/Internal.hs +24/−1
- Text/Megaparsec/Stream.hs +21/−17
- Text/Megaparsec/Unicode.hs +44/−1
- megaparsec.cabal +8/−6
CHANGELOG.md view
@@ -1,5 +1,25 @@ *Megaparsec follows [SemVer](https://semver.org/).* +## Megaparsec 9.8.1++* Fixed the regression introduced by the fix for the [issue+ 572](https://github.com/mrkkrp/megaparsec/issues/572) which caused the+ position marker `^` to be missing in certain cases.+* This release officially supports GHC 9.6. This is the oldest GHC version+ we support at this time.++## Megaparsec 9.8.0++* Fixed the associativity of the `(<|>)` operator. [Issue+ 412](https://github.com/mrkkrp/megaparsec/issues/412).+* Fixed the loss of precision in `decimal`, `binary`, `octal`, and+ `hexadecimal` functions in `Text.Megaparsec.Byte.Lexer` and+ `Text.Megaparsec.Char.Lexer` when they are used to parse floating point+ numbers. [Issue 479](https://github.com/mrkkrp/megaparsec/issues/479).+* Fixed handling of zero-width characters in error messages. To that end,+ added `isZeroWidthChar` function in `Text.Megaparsec.Unicode`. [Issue+ 572](https://github.com/mrkkrp/megaparsec/issues/572).+ ## Megaparsec 9.7.1 * Typo fixes and compatibility with `QuickCheck >= 2.17` for
Text/Megaparsec/Byte/Lexer.hs view
@@ -41,7 +41,7 @@ import Control.Applicative import Data.Functor (void)-import Data.List (foldl')+import qualified Data.List import Data.Proxy import Data.Scientific (Scientific) import qualified Data.Scientific as Sci@@ -122,7 +122,7 @@ m a decimal_ = mkNum <$> takeWhile1P (Just "digit") isDigit where- mkNum = foldl' step 0 . chunkToTokens (Proxy :: Proxy s)+ mkNum = fromInteger . Data.List.foldl' step 0 . chunkToTokens (Proxy :: Proxy s) step a w = a * 10 + fromIntegral (w - 48) {-# INLINE decimal_ #-} @@ -145,7 +145,7 @@ <$> takeWhile1P Nothing isBinDigit <?> "binary integer" where- mkNum = foldl' step 0 . chunkToTokens (Proxy :: Proxy s)+ mkNum = fromInteger . Data.List.foldl' step 0 . chunkToTokens (Proxy :: Proxy s) step a w = a * 2 + fromIntegral (w - 48) isBinDigit w = w == 48 || w == 49 {-# INLINEABLE binary #-}@@ -170,7 +170,7 @@ <$> takeWhile1P Nothing isOctDigit <?> "octal integer" where- mkNum = foldl' step 0 . chunkToTokens (Proxy :: Proxy s)+ mkNum = fromInteger . Data.List.foldl' step 0 . chunkToTokens (Proxy :: Proxy s) step a w = a * 8 + fromIntegral (w - 48) isOctDigit w = w - 48 < 8 {-# INLINEABLE octal #-}@@ -195,7 +195,7 @@ <$> takeWhile1P Nothing isHexDigit <?> "hexadecimal integer" where- mkNum = foldl' step 0 . chunkToTokens (Proxy :: Proxy s)+ mkNum = fromInteger . Data.List.foldl' step 0 . chunkToTokens (Proxy :: Proxy s) step a w | w >= 48 && w <= 57 = a * 16 + fromIntegral (w - 48) | w >= 97 = a * 16 + fromIntegral (w - 87)@@ -256,7 +256,7 @@ m SP dotDecimal_ pxy c' = do void (B.char 46)- let mkNum = foldl' step (SP c' 0) . chunkToTokens pxy+ let mkNum = Data.List.foldl' step (SP c' 0) . chunkToTokens pxy step (SP a e') w = SP (a * 10 + fromIntegral (w - 48))
Text/Megaparsec/Char/Lexer.hs view
@@ -69,7 +69,7 @@ import Control.Applicative import Control.Monad (void) import qualified Data.Char as Char-import Data.List (foldl')+import qualified Data.List import Data.List.NonEmpty (NonEmpty (..)) import Data.Maybe (fromMaybe, isJust, listToMaybe) import Data.Proxy@@ -372,7 +372,7 @@ m a decimal_ = mkNum <$> takeWhile1P (Just "digit") Char.isDigit where- mkNum = foldl' step 0 . chunkToTokens (Proxy :: Proxy s)+ mkNum = fromInteger . Data.List.foldl' step 0 . chunkToTokens (Proxy :: Proxy s) step a c = a * 10 + fromIntegral (Char.digitToInt c) {-# INLINE decimal_ #-} @@ -395,7 +395,7 @@ <$> takeWhile1P Nothing isBinDigit <?> "binary integer" where- mkNum = foldl' step 0 . chunkToTokens (Proxy :: Proxy s)+ mkNum = fromInteger . Data.List.foldl' step 0 . chunkToTokens (Proxy :: Proxy s) step a c = a * 2 + fromIntegral (Char.digitToInt c) isBinDigit x = x == '0' || x == '1' {-# INLINEABLE binary #-}@@ -423,7 +423,7 @@ <$> takeWhile1P Nothing Char.isOctDigit <?> "octal integer" where- mkNum = foldl' step 0 . chunkToTokens (Proxy :: Proxy s)+ mkNum = fromInteger . Data.List.foldl' step 0 . chunkToTokens (Proxy :: Proxy s) step a c = a * 8 + fromIntegral (Char.digitToInt c) {-# INLINEABLE octal #-} @@ -450,7 +450,7 @@ <$> takeWhile1P Nothing Char.isHexDigit <?> "hexadecimal integer" where- mkNum = foldl' step 0 . chunkToTokens (Proxy :: Proxy s)+ mkNum = fromInteger . Data.List.foldl' step 0 . chunkToTokens (Proxy :: Proxy s) step a c = a * 16 + fromIntegral (Char.digitToInt c) {-# INLINEABLE hexadecimal #-} @@ -510,7 +510,7 @@ m SP dotDecimal_ pxy c' = do void (C.char '.')- let mkNum = foldl' step (SP c' 0) . chunkToTokens pxy+ let mkNum = Data.List.foldl' step (SP c' 0) . chunkToTokens pxy step (SP a e') c = SP (a * 10 + fromIntegral (Char.digitToInt c))
Text/Megaparsec/Error.hs view
@@ -415,7 +415,7 @@ pointerLen = if rpshift + elen > slineLen then slineLen - rpshift + 1- else elen+ else max 1 elen pointer = replicate pointerLen '^' lineNumber = (show . unPos . sourceLine) epos padding = replicate (length lineNumber + 1) ' '
Text/Megaparsec/Internal.hs view
@@ -357,9 +357,32 @@ let meerr err ms = let ncerr err' s' = cerr (err' <> err) (longestMatch ms s') neok x s' hs = eok x s' (toHints (stateOffset s') err <> hs)- neerr err' s' = eerr (err' <> err) (longestMatch ms s')+ neerr err' s' =+ let combinedErr = combineErrors (stateOffset s) err err'+ in eerr combinedErr (longestMatch ms s') in unParser n s cok ncerr neok neerr in unParser m s cok cerr eok meerr+ where+ combineErrors altOffset e1 e2 = case (e1, e2) of+ (TrivialError o1 u1 p1, TrivialError o2 u2 p2) ->+ -- When merging alternative errors, if one is ahead due to try, we+ -- bring both to the alternative position and union their expected+ -- tokens.+ if o1 > altOffset || o2 > altOffset+ then+ -- At least one error is ahead, normalize to alt position. Only+ -- include expected tokens from errors at the alt position.+ let p1' = if o1 == altOffset then p1 else E.empty+ p2' = if o2 == altOffset then p2 else E.empty+ -- Use the unexpected from the error at alt position, or the+ -- furthest.+ unexp = case (o1 `compare` altOffset, o2 `compare` altOffset) of+ (EQ, _) -> u1+ (_, EQ) -> u2+ _ -> if o1 >= o2 then u1 else u2+ in TrivialError altOffset unexp (E.union p1' p2')+ else e2 <> e1+ _ -> e2 <> e1 {-# INLINE pPlus #-} -- | From two states, return the one with the greater number of processed
Text/Megaparsec/Stream.hs view
@@ -40,8 +40,9 @@ import qualified Data.ByteString.Lazy as BL import qualified Data.ByteString.Lazy.Char8 as BL8 import Data.Char (chr)-import Data.Foldable (foldl', toList)+import Data.Foldable (toList) import Data.Kind (Type)+import qualified Data.List import Data.List.NonEmpty (NonEmpty (..)) import qualified Data.List.NonEmpty as NE import Data.Maybe (fromMaybe)@@ -514,9 +515,9 @@ instance TraversableStream String where -- NOTE Do not eta-reduce these (breaks inlining) reachOffset o pst =- reachOffset' splitAt foldl' id id ('\n', '\t') charInc o pst+ reachOffset' splitAt Data.List.foldl' id id ('\n', '\t') charInc o pst reachOffsetNoLine o pst =- reachOffsetNoLine' splitAt foldl' ('\n', '\t') charInc o pst+ reachOffsetNoLine' splitAt Data.List.foldl' ('\n', '\t') charInc o pst instance TraversableStream B.ByteString where -- NOTE Do not eta-reduce these (breaks inlining)@@ -568,8 +569,8 @@ (Token s -> Char) -> -- | Newline token and tab token (Token s, Token s) ->- -- | Increment in column position for a token- (Token s -> Pos) ->+ -- | Update column position for a token+ (Token s -> Pos -> Pos) -> -- | Offset to reach Int -> -- | Initial 'PosState' to use@@ -631,7 +632,7 @@ (g . (fromTok ch :)) | otherwise -> St- (SourcePos n l (c <> columnIncrement ch))+ (SourcePos n l (columnIncrement ch c)) (g . (fromTok ch :)) {-# INLINE reachOffset' #-} @@ -645,9 +646,9 @@ (forall b. (b -> Token s -> b) -> b -> Tokens s -> b) -> -- | Newline token and tab token (Token s, Token s) ->+ -- | Update column position for a token+ (Token s -> Pos -> Pos) -> -- | Offset to reach- -- | Increment in column position for a token- (Token s -> Pos) -> Int -> -- | Initial 'PosState' to use PosState s ->@@ -680,7 +681,7 @@ | ch == tabTok -> SourcePos n l (mkPos $ c' + w - ((c' - 1) `rem` w)) | otherwise ->- SourcePos n l (c <> columnIncrement ch)+ SourcePos n l (columnIncrement ch c) {-# INLINE reachOffsetNoLine' #-} -- | Like 'BL.splitAt' but accepts the index as an 'Int'.@@ -764,12 +765,15 @@ go !i n xs = ' ' : go (i + 1) (n - 1) xs w = unPos w' --- | Return increment in column position that corresponds to the given--- 'Char'.-charInc :: Char -> Pos-charInc ch = if Unicode.isWideChar ch then pos1 <> pos1 else pos1+-- | Return updated column position that corresponds to the given 'Char'.+charInc :: Char -> Pos -> Pos+charInc ch c+ | Unicode.isZeroWidthChar ch = c+ | Unicode.isWideChar ch = c <> pos1 <> pos1+ | otherwise = c <> pos1 --- | Return increment in column position that corresponds to the given--- 'Word8'.-byteInc :: Word8 -> Pos-byteInc _ = pos1+-- | Return updated column position that corresponds to the given 'Word8'.+byteInc :: Word8 -> Pos -> Pos+byteInc w c+ | w < 0x20 || (w >= 0x7f && w < 0xa0) = c -- C0 and C1 control chars+ | otherwise = c <> pos1
Text/Megaparsec/Unicode.hs view
@@ -16,6 +16,7 @@ ( stringLength, charLength, isWideChar,+ isZeroWidthChar, ) where @@ -33,7 +34,10 @@ -- -- @since 9.7.0 charLength :: Char -> Int-charLength ch = if isWideChar ch then 2 else 1+charLength ch+ | isZeroWidthChar ch = 0+ | isWideChar ch = 2+ | otherwise = 1 -- | Determine whether the given 'Char' is “wide”, that is, whether it spans -- 2 columns instead of one.@@ -52,6 +56,24 @@ (a, b) = wideCharRanges ! mid n = ord c +-- | Determine whether the given 'Char' is "zero-width", that is, whether it+-- has no visible representation and does not advance the cursor position.+-- This includes control characters and certain Unicode zero-width characters.+--+-- @since 9.8.0+isZeroWidthChar :: Char -> Bool+isZeroWidthChar c = go (bounds zeroWidthCharRanges)+ where+ go (lo, hi)+ | hi < lo = False+ | a <= n && n <= b = True+ | n < a = go (lo, pred mid)+ | otherwise = go (succ mid, hi)+ where+ mid = (lo + hi) `div` 2+ (a, b) = zeroWidthCharRanges ! mid+ n = ord c+ -- | Wide character ranges. wideCharRanges :: Array Int (Int, Int) wideCharRanges =@@ -178,3 +200,24 @@ (0x02f800, 0x02fa1d) ] {-# NOINLINE wideCharRanges #-}++-- | Zero-width character ranges.+zeroWidthCharRanges :: Array Int (Int, Int)+zeroWidthCharRanges =+ listArray+ (0, 12)+ [ (0x0000, 0x001f), -- C0 control characters+ (0x007f, 0x009f), -- DEL and C1 control characters+ (0x00ad, 0x00ad), -- Soft Hyphen+ (0x0300, 0x036f), -- Combining Diacritical Marks+ (0x0483, 0x0489), -- Combining Cyrillic+ (0x0591, 0x05bd), -- Hebrew combining marks+ (0x05bf, 0x05bf), -- Hebrew point+ (0x05c1, 0x05c2), -- Hebrew points+ (0x05c4, 0x05c5), -- Hebrew marks+ (0x05c7, 0x05c7), -- Hebrew point+ (0x0610, 0x061a), -- Arabic combining marks+ (0x200b, 0x200f), -- Zero width chars and directional marks+ (0x202a, 0x202e) -- Directional formatting+ ]+{-# NOINLINE zeroWidthCharRanges #-}
megaparsec.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.4 name: megaparsec-version: 9.7.1+version: 9.8.1 license: BSD-2-Clause license-file: LICENSE.md maintainer: Mark Karpov <markkarpov92@gmail.com>@@ -9,7 +9,9 @@ Paolo Martini <paolo@nemail.it>, Daan Leijen <daan@microsoft.com> -tested-with: ghc ==9.10.3 ghc ==9.12.4 ghc ==9.14.1+tested-with:+ ghc ==9.6.7 ghc ==9.8.4 ghc ==9.10.3 ghc ==9.12.4 ghc ==9.14.1+ homepage: https://github.com/mrkkrp/megaparsec bug-reports: https://github.com/mrkkrp/megaparsec/issues synopsis: Monadic parser combinators@@ -58,7 +60,7 @@ default-language: Haskell2010 build-depends: array >=0.5.3 && <0.6,- base >=4.15 && <5,+ base >=4.18 && <5, bytestring >=0.2 && <0.13, case-insensitive >=1.2 && <1.3, containers >=0.5 && <0.9,@@ -72,7 +74,7 @@ if flag(dev) ghc-options: -Wall -Werror -Wredundant-constraints -Wpartial-fields- -Wunused-packages -Wno-unused-imports+ -Wunused-packages else ghc-options: -O2 -Wall@@ -86,7 +88,7 @@ hs-source-dirs: bench/speed default-language: Haskell2010 build-depends:- base >=4.15 && <5,+ base >=4.18 && <5, bytestring >=0.2 && <0.13, containers >=0.5 && <0.9, criterion >=0.6.2.1 && <1.7,@@ -108,7 +110,7 @@ hs-source-dirs: bench/memory default-language: Haskell2010 build-depends:- base >=4.15 && <5,+ base >=4.18 && <5, bytestring >=0.2 && <0.13, containers >=0.5 && <0.9, deepseq >=1.3 && <1.6,