packages feed

pinchot 0.12.0.0 → 0.14.0.0

raw patch · 9 files changed

+388/−109 lines, 9 filesnew-component:exe:parakeetPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Pinchot: allRulesRecord :: Qualifier -> Name -> Pinchot t a -> DecsQ
+ Pinchot: earleyProduct :: Lift t => Qualifier -> Qualifier -> Pinchot t a -> ExpQ
+ Pinchot: type Qualifier = String
+ Pinchot.Examples.AllRulesRecord: Productions :: Prod r String Char Digit -> Prod r String Char Digit'Seq1 -> Prod r String Char Letter -> Prod r String Char North -> Prod r String Char South -> Prod r String Char East -> Prod r String Char West -> Prod r String Char Direction -> Prod r String Char Street -> Prod r String Char Avenue -> Prod r String Char Way -> Prod r String Char Boulevard -> Prod r String Char Suffix -> Prod r String Char Space -> Prod r String Char Comma -> Prod r String Char Letters -> Prod r String Char PostalWord -> Prod r String Char PreSpacedWord -> Prod r String Char PreSpacedWord'Seq -> Prod r String Char Words -> Prod r String Char Number -> Prod r String Char StreetName -> Prod r String Char City -> Prod r String Char State -> Prod r String Char ZipCode -> Prod r String Char DirectionSpace -> Prod r String Char SpaceSuffix -> Prod r String Char DirectionSpace'Maybe -> Prod r String Char SpaceSuffix'Maybe -> Prod r String Char Address -> Productions r
+ Pinchot.Examples.AllRulesRecord: [a'Address] :: Productions r -> Prod r String Char Address
+ Pinchot.Examples.AllRulesRecord: [a'Avenue] :: Productions r -> Prod r String Char Avenue
+ Pinchot.Examples.AllRulesRecord: [a'Boulevard] :: Productions r -> Prod r String Char Boulevard
+ Pinchot.Examples.AllRulesRecord: [a'City] :: Productions r -> Prod r String Char City
+ Pinchot.Examples.AllRulesRecord: [a'Comma] :: Productions r -> Prod r String Char Comma
+ Pinchot.Examples.AllRulesRecord: [a'Digit'Seq1] :: Productions r -> Prod r String Char Digit'Seq1
+ Pinchot.Examples.AllRulesRecord: [a'Digit] :: Productions r -> Prod r String Char Digit
+ Pinchot.Examples.AllRulesRecord: [a'DirectionSpace'Maybe] :: Productions r -> Prod r String Char DirectionSpace'Maybe
+ Pinchot.Examples.AllRulesRecord: [a'DirectionSpace] :: Productions r -> Prod r String Char DirectionSpace
+ Pinchot.Examples.AllRulesRecord: [a'Direction] :: Productions r -> Prod r String Char Direction
+ Pinchot.Examples.AllRulesRecord: [a'East] :: Productions r -> Prod r String Char East
+ Pinchot.Examples.AllRulesRecord: [a'Letter] :: Productions r -> Prod r String Char Letter
+ Pinchot.Examples.AllRulesRecord: [a'Letters] :: Productions r -> Prod r String Char Letters
+ Pinchot.Examples.AllRulesRecord: [a'North] :: Productions r -> Prod r String Char North
+ Pinchot.Examples.AllRulesRecord: [a'Number] :: Productions r -> Prod r String Char Number
+ Pinchot.Examples.AllRulesRecord: [a'PostalWord] :: Productions r -> Prod r String Char PostalWord
+ Pinchot.Examples.AllRulesRecord: [a'PreSpacedWord'Seq] :: Productions r -> Prod r String Char PreSpacedWord'Seq
+ Pinchot.Examples.AllRulesRecord: [a'PreSpacedWord] :: Productions r -> Prod r String Char PreSpacedWord
+ Pinchot.Examples.AllRulesRecord: [a'South] :: Productions r -> Prod r String Char South
+ Pinchot.Examples.AllRulesRecord: [a'SpaceSuffix'Maybe] :: Productions r -> Prod r String Char SpaceSuffix'Maybe
+ Pinchot.Examples.AllRulesRecord: [a'SpaceSuffix] :: Productions r -> Prod r String Char SpaceSuffix
+ Pinchot.Examples.AllRulesRecord: [a'Space] :: Productions r -> Prod r String Char Space
+ Pinchot.Examples.AllRulesRecord: [a'State] :: Productions r -> Prod r String Char State
+ Pinchot.Examples.AllRulesRecord: [a'StreetName] :: Productions r -> Prod r String Char StreetName
+ Pinchot.Examples.AllRulesRecord: [a'Street] :: Productions r -> Prod r String Char Street
+ Pinchot.Examples.AllRulesRecord: [a'Suffix] :: Productions r -> Prod r String Char Suffix
+ Pinchot.Examples.AllRulesRecord: [a'Way] :: Productions r -> Prod r String Char Way
+ Pinchot.Examples.AllRulesRecord: [a'West] :: Productions r -> Prod r String Char West
+ Pinchot.Examples.AllRulesRecord: [a'Words] :: Productions r -> Prod r String Char Words
+ Pinchot.Examples.AllRulesRecord: [a'ZipCode] :: Productions r -> Prod r String Char ZipCode
+ Pinchot.Examples.AllRulesRecord: data Productions r
+ Pinchot.Examples.EarleyProduct: addressParser :: Grammar r (Prod r String Char Address)
+ Pinchot.Examples.EarleyProduct: allProductions :: Grammar r (Productions r)
+ Pinchot.Internal: allRulesRecord :: Qualifier -> Name -> Pinchot t a -> DecsQ
+ Pinchot.Internal: earleyProduct :: Lift t => Qualifier -> Qualifier -> Pinchot t a -> ExpQ
+ Pinchot.Internal: goPinchot :: Pinchot t a -> Q (Names t, a)
+ Pinchot.Internal: recursiveDo :: [(Name, ExpQ)] -> ExpQ -> ExpQ
+ Pinchot.Internal: type Qualifier = String
- Pinchot: allEarleyGrammars :: Lift t => String -> Pinchot t a -> DecsQ
+ Pinchot: allEarleyGrammars :: Lift t => Qualifier -> Name -> Pinchot t a -> DecsQ
- Pinchot: earleyGrammar :: Lift t => String -> Pinchot t (Rule t) -> Q Exp
+ Pinchot: earleyGrammar :: Lift t => Qualifier -> Pinchot t (Rule t) -> Q Exp
- Pinchot.Examples.AllEarleyGrammars: g'Address :: Grammar r (Prod r [Char] Char Address)
+ Pinchot.Examples.AllEarleyGrammars: g'Address :: Grammar r (Prod r String Char Address)
- Pinchot.Examples.AllEarleyGrammars: g'Avenue :: Grammar r (Prod r [Char] Char Avenue)
+ Pinchot.Examples.AllEarleyGrammars: g'Avenue :: Grammar r (Prod r String Char Avenue)
- Pinchot.Examples.AllEarleyGrammars: g'Boulevard :: Grammar r (Prod r [Char] Char Boulevard)
+ Pinchot.Examples.AllEarleyGrammars: g'Boulevard :: Grammar r (Prod r String Char Boulevard)
- Pinchot.Examples.AllEarleyGrammars: g'City :: Grammar r (Prod r [Char] Char City)
+ Pinchot.Examples.AllEarleyGrammars: g'City :: Grammar r (Prod r String Char City)
- Pinchot.Examples.AllEarleyGrammars: g'Comma :: Grammar r (Prod r [Char] Char Comma)
+ Pinchot.Examples.AllEarleyGrammars: g'Comma :: Grammar r (Prod r String Char Comma)
- Pinchot.Examples.AllEarleyGrammars: g'Digit :: Grammar r (Prod r [Char] Char Digit)
+ Pinchot.Examples.AllEarleyGrammars: g'Digit :: Grammar r (Prod r String Char Digit)
- Pinchot.Examples.AllEarleyGrammars: g'Digit'Seq1 :: Grammar r (Prod r [Char] Char Digit'Seq1)
+ Pinchot.Examples.AllEarleyGrammars: g'Digit'Seq1 :: Grammar r (Prod r String Char Digit'Seq1)
- Pinchot.Examples.AllEarleyGrammars: g'Direction :: Grammar r (Prod r [Char] Char Direction)
+ Pinchot.Examples.AllEarleyGrammars: g'Direction :: Grammar r (Prod r String Char Direction)
- Pinchot.Examples.AllEarleyGrammars: g'DirectionSpace :: Grammar r (Prod r [Char] Char DirectionSpace)
+ Pinchot.Examples.AllEarleyGrammars: g'DirectionSpace :: Grammar r (Prod r String Char DirectionSpace)
- Pinchot.Examples.AllEarleyGrammars: g'DirectionSpace'Maybe :: Grammar r (Prod r [Char] Char DirectionSpace'Maybe)
+ Pinchot.Examples.AllEarleyGrammars: g'DirectionSpace'Maybe :: Grammar r (Prod r String Char DirectionSpace'Maybe)
- Pinchot.Examples.AllEarleyGrammars: g'East :: Grammar r (Prod r [Char] Char East)
+ Pinchot.Examples.AllEarleyGrammars: g'East :: Grammar r (Prod r String Char East)
- Pinchot.Examples.AllEarleyGrammars: g'Letter :: Grammar r (Prod r [Char] Char Letter)
+ Pinchot.Examples.AllEarleyGrammars: g'Letter :: Grammar r (Prod r String Char Letter)
- Pinchot.Examples.AllEarleyGrammars: g'Letters :: Grammar r (Prod r [Char] Char Letters)
+ Pinchot.Examples.AllEarleyGrammars: g'Letters :: Grammar r (Prod r String Char Letters)
- Pinchot.Examples.AllEarleyGrammars: g'North :: Grammar r (Prod r [Char] Char North)
+ Pinchot.Examples.AllEarleyGrammars: g'North :: Grammar r (Prod r String Char North)
- Pinchot.Examples.AllEarleyGrammars: g'Number :: Grammar r (Prod r [Char] Char Number)
+ Pinchot.Examples.AllEarleyGrammars: g'Number :: Grammar r (Prod r String Char Number)
- Pinchot.Examples.AllEarleyGrammars: g'PostalWord :: Grammar r (Prod r [Char] Char PostalWord)
+ Pinchot.Examples.AllEarleyGrammars: g'PostalWord :: Grammar r (Prod r String Char PostalWord)
- Pinchot.Examples.AllEarleyGrammars: g'PreSpacedWord :: Grammar r (Prod r [Char] Char PreSpacedWord)
+ Pinchot.Examples.AllEarleyGrammars: g'PreSpacedWord :: Grammar r (Prod r String Char PreSpacedWord)
- Pinchot.Examples.AllEarleyGrammars: g'PreSpacedWord'Seq :: Grammar r (Prod r [Char] Char PreSpacedWord'Seq)
+ Pinchot.Examples.AllEarleyGrammars: g'PreSpacedWord'Seq :: Grammar r (Prod r String Char PreSpacedWord'Seq)
- Pinchot.Examples.AllEarleyGrammars: g'South :: Grammar r (Prod r [Char] Char South)
+ Pinchot.Examples.AllEarleyGrammars: g'South :: Grammar r (Prod r String Char South)
- Pinchot.Examples.AllEarleyGrammars: g'Space :: Grammar r (Prod r [Char] Char Space)
+ Pinchot.Examples.AllEarleyGrammars: g'Space :: Grammar r (Prod r String Char Space)
- Pinchot.Examples.AllEarleyGrammars: g'SpaceSuffix :: Grammar r (Prod r [Char] Char SpaceSuffix)
+ Pinchot.Examples.AllEarleyGrammars: g'SpaceSuffix :: Grammar r (Prod r String Char SpaceSuffix)
- Pinchot.Examples.AllEarleyGrammars: g'SpaceSuffix'Maybe :: Grammar r (Prod r [Char] Char SpaceSuffix'Maybe)
+ Pinchot.Examples.AllEarleyGrammars: g'SpaceSuffix'Maybe :: Grammar r (Prod r String Char SpaceSuffix'Maybe)
- Pinchot.Examples.AllEarleyGrammars: g'State :: Grammar r (Prod r [Char] Char State)
+ Pinchot.Examples.AllEarleyGrammars: g'State :: Grammar r (Prod r String Char State)
- Pinchot.Examples.AllEarleyGrammars: g'Street :: Grammar r (Prod r [Char] Char Street)
+ Pinchot.Examples.AllEarleyGrammars: g'Street :: Grammar r (Prod r String Char Street)
- Pinchot.Examples.AllEarleyGrammars: g'StreetName :: Grammar r (Prod r [Char] Char StreetName)
+ Pinchot.Examples.AllEarleyGrammars: g'StreetName :: Grammar r (Prod r String Char StreetName)
- Pinchot.Examples.AllEarleyGrammars: g'Suffix :: Grammar r (Prod r [Char] Char Suffix)
+ Pinchot.Examples.AllEarleyGrammars: g'Suffix :: Grammar r (Prod r String Char Suffix)
- Pinchot.Examples.AllEarleyGrammars: g'Way :: Grammar r (Prod r [Char] Char Way)
+ Pinchot.Examples.AllEarleyGrammars: g'Way :: Grammar r (Prod r String Char Way)
- Pinchot.Examples.AllEarleyGrammars: g'West :: Grammar r (Prod r [Char] Char West)
+ Pinchot.Examples.AllEarleyGrammars: g'West :: Grammar r (Prod r String Char West)
- Pinchot.Examples.AllEarleyGrammars: g'Words :: Grammar r (Prod r [Char] Char Words)
+ Pinchot.Examples.AllEarleyGrammars: g'Words :: Grammar r (Prod r String Char Words)
- Pinchot.Examples.AllEarleyGrammars: g'ZipCode :: Grammar r (Prod r [Char] Char ZipCode)
+ Pinchot.Examples.AllEarleyGrammars: g'ZipCode :: Grammar r (Prod r String Char ZipCode)
- Pinchot.Internal: allEarleyGrammars :: Lift t => String -> Pinchot t a -> DecsQ
+ Pinchot.Internal: allEarleyGrammars :: Lift t => Qualifier -> Name -> Pinchot t a -> DecsQ
- Pinchot.Internal: bigTuple :: Foldable c => Name -> c Name -> ExpQ
+ Pinchot.Internal: bigTuple :: Foldable c => ExpQ -> c ExpQ -> ExpQ
- Pinchot.Internal: earleyGrammar :: Lift t => String -> Pinchot t (Rule t) -> Q Exp
+ Pinchot.Internal: earleyGrammar :: Lift t => Qualifier -> Pinchot t (Rule t) -> Q Exp
- Pinchot.Internal: productionDecl :: String -> RuleType t -> DecQ
+ Pinchot.Internal: productionDecl :: String -> Name -> RuleType t -> DecsQ
- Pinchot.Internal: ruleToParser :: Lift t => String -> Rule t -> [StmtQ]
+ Pinchot.Internal: ruleToParser :: Lift t => String -> Rule t -> [(Name, ExpQ)]

Files

+ exe/parakeet.hs view
@@ -0,0 +1,26 @@+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE OverloadedLists #-}++-- | Like @parrot@ but uses+-- 'Pinchot.Examples.EarleyProduct.addressParser'.+-- +-- Reads the string given as the first argument.  Parses it and+-- then, for each parse result, uses 'terminals' to print the+-- terminals.  Each result output should be the same as the input.+module Main where++import Data.Foldable (toList)+import Pinchot+import Pinchot.Examples.Postal+import Pinchot.Examples.EarleyProduct+import Pinchot.Examples.PostalAstAllRules+import System.Environment (getArgs)++import Text.Earley (parser, fullParses)++main :: IO ()+main = do+  a1:[] <- getArgs+  let (ls, _) = fullParses (parser addressParser) a1+      printSeq = putStrLn . toList . t'Address+  mapM_ printSeq ls
exe/parrot.hs view
@@ -1,15 +1,15 @@-{-# LANGUAGE TemplateHaskell #-}-{-# LANGUAGE TypeFamilies #-} {-# LANGUAGE OverloadedLists #-}+{-# LANGUAGE TemplateHaskell #-} --- | Reads the string given as the first argument.  Parses it and--- then, for each parse result, uses 'terminals' to print the+-- Reads the string given as the first argument.  Parses it and+-- then, for each parse result, uses 't'Address' to print the -- terminals.  Each result output should be the same as the input. module Main where -import Data.Foldable (toList) import Pinchot+import Data.Foldable (toList) import Pinchot.Examples.Postal+import Pinchot.Examples.EarleyProduct import System.Environment (getArgs)  import Text.Earley (parser, fullParses)@@ -19,6 +19,6 @@ main :: IO () main = do   a1:[] <- getArgs-  let (ls, _) = fullParses (parser $(earleyGrammar "" postal)) a1-      printSeq = putStrLn . toList . terminals+  let (ls, _) = fullParses (parser $(earleyGrammar "" postal)) a1 +      printSeq = putStrLn . toList . t'Address   mapM_ printSeq ls
lib/Pinchot.hs view
@@ -63,13 +63,19 @@   , (<?>)    -- * Transforming a Pinchot value to code+  -- ** Creating data types   , MakeOptics   , makeOptics   , noOptics   , allRulesToTypes   , ruleTreeToTypes+  , allRulesRecord++  -- ** Creating Earley grammars+  , Qualifier   , earleyGrammar   , allEarleyGrammars+  , earleyProduct   ) where  import Pinchot.Internal
lib/Pinchot/Examples.hs view
@@ -17,6 +17,10 @@ -- "Pinchot.Examples.AllEarleyGrammars" shows you how to use -- 'allEarleyGrammars'. --+-- "Pinchot.Examples.AllRulesRecord" and+-- "Pinchot.Examples.EarleyProduct" show you how to use+-- 'allRulesRecord' and 'earleyProduct'.+-- -- Three executables are included in the @pinchot@ package.  To get -- them, compile @pinchot@ with the @executables@ Cabal flag. --
lib/Pinchot/Examples/AllEarleyGrammars.hs view
@@ -5,8 +5,8 @@  module Pinchot.Examples.AllEarleyGrammars where -import Pinchot-import Pinchot.Examples.Postal-import Pinchot.Examples.PostalAstAllRules+import qualified Pinchot+import qualified Pinchot.Examples.Postal as Postal+import qualified Pinchot.Examples.PostalAstAllRules as PostalAstAllRules -allEarleyGrammars "" postal+Pinchot.allEarleyGrammars "PostalAstAllRules" ''Char Postal.postal
+ lib/Pinchot/Examples/AllRulesRecord.hs view
@@ -0,0 +1,12 @@+-- | Provides an example of the use of 'Pinchot.allRulesRecord'.+-- You will want to look at the source code to see how to write the+-- Template Haskell splice.++{-# LANGUAGE TemplateHaskell #-}+module Pinchot.Examples.AllRulesRecord where++import qualified Pinchot+import qualified Pinchot.Examples.Postal as Postal+import qualified Pinchot.Examples.PostalAstAllRules as AllRules++Pinchot.allRulesRecord "AllRules" ''Char Postal.postal
+ lib/Pinchot/Examples/EarleyProduct.hs view
@@ -0,0 +1,32 @@+{-# LANGUAGE TemplateHaskell #-}++-- | Provides an example of the use of 'Pinchot.earleyProduct'.  You+-- will want to look at the source code, as looking at only the+-- Haddocks will show you only the result of all the Template+-- Haskell splices.+module Pinchot.Examples.EarleyProduct where++import qualified Pinchot++-- You will need to import your Pinchot grammar+import qualified Pinchot.Examples.Postal as Postal++-- And import the types that result from applying+-- 'Pinchot.allRulesToTypes' to the Pinchot grammar+import qualified Pinchot.Examples.PostalAstAllRules as AllRules++-- And, import the product type that results from applying+-- 'Pinchot.allRulesRecord' to your grammar+import qualified Pinchot.Examples.AllRulesRecord as Record++import qualified Text.Earley as Earley++-- | 'Pinchot.earleyProduct' gives you a big product type that has+-- every rule that is in your Pinchot grammar.+allProductions :: Earley.Grammar r (Record.Productions r)+allProductions = $(Pinchot.earleyProduct "AllRules" "Record" Postal.postal)++-- | To get the exact production you're interested in, just use+-- 'fmap'.  Then you can use this value for 'Earley.parser'.+addressParser :: Earley.Grammar r (Earley.Prod r String Char AllRules.Address)+addressParser = fmap Record.a'Address allProductions
lib/Pinchot/Internal.hs view
@@ -28,12 +28,12 @@ import Data.Typeable (Typeable) import Language.Haskell.TH   (ExpQ, ConQ, normalC, mkName, strictType, notStrict, newtypeD,-   cxt, conT, Name, dataD, appT, DecsQ, appE, Q, uInfixE, bindS,-   varE, varP, conE, Pat, Exp, lamE, recC, varStrictType, dyn)+   cxt, conT, Name, dataD, appT, DecsQ, appE, Q, uInfixE,+   varE, varP, conE, Pat, Exp, recC, varStrictType, dyn) import qualified Language.Haskell.TH as TH import qualified Language.Haskell.TH.Syntax as Syntax import Text.Earley (satisfy, rule, symbol)-import qualified Text.Earley ((<?>))+import qualified Text.Earley  -- | Type synonym for the name of a production rule.  This will be the -- name of the type constructor for the corresponding type that will@@ -138,6 +138,16 @@   = Pinchot { runPinchot :: ExceptT Error (State (Names t)) a }   deriving (Functor, Applicative, Monad, MonadFix) +-- | Runs a 'Pinchot' with a starting empty state.  Fails in the Q+-- monad if the grammar is bad.+goPinchot :: Pinchot t a -> Q (Names t, a)+goPinchot (Pinchot pinc) = case fst pair of+  Left err -> fail $ "pinchot: bad grammar: " ++ show err+  Right g -> return (snd pair, g)+  where+    pair = runState (runExceptT pinc)+      (Names Set.empty Set.empty 0 M.empty)+ addRuleName   :: RuleName   -> Pinchot t ()@@ -457,8 +467,8 @@   ty <- makeType typeName derives nm ruleType   lenses <- if doLenses then ruleToOptics typeName nm ruleType     else return []-  inst <- productionDecl nm ruleType-  return (ty : inst : lenses)+  inst <- productionDecl nm typeName ruleType+  return (ty : inst ++ lenses)   makeType@@ -951,12 +961,9 @@   -- ^ The return value from the 'Pinchot' is ignored.    -> DecsQ-allRulesToTypes doOptics typeName derives pinchot = case ei of-  Left err -> fail $ "pinchot: bad grammar: " ++ show err-  Right _ -> thAllRules doOptics typeName derives (allRules st')-  where-    (ei, st') = runState (runExceptT (runPinchot pinchot))-      (Names Set.empty Set.empty 0 M.empty)+allRulesToTypes doOptics typeName derives pinchot = do+  st' <- fmap fst $ goPinchot pinchot+  thAllRules doOptics typeName derives (allRules st')  -- | Creates data types only for the 'Rule' returned from the 'Pinchot', and -- for its ancestors.@@ -980,15 +987,13 @@   -- ^ A data type is created for the 'Rule' that the 'Pinchot'   -- returns, and for the ancestors of the 'Rule'.   -> DecsQ-ruleTreeToTypes doOptics typeName derives pinchot = case ei of-  Left err -> fail $ "pinchot: bad grammar: " ++ show err-  Right r -> fmap join . sequence . toList+ruleTreeToTypes doOptics typeName derives pinchot = do+  r <- fmap snd $ goPinchot pinchot+  fmap join . sequence . toList     . fmap (thRule doOptics typeName derives)     . runCalc . getAncestors $ r   where-    runCalc stateCalc = fst $ runState stateCalc (Set.empty)-    (ei, _) = runState (runExceptT (runPinchot pinchot))-      (Names Set.empty Set.empty 0 M.empty)+    runCalc stateCalc = fst $ runState stateCalc Set.empty  addPrefix   :: String@@ -1003,7 +1008,7 @@   => String   -- ^ Module prefix   -> Rule t-  -> [TH.StmtQ]+  -> [(Name, ExpQ)] ruleToParser prefix (Rule nm mayDescription rt) = case rt of    RTerminal ivls -> [makeRule expression]@@ -1029,7 +1034,7 @@    RSeqTerm sq -> [nestRule, topRule]     where-      nestRule = bindS (varP helper) [| rule $(foldl addTerm start sq) |]+      nestRule = (helper, [| rule $(foldl addTerm start sq) |])         where           start = [|pure Seq.empty|]           addTerm acc x = [| liftA2 (<|) (symbol x) $acc |]@@ -1043,7 +1048,7 @@    RList (Rule innerNm _ _) -> [nestRule, makeRule (wrapper helper)]     where-      nestRule = bindS (varP helper) ([|rule|] `appE` parseSeq)+      nestRule = (helper, ([|rule|] `appE` parseSeq))         where           parseSeq = uInfixE [|pure Seq.empty|] [|(<|>)|] pSeq             where@@ -1051,7 +1056,7 @@    RList1 (Rule innerNm _ _) -> [nestRule, makeRule topExpn]     where-      nestRule = bindS (varP helper) [|rule $(parseSeq)|]+      nestRule = (helper, [|rule $(parseSeq)|])         where           parseSeq = [| pure Seq.empty <|> $pSeq |]             where@@ -1077,8 +1082,8 @@         where-    makeRule expression = varP (ruleName nm) `bindS`-      [|rule ($expression Text.Earley.<?> $(textToExp desc))|]+    makeRule expression = (ruleName nm,+      [|rule ($expression Text.Earley.<?> $(textToExp desc))|])     desc = maybe nm id mayDescription     textToExp txt = [| $(Syntax.lift txt) |]     constructor = constructorName prefix nm@@ -1119,9 +1124,23 @@       f soFar (Rule rule2 _ _) = [| $soFar <*> $(varE (ruleName rule2)) |]   where     constructor = constructorName prefix name++-- # lazyPattern and bigTuple - because TH has no support for+-- mdo notation      -- | Creates a lazy pattern for all the given names.  Adds an empty--- pattern onto the front.+-- pattern onto the front.  This is the counterpart of 'bigTuple'.+-- All of the given names are bound.  In addition, a single,+-- wildcard pattern is bound to the front.+-- +-- For example, @lazyPattern (map mkName ["x", "y", "z"])@ gives a+-- pattern that looks like+--+-- @~(_, (x, (y, (z, ()))))@+--+-- The idea is that the named patterns are needed so that the+-- recursive @do@ notation works, and that the wildcard pattern is+-- the return value, which is not needed here. lazyPattern   :: Foldable c   => c Name@@ -1131,15 +1150,21 @@     gen name rest = [p| ($(varP name), $rest) |]     finish pat = [p| ~(_, $pat) |] +-- | Creates a big tuple.  It is nested in the second element, such+-- as (1, (2, (3, (4, ())))).  Thus, the big tuple is terminated+-- with a unit value.  It resembles a list where each tuple is a+-- cons cell and the terminator is unit. bigTuple   :: Foldable c-  => Name-  -> c Name+  => ExpQ+  -- ^ This expression will be the first one in the tuple.+  -> c ExpQ+  -- ^ Remaining expressions in the tuple.   -> ExpQ bigTuple top = finish . foldr f [| () |]   where-    f n rest = [| ( $(varE n), $rest) |]-    finish tup = [| ($(varE top), $tup) |]+    f n rest = [| ( $(n), $rest) |]+    finish tup = [| ($(top), $tup) |]  -- | Creates an Earley grammar for a given 'Rule'.  For examples of how -- to use this, see the source code for@@ -1149,35 +1174,16 @@ earleyGrammar   :: Syntax.Lift t -  => String-  -- ^ Module prefix.  You have to make sure that the data types you-  -- created with 'ruleTreeToTypes' or with 'allRulesToTypes' are in-  -- scope, either because they were spliced into the same module that-  -- 'earleyParser' is spliced into, or because they are @import@ed-  -- into scope.  The spliced Template Haskell code has to know where-  -- to look for these data types.  If you did an unqualified @import@-  -- or if the types are in the same module as is the splice of-  -- 'earleyParser', just pass the empty string here.  If you did a-  -- qualified import, pass the appropriate namespace here.-  ---  -- For example, if you used @import qualified MyAst@, pass-  -- @\"MyAst\"@ here.  If you used @import qualified-  -- Data.MyLibrary.MyAst as MyLibrary.MyAst@, pass-  -- @\"MyLibrary.MyAst\"@ here.-  ---  -- For an example where the types are in the same module, see-  -- "Pinchot.Examples.PostalAstRuleTree" or-  -- "Pinchot.Examples.PostalAstAllRules".-  ---  -- For an example using a qualified import, see-  -- "Pinchot.Examples.QualifiedImport".+  => Qualifier+  -- ^ Qualifier for data types crated with 'ruleTreeToTypes' or+  -- 'allRulesToTypes'    -> Pinchot t (Rule t)   -- ^ Creates an Earley parser for the 'Rule' that the 'Pinchot'   -- returns.    -> Q Exp-  --  ^ When spliced, this expression has type+  -- ^ When spliced, this expression has type   -- @'Text.Earley.Grammar' r ('Text.Earley.Prod' r 'String' t a)@   --   -- where@@ -1187,12 +1193,38 @@   -- @t@ is the type of the token (usually 'Char')   --   -- @a@ is the type defined by the 'Rule'.-earleyGrammar prefix pinc = case ei of-  Left err -> fail $ "pinchot: bad grammar: " ++ show err-  Right r -> earleyGrammarFromRule prefix r+earleyGrammar prefix pinc = do+  r <- fmap snd $ goPinchot pinc+  earleyGrammarFromRule prefix r++-- | Builds a recursive @do@ expression (because TH has no support+-- for @mdo@ notation).+recursiveDo+  :: [(Name, ExpQ)]+  -- ^ Binding statements+  -> ExpQ+  -- ^ Final return value from @do@ block.  The type of this 'ExpQ'+  -- must be in the same monad as the @do@ block; it must not be a+  -- pure value.+  -> ExpQ+  -- ^ Returns an expression whose value is the final return value+  -- from the @do@ block.+recursiveDo binds final = [| fmap fst $ mfix $(fn) |]   where-    (ei, _) = runState (runExceptT (runPinchot pinc))-      (Names Set.empty Set.empty 0 M.empty)+    fn = [| \ $(lazyPattern (fmap fst binds)) -> $doBlock |]+    doBlock = TH.doE (bindStmts ++ returnStmts)+    bindStmts = map mkBind binds+      where+        mkBind (name, exp)+          = TH.bindS (TH.varP name) exp+    returnStmts = [bindRtnVal, returner]+      where+        rtnValName = TH.mkName "_returner"+        bindRtnVal = TH.bindS (TH.varP rtnValName) final+        returner+          = TH.noBindS+            [| return $(bigTuple (TH.varE rtnValName) +                                 (fmap (TH.varE . fst) binds)) |]  earleyGrammarFromRule   :: Syntax.Lift t@@ -1200,45 +1232,29 @@   -- ^ Module prefix   -> Rule t   -> Q Exp-earleyGrammarFromRule prefix r@(Rule top _ _) = [| fmap fst (mfix $lamb) |]+earleyGrammarFromRule prefix r@(Rule top _ _) = recursiveDo binds final   where-    neededRules = ruleAndAncestors r-    otherNames = rulesDemandedBeforeDefined neededRules-    expression =-      let stmts = concatMap (ruleToParser prefix)-            . toList $ neededRules-          result = bigTuple (ruleName top) otherNames-      in TH.doE (stmts ++ [TH.noBindS ([|return|] `appE` result)])-    lamb = lamE [lazyPattern otherNames] expression+    binds = concatMap (ruleToParser prefix) . toList . ruleAndAncestors $ r+    final = [| return $(TH.varE $ ruleName top) |]  -- | Creates an Earley grammar for each 'Rule' created in a--- 'Pinchot'.+-- 'Pinchot'.  For a 'Pinchot' with a large number of 'Rule's, this+-- can create a large number of declarations that can take a long+-- time to compile--sometimes several minutes.  For lower+-- compilation times, try 'earleyProduct'.  allEarleyGrammars   :: Syntax.Lift t -  => String-  -- ^ Module prefix.  You have to make sure that the data types you-  -- created with 'ruleTreeToTypes' or with 'allRulesToTypes' are in-  -- scope, either because they were spliced into the same module that-  -- 'earleyParser' is spliced into, or because they are @import@ed-  -- into scope.  The spliced Template Haskell code has to know where-  -- to look for these data types.  If you did an unqualified @import@-  -- or if the types are in the same module as is the splice of-  -- 'earleyParser', just pass the empty string here.  If you did a-  -- qualified import, pass the appropriate namespace here.-  ---  -- For example, if you used @import qualified MyAst@, pass-  -- @\"MyAst\"@ here.  If you used @import qualified-  -- Data.MyLibrary.MyAst as MyLibrary.MyAst@, pass-  -- @\"MyLibrary.MyAst\"@ here.-  ---  -- This argument is similar to that for 'earleyGrammar' so-  -- the examples there might be useful.-  ---  -- For an example using this function, please see-  -- "Pinchot.Examples.AllEarleyGrammars".+  => Qualifier+  -- ^ Qualifier for data types created with 'ruleTreeToTypes' or+  -- 'allRulesToTypes' +  -> Name+  -- ^ Name for the terminal type; often this is 'Char'.  Typically+  -- you will use the Template Haskell quoting mechanism--for+  -- example, @\'\'Char@.+   -> Pinchot t a   -- ^ Creates an Earley grammar for each 'Rule' created in the   -- 'Pinchot'.  The return value of the 'Pinchot' computation is@@ -1262,16 +1278,25 @@   --   -- where TYPE_NAME is the name of the type defined in the   -- corresponding 'Rule'.-allEarleyGrammars prefix pinc = case ei of-  Left err -> fail $ "pinchot: bad grammar: " ++ show err-  Right _ -> sequence . fmap makeDecl . fmap snd . M.toList . allRules $ st+allEarleyGrammars prefix termName pinc = do+  st <- fmap fst $ goPinchot pinc+  sequence . concat . fmap makeDecl . fmap snd . M.toList+    . allRules $ st   where-    (ei, st) = runState (runExceptT (runPinchot pinc))-      (Names Set.empty Set.empty 0 M.empty)-    makeDecl rule@(Rule nm _ _) = TH.valD pat body []+    makeDecl rule@(Rule nm _ _) = [signature, TH.valD pat body []]       where-        pat = TH.varP (TH.mkName $ "g'" ++ nm)+        signature = TH.sigD name types+        r = TH.mkName "r"+        types = TH.forallT [TH.PlainTV r] (return [])+          $ [t| Text.Earley.Grammar $(TH.varT r)+              (Text.Earley.Prod $(TH.varT r) String $(TH.conT termName)+                                         $(TH.conT qualRuleName)) |]+        name = TH.mkName $ "g'" ++ nm+        pat = TH.varP name         body = TH.normalB (earleyGrammarFromRule prefix rule)+        qualRuleName+          | null prefix = TH.mkName nm+          | otherwise = TH.mkName (prefix ++ "." ++ nm)   prodDeclName :: String -> TH.Name@@ -1287,10 +1312,17 @@ productionDecl   :: String   -- ^ Rule name+  -> Name+  -- ^ Name of terminal type   -> RuleType t-  -> TH.DecQ-productionDecl n t = TH.funD (prodDeclName n) clauses+  -> TH.DecsQ+productionDecl n termType t+  = sequence [signature, TH.funD (prodDeclName n) clauses]   where+    signature = TH.sigD (prodDeclName n) types+      where+        types = TH.appT (TH.appT TH.arrowT (TH.conT (TH.mkName n)))+          (TH.appT (TH.conT ''Seq) (TH.conT termType))     clauses = case t of       RTerminal _ -> [TH.clause [pat] bdy []]         where@@ -1376,3 +1408,128 @@               where                 newTerm = [| $(prodFn inner) $(TH.varE                               (TH.mkName ("_x'" ++ show idx))) |]++-- | Many functions take an argument that holds the name qualifier+-- for the module that contains the data types created by applying+-- 'ruleTreeToTypes' or 'allRulesToTypes' to the 'Pinchot.'+--+-- You have to make sure that the data types you created with+-- 'ruleTreeToTypes', 'allRulesToTypes', or 'allRulesRecord' are in+-- scope.  The spliced Template Haskell code has to know where to+-- look for these data types.  If you did an unqualified @import@ or+-- if the types are in the same module as is the splice of+-- 'earleyParser', just pass the empty string here.  If you did a+-- qualified import, use the appropriate qualifier here.+--+-- For example, if you used @import qualified MyAst@, pass+-- @\"MyAst\"@ here.  If you used @import qualified+-- Data.MyLibrary.MyAst as MyLibrary.MyAst@, pass+-- @\"MyLibrary.MyAst\"@ here.+--+-- I recommend that you always create a new module and that all you+-- do in that module is apply 'ruleTreeToTypes' or+-- 'allRulesToTypes', and that you then perform an @import+-- qualified@ to bring those names into scope in the module in which+-- you use a function that takes a 'Qualifier' argument.  This+-- avoids unlikely, but possible, issues that could otherwise arise+-- due to naming conflicts.+type Qualifier = String+++-- | Creates a record data type that holds a value of type+--+-- @'Text.Earley.Prod' r 'String' t a@+--+-- for every rule created in the 'Pinchot'.  @r@ is left+-- universally quantified, @t@ is the token type (typically 'Char')+-- and @a@ is the type of the rule.+--+-- This always creates a single product type whose name is+-- @Productions@; currently the name cannot be configured.+--+-- For an example of the use of 'allRulesRecord', please see+-- "Pinchot.Examples.AllRulesRecord".+allRulesRecord+  :: Qualifier+  -- ^ Qualifier for data types created with 'ruleTreeToTypes' or+  -- 'allRulesToTypes'+  -> Name+  -- ^ Name of terminal type.  Typically you will get this through+  -- the Template Haskell quoting mechanism, such as @''Char@.+  -> Pinchot t a+  -- ^ A record is created that holds a value for each 'Rule'+  -- created in the 'Pinchot'; the return value of the 'Pinchot' is+  -- ignored.+  -> DecsQ+  -- ^ When spliced, this will create a single declaration that is a+  -- record with the name @Productions@.  It will have one type variable,+  -- @r@.  Each record in the declaration will have a name like so:+  --+  -- @a'NAME@+  --+  -- where @NAME@ is the name of the type.  Don't count on these+  -- records being in any particular order.+allRulesRecord prefix termName pinc+  = sequence [TH.dataD (return []) (TH.mkName nameStr) tys [con] []]+  where+    nameStr = "Productions"+    tys = [TH.PlainTV (TH.mkName "r")]+    con = do+      names <- fmap fst $ goPinchot pinc+      TH.recC (TH.mkName nameStr)+        (fmap (mkRecord . snd) . M.assocs . allRules $ names)+    mkRecord (Rule ruleNm _ _) = TH.varStrictType recName st+      where+        recName = TH.mkName ("a'" ++ ruleNm)+        st = TH.strictType TH.notStrict ty+          where+            ty = (TH.conT ''Text.Earley.Prod)+              `TH.appT` (TH.varT (TH.mkName "r"))+              `TH.appT` (TH.conT ''String)+              `TH.appT` (TH.conT termName)+              `TH.appT` (TH.conT (TH.mkName nameWithPrefix))+            nameWithPrefix = case prefix of+              [] -> ruleNm+              _ -> prefix ++ '.' : ruleNm++-- | Creates a 'Text.Earley.Grammar' that contains a+-- 'Text.Earley.Prod' for every 'Rule' created in the 'Pinchot'.+earleyProduct+  :: Syntax.Lift t++  => Qualifier+  -- ^ Qualifier for data types created with 'ruleTreeToTypes' or+  -- 'allRulesToTypes'++  -> Qualifier+  -- ^ Module prefix for the type created with 'allRulesRecord'++  -> Pinchot t a+  -- ^ Creates an Earley grammar that contains a 'Text.Earley.Prod'+  -- for each 'Rule' in the 'Pinchot'.  The return value from the+  -- 'Pinchot' is ignored.++  -> ExpQ+  -- ^ When spliced, 'earleyProduct' creates an expression whose+  -- type is @'Text.Earley.Grammar' r (Productions r)@, where+  -- @Productions@ is+  -- the type created by 'allRulesRecord'.+earleyProduct pfxRule pfxRec pinc = do+  names <- fmap fst $ goPinchot pinc+  let binds = concatMap (ruleToParser pfxRule)+        . fmap snd . M.assocs . allRules $ names+      final = [| return+        $(TH.recConE (TH.mkName rulesRecName) (recs names)) |]+  recursiveDo binds final+  where+    rulesRecName+      | null pfxRec = "Productions"+      | otherwise = pfxRec ++ ".Productions"+    recs = fmap mkRec . fmap snd . M.assocs . allRules+      where+        mkRec (Rule n _ _) = return (TH.mkName recName, recVal)+          where+            recName+              | null pfxRec = "a'" ++ n+              | otherwise = pfxRec ++ ".a'" ++ n+            recVal = TH.VarE . ruleName $ n
pinchot.cabal view
@@ -3,11 +3,11 @@ -- http://www.github.com/massysett/cartel -- -- Script name used to generate: genCabal.hs--- Generated on: 2016-02-27 17:45:07.736409 EST+-- Generated on: 2016-03-04 16:15:31.455268 EST -- Cartel library version: 0.14.2.8  name: pinchot-version: 0.12.0.0+version: 0.14.0.0 cabal-version: >= 1.14 license: BSD3 license-file: LICENSE@@ -36,6 +36,8 @@     Pinchot     Pinchot.Examples     Pinchot.Examples.AllEarleyGrammars+    Pinchot.Examples.AllRulesRecord+    Pinchot.Examples.EarleyProduct     Pinchot.Examples.Postal     Pinchot.Examples.PostalAstAllRules     Pinchot.Examples.PostalAstNoLenses@@ -68,6 +70,8 @@       Pinchot       Pinchot.Examples       Pinchot.Examples.AllEarleyGrammars+      Pinchot.Examples.AllRulesRecord+      Pinchot.Examples.EarleyProduct       Pinchot.Examples.Postal       Pinchot.Examples.PostalAstAllRules       Pinchot.Examples.PostalAstNoLenses@@ -100,6 +104,8 @@       Pinchot       Pinchot.Examples       Pinchot.Examples.AllEarleyGrammars+      Pinchot.Examples.AllRulesRecord+      Pinchot.Examples.EarleyProduct       Pinchot.Examples.Postal       Pinchot.Examples.PostalAstAllRules       Pinchot.Examples.PostalAstNoLenses@@ -133,6 +139,42 @@       Pinchot       Pinchot.Examples       Pinchot.Examples.AllEarleyGrammars+      Pinchot.Examples.AllRulesRecord+      Pinchot.Examples.EarleyProduct+      Pinchot.Examples.Postal+      Pinchot.Examples.PostalAstAllRules+      Pinchot.Examples.PostalAstNoLenses+      Pinchot.Examples.PostalAstRuleTree+      Pinchot.Examples.QualifiedImport+      Pinchot.Internal+      Pinchot.Intervals+    hs-source-dirs:+      exe+    build-depends:+        base >= 4.8.0.0 && < 5+      , containers >= 0.5.6.2+      , transformers >= 0.4.2.0+      , template-haskell >= 2.10+      , Earley >= 0.10.1.0+      , lens >= 4.13+    other-extensions:+      TemplateHaskell+    default-language: Haskell2010+    hs-source-dirs:+      lib+  else+    buildable: False++Executable parakeet+  main-is: parakeet.hs+  if flag(executables)+    buildable: True+    other-modules:+      Pinchot+      Pinchot.Examples+      Pinchot.Examples.AllEarleyGrammars+      Pinchot.Examples.AllRulesRecord+      Pinchot.Examples.EarleyProduct       Pinchot.Examples.Postal       Pinchot.Examples.PostalAstAllRules       Pinchot.Examples.PostalAstNoLenses