packages feed

derp 0.1.5 → 0.1.6

raw patch · 2 files changed

+257/−119 lines, 2 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Text.Derp: (==>|) :: (Ord a, Ord b) => Parser a -> (Set a -> Set b) -> Parser b
- Text.Derp: epsM :: Ord a => Set a -> Parser a
- Text.Derp: instance Eq Token
- Text.Derp: instance Ord Token
- Text.Derp: instance Show (Parser a)
- Text.Derp: instance Show Token
- Text.Derp: pzip :: (Ord a, Ord b) => Parser a -> Context a b -> Parser b
+ Text.Derp: instance Eq t => Eq (Token t)
+ Text.Derp: instance Ord t => Ord (Token t)
+ Text.Derp: instance Show (Parser t a)
+ Text.Derp: instance Show t => Show (Token t)
+ Text.Derp: runParseLongestMatch :: (Ord t, Ord a) => Parser t a -> [Token t] -> Maybe (Int, Set a, [Token t])
+ Text.Derp: runParseLongestMatchNum :: (Ord t, Ord a) => Int -> Parser t a -> [Token t] -> Maybe (Int, Set a, [Token t])
+ Text.Derp: runParseStages :: (Ord t, Ord a) => Parser t a -> [Token t] -> [(Parser t a, Set a, [Token t])]
+ Text.Derp: runParseStagesNum :: (Ord t, Ord a) => Int -> Parser t a -> [Token t] -> [(Parser t a, Set a, [Token t])]
+ Text.Derp: someStuff :: [Token String]
+ Text.Derp: someStuffG :: () -> Parser String String
- Text.Derp: (<|>) :: Ord a => Parser a -> Parser a -> Parser a
+ Text.Derp: (<|>) :: (Ord t, Ord a) => Parser t a -> Parser t a -> Parser t a
- Text.Derp: (<~>) :: (Ord a, Ord b) => Parser a -> Parser b -> Parser (a, b)
+ Text.Derp: (<~>) :: (Ord t, Ord a, Ord b) => Parser t a -> Parser t b -> Parser t (a, b)
- Text.Derp: (==>) :: (Ord a, Ord b) => Parser a -> (a -> b) -> Parser b
+ Text.Derp: (==>) :: (Ord t, Ord a, Ord b) => Parser t a -> (a -> b) -> Parser t b
- Text.Derp: Token :: String -> String -> Token
+ Text.Derp: Token :: t -> String -> Token t
- Text.Derp: amb :: () -> Parser String
+ Text.Derp: amb :: () -> Parser String String
- Text.Derp: ambIn :: [Token]
+ Text.Derp: ambIn :: [Token String]
- Text.Derp: compact :: Parser a -> Parser a
+ Text.Derp: compact :: Parser t a -> Parser t a
- Text.Derp: compactNum :: Int -> Parser a -> Parser a
+ Text.Derp: compactNum :: Int -> Parser t a -> Parser t a
- Text.Derp: data Parser a
+ Text.Derp: data Parser t a
- Text.Derp: data Token
+ Text.Derp: data Token t
- Text.Derp: derive :: Parser a -> Token -> Parser a
+ Text.Derp: derive :: Parser t a -> Token t -> Parser t a
- Text.Derp: deriveStep :: Parser a -> Token -> Parser a
+ Text.Derp: deriveStep :: Parser t a -> Token t -> Parser t a
- Text.Derp: deriveStepNum :: Int -> Parser a -> Token -> Parser a
+ Text.Derp: deriveStepNum :: Int -> Parser t a -> Token t -> Parser t a
- Text.Derp: emp :: Ord a => Parser a
+ Text.Derp: emp :: (Ord t, Ord a) => Parser t a
- Text.Derp: eps :: Ord a => a -> Parser a
+ Text.Derp: eps :: (Ord t, Ord a) => a -> Parser t a
- Text.Derp: nul :: Ord a => Parser a -> Parser a
+ Text.Derp: nul :: (Ord t, Ord a) => Parser t a -> Parser t a
- Text.Derp: parens :: () -> Parser String
+ Text.Derp: parens :: () -> Parser String String
- Text.Derp: parensIn :: [Token]
+ Text.Derp: parensIn :: [Token String]
- Text.Derp: parseNull :: Ord a => Parser a -> Set a
+ Text.Derp: parseNull :: (Ord t, Ord a) => Parser t a -> Set a
- Text.Derp: runParse :: Ord a => Parser a -> [Token] -> Set a
+ Text.Derp: runParse :: (Ord t, Ord a) => Parser t a -> [Token t] -> Set a
- Text.Derp: runParseNum :: Ord a => Int -> Parser a -> [Token] -> Set a
+ Text.Derp: runParseNum :: (Ord t, Ord a) => Int -> Parser t a -> [Token t] -> Set a
- Text.Derp: sexp :: () -> Parser String
+ Text.Derp: sexp :: () -> Parser String String
- Text.Derp: sexpIn :: [Token]
+ Text.Derp: sexpIn :: [Token String]
- Text.Derp: ter :: String -> Parser String
+ Text.Derp: ter :: Ord t => t -> Parser t String
- Text.Derp: tokenClass :: Token -> String
+ Text.Derp: tokenClass :: Token t -> t
- Text.Derp: tokenValue :: Token -> String
+ Text.Derp: tokenValue :: Token t -> String
- Text.Derp: xsIn :: [Token]
+ Text.Derp: xsIn :: [Token String]
- Text.Derp: xsL :: () -> Parser String
+ Text.Derp: xsL :: () -> Parser String String
- Text.Derp: xsR :: () -> Parser String
+ Text.Derp: xsR :: () -> Parser String String

Files

derp.cabal view
@@ -1,5 +1,5 @@ Name:                derp-Version:             0.1.5+Version:             0.1.6 Description:         A parser based on derivatives of parser combinators (Might                      and Darais).  Our paper on Arxiv details the theory of                      parsing with derivatives: <http://arxiv.org/abs/1010.5023>.
src/Text/Derp.hs view
@@ -1,21 +1,25 @@-{-# LANGUAGE GADTs, RankNTypes, FlexibleInstances, UndecidableInstances #-}+{-# LANGUAGE GADTs, RankNTypes #-}  module Text.Derp   ( -- * Data Types     Parser, Token(..)   , -- * Parser construction-    (<|>), (<~>), (==>), (==>|), nul, pzip, ter, eps, epsM, emp+    (<|>), (<~>), (==>), nul, ter, eps, emp   , -- * Parser computation steps     derive, compact, parseNull   , -- * Full parsing and result extraction     defaultCompactSteps, compactNum, deriveStepNum, runParseNum+  , runParseStagesNum, runParseStages+  , runParseLongestMatchNum, runParseLongestMatch   , deriveStep, runParse   , -- * Demos     xsR, xsL, xsIn, parens, parensIn, amb, ambIn, sexp, sexpIn-+  , someStuff, someStuffG   ) where +import Data.Maybe import Control.Monad+import Data.Char import Data.Function import Data.IORef import Data.List@@ -33,89 +37,113 @@  --   Languages range of `Token' values. -data Parser a = Parser-  { parserRec      :: ParserRec Parser a+data Parser t a = Parser+  { parserRec      :: ParserRec Parser t a   , parserNullable :: FPValue Bool-  , parserDerive   :: Token -> Parser a-  , parserCompact  :: Parser a+  , parserEmpty    :: FPValue Bool+  , parserDerive   :: Token t -> Parser t a+  , parserCompact  :: Parser t a   } -data ParserRec p a where-  Alt :: (Ord a)        => p a -> p a -> ParserRec p a-  Con :: (Ord a, Ord b) => p a -> p b -> ParserRec p (a, b)-  Red :: (Ord a, Ord b) => (Set a -> Set b) -> p a -> ParserRec p b-  Nul :: (Ord a)        => p a -> ParserRec p a-  Zip :: (Ord a, Ord b) => p a -> ContextR p a b -> ParserRec p b-  Ter ::                   String -> ParserRec p String-  Eps :: (Ord a)        => Set a -> ParserRec p a-  Emp :: (Ord a)        => ParserRec p a+data ParserRec p t a where+  Alt :: (Ord t, Ord a)        => p t a -> p t a -> ParserRec p t a+  Con :: (Ord t, Ord a, Ord b) => p t a -> p t b -> ParserRec p t (a, b)+  Red :: (Ord t, Ord a, Ord b) => (Set a -> Set b) -> p t a -> ParserRec p t b+  Nul :: (Ord t, Ord a)        => p t a -> ParserRec p t a+  Zip :: (Ord t, Ord a, Ord b) => p t a -> ContextR p t a b -> ParserRec p t b+  Ter :: (Ord t)               => Set t -> ParserRec p t String+  Eps :: (Ord t, Ord a)        => Set a -> ParserRec p t a+  Emp :: (Ord t, Ord a)        => ParserRec p t a -data ContextR p a b where-  ConContext :: (Ord a, Ord b) => p b -> ContextR p (a, b) c -> ContextR p a c-  RedContext :: (Ord a, Ord b) => (Set a -> Set b) -> ContextR p b c -> ContextR p a c-  TopContext :: (Ord a)        => ContextR p a a+data ContextR p t a b where+  ConContext :: (Ord t, Ord a, Ord b) => p t b -> ContextR p t (a, b) c -> ContextR p t a c+  RedContext :: (Ord t, Ord a, Ord b) => (Set a -> Set b) -> ContextR p t b c -> ContextR p t a c+  TopContext :: (Ord t, Ord a)        => ContextR p t a a -type Context a b = ContextR Parser a b+type Context t a b = ContextR Parser t a b +data Token t = Token { tokenClass :: t, tokenValue :: String }+  deriving (Eq, Ord, Show)+ -- | The input type for parsing.  For example the parser: ----- > (ter "x") +-- > ter "x" -- --   will parse: ----- > (Token "x" "foo") +-- > Token "x" "foo" -- --   into: ----- > (eps "foo")--data Token = Token { tokenClass :: String, tokenValue :: String }-  deriving (Eq, Ord, Show)+-- > eps "foo" -parser :: (Ord a) => ParserRec Parser a -> FPValue Bool -> Parser a-parser p n = fix $ \ self -> Parser p n (memoFun (deriveImp self)) (compactImp self)+parser :: (Ord t, Ord a) => ParserRec Parser t a -> FPValue Bool -> FPValue Bool -> Parser t a+parser p n e = fix $ \ self -> Parser p n e (memoFun (deriveImp self)) (compactImp self)  -- | Alternation.-(<|>) :: (Ord a) => Parser a -> Parser a -> Parser a-(<|>) a b = parser (Alt a b) FPUndecided +(<|>) :: (Ord t, Ord a) => Parser t a -> Parser t a -> Parser t a+(<|>) a b = parser (Alt a b) FPUndecided FPUndecided -- | Concatenation.-(<~>) :: (Ord a, Ord b) => Parser a -> Parser b -> Parser (a, b)-(<~>) a b = parser (Con a b) FPUndecided +(<~>) :: (Ord t, Ord a, Ord b) => Parser t a -> Parser t b -> Parser t (a, b)+(<~>) a b = parser (Con a b) FPUndecided FPUndecided -- | Reduction.-(==>) :: (Ord a, Ord b) => Parser a -> (a -> b) -> Parser b+(==>) :: (Ord t, Ord a, Ord b) => Parser t a -> (a -> b) -> Parser t b (==>) p f = p ==>| Set.map f -- | Set generalized version of `==>'.-(==>|) :: (Ord a, Ord b) => Parser a -> (Set a -> Set b) -> Parser b-(==>|) p f = parser (Red f p) FPUndecided +(==>|) :: (Ord t, Ord a, Ord b) => Parser t a -> (Set a -> Set b) -> Parser t b+(==>|) p f = parser (Red f p) FPUndecided FPUndecided -- | Null-parse extraction.-nul :: (Ord a) => Parser a -> Parser a-nul p = parser (Nul p) FPUndecided +nul :: (Ord t, Ord a) => Parser t a -> Parser t a+nul p = parser (Nul p) FPUndecided FPUndecided -- | One-hole-context focus.-pzip :: (Ord a, Ord b) => Parser a -> Context a b -> Parser b-pzip p c = parser (Zip p c) (FPDecided False) +pzip :: (Ord t, Ord a, Ord b) => Parser t a -> Context t a b -> Parser t b+pzip p c = parser (Zip p c) (FPDecided False) (FPDecided False) -- | Terminal.-ter :: String -> Parser String-ter t = parser (Ter t) (FPDecided False) +ter :: (Ord t) => t -> Parser t String+ter = terM . Set.singleton+-- | Set generalized version of `ter'.+terM :: (Ord t) => Set t -> Parser t String+terM tM = parser (Ter tM) (FPDecided False) (FPDecided False) -- | Epsilon/empty-string.-eps :: (Ord a) => a -> Parser a+eps :: (Ord t, Ord a) => a -> Parser t a eps = epsM . Set.singleton -- | Set generalized version of `eps'.-epsM :: (Ord a) => Set a -> Parser a-epsM e = parser (Eps e) (FPDecided True) +epsM :: (Ord t, Ord a) => Set a -> Parser t a+epsM e = parser (Eps e) (FPDecided True) (FPDecided False) -- | The empty language.-emp :: (Ord a) => Parser a-emp = parser Emp (FPDecided False) +emp :: (Ord t, Ord a) => Parser t a+emp = parser Emp (FPDecided False) (FPDecided True)  infixr 3 <~> infixr 1 <|> infix 2 ==>, ==>| +-- | Kleene Star+star :: (Ord t, Ord a) => Parser t a -> Parser t [a]+star p = r+  where+    r = eps [] <|> p <~> r ==> uncurry (:)++star1 :: (Ord t, Ord a) => Parser t a -> Parser t [a]+star1 p = p <~> star p ==> uncurry (:)++option :: (Ord t, Ord a) => Parser t a -> Parser t (Maybe a)+option p = r+  where+    r = eps Nothing <|> p ==> Just++terS :: (Ord t) => [t] -> Parser t String+terS ts = m ts ==> concat+  where+    m [] = eps []+    m (a:as) = ter a <~> m as ==> uncurry (:)+ -- | The main derivative function. -derive :: Parser a -> Token -> Parser a+derive :: Parser t a -> Token t -> Parser t a derive = parserDerive -deriveImp :: Parser a -> Token -> Parser a+deriveImp :: Parser t a -> Token t -> Parser t a deriveImp p' x' = deriveImpRec (parserRec p') x'   where     deriveImpRec (Alt a b) x = derive a x <|> derive b x@@ -123,90 +151,102 @@     deriveImpRec (Red f a) x = derive a x ==>| f     deriveImpRec (Nul _) _ = emp     deriveImpRec (Zip p c) t = pzip (derive p t) c -    deriveImpRec (Ter c) (Token x t) | c == x = eps t | otherwise = emp+    deriveImpRec (Ter c) (Token x t) | x `Set.member` c = eps t | otherwise = emp     deriveImpRec (Eps _) _ = emp     deriveImpRec Emp _ = emp  -- | The optimization step of the algorithm. -compact :: Parser a -> Parser a+compact :: Parser t a -> Parser t a compact = parserCompact -compactImp :: (Ord a) => Parser a -> Parser a+compactImp :: (Ord t, Ord a) => Parser t a -> Parser t a compactImp p = compactImpRec $ parserRec p   where-    compactImpRec (Alt (Parser Emp _ _ _) (Parser Emp _ _ _)) = emp-    compactImpRec (Alt (Parser Emp _ _ _) b) = compact b-    compactImpRec (Alt a (Parser Emp _ _ _)) = compact a-    compactImpRec (Alt (Parser (Eps sM) _ _ _) (Parser (Eps tM) _ _ _)) = epsM (sM `Set.union` tM)-    compactImpRec (Alt a b) = (compact a <|> compact b) { parserNullable = parserNullable a <||> parserNullable b }-    compactImpRec (Con (Parser Emp _ _ _) _) = emp-    compactImpRec (Con _ (Parser Emp _ _ _)) = emp-    compactImpRec (Con (Parser (Eps sM) _ _ _) b) = compact b ==>| (\ xM -> Set.fromList [ (s, x) | s <- Set.toList sM, x <- Set.toList xM ])-    compactImpRec (Con a (Parser (Eps sM) _ _ _)) = compact a ==>| (\ xM -> Set.fromList [ (x, s) | x <- Set.toList xM, s <- Set.toList sM ])-    compactImpRec (Con a b) | parserNullable a == FPDecided False && parserNullable b == FPDecided False -      = pzip (compact a) (ConContext (compact b) TopContext)-    compactImpRec (Con a b) = (compact a <~> compact b) { parserNullable = parserNullable a <&&> parserNullable b }-    compactImpRec (Red _ (Parser Emp _ _ _)) = emp-    compactImpRec (Red f (Parser (Eps sM) _ _ _)) = epsM (f sM)-    compactImpRec (Red f (Parser (Red g a) _ _ _)) = compact a ==>| f . g-    compactImpRec (Red f a) = (compact a ==>| f) { parserNullable = parserNullable a }-    compactImpRec (Nul (Parser (Con a b) _ _ _)) = nul (compact a) <~> nul (compact b)-    compactImpRec (Nul (Parser (Alt a b) _ _ _)) = nul (compact a) <|> nul (compact b)-    compactImpRec (Nul (Parser (Red f a) _ _ _)) = nul (compact a) ==>| f-    compactImpRec (Nul (Parser (Zip a c) _ _ _)) = pzip (nul a) (nulContext c)-    compactImpRec (Nul a@(Parser (Nul _) _ _ _)) = compact a-    compactImpRec (Nul (Parser (Eps sM) _ _ _)) = epsM sM-    compactImpRec (Nul (Parser (Ter _) _ _ _)) = emp-    compactImpRec (Nul (Parser Emp _ _ _)) = emp+    compactImpRec (Alt (Parser Emp _ _ _ _) (Parser Emp _ _ _ _)) = emp+    compactImpRec (Alt (Parser Emp _ _ _ _) b) = compact b+    compactImpRec (Alt a (Parser Emp _ _ _ _)) = compact a+    compactImpRec (Alt (Parser (Eps sM) _ _ _ _) (Parser (Eps tM) _ _ _ _)) = epsM (sM `Set.union` tM)+    compactImpRec (Alt a b) = (compact a <|> compact b) +      { parserNullable = parserNullable a <||> parserNullable b +      , parserEmpty = parserEmpty a <&&> parserEmpty b+      }+    compactImpRec (Con (Parser Emp _ _ _ _) _) = emp+    compactImpRec (Con _ (Parser Emp _ _ _ _)) = emp+    compactImpRec (Con (Parser (Eps sM) _ _ _ _) b) = compact b ==>| (\ xM -> Set.fromList [ (s, x) | s <- Set.toList sM, x <- Set.toList xM ])+    compactImpRec (Con a (Parser (Eps sM) _ _ _ _)) = compact a ==>| (\ xM -> Set.fromList [ (x, s) | x <- Set.toList xM, s <- Set.toList sM ])+    compactImpRec (Con a b) +      | parserNullable a == FPDecided False && parserNullable b == FPDecided False +        && parserEmpty a == FPDecided False && parserEmpty b == FPDecided False = +      pzip (compact a) (ConContext (compact b) TopContext)+    compactImpRec (Con a b) = (compact a <~> compact b) +      { parserNullable = parserNullable a <&&> parserNullable b +      , parserEmpty = parserEmpty a <||> parserEmpty b+      }+    compactImpRec (Red _ (Parser Emp _ _ _ _)) = emp+    compactImpRec (Red f (Parser (Eps sM) _ _ _ _)) = epsM (f sM)+    compactImpRec (Red f (Parser (Red g a) _ _ _ _)) = compact a ==>| f . g+    compactImpRec (Red f a) = (compact a ==>| f) +      { parserNullable = parserNullable a +      , parserEmpty = parserEmpty a+      }+    compactImpRec (Nul (Parser (Con a b) _ _ _ _)) = nul (compact a) <~> nul (compact b)+    compactImpRec (Nul (Parser (Alt a b) _ _ _ _)) = nul (compact a) <|> nul (compact b)+    compactImpRec (Nul (Parser (Red f a) _ _ _ _)) = nul (compact a) ==>| f+    compactImpRec (Nul (Parser (Zip a c) _ _ _ _)) = pzip (nul a) (nulContext c)+    compactImpRec (Nul a@(Parser (Nul _) _ _ _ _)) = compact a+    compactImpRec (Nul (Parser (Eps sM) _ _ _ _)) = epsM sM+    compactImpRec (Nul (Parser (Ter _) _ _ _ _)) = emp+    compactImpRec (Nul (Parser Emp _ _ _ _)) = emp     compactImpRec (Zip a TopContext) = compact a-    compactImpRec (Zip (Parser Emp _ _ _) _) = emp-    compactImpRec (Zip a c) | parserNullable a /= FPDecided False = unfoldOne (compactImp a) c-    compactImpRec (Zip (Parser (Zip a c) _ _ _) d) = pzip (compact a) (thread c d)-    compactImpRec (Zip (Parser (Red f a) _ _ _) c) = pzip (compact a) (RedContext f c)+    compactImpRec (Zip (Parser Emp _ _ _ _) _) = emp+    compactImpRec (Zip a c) | parserNullable a /= FPDecided False = unfoldOne (compact a) c+    compactImpRec (Zip (Parser (Zip a c) _ _ _ _) d) = pzip (compact a) (thread c d)+    compactImpRec (Zip (Parser (Red f a) _ _ _ _) c) = pzip (compact a) (RedContext f c)     compactImpRec (Zip a c) = pzip (compact a) c     compactImpRec (Ter _) = p     compactImpRec (Eps sM) | sM == Set.empty = emp     compactImpRec (Eps _) = p     compactImpRec Emp = p -    nulContext :: Context a b -> Context a b+    nulContext :: Context t a b -> Context t a b     nulContext (ConContext a c) = ConContext (nul a) (nulContext c)     nulContext (RedContext f c) = RedContext f (nulContext c)     nulContext TopContext = TopContext -    thread :: (Ord a, Ord b, Ord c) => Context a b -> Context b c -> Context a c+    thread :: (Ord t, Ord a, Ord b, Ord c) => Context t a b -> Context t b c -> Context t a c     thread TopContext d = d     thread (RedContext f c) d = RedContext f (thread c d)     thread (ConContext a c) d = ConContext a (thread c d) -    unfoldOne :: (Ord a, Ord b) => Parser a -> Context a b -> Parser b+    unfoldOne :: (Ord t, Ord a, Ord b) => Parser t a -> Context t a b -> Parser t b     unfoldOne a (ConContext b c) = pzip (a <~> b) c     unfoldOne a (RedContext f c) = unfoldOne (a ==>| f) c     unfoldOne _ TopContext = error "cannot unfold top"  -- | Extract the parse-null set of a parser. -parseNull :: (Ord a) => Parser a -> Set a+parseNull :: (Ord t, Ord a) => Parser t a -> Set a parseNull p = work $ nul p   where-    work (Parser (Eps sM) _ _ _) = sM-    work (Parser Emp _ _ _) = Set.empty+    work (Parser (Eps sM) _ _ _ _) = sM+    work (Parser Emp _ _ _ _) = Set.empty     work other = work $ compact other  -- running parsers  -- | A specified number of compactions.-compactNum :: Int -> Parser a -> Parser a+compactNum :: Int -> Parser t a -> Parser t a compactNum 0 p = p compactNum n p = compactNum (n - 1) (compact p) --- | Derivation followed by specified number of compactions.-deriveStepNum :: Int -> Parser a -> Token -> Parser a+-- | Derivation followed by a specified number of compactions.+deriveStepNum :: Int -> Parser t a -> Token t -> Parser t a deriveStepNum n p i = compactNum n $ derive p i  -- | Parse using a specified number of intermediate compactions.-runParseNum :: (Ord a) => Int -> Parser a -> [Token] -> Set a+runParseNum :: (Ord t, Ord a) => Int -> Parser t a -> [Token t] -> Set a+runParseNum _ (Parser Emp _ _ _ _) _ = Set.empty runParseNum _ p [] = parseNull p runParseNum n p (i:is) = runParseNum n (deriveStepNum n p i) is @@ -216,7 +256,7 @@ defaultCompactSteps = 10  -- | Derivation followed by the default number of compactions.-deriveStep :: Parser a -> Token -> Parser a+deriveStep :: Parser t a -> Token t -> Parser t a deriveStep = deriveStepNum defaultCompactSteps  -- | Parse using the default number of intermediate compactions.  This is the@@ -238,12 +278,35 @@ -- -- > Set.fromList [9] ---runParse :: (Ord a) => Parser a -> [Token] -> Set a+runParse :: (Ord t, Ord a) => Parser t a -> [Token t] -> Set a runParse = runParseNum defaultCompactSteps +runParseStagesNum :: (Ord t, Ord a) => Int -> Parser t a -> [Token t] -> [(Parser t a, Set a, [Token t])]+runParseStagesNum n p input = ((p, parseNull p, input) :) $+  case input of+    [] -> []+    (i:is) -> runParseStagesNum n (deriveStepNum n p i) is++runParseStages :: (Ord t, Ord a) => Parser t a -> [Token t] -> [(Parser t a, Set a, [Token t])]+runParseStages = runParseStagesNum defaultCompactSteps++runParseLongestMatchNum :: (Ord t, Ord a) => Int -> Parser t a -> [Token t] -> Maybe (Int, Set a, [Token t])+runParseLongestMatchNum n p input = findLongestMatch 0 $ runParseStagesNum n p input+  where+    findLongestMatch _ [] = Nothing+    findLongestMatch _ ((Parser Emp _ _ _ _, _, _):_) = Nothing+    findLongestMatch l ((_, np, ts):others) = case findLongestMatch (l + 1) others of+      (Just result) -> Just result+      Nothing+        | np == Set.empty -> Nothing+        | otherwise       -> Just (l, np, ts)++runParseLongestMatch :: (Ord t, Ord a) => Parser t a -> [Token t] -> Maybe (Int, Set a, [Token t])+runParseLongestMatch = runParseLongestMatchNum defaultCompactSteps+ -- inspecting parsers -parserChildren :: Parser a -> [GenParser]+parserChildren :: Parser t a -> [GenParser] parserChildren = parserRecChildren . parserRec   where     parserRecChildren (Con a b) = [genParser a, genParser b]@@ -255,23 +318,23 @@     parserRecChildren (Eps _)   = []     parserRecChildren Emp       = [] -foldlParserChildrenM :: (forall b. t -> Parser b -> IO t) -> t -> Parser a -> IO t+foldlParserChildrenM :: (forall t b. c -> Parser t b -> IO c) -> c -> Parser t2 a -> IO c foldlParserChildrenM f i p = foldM g i $ parserChildren p   where     g t (GenParser h) = h (f t) -newtype GenParser = GenParser { unGenParser :: forall c. (forall b. Parser b -> c) -> c }+newtype GenParser = GenParser { unGenParser :: forall c. (forall t b. Parser t b -> c) -> c } -genParser :: Parser a -> GenParser+genParser :: Parser t a -> GenParser genParser p = GenParser $ \ f -> f p -runGenParser :: (forall b. Parser b -> c) -> GenParser -> c+runGenParser :: (forall t b. Parser t b -> c) -> GenParser -> c runGenParser f g = unGenParser g f  data ParserRecType = ConType | AltType | RedType | NulType | ZipType | TerType | EpsType | EmpType   deriving (Eq, Ord, Show) -parserType :: Parser a -> ParserRecType+parserType :: Parser t a -> ParserRecType parserType = parserRecType . parserRec   where     parserRecType (Con _ _) = ConType@@ -283,11 +346,11 @@     parserRecType (Eps _)   = EpsType     parserRecType Emp       = EmpType -type ParserInspect t =  (forall a. Parser a -> IO Integer) -                     -> (forall a. Parser a -> IO Bool) -                     -> (forall a. Parser a -> IO t)+type ParserInspect b =  (forall t a. Parser t a -> IO Integer) +                     -> (forall t a. Parser t a -> IO Bool) +                     -> (forall t a. Parser t a -> IO b) -inspectParser :: ParserInspect t -> Parser a -> t+inspectParser :: ParserInspect b -> Parser t a -> b inspectParser f p = unsafePerformIO $ do   reifiedPt <- newIORef Map.empty   seenPt    <- newIORef Map.empty@@ -296,7 +359,7 @@  lookupId :: IORef (Map Int [(StableName (), Integer)])           -> IORef Integer -         -> Parser a +         -> Parser t a           -> IO Integer lookupId reifiedPt uidPt p    | p `seq` True = do@@ -312,7 +375,7 @@         return thisId   | otherwise = error "seq failed" -seenId :: IORef (Map Int [(StableName (), ())]) -> Parser a -> IO Bool+seenId :: IORef (Map Int [(StableName (), ())]) -> Parser t a -> IO Bool seenId seenPt p    | p `seq` True = do      stblName <- genericStableName p@@ -337,9 +400,9 @@                                   | otherwise   -> process (Just xs)       Nothing                                   -> Nothing -type ParserFoldL t = forall a. t -> Parser a -> Integer -> Integer -> [Integer] -> t+type ParserFoldL b = forall t a. b -> Parser t a -> Integer -> Integer -> [Integer] -> b -parserDeepFoldL :: ParserFoldL t -> t -> Parser a -> t+parserDeepFoldL :: ParserFoldL b -> b -> Parser t a -> b parserDeepFoldL f i = inspectParser $ inspectf f i  inspectf :: ParserFoldL t -> t -> ParserInspect t@@ -358,7 +421,7 @@                              (FPValue Bool) -- nullable                              [Integer] -- children -parserToGraph :: Parser a -> [ParserInfo]+parserToGraph :: Parser t a -> [ParserInfo] parserToGraph = reverse . parserDeepFoldL f []   where     f :: ParserFoldL [ParserInfo]@@ -381,7 +444,13 @@              (showFPBool n)              (show children) -instance Show (Parser a) where+parserSize :: Parser t a -> Int+parserSize = parserDeepFoldL f 0+  where+    f :: ParserFoldL Int+    f n _ _ _ _ = n + 1++instance Show (Parser t a) where   show = showParserGraph . parserToGraph  -- FPValue@@ -426,41 +495,110 @@  -- demos -xsR :: () -> Parser String+xsR :: () -> Parser String String xsR () = p   where     p = eps "" <|> ter "x" <~> p ==> uncurry (++) -xsL :: () -> Parser String+xsL :: () -> Parser String String xsL () = p   where     p = eps "" <|> p <~> ter "x" ==> uncurry (++) -xsIn :: [Token]+xsIn :: [Token String] xsIn = replicate 60 (Token "x" "x") -parens :: () -> Parser String+parens :: () -> Parser String String parens () = p   where     p = eps "" <|> ter "(" <~> p <~> ter ")" ==> (\(s1,(s2,s3)) -> s1 ++ s2 ++ s3) -parensIn :: [Token]+parensIn :: [Token String] parensIn = replicate 80 (Token "(" "(") ++ replicate 80 (Token ")" ")") -amb :: () -> Parser String+amb :: () -> Parser String String amb () = p   where     p = ter "1" <|> p <~> ter "+" <~> p ==> (\(s1,(s2,s3)) -> "(" ++ s1 ++ s2 ++ s3 ++ ")") -ambIn :: [Token]+ambIn :: [Token String] ambIn = intersperse (Token "+" "+") (replicate 7 (Token "1" "1")) -sexp :: () -> Parser String+sexp :: () -> Parser String String sexp () = p   where     p = ter "(" <~> pl <~> ter ")" ==> (\(s1,(s2,s3)) -> s1 ++ s2 ++ s3) <|> ter "s"-    pl = p <~> pl ==> uncurry (++) <|> eps ""+    pl = pl <~> p ==> uncurry (++) <|> eps "" -sexpIn :: [Token]+sexpIn :: [Token String] sexpIn = map (\x -> Token x x) $ words "( s ( s ( s s ( s s s ( s s s ( s ) ( s s ) s s ) s s ) s ) s ) )" +makeSExpIn :: Int -> [Token String]+makeSExpIn n = map (\x -> Token x x) . words $ "( " ++ build n "s" ++ " )"+  where+    build 0 x = x+    build n s = build (n - 1) s'+      where+        s' = "s ( " ++ s ++ " )"++someStuff :: [Token String]+someStuff = map (\x -> Token x x) $ words "x x x x y y y x x"++someStuffG :: () -> Parser String String+someStuffG () = p+  where+    p = eps "" <|> p <~> ter "x" ==> uncurry (++)+++nilsE :: () -> Parser String ()+nilsE () = expr+  where +    expr = op <|> atom+    op = expr <~> internal ==> const ()+    atom = ter "x" ==> const ()+    internal = ter "[" <~> expr <~> ter "]" ==> const ()+      ++exprIn :: Int -> [String]+exprIn n =+  foldr (.) id+        (replicate n (\s -> ("x" :) . ("[" :) . s . ("]" :)))+        ("x" :) +        []++exprIn2 :: [String]+exprIn2 = words "x [ x ] [ x ]"++-- lexing++stepParsers :: (Ord t, Ord a) => [Parser t a] -> [Token t] -> [(Int, Set a, [Token t])]+stepParsers ps ts = catMaybes $ map (flip runParseLongestMatch ts) ps++longestFirstMatch :: [(Int, Set a, [Token t])] -> Maybe (a, [Token t])+longestFirstMatch rs = fmap extract $ foldl pick Nothing rs+  where+    pick Nothing s = Just s+    pick tM@(Just (tlen, _, _)) c@(clen, _, _) | clen > tlen = Just c+                                               | otherwise   = tM+    extract (_, res, con) = (Set.toList res !! 0, con)++fullLex :: (Show t, Ord t, Ord a) => [Parser t a] -> [Token t] -> Either String [a]+fullLex ps [] = Right []+fullLex ps ts = case longestFirstMatch (stepParsers ps ts) of+  Nothing -> Left $ printf "cannot parse: %s" (show ts)+  Just (r, ts') -> fmap (r :) $ fullLex ps ts'+                    +charToken :: Char -> Token Char+charToken c = Token c [c]++-- sizes++reportSizes :: Parser t a -> [Token t] -> String+reportSizes = reportSizesN 0++reportSizesN :: Int -> Parser t a -> [Token t] -> String+reportSizesN _ _ [] = ""+reportSizesN n p (i:is) = printf "%3s :: %s\n" (show n) (show size) ++ reportSizesN (n + 1) p' is+  where+    p' = deriveStep p i+    size = parserSize p'