packages feed

uu-parsinglib 2.7.4.3 → 2.8.1

raw patch · 9 files changed

+69/−299 lines, 9 filesdep +uu-interleaveddep ~basePVP ok

version bump matches the API change (PVP)

Dependencies added: uu-interleaved

Dependency ranges changed: base

API changes (from Hackage documentation)

- Text.ParserCombinators.UU.Core: doNotInterpret :: ExtAlternative p => p a -> p a
- Text.ParserCombinators.UU.Demo.MergeAndPermute: pA :: Grammar String
- Text.ParserCombinators.UU.Demo.MergeAndPermute: pABC :: Gram (P (Str Char String LineColPos)) Char
- Text.ParserCombinators.UU.Demo.MergeAndPermute: pABC' :: Grammar String
- Text.ParserCombinators.UU.Demo.MergeAndPermute: pB :: Grammar String
- Text.ParserCombinators.UU.Demo.MergeAndPermute: pC :: Grammar String
- Text.ParserCombinators.UU.Demo.MergeAndPermute: pDigit' :: (ListLike state Char, IsLocationUpdatedBy loc Char) => Gram (P (Str Char state loc)) Char
- Text.ParserCombinators.UU.Demo.MergeAndPermute: pNat :: Grammar Int
- Text.ParserCombinators.UU.Demo.MergeAndPermute: show_demos :: IO ()
- Text.ParserCombinators.UU.Demo.MergeAndPermute: three :: Applicative f => f a -> f (a, a, a)
- Text.ParserCombinators.UU.Demo.MergeAndPermute: two :: Applicative f => f [a] -> f [a]
- Text.ParserCombinators.UU.Demo.MergeAndPermute: type Grammar a = Gram (P (Str Char String LineColPos)) a
- Text.ParserCombinators.UU.MergeAndPermute: (<<||>) :: Functor f => Gram f (b -> a) -> Gram f b -> Gram f a
- Text.ParserCombinators.UU.MergeAndPermute: (<||>) :: Functor f => Gram f (b -> a) -> Gram f b -> Gram f a
- Text.ParserCombinators.UU.MergeAndPermute: Bind :: (f b) -> (b -> Gram f a) -> Alt f a
- Text.ParserCombinators.UU.MergeAndPermute: Gram :: [Alt f a] -> (Maybe a) -> Gram f a
- Text.ParserCombinators.UU.MergeAndPermute: Seq :: (f b) -> (Gram f (b -> a)) -> Alt f a
- Text.ParserCombinators.UU.MergeAndPermute: data Alt f a
- Text.ParserCombinators.UU.MergeAndPermute: data Gram f a
- Text.ParserCombinators.UU.MergeAndPermute: instance Functor f => Alternative (Gram f)
- Text.ParserCombinators.UU.MergeAndPermute: instance Functor f => Applicative (Gram f)
- Text.ParserCombinators.UU.MergeAndPermute: instance Functor f => ExtAlternative (Gram f)
- Text.ParserCombinators.UU.MergeAndPermute: instance Functor f => Functor (Alt f)
- Text.ParserCombinators.UU.MergeAndPermute: instance Functor f => Functor (Gram f)
- Text.ParserCombinators.UU.MergeAndPermute: instance Functor f => IsParser (Gram f)
- Text.ParserCombinators.UU.MergeAndPermute: instance Monad (Gram f)
- Text.ParserCombinators.UU.MergeAndPermute: instance Show a => Show (Gram f a)
- Text.ParserCombinators.UU.MergeAndPermute: mkGram :: P t a -> Gram (P t) a
- Text.ParserCombinators.UU.MergeAndPermute: mkParserM :: (Monad f, Applicative f, ExtAlternative f) => Gram f a -> f a
- Text.ParserCombinators.UU.MergeAndPermute: mkParserS :: (Monad f, Applicative f, ExtAlternative f) => f b -> Gram f a -> f a
- Text.ParserCombinators.UU.MergeAndPermute: pmMany :: Functor f => Gram f a -> Gram f [a]
+ Text.ParserCombinators.UU.BasicInstances: pMunchL :: (Show a, loc IsLocationUpdatedBy a, ListLike state a) => (a -> Bool) -> String -> P (Str a state loc) [a]
+ Text.ParserCombinators.UU.Core: P :: (T st a) -> (Maybe (T st a)) -> (Maybe a) -> Nat -> P st a
+ Text.ParserCombinators.UU.Interleaved: doNotInterpret :: P st a -> P st a
+ Text.ParserCombinators.UU.Interleaved: instance Functor f => ExtAlternative (Gram f)
+ Text.ParserCombinators.UU.Interleaved: instance IsParser (Gram (P st))
+ Text.ParserCombinators.UU.Interleaved: instance Splittable (P st)
+ Text.ParserCombinators.UU.Interleaved: mkP :: Gram (P st) a -> P st a
- Text.ParserCombinators.UU.Core: class Alternative p => ExtAlternative p where doNotInterpret = id opt p v = must_be_non_empty "opt" p (p <<|> pure v)
+ Text.ParserCombinators.UU.Core: class Alternative p => ExtAlternative p where opt p v = must_be_non_empty "opt" p (p <<|> pure v)
- Text.ParserCombinators.UU.Core: data Steps a
+ Text.ParserCombinators.UU.Core: data Steps :: * -> *
- Text.ParserCombinators.UU.Utils: execParser :: ListLike state Char => P (Str Char state LineColPos) a -> state -> (a, [Error LineColPos])
+ Text.ParserCombinators.UU.Utils: execParser :: Parser a -> String -> (a, [Error LineColPos])
- Text.ParserCombinators.UU.Utils: runParser :: String -> P (Str Char String LineColPos) a -> String -> a
+ Text.ParserCombinators.UU.Utils: runParser :: String -> Parser a -> String -> a

Files

src/Text/ParserCombinators/UU.hs view
@@ -19,11 +19,9 @@  module Text.ParserCombinators.UU ( module Text.ParserCombinators.UU.Core                                  , module Text.ParserCombinators.UU.Derived-                                 , module Text.ParserCombinators.UU.MergeAndPermute                                  ) where import Text.ParserCombinators.UU.Core import Text.ParserCombinators.UU.Derived-import Text.ParserCombinators.UU.MergeAndPermute   
src/Text/ParserCombinators/UU/BasicInstances.hs view
@@ -39,6 +39,7 @@    pToken,    pTokenCost,    pMunch,+   pMunchL ) where import Text.ParserCombinators.UU.Core import Data.Maybe@@ -190,7 +191,7 @@                            else show_munch ("Accepting munch: " ++ msg ++ " as emtty munch " ++ show pos ++ "\n") (k [] inp)                ) --- | `pMunch` recognises the longest prefix of the input for which the passed predicate holds. The message parameer is used when tracing has been switched on. +-- | `pMunch` recognises the longest prefix of the input for which the passed predicate holds.   pMunch :: forall loc state a .((Show a,  loc `IsLocationUpdatedBy` a, LL.ListLike state a) => (a -> Bool)  -> P (Str  a state loc) [a]) pMunch  p   = pMunchL p "" 
src/Text/ParserCombinators/UU/CHANGELOG.hs view
@@ -1,13 +1,5 @@ -- | This module just contains the CHANGELOG ----- Version 2.7.4.3--- --- Fixed bug with exact location of reporting  errors in runParser (thanks Markus Klinik)------ Version 2.7.4.2------ Changed a  types of execParser and runParser; thanks due to Benjamin Moseley--- -- Version 2.7.4.1 --  -- export of constructors of LineCol and LineColPos 
src/Text/ParserCombinators/UU/Core.hs view
@@ -2,7 +2,8 @@               GADTs,               MultiParamTypeClasses,               FunctionalDependencies,-              FlexibleInstances #-}+              FlexibleInstances,  +              KindSignatures #-} -- | The module `Core` contains the basic functionality of the parser library. --   It defines the types and implementations of the elementary  parsers and  recognisers involved.   @@ -17,7 +18,7 @@     HasPosition (..),     -- * Types     -- ** The parser descriptor-    P (),+    P (..),     -- ** The progress information     Steps (..),     Cost,@@ -53,11 +54,17 @@ import Control.Monad  import Data.Char import Debug.Trace+import Prelude hiding ((.)) import Data.Maybe +f . g = \x ->  f ( g x)++{-# INLINE (.) #-}+ -- | In the class `IsParser` we assemble the basic properties we expect parsers to have. The class itself does not have any methods.  --   Most properties  come directly from the standard  --   "Control.Applicative" module. The class `ExtAlternative` contains some extra methods we expect our parsers to have.+ class (Alternative p, Applicative p, ExtAlternative p) => IsParser p  instance  MonadPlus (P st) where@@ -75,10 +82,6 @@    --   Quite often it is more informative to get e.g. the name of the non-terminal .     --   The `<?>` combinator replaces this list of symbols by the string argument.       (<?>)   :: p a -> String -> p a-   -- | `doNotInterpret` makes a parser opaque for abstract interpretation; used when permuting parsers-   --    where we do not want to compare lengths.-   doNotInterpret :: p a -> p a-   doNotInterpret = id    -- |  `must_be_non_empty` checks whether its second argument    --    is a parser which can recognise the empty input. If so, an error message is    --    given using the  String parameter. If not, then the third argument is@@ -167,8 +170,8 @@  data  P   st  a =  P  (T  st a)         --   actual parsers                       (Maybe (T st a))  --   non-empty parsers; Nothing if  they are absent-                      (Maybe a)         --   the possibly  empty alternative with value -                      Nat               --   minimal length of the non-empty part+                      (Maybe a)         --   the possibly  empty alternative with its value +                      Nat               --   minimal number of symbols accepted by  the non-empty part   instance Show (P st a) where@@ -250,8 +253,6 @@                                                                                   ( \ k inp -> replaceExpected (norm  ( pf k inp)))                                                                                   ( \ k inp -> replaceExpected (norm  ( pr k inp))))                                 in mkParser nnp pe pl-  -- | `doNotInterpret` forgets the computed minimal number of tokens recognised by this parser-  doNotInterpret (P t nep e _) = P t nep e Unspecified   must_be_non_empty msg p@(P _ _ _ (Zero _)) _              = error ("The combinator " ++ msg ++  " requires that it's argument cannot recognise the empty string\n")   must_be_non_empty _ _      q  = q@@ -326,7 +327,6 @@ pErrors = let nnp = Just (T ( \ k inp -> let (errs, inp') = getErrors inp in k    errs    inp' )                             ( \ k inp -> let (errs, inp') = getErrors inp in push errs (k inp'))                             ( \ k inp -> let (errs, inp') = getErrors inp in            k inp' ))-              nep =  (Just (error "pErrors cannot occur in lhs of bind"))  -- the errors consumed cannot be determined statically!           in mkParser nnp  Nothing (Zero Infinite)  -- | `pPos` returns the current input position.@@ -334,7 +334,6 @@ pPos =  let nnp = Just ( T ( \ k inp -> let pos = getPos inp in k    pos    inp )                            ( \ k inp -> let pos = getPos inp in push pos (k inp))                            ( \ k inp ->                                   k inp ))-            nep =  Just (error "pPos cannot occur in lhs of bind")  -- the errors consumed cannot be determined statically!         in mkParser nnp Nothing (Zero Infinite)  -- | `pState` returns the current input state@@ -415,7 +414,7 @@   -data  Steps   a  where+data  Steps :: * -> *  where       Step   ::                 Progress       ->  Steps a                             -> Steps   a       Apply  ::  forall a b.    (b -> a)       ->  Steps   b                           -> Steps   a       Fail   ::                 Strings        ->  [Strings   ->  (Cost , Steps   a)]  -> Steps   a@@ -434,7 +433,7 @@ push v      =  Apply (\ r -> (v, r))  apply2fst   :: (b -> a) -> Steps (b, r) -> Steps (a, r)-apply2fst f = Apply (\ (b, r) -> (f b, r)) +apply2fst f = Apply (\ br -> let (b, r) = br in (f b, r))   {- succeedAlways :: Steps a@@ -451,9 +450,12 @@ has_success (Step _ _) = True has_success _        = False  --- | @`eval`@ removes the progress information from a sequence of steps, and constructs the value embedded in it.---   If you are really desparate to see how your parsers are making progress (e.g. when you have written an ambiguous parser, and you cannot find the cause of---   the exponential blow-up of your parsing process), you may switch on the trace in the function @`eval`@ (you will need to edit the library source code).+-- | @`eval`@ removes the progress information from a sequence of steps, +--   and constructs the value embedded in it.+--   If you are really desparate to see how your parsers are making progress+--   (e.g. when you have written an ambiguous parser, and you cannot find +--   the cause of the exponential blow-up of your parsing process), +--   you may switch on the trace in the function @`eval`@ (you will need to edit the library source code). --  eval :: Steps   a      ->  a eval (Step  n    l)     =   trace' ("Step " ++ show n ++ "\n") (eval l)@@ -463,7 +465,7 @@ eval (End_f   _  _   )  =   error "dangling End_f constructor" eval (End_h   _  _   )  =   error "dangling End_h constructor" --- | `norm` makes sure that the head of the seqeunce contains progress information. +-- | `norm` makes sure that the head of the sequence contains progress information.  --   It does so by pushing information about the result (i.e. the `Apply` steps) backwards. -- norm ::  Steps a ->  Steps   a
− src/Text/ParserCombinators/UU/Demo/MergeAndPermute.hs
@@ -1,139 +0,0 @@-{-# LANGUAGE NoMonomorphismRestriction,-             RankNTypes,-             FlexibleContexts,-             CPP  #-}-#define DEMO(p,i) demo "p" i p-#define DEMOG(p,i) demo "p" i (mkParserM (p))-module Text.ParserCombinators.UU.Demo.MergeAndPermute where--import Text.ParserCombinators.UU-import Text.ParserCombinators.UU.MergeAndPermute-import Text.ParserCombinators.UU.BasicInstances hiding (Parser)-import Text.ParserCombinators.UU.Utils-import Text.ParserCombinators.UU.Demo.Examples hiding (show_demos)-import qualified Data.ListLike as LL --type Grammar a =  Gram (P (Str Char String  LineColPos)) a---- | By running the function `show_demos` you will get a demonstration of the merging parsers.------ >>>   run ((,,) <$> two pA <||> three pB <||> pBetween 2 4 pC )  "cababbcccc"---  Result: ("aa",("b","b","b"),["c","c","c","c"])---  Correcting steps: ---    The token 'c' was not consumed by the parsing process.--- --- >>>   run (amb (mkParserM ((,) <$> pmMany ((,) <$>  pA <*> pC) <||> pmMany pB)))    "aabbcaabbccc"---  Result: [([("a","c"),("a","c"),("a","c"),("a","c")],["b","b","b","b"]),([("a","c"),("a","c"),("a","c"),("a","c")],["b","b","b","b"]),---           ([("a","c"),("a","c"),("a","c"),("a","c")],["b","b","b","b"]),([("a","c"),("a","c"),("a","c"),("a","c")],["b","b","b","b"]),---           ([("a","c"),("a","c"),("a","c"),("a","c")],["b","b","b","b"]),([("a","c"),("a","c"),("a","c"),("a","c")],["b","b","b","b"]),---           ([("a","c"),("a","c"),("a","c"),("a","c")],["b","b","b","b"]),([("a","c"),("a","c"),("a","c"),("a","c")],["b","b","b","b"]),---           ([("a","c"),("a","c"),("a","c"),("a","c")],["b","b","b","b"]),([("a","c"),("a","c"),("a","c"),("a","c")],["b","b","b","b"]),---           ([("a","c"),("a","c"),("a","c"),("a","c")],["b","b","b","b"]),([("a","c"),("a","c"),("a","c"),("a","c")],["b","b","b","b"])]--- --- >>>   run (pmMany(pABC))                                                            "a2a1b1b2c2a3b3c1c3"---  Result: ["2a","1a","3a"]--- --- >>>   run ((,)    <$> pBetween 2 3 pA <||> pBetween 1 2 pB)                         "abba"---  Result: (["a","a"],["b","b"])--- --- >>>   run ((,)    <$> pBetween 2 3 pA <||> pBetween 1 2 pB)                         "bba"---  Result: (["a","a"],["b","b"])---  Correcting steps: ---    Inserted  'a' at position LineColPos 0 3 3 expecting 'a'--- --- >>>   run (amb (mkParserM( ((,)    <$> pBetween 2 3 pA <||> pBetween 1 2 pA))))      "aaa"---  Result: [(["a","a"],["a"]),(["a","a"],["a"]),(["a","a"],["a"])]--- --- The 'a' at the right hand side can b any of the three 'a'-s in the input:------ >>>   run ((,)    <$> pAtLeast 3 pA <||> pAtMost 3 pB)                              "ababbb"---  Result: (["a","a","a"],["b","b","b"])---  Correcting steps: ---    Deleted   'b' at position LineColPos 0 5 5 expecting 'a'---    Inserted  'a' at position LineColPos 0 6 6 expecting 'a'--- --- >>>   run ((,)    <$> pSome pA <||> pMany pB)                                       "abba"---  Result: (["a","a"],["b","b"])--- --- >>>   run ((,)    <$> pSome pA <||> pMany pB)                                       "abba"---  Result: (["a","a"],["b","b"])--- --- >>>   run ((,)    <$> pSome pA <||> pMany pB)                                       ""---  Result: (["a"],[])---  Correcting steps: ---    Inserted  'a' at position LineColPos 0 0 0 expecting one of ['a', 'b']--- --- >>>   run ((,)    <$> pMany pB <||> pSome pC)                                       "bcbc"---  Result: (["b","b"],["c","c"])--- --- >>>   run ((,)    <$> pSome pB <||> pMany pC)                                       "bcbc"---  Result: (["b","b"],["c","c"])--- --- >>>   run ((,,,)   <$> pSome pA <||> pMany pB <||> pC <||> (pNat `opt` 5) )         "bcab45"---  Result: (["a"],["b","b"],"c",45)--- --- >>>   run ((,)    <$> pMany (pA <|> pB) <||> pSome  pNat)                           "1ab12aab14"---  Result: (["a","b","a","a","b"],[1,12,14])--- --- >>>   run ( (,)   <$> ((++) <$> pMany pA <||> pMany pB) <||> pC)                    "abcaaab"---  Result: (["a","a","a","a","b","b"],"c")--- --- >>>   run (pc `mkParserS` ((,) <$> pMany pA <||> pMany pB))                         "acbcacb"---  Result: (["a","a"],["b","b"])--- --show_demos :: IO ()-show_demos = do DEMOG (((,,) <$> two pA <||> three pB <||> pBetween 2 4 pC ), "cababbcccc")-                DEMO  ((amb (mkParserM ((,) <$> pmMany ((,) <$>  pA <*> pC) <||> pmMany pB)))  , "aabbcaabbccc")-                DEMOG ((pmMany(pABC))                                                          , "a2a1b1b2c2a3b3c1c3")-                DEMOG (((,)    <$> pBetween 2 3 pA <||> pBetween 1 2 pB)                       , "abba")  -                DEMOG (((,)    <$> pBetween 2 3 pA <||> pBetween 1 2 pB)                       , "bba")-                DEMO ((amb (mkParserM( ((,)    <$> pBetween 2 3 pA <||> pBetween 1 2 pA))))    , "aaa")-                putStr "-- The 'a' at the right hand side can b any of the three 'a'-s in the input\n"-                DEMOG (((,)    <$> pAtLeast 3 pA <||> pAtMost 3 pB)                            , "ababbb")  -                DEMOG (((,)    <$> pSome pA <||> pMany pB)                                     , "abba")       -                DEMOG (((,)    <$> pSome pA <||> pMany pB)                                     , "abba")           -                DEMOG (((,)    <$> pSome pA <||> pMany pB)                                     , "")         -                DEMOG (((,)    <$> pMany pB <||> pSome pC)                                     , "bcbc")          -                DEMOG (((,)    <$> pSome pB <||> pMany pC)                                     , "bcbc")-                DEMOG (((,,,)   <$> pSome pA <||> pMany pB <||> pC <||> (pNat `opt` 5) )       , "bcab45" )-                DEMOG (((,)    <$> pMany (pA <|> pB) <||> pSome  pNat)                         , "1ab12aab14")-                DEMOG (( (,)   <$> ((++) <$> pMany pA <||> pMany pB) <||> pC)                  , "abcaaab")-                DEMO  ((pc `mkParserS` ((,) <$> pMany pA <||> pMany pB))                       , "acbcacb")--pA, pB, pC:: Grammar String-pA   = mkGram pa-pB   = mkGram pb-pC   = mkGram (lift <$> pSym 'c')---pNat ::  Grammar Int-pNat = mkGram pNatural---pDigit' = mkGram pDigit---- | `two` recognises two instance of p as part of the input sequence-two :: Applicative f => f [a] -> f [a]-two p = (++) <$> p <*> p--- | `three` recognises two instance of p as part of the input sequence and concatenates the results-three :: Applicative f => f a-> f (a,a,a)-three p = (,,) <$> p <*> p <*> p---- | `pABC` minimcs a series of events (here an @a@, a @b@ and a @c@), which belong to the same transaction. ---   The transaction is identified by a digit: hence a full transaction is a string like \"a5b5c5\". ---   The third element in the body of `show_demos` below shows how the different transactions can be recovered from  ---   a log-file which contains all events generated by a collection of concurrently running transactions.-{--pABC :: Grammar Char-pABC = mkGram (pa *> pDigit ) >>= (\ d ->  mkGram (pb *> pSym d) *> mkGram (pc *> pSym d))--}-pABC =    do  d <- mkGram (pa *> pDigit ) -              mkGram (pb *> pSym d) *> mkGram (pc *> pSym d)--pABC' :: Grammar String	-pABC' = (\ a d -> d:a) <$> pA <*> (pDigit' >>= \d ->  pB *> mkGram (pSym d) *> pC *> mkGram (pSym d))----
+ src/Text/ParserCombinators/UU/Interleaved.hs view
@@ -0,0 +1,39 @@+{-# LANGUAGE ExistentialQuantification,+             FlexibleInstances #-}++-- | This module contains the additional data types, instance definitions and functions to run parsers in an interleaved way.+--   If all the interleaved parsers recognise a single connected piece of the input text this incorporates the permutation parsers.+--   For some examples see the module "Text.ParserCombinators.UU.Demo.MergeAndPermute".++module Text.ParserCombinators.UU.Interleaved where+import Control.Applicative.Interleaved hiding (mkP)+import Text.ParserCombinators.UU.Core++mkP :: Gram (P st) a -> P st a+mkP (Gram ls le) = foldr (\ p pp -> doNotInterpret p <|> pp) (maybe empty pure le) (map mkParserAlt ls)+   where mkParserAlt (p   `Seq`  pp  ) = p <*> mkP pp+         mkParserAlt (fc  `Bind` c2fa) = fc >>=  (mkP . c2fa)++instance Splittable (P st) where+  getPure    = getZeroP+  getNonPure = getOneP++instance Functor f => ExtAlternative (Gram f) where+  p <<|> q                    = p <|> q+  p <?> s                     = error "No <?> defined for Grammars yet. If you need ask for it"+  must_be_non_empty msg (Gram _ (Just _)) _+    = error ("The combinator " ++ msg ++  " requires that it's argument cannot recognise the empty string\n")+  must_be_non_empty _ _  q  = q+  must_be_non_empties  msg (Gram _ (Just _)) (Gram _ (Just _)) _ +    = error ("The combinator " ++ msg ++  " requires that not both arguments can recognise the empty string\n")+  must_be_non_empties  msg _  _ q = q++-- | `doNotInterpret` forgets the computed minimal number of tokens recognised by this parser+--    which  makes a parser opaque for abstract interpretation; used when interleaving parsers+--    where we do not want to compare lengths.++doNotInterpret :: P st a -> P st a+doNotInterpret (P t nep e _) = P t nep e Unspecified++instance  IsParser (Gram (P st))+
− src/Text/ParserCombinators/UU/MergeAndPermute.hs
@@ -1,124 +0,0 @@-{-# LANGUAGE ExistentialQuantification #-}---- | This module contains the additional data types, instance definitions and functions to run parsers in an interleaved way.---   If all the interleaved parsers recognise a single connected piece of the input text this incorporates the permutation parsers.---   For some examples see the module "Text.ParserCombinators.UU.Demo.MergeAndPermute".--module Text.ParserCombinators.UU.MergeAndPermute where-import Text.ParserCombinators.UU.Core-import Debug.Trace--infixl 4  <||>, <<||> ------ * The data type `Gram`--- | Since we want to get access to the individual parsers which recognise a consecutive piece of the input text we---   define a new data type, which lifts the underlying parsers to the grammatical level, so they can be transformed, manipulated, and run in a piecewise way.---   `Gram` is defined in such a way that we can always access the first parsers to be ran from such a structure.---   We require that all the `Alt`s do not recognise the empty string. These should be covered by the `Maybe` in the `Gram` constructor.-data Gram f a =             Gram  [Alt f a]  (Maybe a) -data Alt  f a =  forall b . Seq   (f b)      (Gram f (b -> a)) -              |  forall b.  Bind  (f b)      (b -> Gram f a)--instance (Show a) => Show (Gram f a) where-  show (Gram l ma) = "Gram " ++ show  (length l) ++ " " ++ show ma ---- | The function `mkGram` splits a simple parser into the possibly empty part and the non-empty part.---   The non-empty part recognises a consecutive part of the input.---   Here we use the functions `getOneP` and `getZeroP` which are provided in the uu-parsinglib package,---   but they could easily be provided by other packages too.--mkGram ::  P t a -> Gram (P t) a-mkGram p =  case getOneP p of-            Just q  -> Gram [q `Seq` Gram  [] (Just id)] (getZeroP p)-            Nothing -> Gram []                           (getZeroP p)---- * Class instances for Gram--- | We define instances for the data type `Gram` for `Functor`, `Applicative`,  `Alternative` and `ExtAlternative`-instance Functor f => Functor (Gram f) where-  fmap f (Gram alts e) = Gram (map (f <$>) alts) (f <$> e)--instance Functor f => Functor (Alt f) where-  fmap a2c (fb `Seq`  fb2a) = fb `Seq` ( (a2c .) <$> fb2a)-  fmap a2c (fb `Bind` b2fa) = fb `Bind` (\b -> fmap a2c (b2fa b))---- | The left hand side operand is gradually transformed so we get access to its first component-instance Functor f => Applicative (Gram f) where-  pure a = Gram [] (Just a)-  Gram l le  <*> ~rg@(Gram r re) -    =   Gram  ((map (`fwdby` rg) l) ++ maybe [] (\e -> map (e <$>) r) le) (le <*> re)-        where (fb `Seq`  fb2c2a) `fwdby` fc = fb  `Seq`  (flip <$> fb2c2a <*> fc)-              (fb `Bind` b2fc2a) `fwdby` fc = fb  `Bind` ((<*> fc) . b2fc2a)--instance  Functor f => Alternative (Gram f) where-  empty                     = Gram [] Nothing-  Gram ps pe <|> Gram qs qe = Gram (ps++qs) (pe <|> qe)--instance Functor f => ExtAlternative (Gram f) where-  p <<|> q                    = p <|> q-  p <?> s                     = error "No <?> defined for Grammars yet. If you need ask for it"-  must_be_non_empty msg (Gram _ (Just _)) _-    = error ("The combinator " ++ msg ++  " requires that it's argument cannot recognise the empty string\n")-  must_be_non_empty _ _  q  = q-  must_be_non_empties  msg (Gram _ (Just _)) (Gram _ (Just _)) _ -    = error ("The combinator " ++ msg ++  " requires that not both arguments can recognise the empty string\n")-  must_be_non_empties  msg _  _ q = q----- * `Gram` is a `Monad`-instance  Monad (Gram f) where-  return a = Gram [] (Just a)-  Gram ps pe >>= a2qs = -     let bindto :: Alt f b -> (b -> Gram f a) -> Alt f a-         (b `Seq` b2a)  `bindto` a2c = b `Bind` (\b -> b2a >>= ((\b2a -> a2c (b2a b))))-         (b `Bind` b2a) `bindto` a2c = b `Bind` (\b -> b2a b >>= a2c)-         psa2qs = (map (`bindto` a2qs) ps)-     in case pe of-        Nothing -> Gram psa2qs Nothing-        Just a  -> let Gram qs qe = a2qs a-                   in  Gram (psa2qs ++ qs) qe--instance Functor f => IsParser (Gram f)-  --- | The function `<||>` is the merging equivalent of `<*>`. Instead of running its two arguments consecutively, ---   the input is split into parts which serve as input for the left operand and parts which are served to the right operand. -(<||>):: Functor f => Gram f (b->a) -> Gram f b -> Gram f a-pg@(Gram pl pe) <||> qg@(Gram ql qe)-   = Gram (   [ p `Seq` (flip  <$> pp <||> qg)     | p `Seq` pp <- pl      ]-           ++ [ q `Seq` ((.)   <$> pg <||> qq)     | q `Seq` qq <- ql      ]-           ++ [ fc `Bind` (\c -> c2fb2a c <||> qg) | fc `Bind` c2fb2a <- pl]-           ++ [ fc `Bind` (\c -> pg <||> c2fb c)   | fc `Bind` c2fb   <- ql]-          )   (pe <*> qe)                                         ---- |  The function `<<||>` is a special version of `<||>`, which only starts a new instance of its right operand when the left operand cannot proceed.---   This is used in the function 'pmMany', where we want to merge as many instances of its argument, but no more than that.-(<<||>):: Functor f => Gram f (b->a) -> Gram f b -> Gram f a-pg@(Gram pl pe) <<||> ~qg@(Gram ql qe)-   = Gram (   [ p `Seq` (flip  <$> pp <||> qg)| p `Seq` pp <- pl] ++ [p `Bind` (\ a -> pp a <||> qg)| p `Bind` pp <- pl]-          )   (pe <*> qe)----- | 'mkParserM' converts a `Gram`mar back into a parser, which can subsequenly be run.-mkParserM :: (Monad f, Applicative f, ExtAlternative f) => Gram f a -> f a-mkParserM (Gram ls le) = foldr (\ p pp -> doNotInterpret p <|> pp) (maybe empty pure le) (map mkParserAlt ls)-   where mkParserAlt (p   `Seq`  pp  ) = p <**> mkParserM pp-         mkParserAlt (fc  `Bind` c2fa) = fc >>=  (mkParserM . c2fa)- ---- | `mkParserS` is like `mkParserM`, with the additional feature that we allow separators between the components. Only useful in the permuting case.-mkParserS :: (Monad f, Applicative f, ExtAlternative f) => f b -> Gram f a -> f a-mkParserS sep (Gram ls le) = foldr  (\ p pp -> doNotInterpret p <|> pp) (maybe empty pure le) (map mkParserAlt ls)-   where mkParserAlt (p `Seq` pp) = p <**> mkParserP sep pp-         mkParserAlt (fc `Bind` c2fa) = fc >>=  (mkParserS sep . c2fa)-         mkParserP :: (Monad f, Applicative f, ExtAlternative f) => f b -> Gram f a -> f a-         mkParserP sep (Gram ls le) = foldr (\ p pp -> doNotInterpret p <|> pp) (maybe empty pure le) (map mkParserAlt ls)-             where mkParserAlt (p `Seq` pp) = sep *> p <**> mkParserP sep pp-                   mkParserAlt (fc `Bind` c2fa) = fc >>=  (mkParserP sep . c2fa)---- | Run a sufficient number of  @p@'s in a merged fashion, but no more than necessary!!-pmMany :: Functor f => Gram f a -> Gram f [a]-pmMany p = let pm = ( (:) <$> p <<||> pm ) <|> pure [] in pm---
src/Text/ParserCombinators/UU/Utils.hs view
@@ -277,13 +277,13 @@ -- * Running parsers straightforwardly  -- | The lower-level interface. Returns all errors. -execParser :: LL.ListLike state Char => P (Str Char state LineColPos) a -> state -> (a, [Error LineColPos])+execParser :: Parser a -> String -> (a, [Error LineColPos]) execParser p = parse_h ((,) <$> p <*> pEnd) . createStr (LineColPos 0 0 0)  -- | The higher-level interface. (Calls 'error' with a simplified error).   --   Runs the parser; if the complete input is accepted without problems  return the --   result else fail with reporting unconsumed tokens-runParser ::String -> P (Str Char String LineColPos) a -> String -> a+runParser :: String -> Parser a -> String -> a runParser inputName p s | (a,b) <- execParser p s =     if null b     then a
uu-parsinglib.cabal view
@@ -1,5 +1,5 @@ Name:                uu-parsinglib-Version:             2.7.4.3+Version:             2.8.1 Build-Type:          Simple License:             MIT Copyright:           S Doaitse Swierstra @@ -20,7 +20,9 @@                      .                      The modules "Text.ParserCombinators.UU.Demo.Examples", "Text.ParserCombinators.UU.Idioms" and "Text.ParserCombinators.UU.Demo.MergeAndpermute"                       contain a ready-made  @show_examples@  function,-                     which can be called (e.g. from @ghci@) to see e.g. the error correction at work. It contains extensive haddock documentation, so why not just take a look                           to see the correction process at work, and to get a feeling for how the various combinators can be used? +                     which can be called (e.g. from @ghci@) to see e.g. the error correction at work. +                     It contains extensive haddock documentation, so why not just take a look                           +                     to see the correction process at work, and to get a feeling for how the various combinators can be used?                       .                      The file "Text.ParserCombinators.UU.CHANGELOG" contains a log of the most recent changes and additions.                      .@@ -38,16 +40,15 @@ Library   hs-source-dirs:    src -  Build-Depends:     base >= 4.2 && <5, time, ListLike >= 3.0.1+  Build-Depends:     base >= 4.2 && <5, time, ListLike >= 3.0.1, uu-interleaved >= 0.1.0 && < 0.2    Exposed-modules:   Text.ParserCombinators.UU                      Text.ParserCombinators.UU.CHANGELOG                      Text.ParserCombinators.UU.README                      Text.ParserCombinators.UU.Core                      Text.ParserCombinators.UU.BasicInstances+                     Text.ParserCombinators.UU.Interleaved                      Text.ParserCombinators.UU.Derived-                     Text.ParserCombinators.UU.MergeAndPermute                      Text.ParserCombinators.UU.Utils                      Text.ParserCombinators.UU.Idioms                      Text.ParserCombinators.UU.Demo.Examples-                     Text.ParserCombinators.UU.Demo.MergeAndPermute