packages feed

uu-interleaved (empty) → 0.1.0.0

raw patch · 4 files changed

+205/−0 lines, 4 filesdep +basesetup-changed

Dependencies added: base

Files

+ LICENSE view
@@ -0,0 +1,22 @@+Copyright (c) 2010, SD Swierstra+All rights reserved.++The MIT License++Permission is hereby granted, free of charge, to any person obtaining a copy+of this software and associated documentation files (the "Software"), to deal+in the Software without restriction, including without limitation the rights+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+copies of the Software, and to permit persons to whom the Software is+furnished to do so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in+all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN+THE SOFTWARE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ src/Control/Applicative/Interleaved.hs view
@@ -0,0 +1,151 @@+{-# LANGUAGE ExistentialQuantification,+             ScopedTypeVariables,+             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 Control.Applicative.Interleaved   +(   -- * Classes+    Splittable (..),+    -- * Types+    Gram (..),+    Alt (..),+    -- * Functions+    mkG,+    mkP,+    (<<||>),+    (<||>),+    sepBy,+    gmList,+   -- * Modules+    module Control.Applicative,+    module Data.Monoid+  ) where++-- import Text.ParserCombinators.UU.Core+import Control.Applicative+import Data.Monoid+++infixl 4  <||>+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 -> a)) (Gram f b) +              |  forall b.  Bind   (f b)        (b -> Gram f a)++-- * The requirement that we can split of a possible empty part+class Splittable f where+  getNonPure    :: f a  -> Maybe (f  a)       +  getPure       :: f a  -> Maybe     a++-- * Grammars can be used as a monoid using the <||> combinator to combine them and (.) for composing  results++instance Functor f => Monoid (Gram f (r -> r)) where+  mappend p q = (.) <$> p <||> q+  mempty      = empty++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.++++mkG::  (Splittable f, Functor f) => f a -> Gram f a+mkG p =  Gram   (maybe [] (\p -> [(const <$> p) `Seq` pure ()]) (getNonPure p)) +                (getPure 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 (fb2a `Seq`  gb)   = ((a2c.) <$> fb2a) `Seq`  gb+  fmap a2c (fb   `Bind` b2ga) = fb                `Bind` (\b -> fmap a2c (b2ga b))++-- |  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+gb2a@(Gram lb2a eb2a) <<||> ~gb@(Gram _ eb)+   = Gram ( map (`fwdby` gb) lb2a)   (eb2a <*> eb)+     where (fc2b2a `Seq`   gc)      `fwdby` gb = (uncurry <$> fc2b2a) `Seq` ((,)  <$> gc <||> gb)+           (fc     `Bind`  c2gb2a)  `fwdby` gb =  fc `Bind` (\ c ->  c2gb2a c <||> gb)  +++-- | 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. ++fb2a <||> fb = fb2a <<||> fb <|> flip ($) <$> fb <<||> fb2a++-- | 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 lb2a mb2a  <*> ~gb@(Gram lb mb) +    =   Gram  (map (`fwdby` gb) lb2a ++ [b2a <$> fb | Just b2a <- [mb2a], fb <- lb]) (mb2a <*> mb)+        where (fc2b2a `Seq`  gc) `fwdby` gb = (uncurry <$> fc2b2a)  `Seq`  ((,) <$> gc <*> gb)+              (fc `Bind` c2gb2a) `fwdby` gb = fc  `Bind` (\b -> c2gb2a b               <*> gb)+++instance Functor f => Alternative (Gram f) where+  empty                     = Gram [] Nothing+  Gram ps pe <|> Gram qs qe = Gram (ps++qs) (pe <|> qe)+++-- * `Gram` is a `Monad`+instance  Functor f =>  Monad (Gram f) where+  return a = Gram [] (Just a)+  Gram lb mb >>= b2g_a = +     let bindto :: Functor f => Alt f b -> (b -> Gram f a) -> Alt f a+         (f_c2b `Seq`  g_c)   `bindto` b2g_a = f_c2b `Bind` \ c2b  -> c2b <$> g_c   >>= b2g_a+         (f_c   `Bind` c2g_b) `bindto` b2g_a = f_c   `Bind` \ c    -> c2g_b c       >>= b2g_a+         la = map (`bindto` b2g_a) lb+     in case mb of+        Nothing -> Gram la Nothing+        Just b  -> let Gram lra ma =  b2g_a b+                   in  Gram (la ++ lra) ma+ +++-- | 'mkParser' converts a `Gram`mar back into a parser, which can subsequenly be run.+mkP :: (Monad f, Applicative f, Alternative f) => Gram f a -> f a+mkP (Gram l_a m_a) = foldr  (<|>) (maybe empty pure m_a) +                                  (map mkP_Alt l_a)+   where  mkP_Alt (f_b2a  `Seq`  g_b  )   = f_b2a  <*>    mkP g_b+          mkP_Alt (f_b    `Bind` b2g_a)   = f_b    >>=   (mkP . b2g_a)+++-- | `sepBy` is like `mkP`, with the additional feature that we require separators between the components. Probably only useful in the permuting case.+sepBy :: (Monad f, Applicative f, Alternative f) =>  Gram f a -> f b -> f a+sepBy  g sep = mkP (insertSep sep g)++insertSep :: (Applicative f) => f b -> Gram f a -> Gram f a+insertSep sep (Gram na ea :: Gram f a) = Gram (map insertSepInAlt na) ea+   where insertSepInAlt (fb2a `Seq` gb   ) = fb2a `Seq` prefixSepInGram gb+         insertSepInAlt (fc   `Bind` c2ga) = fc `Bind` (insertSep sep . c2ga)+         prefixSepInGram (Gram na ne) = Gram (map prefixSepInAlt na) ne+         prefixSepInAlt ::  Alt f b -> Alt f b+         prefixSepInAlt (fb2a `Seq` gb)   = (sep *> fb2a) `Seq` prefixSepInGram  gb++-- | Run a sufficient number of  @p@'s in a merged fashion, but no more than necessary!!+gmList :: Functor f => Gram f a -> Gram f [a]+gmList p = let pm = ( (:) <$> p <<||> pm ) <|> pure [] in pm+++
+ uu-interleaved.cabal view
@@ -0,0 +1,30 @@+Name:                uu-interleaved+Version:             0.1.0.0+Build-Type:          Simple+License:             MIT+Copyright:           S Doaitse Swierstra +License-file:        LICENSE+Author:              Doaitse Swierstra, Utrecht University+Maintainer:          Doaitse Swierstra      +Stability:           stable, but evolving+Homepage:            http://www.cs.uu.nl/wiki/bin/view/HUT/ParserCombinators+Bug-reports:         mailto:doaitse@swierstra.net      +Synopsis:            Providing an interleaving combinator for use with applicative/alternative style implementations.+Description:         This module contains parser library independent code which can be used to describe inlerleaved execution of applicative style structures. +                     It is amongst other used in the uu-options package, which provides facilities for parsing command-line options or files containing preferences. +                     It gneralises the permuting parsers and the list merging parsers as e.g. found in the uulib library. For  a fuller description see the Technical Report +                     describing its implementation and application at: http://www.cs.uu.nl/research/techreps/UU-CS-2013-005.html+Category:            Control, Applicative, Parsing, Text++cabal-version:       >= 1.6++source-repository head+     type: svn+     location: https://svn.science.uu.nl/repos/project.STEC.uu-parsinglib/uu-interleaved++Library+  hs-source-dirs:    src++  Build-Depends:     base >= 4.2 && <5++  Exposed-modules:   Control.Applicative.Interleaved