packages feed

parsec 3.1.13.0 → 3.1.18.0

raw patch · 29 files changed

Files

ChangeLog.md view
@@ -1,3 +1,34 @@+### 3.1.18.0++- Drop support for GHCs prior 8.6.5++### 3.1.17.0++- Move `many1 :: ParsecT s u m a -> ParsecT s u m [a]` to `Text.Parsec.Prim`.+  Drop `Stream` constraint requirement.+- Change the position comparison in `mergeError` to not compare source names.+  This doesn't alter reported error positions when only a single source is parsed.+  This fixes performance issue caused by long source names.+- Add `Exception ParseError` instance++### 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+- Support recent versions of dependencies+- Fix memory leak in `>>=` https://github.com/haskell/parsec/issues/127++### 3.1.14.0++- Add `parseFromFile` to `Text.Parsec.Text.Lazy` and `Text.Parsec.Text` (#103, #104).++- Clarify Haddock documentation in various places (#105,#101,#102).++- Add support for `base-4.13`.+ ### 3.1.13.0  - Add official support for [`SafeHaskell`](http://downloads.haskell.org/~ghc/latest/docs/html/users_guide/safe_haskell.html)@@ -45,7 +76,7 @@  ### 3.1.9 -- Many and various updates to documentation and package description (inlcuding+- Many and various updates to documentation and package description (including   the homepage links). - Add an `Eq` instance for `ParseError` - Fixed a regression from 3.1.6: `runP` is again exported from module
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,127 +1,179 @@-cabal-version:  1.12-name:           parsec-version:        3.1.13.0+cabal-version:      1.12+name:               parsec+version:            3.1.18.0+synopsis:           Monadic parser combinators+description:+  Parsec is designed from scratch as an industrial-strength parser+  library.  It is simple, safe, well documented (on the package+  homepage), has extensive libraries, good error messages,+  and is fast.  It is defined as a monad transformer that can be+  stacked on arbitrary monads, and it is also parametric in the+  input stream type.+  .+  The main entry point is the "Text.Parsec" module which provides+  defaults for parsing 'Char'acter data.+  .+  The "Text.ParserCombinators.Parsec" module hierarchy contains+  the legacy @parsec-2@ API and may be removed at some point in+  the future. -synopsis:       Monadic parser combinators-description:    Parsec is designed from scratch as an industrial-strength parser-                library.  It is simple, safe, well documented (on the package-                homepage), has extensive libraries, good error messages,-                and is fast.  It is defined as a monad transformer that can be-                stacked on arbitrary monads, and it is also parametric in the-                input stream type.-                .-                The main entry point is the "Text.Parsec" module which provides-                defaults for parsing 'Char'acter data.-                .-                The "Text.ParserCombinators.Parsec" module hierarchy contains-                the legacy @parsec-2@ API and may be removed at some point in-                the future.+license:            BSD2+license-file:       LICENSE+author:+  Daan Leijen <daan@microsoft.com>, Paolo Martini <paolo@nemail.it>, Antoine Latter <aslatter@gmail.com> -license:        BSD3-license-file:   LICENSE-author:         Daan Leijen <daan@microsoft.com>, Paolo Martini <paolo@nemail.it>, Antoine Latter <aslatter@gmail.com>-maintainer:     Herbert Valerio Riedel <hvr@gnu.org>-homepage:       https://github.com/hvr/parsec-bug-reports:    https://github.com/hvr/parsec/issues-category:       Parsing+maintainer:+  Oleg Grenrus <oleg.grenrus@iki.fi>, Herbert Valerio Riedel <hvr@gnu.org> -build-type:     Simple-tested-with:    GHC ==8.4.1 || ==8.2.2 || ==8.0.2 || ==7.10.3 || ==7.8.4 || ==7.6.3 || ==7.4.2+homepage:           https://github.com/haskell/parsec+bug-reports:        https://github.com/haskell/parsec/issues+category:           Parsing+build-type:         Simple+tested-with:+  GHC ==8.6.5+   || ==8.8.4+   || ==8.10.7+   || ==9.0.2+   || ==9.2.8+   || ==9.4.8+   || ==9.6.4+   || ==9.8.2+   || ==9.10.1+   || ==9.12.1 -extra-source-files: ChangeLog.md, README.md+extra-source-files:+  ChangeLog.md+  README.md  source-repository head-    type: git-    location: https://github.com/hvr/parsec+  type:     git+  location: https://github.com/haskell/parsec  library-    hs-source-dirs: src-    exposed-modules:-        Text.Parsec-        Text.Parsec.String-        Text.Parsec.ByteString-        Text.Parsec.ByteString.Lazy-        Text.Parsec.Text-        Text.Parsec.Text.Lazy-        Text.Parsec.Pos-        Text.Parsec.Error-        Text.Parsec.Prim-        Text.Parsec.Char-        Text.Parsec.Combinator-        Text.Parsec.Token-        Text.Parsec.Expr-        Text.Parsec.Language-        Text.Parsec.Perm-        Text.ParserCombinators.Parsec-        Text.ParserCombinators.Parsec.Char-        Text.ParserCombinators.Parsec.Combinator-        Text.ParserCombinators.Parsec.Error-        Text.ParserCombinators.Parsec.Expr-        Text.ParserCombinators.Parsec.Language-        Text.ParserCombinators.Parsec.Perm-        Text.ParserCombinators.Parsec.Pos-        Text.ParserCombinators.Parsec.Prim-        Text.ParserCombinators.Parsec.Token+  hs-source-dirs:   src+  exposed-modules:+    Text.Parsec+    Text.Parsec.ByteString+    Text.Parsec.ByteString.Lazy+    Text.Parsec.Char+    Text.Parsec.Combinator+    Text.Parsec.Error+    Text.Parsec.Expr+    Text.Parsec.Language+    Text.Parsec.Perm+    Text.Parsec.Pos+    Text.Parsec.Prim+    Text.Parsec.String+    Text.Parsec.Text+    Text.Parsec.Text.Lazy+    Text.Parsec.Token+    Text.ParserCombinators.Parsec+    Text.ParserCombinators.Parsec.Char+    Text.ParserCombinators.Parsec.Combinator+    Text.ParserCombinators.Parsec.Error+    Text.ParserCombinators.Parsec.Expr+    Text.ParserCombinators.Parsec.Language+    Text.ParserCombinators.Parsec.Perm+    Text.ParserCombinators.Parsec.Pos+    Text.ParserCombinators.Parsec.Prim+    Text.ParserCombinators.Parsec.Token -    build-depends:-        base       >= 4.5.1   && < 4.12,-        mtl        >= 1.1.1   && < 2.3,-        bytestring >= 0.9.2.1 && < 0.11,-        text       >= 0.11.3  && < 1.3+  build-depends:+      base        >=4.12.0.0 && <4.22+    , bytestring  >=0.10.8.2 && <0.13+    , mtl         >=2.2.2    && <2.4+    , text        >=1.2.3.0  && <1.3  || >=2.0 && <2.2 -    default-language: Haskell2010-    other-extensions:-        CPP-        DeriveDataTypeable-        ExistentialQuantification-        FlexibleContexts-        FlexibleInstances-        FunctionalDependencies-        MultiParamTypeClasses-        PolymorphicComponents-        StandaloneDeriving-        Safe-        Trustworthy-        UndecidableInstances+  default-language: Haskell2010+  other-extensions:+    CPP+    DeriveDataTypeable+    ExistentialQuantification+    FlexibleContexts+    FlexibleInstances+    FunctionalDependencies+    MultiParamTypeClasses+    PolymorphicComponents+    Safe+    StandaloneDeriving+    Trustworthy+    UndecidableInstances -    ghc-options: -Wall-    if impl(ghc >= 8.0)-        ghc-options: -Wcompat -Wnoncanonical-monad-instances -Wnoncanonical-monadfail-instances -Wno-trustworthy-safe-    else-        -- provide/emulate `Control.Monad.Fail` and `Semigroup` API for pre-GHC8-        build-depends: fail == 4.9.*, semigroups == 0.18.*+  ghc-options:      -Wall+  ghc-options:+    -Wcompat -Wnoncanonical-monad-instances -Wno-trustworthy-safe -        if impl(ghc >= 7.10)-            ghc-options: -fno-warn-trustworthy-safe+  if impl(ghc <8.8)+    ghc-options: -Wnoncanonical-monadfail-instances -test-suite parsec.-    type: exitcode-stdio-1.0+-- 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 -    hs-source-dirs: test-    main-is: Main.hs-    other-modules:-        Bugs-        Bugs.Bug2-        Bugs.Bug6-        Bugs.Bug9-        Bugs.Bug35-        Features-        Features.Feature80-        Util+test-suite parsec-tests+  type:             exitcode-stdio-1.0+  hs-source-dirs:   test+  main-is:          Main.hs+  other-modules:+    Bugs+    Bugs.Bug2+    Bugs.Bug35+    Bugs.Bug6+    Bugs.Bug9+    Features+    Features.Feature150+    Features.Feature80+    Util -    build-depends:-        base,-        mtl,-        parsec,-        -- dependencies whose version bounds are not inherited via lib:parsec-        HUnit                == 1.6.* || (>= 1.3.1.2 && < 1.4),-        test-framework       == 0.8.*,-        test-framework-hunit == 0.3.*+  build-depends:+      base+    , mtl+    , parsec+    , tasty        >=1.4  && <1.6+    , tasty-hunit  >=0.10 && <0.11 -    default-language: Haskell2010+  -- dependencies whose version bounds are not inherited via lib:parsec+  default-language: Haskell2010+  ghc-options:      -Wall -    ghc-options: -Wall-    if impl(ghc >= 8.0)-        ghc-options: -Wcompat -Wnoncanonical-monad-instances -Wnoncanonical-monadfail-instances-    else-        build-depends: semigroups == 0.18.*+  if impl(ghc >=8.0)+    ghc-options:+      -Wcompat -Wnoncanonical-monad-instances+      -Wnoncanonical-monadfail-instances++  else+    build-depends: semigroups++test-suite parsec-issue127+  default-language: Haskell2010+  type:             exitcode-stdio-1.0+  main-is:          issue127.hs+  hs-source-dirs:   test+  build-depends:+      base+    , parsec++test-suite parsec-issue171+  default-language: Haskell2010+  type:             exitcode-stdio-1.0+  main-is:          issue171.hs+  hs-source-dirs:   test+  build-depends:+      base+    , deepseq+    , parsec+    , tasty+    , tasty-hunit++test-suite parsec-issue175+  default-language: Haskell2010+  type:             exitcode-stdio-1.0+  main-is:          issue175.hs+  hs-source-dirs:   test+  build-depends:+      base+    , parsec+    , tasty+    , tasty-hunit
src/Text/Parsec/ByteString.hs view
@@ -10,7 +10,7 @@ -- Stability   :  provisional -- Portability :  portable ----- Convinience definitions for working with 'C.ByteString's.+-- Convenience definitions for working with 'C.ByteString's. -- ----------------------------------------------------------------------------- @@ -18,11 +18,11 @@     ( Parser, GenParser, parseFromFile     ) where +import qualified Data.ByteString.Char8 as C+ import Text.Parsec.Error import Text.Parsec.Prim -import qualified Data.ByteString.Char8 as C- type Parser = Parsec C.ByteString () type GenParser t st = Parsec C.ByteString st @@ -36,7 +36,7 @@ -- >                  Right xs  -> print (sum xs) -- >              } -parseFromFile :: Parser a -> String -> IO (Either ParseError a)+parseFromFile :: Parser a -> FilePath -> IO (Either ParseError a) parseFromFile p fname     = do input <- C.readFile fname          return (runP p () fname input)
src/Text/Parsec/ByteString/Lazy.hs view
@@ -10,7 +10,7 @@ -- Stability   :  provisional -- Portability :  portable ----- Convinience definitions for working with lazy 'C.ByteString's.+-- Convenience definitions for working with lazy 'C.ByteString's. -- ----------------------------------------------------------------------------- @@ -18,11 +18,11 @@     ( Parser, GenParser, parseFromFile     ) where +import qualified Data.ByteString.Lazy.Char8 as C+ import Text.Parsec.Error import Text.Parsec.Prim -import qualified Data.ByteString.Lazy.Char8 as C- type Parser = Parsec C.ByteString () type GenParser t st = Parsec C.ByteString st @@ -35,7 +35,8 @@ -- >                  Left err  -> print err -- >                  Right xs  -> print (sum xs) -- >              }-parseFromFile :: Parser a -> String -> IO (Either ParseError a)++parseFromFile :: Parser a -> FilePath -> IO (Either ParseError a) parseFromFile p fname     = do input <- C.readFile fname          return (runP p () fname input)
src/Text/Parsec/Char.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE CPP, FlexibleContexts, Safe #-}+{-# LANGUAGE FlexibleContexts, Safe #-}  ----------------------------------------------------------------------------- -- |@@ -16,12 +16,10 @@  module Text.Parsec.Char where -import Data.Char+import Data.Char (isSpace, isUpper, isLower, isAlphaNum, isAlpha, isDigit, isHexDigit, isOctDigit)+ import Text.Parsec.Pos import Text.Parsec.Prim-#if !(MIN_VERSION_base(4,8,0))-import Control.Applicative ((*>))-#endif  -- | @oneOf cs@ succeeds if the current character is in the supplied -- list of characters @cs@. Returns the parsed character. See also@@ -30,6 +28,7 @@ -- >   vowel  = oneOf "aeiou"  oneOf :: (Stream s m Char) => [Char] -> ParsecT s u m Char+{-# INLINABLE oneOf #-} oneOf cs            = satisfy (\c -> elem c cs)  -- | As the dual of 'oneOf', @noneOf cs@ succeeds if the current@@ -39,28 +38,33 @@ -- >  consonant = noneOf "aeiou"  noneOf :: (Stream s m Char) => [Char] -> ParsecT s u m Char+{-# INLINABLE noneOf #-} noneOf cs           = satisfy (\c -> not (elem c cs))  -- | Skips /zero/ or more white space characters. See also 'skipMany'.  spaces :: (Stream s m Char) => ParsecT s u m ()+{-# INLINABLE spaces #-} spaces              = skipMany space        <?> "white space"  -- | Parses a white space character (any character which satisfies 'isSpace') -- Returns the parsed character.  space :: (Stream s m Char) => ParsecT s u m Char+{-# INLINABLE space #-} space               = satisfy isSpace       <?> "space"  -- | Parses a newline character (\'\\n\'). Returns a newline character.  newline :: (Stream s m Char) => ParsecT s u m Char+{-# INLINABLE newline #-} newline             = char '\n'             <?> "lf new-line"  -- | Parses a carriage return character (\'\\r\') followed by a newline character (\'\\n\'). -- Returns a newline character.  crlf :: (Stream s m Char) => ParsecT s u m Char+{-# INLINABLE crlf #-} crlf                = char '\r' *> char '\n' <?> "crlf new-line"  -- | Parses a CRLF (see 'crlf') or LF (see 'newline') end-of-line.@@ -70,52 +74,66 @@ --  endOfLine :: (Stream s m Char) => ParsecT s u m Char+{-# INLINABLE endOfLine #-} endOfLine           = newline <|> crlf       <?> "new-line"  -- | Parses a tab character (\'\\t\'). Returns a tab character.  tab :: (Stream s m Char) => ParsecT s u m Char+{-# INLINABLE tab #-} tab                 = char '\t'             <?> "tab"  -- | Parses an upper case letter (according to 'isUpper'). -- Returns the parsed character.  upper :: (Stream s m Char) => ParsecT s u m Char+{-# INLINABLE upper #-} upper               = satisfy isUpper       <?> "uppercase letter"  -- | Parses a lower case character (according to 'isLower'). -- Returns the parsed character.  lower :: (Stream s m Char) => ParsecT s u m Char+{-# INLINABLE lower #-} lower               = satisfy isLower       <?> "lowercase letter" --- | Parses a letter or digit (a character between \'0\' and \'9\')+-- | Parses a alphabetic or numeric Unicode characters -- according to 'isAlphaNum'. Returns the parsed character.+--+-- Note that numeric digits outside the ASCII range (such as arabic-indic digits like e.g. \"٤\" or @U+0664@),+-- as well as numeric characters which aren't digits, are parsed by this function+-- but not by 'digit'.  alphaNum :: (Stream s m Char => ParsecT s u m Char)+{-# INLINABLE alphaNum #-} alphaNum            = satisfy isAlphaNum    <?> "letter or digit" --- | Parses a letter (an upper case or lower case character according--- to 'isAlpha'). Returns the parsed character.+-- | Parses an alphabetic Unicode characters (lower-case, upper-case and title-case letters,+-- plus letters of caseless scripts and modifiers letters according to 'isAlpha').+-- Returns the parsed character.  letter :: (Stream s m Char) => ParsecT s u m Char+{-# INLINABLE letter #-} letter              = satisfy isAlpha       <?> "letter" --- | Parses a digit. Returns the parsed character.+-- | Parses an ASCII digit. Returns the parsed character.  digit :: (Stream s m Char) => ParsecT s u m Char+{-# INLINABLE digit #-} digit               = satisfy isDigit       <?> "digit"  -- | Parses a hexadecimal digit (a digit or a letter between \'a\' and -- \'f\' or \'A\' and \'F\'). Returns the parsed character.  hexDigit :: (Stream s m Char) => ParsecT s u m Char+{-# INLINABLE hexDigit #-} hexDigit            = satisfy isHexDigit    <?> "hexadecimal digit"  -- | Parses an octal digit (a character between \'0\' and \'7\'). Returns -- the parsed character.  octDigit :: (Stream s m Char) => ParsecT s u m Char+{-# INLINABLE octDigit #-} octDigit            = satisfy isOctDigit    <?> "octal digit"  -- | @char c@ parses a single character @c@. Returns the parsed@@ -124,11 +142,13 @@ -- >  semiColon  = char ';'  char :: (Stream s m Char) => Char -> ParsecT s u m Char+{-# INLINABLE char #-} char c              = satisfy (==c)  <?> show [c]  -- | This parser succeeds for any character. Returns the parsed character.  anyChar :: (Stream s m Char) => ParsecT s u m Char+{-# INLINABLE anyChar #-} anyChar             = satisfy (const True)  -- | The parser @satisfy f@ succeeds for any character for which the@@ -139,15 +159,31 @@ -- >  oneOf cs  = satisfy (\c -> c `elem` cs)  satisfy :: (Stream s m Char) => (Char -> Bool) -> ParsecT s u m Char+{-# INLINABLE satisfy #-} satisfy f           = tokenPrim (\c -> show [c])                                 (\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"+--+-- @since 3.1.16.0++string' :: (Stream s m Char) => String -> ParsecT s u m String+{-# INLINABLE string' #-}+string' s            = tokens' show updatePosString s
src/Text/Parsec/Combinator.hs view
@@ -42,15 +42,17 @@     , parserTrace, parserTraced     ) where -import Control.Monad-import Text.Parsec.Prim+import Control.Monad (mzero, liftM) import Debug.Trace (trace) +import Text.Parsec.Prim+ -- | @choice ps@ tries to apply the parsers in the list @ps@ in order, -- until one of them succeeds. Returns the value of the succeeding -- parser.  choice :: (Stream s m t) => [ParsecT s u m a] -> ParsecT s u m a+{-# INLINABLE choice #-} choice ps           = foldr (<|>) mzero ps  -- | @option x p@ tries to apply parser @p@. If @p@ fails without@@ -62,6 +64,7 @@ -- >                          })  option :: (Stream s m t) => a -> ParsecT s u m a -> ParsecT s u m a+{-# INLINABLE option #-} option x p          = p <|> return x  -- | @optionMaybe p@ tries to apply parser @p@.  If @p@ fails without@@ -69,6 +72,7 @@ -- 'Just' the value returned by @p@.  optionMaybe :: (Stream s m t) => ParsecT s u m a -> ParsecT s u m (Maybe a)+{-# INLINABLE optionMaybe #-} optionMaybe p       = option Nothing (liftM Just p)  -- | @optional p@ tries to apply parser @p@.  It will parse @p@ or nothing.@@ -76,6 +80,7 @@ -- of @p@.  optional :: (Stream s m t) => ParsecT s u m a -> ParsecT s u m ()+{-# INLINABLE optional #-} optional p          = do{ _ <- p; return ()} <|> return ()  -- | @between open close p@ parses @open@, followed by @p@ and @close@.@@ -85,6 +90,7 @@  between :: (Stream s m t) => ParsecT s u m open -> ParsecT s u m close             -> ParsecT s u m a -> ParsecT s u m a+{-# INLINABLE between #-} between open close p                     = do{ _ <- open; x <- p; _ <- close; return x } @@ -92,6 +98,7 @@ -- its result.  skipMany1 :: (Stream s m t) => ParsecT s u m a -> ParsecT s u m ()+{-# INLINABLE skipMany1 #-} skipMany1 p         = do{ _ <- p; skipMany p } {- skipMany p          = scan@@ -99,35 +106,20 @@                       scan  = do{ p; scan } <|> return () -} --- | @many1 p@ applies the parser @p@ /one/ or more times. Returns a--- list of the returned values of @p@.------ >  word  = many1 letter--many1 :: (Stream s m t) => ParsecT s u m a -> ParsecT s u m [a]-many1 p             = do{ x <- p; xs <- many p; return (x:xs) }-{--many p              = scan id-                    where-                      scan f    = do{ x <- p-                                    ; scan (\tail -> f (x:tail))-                                    }-                                <|> return (f [])--}-- -- | @sepBy p sep@ parses /zero/ or more occurrences of @p@, separated -- by @sep@. Returns a list of values returned by @p@. -- -- >  commaSep p  = p `sepBy` (symbol ",")  sepBy :: (Stream s m t) => ParsecT s u m a -> ParsecT s u m sep -> ParsecT s u m [a]+{-# INLINABLE sepBy #-} sepBy p sep         = sepBy1 p sep <|> return []  -- | @sepBy1 p sep@ parses /one/ or more occurrences of @p@, separated -- by @sep@. Returns a list of values returned by @p@.  sepBy1 :: (Stream s m t) => ParsecT s u m a -> ParsecT s u m sep -> ParsecT s u m [a]+{-# INLINABLE sepBy1 #-} sepBy1 p sep        = do{ x <- p                         ; xs <- many (sep >> p)                         ; return (x:xs)@@ -139,6 +131,7 @@ -- returned by @p@.  sepEndBy1 :: (Stream s m t) => ParsecT s u m a -> ParsecT s u m sep -> ParsecT s u m [a]+{-# INLINABLE sepEndBy1 #-} sepEndBy1 p sep     = do{ x <- p                         ; do{ _ <- sep                             ; xs <- sepEndBy p sep@@ -154,6 +147,7 @@ -- >  haskellStatements  = haskellStatement `sepEndBy` semi  sepEndBy :: (Stream s m t) => ParsecT s u m a -> ParsecT s u m sep -> ParsecT s u m [a]+{-# INLINABLE sepEndBy #-} sepEndBy p sep      = sepEndBy1 p sep <|> return []  @@ -161,6 +155,7 @@ -- and ended by @sep@. Returns a list of values returned by @p@.  endBy1 :: (Stream s m t) => ParsecT s u m a -> ParsecT s u m sep -> ParsecT s u m [a]+{-# INLINABLE endBy1 #-} endBy1 p sep        = many1 (do{ x <- p; _ <- sep; return x })  -- | @endBy p sep@ parses /zero/ or more occurrences of @p@, separated@@ -169,6 +164,7 @@ -- >   cStatements  = cStatement `endBy` semi  endBy :: (Stream s m t) => ParsecT s u m a -> ParsecT s u m sep -> ParsecT s u m [a]+{-# INLINABLE endBy #-} endBy p sep         = many (do{ x <- p; _ <- sep; return x })  -- | @count n p@ parses @n@ occurrences of @p@. If @n@ is smaller or@@ -176,6 +172,7 @@ -- @n@ values returned by @p@.  count :: (Stream s m t) => Int -> ParsecT s u m a -> ParsecT s u m [a]+{-# INLINABLE count #-} count n p           | n <= 0    = return []                     | otherwise = sequence (replicate n p) @@ -186,6 +183,7 @@ -- returned.  chainr :: (Stream s m t) => ParsecT s u m a -> ParsecT s u m (a -> a -> a) -> a -> ParsecT s u m a+{-# INLINABLE chainr #-} chainr p op x       = chainr1 p op <|> return x  -- | @chainl p op x@ parses /zero/ or more occurrences of @p@,@@ -195,6 +193,7 @@ -- returned.  chainl :: (Stream s m t) => ParsecT s u m a -> ParsecT s u m (a -> a -> a) -> a -> ParsecT s u m a+{-# INLINABLE chainl #-} chainl p op x       = chainl1 p op <|> return x  -- | @chainl1 p op@ parses /one/ or more occurrences of @p@,@@ -214,6 +213,7 @@ -- >          <|> do{ symbol "-"; return (-) }  chainl1 :: (Stream s m t) => ParsecT s u m a -> ParsecT s u m (a -> a -> a) -> ParsecT s u m a+{-# INLINABLE chainl1 #-} chainl1 p op        = do{ x <- p; rest x }                     where                       rest x    = do{ f <- op@@ -228,6 +228,7 @@ -- by @p@.  chainr1 :: (Stream s m t) => ParsecT s u m a -> ParsecT s u m (a -> a -> a) -> ParsecT s u m a+{-# INLINABLE chainr1 #-} chainr1 p op        = scan                     where                       scan      = do{ x <- p; rest x }@@ -245,6 +246,7 @@ -- used to implement 'eof'. Returns the accepted token.  anyToken :: (Stream s m t, Show t) => ParsecT s u m t+{-# INLINABLE anyToken #-} anyToken            = tokenPrim show (\pos _tok _toks -> pos) Just  -- | This parser only succeeds at the end of the input. This is not a@@ -253,6 +255,7 @@ -- >  eof  = notFollowedBy anyToken <?> "end of input"  eof :: (Stream s m t, Show t) => ParsecT s u m ()+{-# INLINABLE eof #-} eof                 = notFollowedBy anyToken <?> "end of input"  -- | @notFollowedBy p@ only succeeds when parser @p@ fails. This parser@@ -279,6 +282,7 @@ -- for more details.  notFollowedBy :: (Stream s m t, Show a) => ParsecT s u m a -> ParsecT s u m ()+{-# INLINABLE notFollowedBy #-} notFollowedBy p     = try (do{ c <- try p; unexpected (show c) }                            <|> return ()                           )@@ -295,6 +299,7 @@ --    therefore the use of the 'try' combinator.  manyTill :: (Stream s m t) => ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]+{-# INLINABLE manyTill #-} manyTill p end      = scan                     where                       scan  = do{ _ <- end; return [] }@@ -311,6 +316,7 @@ -- -- @since 3.1.12.0 parserTrace :: (Show t, Stream s m t) => String -> ParsecT s u m ()+{-# INLINABLE parserTrace #-} parserTrace s = pt <|> return ()     where         pt = try $ do@@ -332,6 +338,7 @@ -- -- @since 3.1.12.0 parserTraced :: (Stream s m t, Show t) => String -> ParsecT s u m b -> ParsecT s u m b+{-# INLINABLE parserTraced #-} parserTraced s p = do   parserTrace s   p <|> trace (s ++ " backtracked") (fail s)
src/Text/Parsec/Error.hs view
@@ -25,8 +25,10 @@     , mergeError     ) where +import Control.Exception ( Exception ) import Data.List ( nub, sort ) import Data.Typeable ( Typeable )+import qualified Data.Monoid as Mon  import Text.Parsec.Pos @@ -145,12 +147,17 @@     | null msgs2 && not (null msgs1) = e1     | null msgs1 && not (null msgs2) = e2     | otherwise-    = case pos1 `compare` pos2 of+      -- perfectly we'd compare the consumed token count+      -- https://github.com/haskell/parsec/issues/175+    = case compareErrorPos pos1 pos2 of         -- select the longest match         EQ -> ParseError pos1 (msgs1 ++ msgs2)         GT -> e1         LT -> e2 +compareErrorPos :: SourcePos -> SourcePos -> Ordering+compareErrorPos x y = Mon.mappend (compare (sourceLine x) (sourceLine y)) (compare (sourceColumn x) (sourceColumn y))+ instance Show ParseError where     show err         = show (errorPos err) ++ ":" ++@@ -164,6 +171,9 @@         where           messageStrs = map messageString . errorMessages +-- | @since 3.1.17.0+instance Exception ParseError+ -- Language independent show function  --  TODO@@ -189,12 +199,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/Expr.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE CPP #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE Safe #-} @@ -46,9 +45,7 @@ data Operator s u m a   = Infix (ParsecT s u m (a -> a -> a)) Assoc                         | Prefix (ParsecT s u m (a -> a))                         | Postfix (ParsecT s u m (a -> a))-#if MIN_VERSION_base(4,7,0)     deriving ( Typeable )-#endif  -- | An @OperatorTable s u m a@ is a list of @Operator s u m a@ -- lists. The list is ordered in descending@@ -96,6 +93,7 @@                       => OperatorTable s u m a                       -> ParsecT s u m a                       -> ParsecT s u m a+{-# INLINABLE buildExpressionParser #-} buildExpressionParser operators simpleExpr     = foldl (makeParser) simpleExpr operators     where
src/Text/Parsec/Language.hs view
@@ -98,7 +98,7 @@ -- Haskell ----------------------------------------------------------- --- | A lexer for the haskell language.+-- | A lexer for the Haskell language.  haskell :: TokenParser st haskell      = makeTokenParser haskellDef@@ -135,7 +135,7 @@ -- Mondrian ----------------------------------------------------------- --- | A lexer for the mondrian language.+-- | A lexer for the Mondrian language.  mondrian :: TokenParser st mondrian    = makeTokenParser mondrianDef
src/Text/Parsec/Perm.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE CPP #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE ExistentialQuantification #-} {-# LANGUAGE FlexibleContexts #-}@@ -23,6 +22,12 @@ -- by Arthur Baars, Andres Loh and Doaitse Swierstra. -- Published as a functional pearl at the Haskell Workshop 2001. --+-- From the abstract: +--+-- A permutation phrase is a sequence of elements (possibly of different types) +-- in which each element occurs exactly once and the order is irrelevant. +-- Some of the permutable elements may be optional.+-- -----------------------------------------------------------------------------  @@ -35,15 +40,9 @@     , (<|?>), (<$?>)     ) where -import Text.Parsec--import Control.Monad.Identity-#if MIN_VERSION_base(4,7,0)+import Control.Monad.Identity ( Identity ) import Data.Typeable ( Typeable )-#else--- For GHC 7.6-import Data.Typeable ( Typeable3 )-#endif+import Text.Parsec  infixl 1 <||>, <|?> infixl 2 <$$>, <$?>@@ -131,20 +130,12 @@ -- using 'permute'.  data StreamPermParser s st a = Perm (Maybe a) [StreamBranch s st a]-#if MIN_VERSION_base(4,7,0)     deriving ( Typeable )-#else-deriving instance Typeable3 StreamPermParser-#endif  -- type Branch st a = StreamBranch String st a  data StreamBranch s st a = forall b. Branch (StreamPermParser s st (b -> a)) (Parsec s st b)-#if MIN_VERSION_base(4,7,0)     deriving ( Typeable )-#else-deriving instance Typeable3 StreamBranch-#endif  -- | The parser @permute perm@ parses a permutation of parser described -- by @perm@. For example, suppose we want to parse a permutation of:
src/Text/Parsec/Prim.hs view
@@ -53,6 +53,7 @@     , lookAhead     , Stream(..)     , tokens+    , tokens'     , try     , token     , tokenPrim@@ -60,6 +61,7 @@     , many     , skipMany     , manyAccum+    , many1     , runPT     , runP     , runParserT@@ -99,15 +101,15 @@ import qualified Data.Monoid as Monoid ( Monoid(..) )  import qualified Control.Applicative as Applicative ( Applicative(..), Alternative(..), liftA2 )-import Control.Monad hiding (sequence)-import Control.Monad.Trans-import Control.Monad.Identity hiding (sequence)+import Control.Monad (MonadPlus (..), ap, void, liftM)+import Control.Monad.Trans (MonadTrans (lift), MonadIO (liftIO))+import Control.Monad.Identity (Identity, runIdentity) import qualified Control.Monad.Fail as Fail -import Control.Monad.Reader.Class-import Control.Monad.State.Class-import Control.Monad.Cont.Class-import Control.Monad.Error.Class+import Control.Monad.Reader.Class (MonadReader (..))+import Control.Monad.State.Class (MonadState (..))+import Control.Monad.Cont.Class (MonadCont (..))+import Control.Monad.Error.Class (MonadError (..))  import Text.Parsec.Pos import Text.Parsec.Error@@ -147,15 +149,12 @@               -> (ParseError -> m b)                   -- empty err               -> m b              }-#if MIN_VERSION_base(4,7,0)      deriving ( Typeable )-     -- GHC 7.6 doesn't like deriving instances of Typeabl1 for types with-     -- non-* type-arguments.-#endif  -- | Low-level unpacking of the ParsecT type. To run your parser, please look to -- runPT, runP, runParserT, runParser and other such functions. runParsecT :: Monad m => ParsecT s u m a -> State s u -> m (Consumed (m (Reply s u a)))+{-# INLINABLE runParsecT #-} runParsecT p s = unParser p s cok cerr eok eerr     where cok a s' err = return . Consumed . return $ Ok a s' err           cerr err = return . Consumed . return $ Error err@@ -164,6 +163,7 @@  -- | Low-level creation of the ParsecT type. You really shouldn't have to do this. mkPT :: Monad m => (State s u -> m (Consumed (m (Reply s u a)))) -> ParsecT s u m a+{-# INLINABLE mkPT #-} mkPT k = ParsecT $ \s cok cerr eok eerr -> do            cons <- k s            case cons of@@ -218,11 +218,7 @@     --  discarding the first.     (<>)     = Applicative.liftA2 (Semigroup.<>) -#if MIN_VERSION_base(4,8,0)     sconcat  = fmap Semigroup.sconcat . sequence-#else-    sconcat  = fmap (Semigroup.sconcat . NE.fromList) . sequence . NE.toList-#endif     stimes b = Semigroup.sconcat . NE.fromList . genericReplicate b  -- | The 'Monoid' instance for 'ParsecT' is used for the same purposes as@@ -267,11 +263,19 @@     empty = mzero     (<|>) = mplus +    -- TODO: https://github.com/haskell/parsec/issues/179+    -- investigate what's wrong with haddock+    --+    -- many = many+    -- some = many1+ instance Monad (ParsecT s u m) where     return = Applicative.pure     p >>= f = parserBind p f     (>>) = (Applicative.*>)+#if !MIN_VERSION_base(4,13,0)     fail = Fail.fail+#endif  -- | @since 3.1.12.0 instance Fail.MonadFail (ParsecT s u m) where@@ -314,9 +318,11 @@   = ParsecT $ \s cok cerr eok eerr ->     let         -- consumed-okay case for m-        mcok x s err =+        mcok x s err+          | errorIsUnknown err = unParser (k x) s cok cerr cok cerr+          | otherwise =             let-                 -- if (k x) consumes, those go straigt up+                 -- if (k x) consumes, those go straight up                  pcok = cok                  pcerr = cerr @@ -331,7 +337,9 @@             in  unParser (k x) s pcok pcerr peok peerr          -- empty-ok case for m-        meok x s err =+        meok x s err+          | errorIsUnknown err = unParser (k x) s cok cerr eok eerr+          | otherwise =             let                 -- in these cases, (k x) can return as empty                 pcok = cok@@ -515,6 +523,46 @@                 | tok == x  -> walk toks xs                 | otherwise -> eerr $ errExpect x +-- | Like 'tokens', but doesn't consume matching prefix.+--+-- @since 3.1.16.0+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+                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+ -- | The parser @try p@ behaves like parser @p@, except that it -- pretends that it hasn't consumed any input when an error occurs. --@@ -584,6 +632,7 @@       -> (t -> SourcePos)         -- ^ Computes the position of a token.       -> (t -> Maybe a)           -- ^ Matching function for the token to parse.       -> Parsec s u a+{-# INLINABLE token #-} token showToken tokpos test = tokenPrim showToken nextpos test     where         nextpos _ tok ts = case runIdentity (uncons ts) of@@ -665,6 +714,15 @@   = do xs <- manyAccum (:) p        return (reverse xs) +-- | @many1 p@ applies the parser @p@ /one/ or more times. Returns a+-- list of the returned values of @p@.+--+-- >  word  = many1 letter++many1 :: ParsecT s u m a -> ParsecT s u m [a]+{-# INLINABLE many1 #-}+many1 p = do{ x <- p; xs <- many p; return (x:xs) }+ -- | @skipMany p@ applies the parser @p@ /zero/ or more times, skipping -- its result. --@@ -696,6 +754,7 @@  runPT :: (Stream s m t)       => ParsecT s u m a -> u -> SourceName -> s -> m (Either ParseError a)+{-# INLINABLE runPT #-} runPT p u name s     = do res <- runParsecT p (State s (initialPos name) u)          r <- parserReply res
src/Text/Parsec/String.hs view
@@ -33,7 +33,7 @@ -- >                  Left err  -> print err -- >                  Right xs  -> print (sum xs) -- >              }-parseFromFile :: Parser a -> String -> IO (Either ParseError a)+parseFromFile :: Parser a -> FilePath -> IO (Either ParseError a) parseFromFile p fname     = do input <- readFile fname          return (runP p () fname input)
src/Text/Parsec/Text.hs view
@@ -10,16 +10,36 @@ -- Stability   :  provisional -- Portability :  portable ----- Convinience definitions for working with 'Text.Text'.+-- Convenience definitions for working with 'Text.Text'. -- -----------------------------------------------------------------------------  module Text.Parsec.Text-    ( Parser, GenParser+    ( Parser, GenParser, parseFromFile     ) where  import qualified Data.Text as Text+import qualified Data.Text.IO as T+ import Text.Parsec.Prim+import Text.Parsec.Error  type Parser = Parsec Text.Text () type GenParser st = Parsec Text.Text st++-- | @parseFromFile p filePath@ runs a strict text parser @p@ on the+-- input read from @filePath@ using 'Data.Text.IO.readFile'. Returns either a 'ParseError'+-- ('Left') or a value of type @a@ ('Right').+--+-- >  main    = do{ result <- parseFromFile numbers "digits.txt"+-- >              ; case result of+-- >                  Left err  -> print err+-- >                  Right xs  -> print (sum xs)+-- >              }+--+-- @since 3.1.14.0++parseFromFile :: Parser a -> FilePath -> IO (Either ParseError a)+parseFromFile p fname+    = do input <- T.readFile fname+         return (runP p () fname input)
src/Text/Parsec/Text/Lazy.hs view
@@ -15,11 +15,31 @@ -----------------------------------------------------------------------------  module Text.Parsec.Text.Lazy-    ( Parser, GenParser+    ( Parser, GenParser, parseFromFile     ) where  import qualified Data.Text.Lazy as Text+import qualified Data.Text.Lazy.IO as TL+ import Text.Parsec.Prim+import Text.Parsec.Error  type Parser = Parsec Text.Text () type GenParser st = Parsec Text.Text st++-- | @parseFromFile p filePath@ runs a strict text parser @p@ on the+-- input read from @filePath@ using 'Data.Text.Lazy.IO.readFile'. Returns either a 'ParseError'+-- ('Left') or a value of type @a@ ('Right').+--+-- >  main    = do{ result <- parseFromFile numbers "digits.txt"+-- >              ; case result of+-- >                  Left err  -> print err+-- >                  Right xs  -> print (sum xs)+-- >              }+--+-- @since 3.1.14.0++parseFromFile :: Parser a -> FilePath -> IO (Either ParseError a)+parseFromFile p fname+    = do input <- TL.readFile fname+         return (runP p () fname input)
src/Text/Parsec/Token.hs view
@@ -1,5 +1,3 @@-{-# LANGUAGE CPP #-}-{-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE PolymorphicComponents #-} {-# LANGUAGE Safe #-}@@ -30,11 +28,10 @@     ) where  import Data.Char ( isAlpha, toLower, toUpper, isSpace, digitToInt )-#if MIN_VERSION_base(4,7,0) import Data.Typeable ( Typeable )-#endif import Data.List ( nub, sort )-import Control.Monad.Identity+import Control.Monad.Identity (Identity)+ import Text.Parsec.Prim import Text.Parsec.Char import Text.Parsec.Combinator@@ -106,9 +103,7 @@     caseSensitive  :: Bool      }-#if MIN_VERSION_base(4,7,0)     deriving ( Typeable )-#endif  ----------------------------------------------------------- -- A first class module: TokenParser@@ -171,7 +166,7 @@          stringLiteral    :: ParsecT s u m String, -        -- | This lexeme parser parses a natural number (a positive whole+        -- | This lexeme parser parses a natural number (a non-negative whole         -- number). Returns the value of the number. The number can be         -- specified in 'decimal', 'hexadecimal' or         -- 'octal'. The number is parsed according to the grammar@@ -201,19 +196,19 @@          naturalOrFloat   :: ParsecT s u m (Either Integer Double), -        -- | Parses a positive whole number in the decimal system. Returns the+        -- | Parses a non-negative whole number in the decimal system. Returns the         -- value of the number.          decimal          :: ParsecT s u m Integer, -        -- | Parses a positive whole number in the hexadecimal system. The number-        -- should be prefixed with \"0x\" or \"0X\". Returns the value of the+        -- | Parses a non-negative whole number in the hexadecimal system. The+        -- number should be prefixed with \"x\" or \"X\". Returns the value of the         -- number.          hexadecimal      :: ParsecT s u m Integer, -        -- | Parses a positive whole number in the octal system. The number-        -- should be prefixed with \"0o\" or \"0O\". Returns the value of the+        -- | Parses a non-negative whole number in the octal system. The number+        -- should be prefixed with \"o\" or \"O\". Returns the value of the         -- number.          octal            :: ParsecT s u m Integer,@@ -316,9 +311,7 @@          commaSep1        :: forall a . ParsecT s u m a -> ParsecT s u m [a]     }-#if MIN_VERSION_base(4,7,0)     deriving ( Typeable )-#endif  ----------------------------------------------------------- -- Given a LanguageDef, create a token parser.@@ -329,7 +322,7 @@ -- defined using the definitions in the @language@ record. -- -- The use of this function is quite stylized - one imports the--- appropiate language definition and selects the lexical parsers that+-- appropriate language definition and selects the lexical parsers that -- are needed from the resulting 'GenTokenParser'. -- -- >  module Main where@@ -357,6 +350,7 @@  makeTokenParser :: (Stream s m Char)                 => GenLanguageDef s u m -> GenTokenParser s u m+{-# INLINABLE makeTokenParser #-} makeTokenParser languageDef     = TokenParser{ identifier = identifier                  , reserved = reserved
src/Text/ParserCombinators/Parsec/Expr.hs view
@@ -25,7 +25,7 @@ import qualified Text.Parsec.Expr as N import Text.ParserCombinators.Parsec(GenParser) -import Control.Monad.Identity+import Control.Monad.Identity (Identity)  data Operator tok st a   = Infix  (GenParser tok st (a -> a -> a)) Assoc                          | Prefix (GenParser tok st (a -> a))
test/Bugs.hs view
@@ -3,14 +3,14 @@        ( bugs        ) where -import Test.Framework+import Test.Tasty  import qualified Bugs.Bug2 import qualified Bugs.Bug6 import qualified Bugs.Bug9 import qualified Bugs.Bug35 -bugs :: [Test]+bugs :: [TestTree] bugs = [ Bugs.Bug2.main        , Bugs.Bug6.main        , Bugs.Bug9.main
test/Bugs/Bug2.hs view
@@ -3,16 +3,15 @@        ( main        ) where -import Test.HUnit hiding ( Test )-import Test.Framework-import Test.Framework.Providers.HUnit+import Test.Tasty+import Test.Tasty.HUnit  import Text.Parsec import Text.Parsec.String import qualified Text.Parsec.Token as P import Text.Parsec.Language (haskellDef) -main :: Test+main :: TestTree main =   testCase "Control Char Parsing (#2)" $   parseString "\"test\\^Bstring\"" @?= "test\^Bstring"
test/Bugs/Bug35.hs view
@@ -6,9 +6,8 @@ import Text.Parsec.String import qualified Text.Parsec.Token as Token -import Test.HUnit hiding (Test)-import Test.Framework-import Test.Framework.Providers.HUnit+import Test.Tasty+import Test.Tasty.HUnit  trickyFloats :: [String] trickyFloats =@@ -36,5 +35,5 @@ testBatch = mapM_ testFloat trickyFloats     where testFloat x = parse float "" x @?= Right (read x :: Double) -main :: Test+main :: TestTree main = testCase "Quality of output of Text.Parsec.Token.float (#35)" testBatch
test/Bugs/Bug6.hs view
@@ -3,16 +3,15 @@        ( main        ) where -import Test.HUnit hiding ( Test )-import Test.Framework-import Test.Framework.Providers.HUnit+import Test.Tasty+import Test.Tasty.HUnit  import Text.Parsec import Text.Parsec.String  import Util -main :: Test+main :: TestTree main =   testCase "Look-ahead preserving error location (#6)" $   parseErrors variable "return" @?= ["'return' is a reserved keyword"]
test/Bugs/Bug9.hs view
@@ -7,16 +7,15 @@ import           Text.Parsec.String             (Parser) import qualified Text.Parsec.Token              as P -import           Test.Framework-import           Test.Framework.Providers.HUnit-import           Test.HUnit                     hiding (Test)+import           Test.Tasty+import           Test.Tasty.HUnit  import           Util  data Expr = Const Integer | Op Expr Expr   deriving Show -main :: Test+main :: TestTree main =   testCase "Tracing of current position in error message (#9)"   $ result @?= ["unexpected '>'","expecting operator or end of input"]@@ -25,7 +24,7 @@     result :: [String]     result = parseErrors parseTopLevel "4 >> 5" --- Syntax analaysis+-- Syntax analysis  parseTopLevel :: Parser Expr parseTopLevel = parseExpr <* eof
test/Features.hs view
@@ -2,11 +2,13 @@        ( features        ) where -import Test.Framework+import Test.Tasty  import qualified Features.Feature80+import qualified Features.Feature150 -features :: [Test]-features = [-             Features.Feature80.main-           ]+features :: [TestTree]+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"
test/Features/Feature80.hs view
@@ -4,13 +4,12 @@ import           Control.Monad.Identity import           Data.List.NonEmpty import           Data.Semigroup-import           Test.Framework-import           Test.Framework.Providers.HUnit-import           Test.HUnit                     hiding (Test)+import           Test.Tasty+import           Test.Tasty.HUnit  import           Text.Parsec -main :: Test+main :: TestTree main =   testCase "Monoid instance (#80)" $ do     parseString (as <> bs) "aabbb" @?= "aabbb"
test/Main.hs view
@@ -1,12 +1,12 @@ -import Test.Framework+import Test.Tasty  import Bugs ( bugs ) import Features ( features )  main :: IO () main = do-  defaultMain+  defaultMain $ testGroup "All"     [ testGroup "Bugs" bugs     , testGroup "Features" features     ]
+ test/issue127.hs view
@@ -0,0 +1,14 @@+-- this should run in constant memory+module Main (main) where+  +import Text.Parsec+import System.Environment (getArgs)+import Control.Monad (replicateM_)++main :: IO ()+main = do+  n <- getArgs >>= \args -> return $ case args of+      arg : _ -> read arg+      _       -> 1000000++  print $ runParser (replicateM_ n $ return ()) () "test" ""
+ test/issue171.hs view
@@ -0,0 +1,29 @@+-- this should be fast+module Main (main) where++import Control.DeepSeq (NFData (..))+import System.CPUTime (getCPUTime)+import Text.Printf (printf)+import Test.Tasty (defaultMain)+import Test.Tasty.HUnit (testCaseSteps, assertBool)++import Text.Parsec+import Text.Parsec.String (Parser)++main :: IO ()+main = defaultMain $ testCaseSteps "issue-171" $ \info -> do+  time0 <- getCPUTime+  check $ concat $ replicate 100000 "a "+  time1 <- getCPUTime+  let diff = (time1 - time0) `div` 1000000000+  info $ printf "%d milliseconds\n" diff+  assertBool "" (diff < 200)++parser :: Parser [String]+parser = many (char 'a' <|> char 'b') `sepBy` char ' '++check :: String -> IO ()+check s = putStrLn $ either onError (const "") $ parse parser {- important: pass input as SourceName -} s s++onError :: ParseError -> String+onError err = rnf (show err) `seq` "error"
+ test/issue175.hs view
@@ -0,0 +1,26 @@+module Main (main) where++import Text.Parsec+import Text.Parsec.Error+import Text.Parsec.String (Parser)+import Text.Parsec.Pos (newPos)++import Test.Tasty (defaultMain)+import Test.Tasty.HUnit (assertFailure, testCaseSteps, (@?=))++main :: IO ()+main = defaultMain $ testCaseSteps "issue175" $ \info -> do+    case parse p "" "x" of+        Right _ -> assertFailure "Unexpected success"+        -- with setPosition the "longest match" is arbitrary+        -- megaparsec tracks consumed tokens separately, but we don't.+        -- so our position is arbitrary.+        Left err -> do+            info $ show err+            errorPos err @?= newPos "aaa" 9 1  -- can be arbitrary+            length (errorMessages err) @?= 2++p :: Parser Char+p = p1 <|> p2 where+    p1 = setPosition (newPos "aaa" 9 1) >> char 'a'+    p2 = setPosition (newPos "zzz" 1 1) >> char 'b'