cabal-version: 3.0 name: attoparsec-isotropic version: 0.14.5 license: BSD-3-Clause license-file: LICENSE category: Text, Parsing author: Daniil Iaitskov maintainer: Daniil Iaitskov stability: experimental synopsis: right-to-left parser backward compatible with attoparsec homepage: https://github.com/yaitskov/attoparsec-isotropic bug-reports: https://github.com/yaitskov/attoparsec-isotropic/issues build-type: Simple description: A fork of library allows to define omnidirected parsers or parsers consuming input from right-to-left. The library is highly backward compabitle with original interface. Idea to do the fork is inspired by the need to parse a CSV file in in one go with “constant” memory footprint and rows in reverse chronological order. == Example #example# > {-# LANGUAGE OverloadedStrings #-} > {-# LANGUAGE TupleSections #-} > import Data.Attoparsec.ByteString > > test = parseOnly ab "ab" == parseBackOnly ba "ab" > where > ab = (,) <$> string "a" <*> string "b" > ba = (,) <$> string "b" <*> string "a" > > test2 = parseOnly ab "ab" == parseBackOnly ab "ba" > where > ab = string "a" >*< string "b" == Running parser in reverse incrementally #running-parser-in-reverse-incrementally# Snippet from the CSV parser app: > consumeFile :: Handle -> (RobinRow -> ProfitM ()) -> ProfitM () > consumeFile h handleRow = do > input <- readBlock h > go Nothing input > where > go !loopDetector input = do > iBlock <- gets (^. #currentBlock) > if iBlock < 0 && input == mempty > then pure () > else do > parseBackWith (readBlock h) parseRow input >>= \case > Fail _unconsumed ctx er -> do > erpos <- liftIO $ hTell h > fail $ "Failed to parse CSV file around " <> show erpos <> " byte; due: " > <> show er <> "; context: " <> show ctx > Partial _ -> fail "CSV file is partial" > Done (unconsumed :: ByteString) (rawRow :: [ByteString]) -> do > iBlock' <- gets (^. #currentBlock) > if loopDetector == Just (unconsumed, iBlock') > then > fail $ "Loop detected. Unconsumed input: " <> show unconsumed > else do > trashCodes <- asks (^. #codesToSkip) > case parseRobinRow trashCodes rawRow of > Left e -> fail e > Right row -> do > forM_ row handleRow > go (Just (unconsumed, iBlock')) unconsumed tested-with: GHC == 9.10.1, GHC == 9.12.2 extra-source-files: benchmarks/*.txt benchmarks/json-data/*.json benchmarks/Makefile benchmarks/med.txt.bz2 examples/*.c examples/*.hs examples/Makefile extra-doc-files: README.md changelog.md Flag developer Description: Whether to build the library in development mode Default: False Manual: True common base default-language: GHC2024 ghc-options: -Wall default-extensions: CPP DefaultSignatures OverloadedStrings TemplateHaskell TypeFamilies build-depends: array < 1 , base < 5 , bytestring < 1 , containers < 1 , deepseq < 2 , fail < 5 , haddock-use-refs < 2 , scientific < 1 , semigroups < 0.21 , tagged < 1 , text < 3 , trace-embrace >= 1.2 && < 3 , transformers < 1 -- We need to test and benchmark these modules, -- but do not want to expose them to end users library attoparsec-isotropic-internal import: base hs-source-dirs: internal exposed-modules: Data.Attoparsec.ByteString.Buffer Data.Attoparsec.ByteString.FastSet Data.Attoparsec.Internal.Compat Data.Attoparsec.Internal.Fhthagn Data.Attoparsec.Text.Buffer Data.Attoparsec.Text.FastSet ghc-options: -O2 -Wall library import: base build-depends: attoparsec-isotropic-internal , ghc-prim < 0.14 exposed-modules: Data.Attoparsec Data.Attoparsec.ByteString Data.Attoparsec.ByteString.Char8 Data.Attoparsec.ByteString.Lazy Data.Attoparsec.Char8 Data.Attoparsec.Combinator Data.Attoparsec.Internal Data.Attoparsec.Internal.Types Data.Attoparsec.Lazy Data.Attoparsec.Number Data.Attoparsec.Text Data.Attoparsec.Text.Lazy Data.Attoparsec.Types Data.Attoparsec.Zepto other-modules: Data.Attoparsec.ByteString.Internal Data.Attoparsec.Text.Internal ghc-options: -O2 -Wall if flag(developer) ghc-prof-options: -auto-all ghc-options: -Werror test-suite attoparsec-isotropic-tests import: base type: exitcode-stdio-1.0 hs-source-dirs: tests main-is: QC.hs other-modules: QC.Buffer QC.ByteString QC.ByteStringRightToLeft QC.Combinator QC.CombinatorRight QC.Common QC.IPv6.Internal QC.IPv6.Types QC.MonoidalScientific QC.Rechunked QC.Simple QC.Text QC.Text.FastSet QC.Text.Regressions ghc-options: -Wall -threaded -rtsopts if flag(developer) ghc-options: -Werror build-depends: QuickCheck >= 2.13.2 && < 2.16 , attoparsec-isotropic , attoparsec-isotropic-internal , quickcheck-unicode , tasty >= 1 && < 2 , tasty-bench >= 0.3 && < 1 , tasty-quickcheck >= 0.8 && < 1 , vector -- benchmark dependencies -- cabal2nix skips dependencies from benchmark , http-types benchmark attoparsec-isotropic-benchmarks import: base type: exitcode-stdio-1.0 hs-source-dirs: benchmarks benchmarks/warp-3.0.1.1 ghc-options: -O2 -Wall -rtsopts main-is: Benchmarks.hs other-modules: Aeson Common Genome HeadersByteString HeadersByteString.Atto HeadersText Links Network.Wai.Handler.Warp.ReadInt Network.Wai.Handler.Warp.RequestHeader Numbers Sets TextFastSet Warp ghc-options: -O2 -Wall if flag(developer) ghc-options: -Werror build-depends: attoparsec-isotropic , attoparsec-isotropic-internal , case-insensitive , directory , filepath , ghc-prim , http-types , parsec >= 3.1.2 , tasty-bench >= 0.3 && < 1 , unordered-containers , vector source-repository head type: git location: https://github.com/yaitskov/attoparsec-isotropic.git