parsec 3.1.15.1 → 3.1.16.0
raw patch · 8 files changed
+124/−19 lines, 8 filesdep ~base
Dependency ranges changed: base
Files
- ChangeLog.md +4/−0
- README.md +2/−2
- parsec.cabal +9/−7
- src/Text/Parsec/Char.hs +13/−1
- src/Text/Parsec/Error.hs +6/−6
- src/Text/Parsec/Prim.hs +39/−0
- test/Features.hs +5/−3
- test/Features/Feature150.hs +46/−0
ChangeLog.md view
@@ -1,3 +1,7 @@+### 3.1.16.0++- Add `tokens'` and `string'` combinators which don't consume the prefix.+ ### 3.1.15.0 - Add `INLINABLE` pragmas to most overloaded combinators
README.md view
@@ -19,9 +19,9 @@ thanks to Microsoft Research). * [Using Parsec](http://book.realworldhaskell.org/read/using-parsec.html), chapter 16 of [Real World Haskell](http://book.realworldhaskell.org/).-* [An introduction to the Parsec library](http://kunigami.wordpress.com/2014/01/21/an-introduction-to-the-parsec-library)+* [An introduction to the Parsec library](https://www.kuniga.me/blog/2014/01/21/an-introduction-to-the-parsec-library.html) on Kunigami's blog.-* [An introduction to parsing text in Haskell with Parsec](http://unbui.lt/#!/post/haskell-parsec-basics) on Wilson's blog.+* [An introduction to parsing text in Haskell with Parsec](https://jsdw.me/posts/haskell-parsec-basics/) on Wilson's blog. * Differences between Parsec and [Attoparsec](http://hackage.haskell.org/package/attoparsec) (Haskell's other prominent parser library) as explained in
parsec.cabal view
@@ -1,6 +1,6 @@ cabal-version: 1.12 name: parsec-version: 3.1.15.1+version: 3.1.16.0 synopsis: Monadic parser combinators description: Parsec is designed from scratch as an industrial-strength parser@@ -64,7 +64,7 @@ Text.ParserCombinators.Parsec.Token build-depends:- base >= 4.5.1.0 && < 4.18,+ base >= 4.5.1.0 && < 4.19, mtl >= 2.1.3.1 && < 2.4, bytestring >= 0.9.2.1 && < 0.12, text (>= 1.2.3.0 && < 1.3)@@ -97,12 +97,13 @@ if impl(ghc >= 7.10) ghc-options: -fno-warn-trustworthy-safe - if impl(ghc >= 9.0)- -- these flags may abort compilation with GHC-8.10- -- https://gitlab.haskell.org/ghc/ghc/-/merge_requests/3295- ghc-options: -Winferred-safe-imports -Wmissing-safe-haskell-mode+ -- these flags may abort compilation with GHC-8.10+ -- https://gitlab.haskell.org/ghc/ghc/-/merge_requests/3295+ -- https://gitlab.haskell.org/ghc/ghc/-/issues/22728+ -- if impl(ghc >= 9.0)+ -- -- ghc-options: -Winferred-safe-imports -Wmissing-safe-haskell-mode -test-suite parsec.+test-suite parsec-tests type: exitcode-stdio-1.0 hs-source-dirs: test@@ -115,6 +116,7 @@ Bugs.Bug35 Features Features.Feature80+ Features.Feature150 Util build-depends:
src/Text/Parsec/Char.hs view
@@ -167,12 +167,24 @@ (\pos c _cs -> updatePosChar pos c) (\c -> if f c then Just c else Nothing) --- | @string s@ parses a sequence of characters given by @s@. Returns+-- | @'string' s@ parses a sequence of characters given by @s@. Returns -- the parsed string (i.e. @s@). -- -- > divOrMod = string "div" -- > <|> string "mod"+--+-- Consider using 'string''. string :: (Stream s m Char) => String -> ParsecT s u m String {-# INLINABLE string #-} string s = tokens show updatePosString s++-- | @'string'' s@ parses a sequence of characters given by @s@.+-- Doesn't consume matching prefix.+--+-- > carOrCdr = string' "car"+-- > <|> string' "cdr"++string' :: (Stream s m Char) => String -> ParsecT s u m String+{-# INLINABLE string' #-}+string' s = tokens' show updatePosString s
src/Text/Parsec/Error.hs view
@@ -189,12 +189,12 @@ showExpect = showMany msgExpecting expect showUnExpect = showMany msgUnExpected unExpect- showSysUnExpect | not (null unExpect) ||- null sysUnExpect = ""- | null firstMsg = msgUnExpected ++ " " ++ msgEndOfInput- | otherwise = msgUnExpected ++ " " ++ firstMsg- where- firstMsg = messageString (head sysUnExpect)+ showSysUnExpect+ | not (null unExpect) = ""+ | [] <- sysUnExpect = ""+ | msg : _ <- sysUnExpect+ , null (messageString msg) = msgUnExpected ++ " " ++ msgEndOfInput+ | msg : _ <- sysUnExpect = msgUnExpected ++ " " ++ messageString msg showMessages = showMany "" messages
src/Text/Parsec/Prim.hs view
@@ -53,6 +53,7 @@ , lookAhead , Stream(..) , tokens+ , tokens' , try , token , tokenPrim@@ -511,6 +512,44 @@ Nothing -> cerr $ errEof Just (x,xs) | t == x -> walk ts xs | otherwise -> cerr $ errExpect x++ ok rs = let pos' = nextposs pos tts+ s' = State rs pos' u+ in cok tts s' (newErrorUnknown pos')+ in do+ sr <- uncons input+ case sr of+ Nothing -> eerr $ errEof+ Just (x,xs)+ | tok == x -> walk toks xs+ | otherwise -> eerr $ errExpect x++-- | Like 'tokens', but doesn't consume matching prefix.+tokens' :: (Stream s m t, Eq t)+ => ([t] -> String) -- Pretty print a list of tokens+ -> (SourcePos -> [t] -> SourcePos)+ -> [t] -- List of tokens to parse+ -> ParsecT s u m [t]+{-# INLINE tokens' #-}+tokens' _ _ []+ = ParsecT $ \s _ _ eok _ ->+ eok [] s $ unknownError s+tokens' showTokens nextposs tts@(tok:toks)+ = ParsecT $ \(State input pos u) cok cerr _eok eerr ->+ let+ errEof = (setErrorMessage (Expect (showTokens tts))+ (newErrorMessage (SysUnExpect "") pos))++ errExpect x = (setErrorMessage (Expect (showTokens tts))+ (newErrorMessage (SysUnExpect (showTokens [x])) pos))++ walk [] rs = ok rs+ walk (t:ts) rs = do+ sr <- uncons rs+ case sr of+ Nothing -> eerr $ errEof+ Just (x,xs) | t == x -> walk ts xs+ | otherwise -> eerr $ errExpect x ok rs = let pos' = nextposs pos tts s' = State rs pos' u
test/Features.hs view
@@ -5,8 +5,10 @@ import Test.Tasty import qualified Features.Feature80+import qualified Features.Feature150 features :: [TestTree]-features = [- Features.Feature80.main- ]+features =+ [ Features.Feature80.main+ , Features.Feature150.main+ ]
+ test/Features/Feature150.hs view
@@ -0,0 +1,46 @@+module Features.Feature150 ( main ) where++import Control.Applicative ((*>))+import Control.Monad.Identity+import Test.Tasty+import Test.Tasty.HUnit++import Text.Parsec++main :: TestTree+main =+ testCase "string' (#150)" $ do+ parseString (boot <|> bool) "boot" @?= "boot"+ parseFail (boot <|> bool) "bool" @?= "no parse"+ parseFail (boot <|> bool) "booz" @?= "no parse"++ parseString (boot' <|> bool') "boot" @?= "boot"+ parseString (boot' <|> bool') "bool" @?= "bool"+ parseFail (boot' <|> bool') "booz" @?= "no parse"++ parseString (boot' <|> bool' <|> char 'b' *> many anyChar) "boomerang" @?= "oomerang"++ where+ boot :: ParsecT String () Identity String+ boot = string "boot"++ bool :: ParsecT String () Identity String+ bool = string "bool"++ boot' :: ParsecT String () Identity String+ boot' = string' "boot"++ bool' :: ParsecT String () Identity String+ bool' = string' "bool"++ parseString :: ParsecT String () Identity String -> String -> String+ parseString p input =+ case parse p "Example" input of+ Left{} -> error "Parse failure"+ Right str -> str++ parseFail :: ParsecT String () Identity String -> String -> String+ parseFail p input =+ case parse p "Example" input of+ Left{} -> "no parse"+ Right _ -> error "Parsed but shouldn't"