packages feed

looksee 0.5.2 → 0.5.3

raw patch · 4 files changed

+136/−6 lines, 4 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Looksee: instance Looksee.HasErrMessage Data.Void.Void
+ Looksee: branchP :: (Monad m, Foldable f) => f (ParserT e m (), ParserT e m a) -> ParserT e m a
+ Looksee: commitP :: (Monad m, Foldable f) => f (ParserT e m (), ParserT e m a) -> ParserT e m a
+ Looksee: instance Looksee.HasErrMessage GHC.Base.Void
+ Looksee: spanAroundP :: Monad m => (Span Int -> a -> b) -> ParserT e m a -> ParserT e m b

Files

looksee.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack  name:           looksee-version:        0.5.2+version:        0.5.3 synopsis:       A simple text parser with decent errors description:    Please see the README on GitHub at <https://github.com/ejconlon/looksee#readme> category:       Parsing@@ -17,7 +17,7 @@ license:        BSD3 build-type:     Simple tested-with:-    GHC == 9.4.5+    GHC == 9.6.3 extra-source-files:     README.md @@ -51,6 +51,8 @@       LambdaCase       KindSignatures       MultiParamTypeClasses+      MultiWayIf+      PatternSynonyms       Rank2Types       ScopedTypeVariables       StandaloneDeriving@@ -97,6 +99,8 @@       LambdaCase       KindSignatures       MultiParamTypeClasses+      MultiWayIf+      PatternSynonyms       Rank2Types       ScopedTypeVariables       StandaloneDeriving
src/Looksee.hs view
@@ -23,12 +23,15 @@   , parse   , parseI   , spanP+  , spanAroundP   , throwP   , altP   , emptyP   , endP   , optP   , lookP+  , branchP+  , commitP   , labelP   , textP   , textP_@@ -97,7 +100,7 @@   ) where -import Control.Applicative (Alternative (..), liftA2)+import Control.Applicative (Alternative (..)) import Control.Exception (Exception) import Control.Monad (ap, void) import Control.Monad.Except (ExceptT, MonadError (..), runExceptT)@@ -422,10 +425,18 @@ -- an `n`-character document. The start offset will increase as input is consumed, -- and the end offset will decrease as lookahead delimits the range. To evaluate -- the "real" range of characters consumed by a parser, construct a span with the--- starting offsets before and after executing a subparser.+-- starting offsets before and after executing a subparser (or use 'spanAroundP'). spanP :: (Monad m) => ParserT e m (Span Int) spanP = getsP stSpan +-- | Incorporate span information into a parsed object.+spanAroundP :: (Monad m) => (Span Int -> a -> b) -> ParserT e m a -> ParserT e m b+spanAroundP f p = do+  Span start _ <- spanP+  a <- p+  Span end _ <- spanP+  pure (f (Span start end) a)+ -- | Throw a custom parse error throwP :: (Monad m) => e -> ParserT e m a throwP = errP . ReasonCustom@@ -479,6 +490,50 @@ lookP (ParserT g) = ParserT $ \j -> do   st0 <- get   g (\ea -> put st0 >> j (first (Err . ErrF (stSpan st0) . ReasonLook) ea))++-- private+subBranchP+  :: (Monad m)+  => (Either (Err e) a -> T e m r)+  -> St+  -> Seq (AltPhase, Err e)+  -> [(ParserT e m (), ParserT e m a)]+  -> T e m r+subBranchP j st0 = go+ where+  go !errs = \case+    [] -> mkErrT (if Seq.null errs then ReasonEmpty else ReasonAlt errs) >>= j . Left+    (ParserT gl, ParserT gx) : rest -> gl $ \case+      Left _ -> put st0 >> go errs rest+      Right _ -> do+        put st0+        gx $ \case+          Left e -> put st0 >> go (errs :|> (AltPhaseBranch, e)) rest+          Right r -> do+            es <- tryT (j (Right r))+            case es of+              Left e -> put st0 >> go (errs :|> (AltPhaseCont, e)) rest+              Right s -> pure s++-- | Branches guarded by lookahead. Use this for more concise errors.+-- 'altP' will happily tell you about each of the errors it encountered in+-- every branch, but this will quietly prune non-matching branches.+-- Tries until first success (in order), so you can tack on a fallthrough case even if+-- you tried a branch earlier.+branchP :: (Monad m, Foldable f) => f (ParserT e m (), ParserT e m a) -> ParserT e m a+branchP falts = ParserT (\j -> get >>= \st0 -> subBranchP j st0 Empty (toList falts))++-- | An alternative to 'branchP' that does not backtrack after committing to a branch.+commitP :: (Monad m, Foldable f) => f (ParserT e m (), ParserT e m a) -> ParserT e m a+commitP = go . toList+ where+  go = \case+    [] -> emptyP+    (p, q) : rest -> do+      mx <- optP (lookP p)+      case mx of+        Nothing -> go rest+        Just _ -> q  -- | Labels parse errors labelP :: (Monad m) => Label -> ParserT e m a -> ParserT e m a
src/Looksee/Examples.hs view
@@ -18,7 +18,24 @@ import Data.Sequence (Seq) import Data.Text (Text) import Data.Void (Void)-import Looksee (Parser, altP, betweenP, decP, doubleStrP, infixRP, intP, labelP, sciP, sepByP, space1P, stripEndP, stripP, stripStartP, takeWhile1P, textP_)+import Looksee+  ( Parser+  , altP+  , betweenP+  , decP+  , doubleStrP+  , infixRP+  , intP+  , labelP+  , sciP+  , sepByP+  , space1P+  , stripEndP+  , stripP+  , stripStartP+  , takeWhile1P+  , textP_+  )  -- | A JSON value data Json
test/Main.hs view
@@ -3,7 +3,7 @@  module Main (main) where -import Control.Applicative (Alternative (..), liftA2)+import Control.Applicative (Alternative (..)) import Control.Exception (throwIO) import Control.Monad (join) import Data.Foldable (for_, toList)@@ -69,6 +69,8 @@       , ("repeat1", testRepeat1)       , ("or", testOr)       , ("alt", testAlt)+      , ("branch", testBranch)+      , ("commit", testCommit)       , ("opt (empty)", testOptEmpty)       , ("opt", testOpt)       , ("bind (1)", testBind1)@@ -249,6 +251,58 @@     , ParserCase "first" parser "hi" (suc "h" 1)     , ParserCase "middle" parser "zi" (suc "y" 1)     , ParserCase "last" parser "xi" (suc "y" 1)+    ]++testBranch :: [TestTree]+testBranch = fmap testParserCase cases+ where+  parser =+    branchP+      [ (charP_ 'h', textP "hi")+      , (charP_ 'y', textP "yi")+      , (charP_ 'y', textP "ya")+      ]+      :: TestParser Text+  cases =+    [ ParserCase "empty" parser "" $+        err (Span 0 0) ReasonEmpty+    , ParserCase "first" parser "hi" (suc "hi" 0)+    , ParserCase "fail first" parser "ho" $+        errAlt+          (Span 0 2)+          [ (AltPhaseBranch, Span 2 2, ReasonExpect "hi" "ho")+          ]+    , ParserCase "middle" parser "yi" (suc "yi" 0)+    , ParserCase "last" parser "ya" (suc "ya" 0)+    , ParserCase "fail rest" parser "yo" $+        errAlt+          (Span 0 2)+          [ (AltPhaseBranch, Span 2 2, ReasonExpect "yi" "yo")+          , (AltPhaseBranch, Span 2 2, ReasonExpect "ya" "yo")+          ]+    ]++testCommit :: [TestTree]+testCommit = fmap testParserCase cases+ where+  parser =+    commitP+      [ (charP_ 'h', textP "hi")+      , (charP_ 'y', textP "yi")+      , (charP_ 'y', textP "ya")+      ]+      :: TestParser Text+  cases =+    [ ParserCase "empty" parser "" $+        err (Span 0 0) ReasonEmpty+    , ParserCase "first" parser "hi" (suc "hi" 0)+    , ParserCase "fail first" parser "ho" $+        err (Span 2 2) (ReasonExpect "hi" "ho")+    , ParserCase "middle" parser "yi" (suc "yi" 0)+    , ParserCase "fail last" parser "ya" $+        err (Span 2 2) (ReasonExpect "yi" "ya")+    , ParserCase "fail rest" parser "yo" $+        err (Span 2 2) (ReasonExpect "yi" "yo")     ]  testOptEmpty :: [TestTree]