{-# 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))