grammar-combinators 0.2 → 0.2.1
raw patch · 5 files changed
+267/−3 lines, 5 files
Files
- Text/GrammarCombinators/Base/Domain.hs +2/−2
- Text/GrammarCombinators/Library/Numeric.hs +101/−0
- Text/GrammarCombinators/Utils/LiftGrammar.hs +115/−0
- Text/GrammarCombinators/Utils/MemoizeGrammar.hs +45/−0
- grammar-combinators.cabal +4/−1
Text/GrammarCombinators/Base/Domain.hs view
@@ -146,8 +146,8 @@ instance (MemoFam phiL, MemoFam phiR) => MemoFam (MergeDomain phiL phiR) where data Memo (MergeDomain phiL phiR) v = MemoMD (Memo phiL (SubVal LeftIx v)) (Memo phiR (SubVal RightIx v))- fromMemo (MemoMD ml mr) (LeftIdx idx) = unSubVal $ fromMemo ml idx- fromMemo (MemoMD ml mr) (RightIdx idx) = unSubVal $ fromMemo mr idx+ fromMemo (MemoMD ml _) (LeftIdx idx) = unSubVal $ fromMemo ml idx+ fromMemo (MemoMD _ mr) (RightIdx idx) = unSubVal $ fromMemo mr idx toMemo f = MemoMD (toMemo (MkSubVal . f . LeftIdx)) (toMemo (MkSubVal . f . RightIdx)) instance (ShowFam phiL, ShowFam phiR) =>
+ Text/GrammarCombinators/Library/Numeric.hs view
@@ -0,0 +1,101 @@+{- Copyright 2010 Dominique Devriese++ This file is part of the grammar-combinators library.++ The grammar-combinators library is free software: you can+ redistribute it and/or modify it under the terms of the GNU+ Lesser General Public License as published by the Free+ Software Foundation, either version 3 of the License, or (at+ your option) any later version.++ Foobar is distributed in the hope that it will be useful, but+ WITHOUT ANY WARRANTY; without even the implied warranty of+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+ GNU Lesser General Public License for more details.++ You should have received a copy of the GNU Lesser General+ Public License along with Foobar. If not, see+ <http://www.gnu.org/licenses/>.+-}++{-# LANGUAGE EmptyDataDecls #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE TypeFamilies #-}++module Text.GrammarCombinators.Library.Numeric ( + DecimalInteger,+ NumericDomain (DecimalInteger),+ NumericValue (NVI),+ numericGrammar,+ procNumericGrammar+ ) where++import Text.GrammarCombinators.Base++data DecimalDigit+data DecimalNonZeroDigit+data DecimalInteger++-- | This domain is intended to be reused in grammars where decimal integers are used.+-- You can refer to the DecimalInteger non-terminal using the 'lib' primitive from the 'ProductionRuleWithLibrary' type class +-- and then obtain the combined grammar by combining your grammar with 'procNumericGrammar' using the +-- 'Text.GrammarCombinators.Transform.CombineGrammars.combineGrammars' function+data NumericDomain ix where+ DecimalDigit :: NumericDomain DecimalDigit+ DecimalNonZeroDigit :: NumericDomain DecimalNonZeroDigit+ DecimalInteger :: NumericDomain DecimalInteger++instance ShowFam NumericDomain where+ showIdx DecimalDigit = "DecimalDigit"+ showIdx DecimalNonZeroDigit = "DecimalNonZeroDigit"+ showIdx DecimalInteger = "DecimalInteger"++instance FoldFam NumericDomain where+ foldFam f n = f DecimalDigit $ f DecimalNonZeroDigit $ f DecimalInteger n++instance MemoFam NumericDomain where+ data Memo NumericDomain v = MND (v DecimalDigit) (v DecimalNonZeroDigit) (v DecimalInteger)+ toMemo f = MND (f DecimalDigit) (f DecimalNonZeroDigit) (f DecimalInteger)+ fromMemo (MND v _ _) DecimalDigit = v+ fromMemo (MND _ v _) DecimalNonZeroDigit = v+ fromMemo (MND _ _ v) DecimalInteger = v++instance EqFam NumericDomain where+ overrideIdx _ DecimalDigit v DecimalDigit = v+ overrideIdx _ DecimalNonZeroDigit v DecimalNonZeroDigit = v+ overrideIdx _ DecimalInteger v DecimalInteger = v+ overrideIdx f _ _ idx = f idx++instance Domain NumericDomain++data PFNum r ix where+ DecimalDigitF :: Char -> PFNum r DecimalDigit+ DecimalNonZeroDigitF :: Char -> PFNum r DecimalNonZeroDigit+ DecimalIntegerF :: r DecimalNonZeroDigit -> [r DecimalDigit] -> PFNum r DecimalInteger++type instance PF NumericDomain = PFNum++numericGrammar :: ExtendedContextFreeGrammar NumericDomain Char+numericGrammar DecimalInteger = DecimalIntegerF $>> ref DecimalNonZeroDigit >>> manyRef DecimalDigit+numericGrammar DecimalDigit = DecimalDigitF $>> tokenRange ['0'..'9']+numericGrammar DecimalNonZeroDigit = DecimalNonZeroDigitF $>> tokenRange ['1'..'9']++data family NumericValue n ix+data instance NumericValue n DecimalInteger = NVI n+data instance NumericValue n DecimalDigit = NVD { unNVD :: Char }+data instance NumericValue n DecimalNonZeroDigit = NVND Char++processNumerics :: (Read n) => Processor NumericDomain (NumericValue n)+processNumerics DecimalDigit (DecimalDigitF c) = NVD c +processNumerics DecimalNonZeroDigit (DecimalNonZeroDigitF c) = NVND c +processNumerics DecimalInteger (DecimalIntegerF (NVND c) wcs) = NVI num+ where num = read $ c : cs+ cs = map unNVD wcs++-- | The standard processing grammar for domain 'NumericDomain', intended to be combined with other grammars using+-- the 'Text.GrammarCombinators.Transform.CombineGrammars.combineGrammars' function.+procNumericGrammar :: (Read n) => ProcessingExtendedContextFreeGrammar NumericDomain Char (NumericValue n)+procNumericGrammar = applyProcessorE numericGrammar processNumerics
+ Text/GrammarCombinators/Utils/LiftGrammar.hs view
@@ -0,0 +1,115 @@+{- Copyright 2010 Dominique Devriese++ This file is part of the grammar-combinators library.++ The grammar-combinators library is free software: you can+ redistribute it and/or modify it under the terms of the GNU+ Lesser General Public License as published by the Free+ Software Foundation, either version 3 of the License, or (at+ your option) any later version.++ Foobar is distributed in the hope that it will be useful, but+ WITHOUT ANY WARRANTY; without even the implied warranty of+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+ GNU Lesser General Public License for more details.++ You should have received a copy of the GNU Lesser General+ Public License along with Foobar. If not, see+ <http://www.gnu.org/licenses/>.+-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TemplateHaskell #-}++module Text.GrammarCombinators.Utils.LiftGrammar (+ liftGrammar,+ unfoldAndLiftGrammar+ ) where++import Text.GrammarCombinators.Base++import Language.Haskell.TH.Syntax++import Control.Monad++data LiftedRule (phi :: * -> *) (r :: * -> *) t v = + MkLR { liftRule :: Q Exp -> Q Exp -> Q Exp -> Q Exp }++instance ProductionRule (LiftedRule phi r t) where+ endOfInput = MkLR $ \_ _ _ -> [| endOfInput |]+ a >>> b = MkLR $ \r mr m1r -> [| $(liftRule a r mr m1r) >>> $(liftRule b r mr m1r) |]+ a ||| b = MkLR $ \r mr m1r -> [| $(liftRule a r mr m1r) ||| $(liftRule b r mr m1r) |]+ die = MkLR $ \_ _ _ -> [| die |]++instance BiasedProductionRule (LiftedRule phi r t) where+ a >||| b = MkLR $ \r mr m1r -> [| $(liftRule a r mr m1r) >||| $(liftRule b r mr m1r) |]+ a <||| b = MkLR $ \r mr m1r -> [| $(liftRule a r mr m1r) <||| $(liftRule b r mr m1r) |]++instance PenaltyProductionRule (LiftedRule phi r t) where+ penalty p br = MkLR $ \r mr m1r -> [| penalty p $(liftRule br r mr m1r) |]++instance LiftableProductionRule (LiftedRule phi r t) where+ epsilonL _ q = MkLR $ \_ _ _ -> [|epsilon $(q)|]++instance (Token t) => TokenProductionRule (LiftedRule phi r t) t where+ token tt = MkLR $ \_ _ _ -> [| token $(lift tt) |]+ anyToken = MkLR $ \_ _ _ -> [| anyToken |]++instance (LiftFam phi) =>+ RecProductionRule (LiftedRule phi r t) phi r where+ ref idx = MkLR $ \r _ _ -> [| $(r) $(return $ liftIdxE idx) |]++instance (LiftFam phi) =>+ LoopProductionRule (LiftedRule phi r t) phi r where+ manyRef idx = MkLR $ \_ mr _ -> [| $(mr) $(return $ liftIdxE idx) |]+ many1Ref idx = MkLR $ \_ _ m1r -> [| $(m1r) $(return $ liftIdxE idx) |]++liftGrammar' :: forall phi t r rr. (FoldFam phi, LiftFam phi, Token t) =>+ GLAnyExtendedContextFreeGrammar phi t r rr -> Name ->+ Q Exp -> Q Exp -> Q Exp ->+ Q Dec+liftGrammar' gram name refQ manyRefQ many1RefQ = + let + clause :: phi ix -> Q Clause+ clause idx = do lr <- liftRule (gram idx) refQ manyRefQ many1RefQ+ return $ Clause [liftIdxP idx] (NormalB lr) []+ addClause idx b = do c <- clause idx+ cs <- b+ return (c:cs)+ clauses = foldFam addClause (return [])+ in liftM (FunD name) clauses++-- | Lift a given grammar to Template Haskell +liftGrammar :: forall phi t r rr. (FoldFam phi, LiftFam phi, Token t) =>+ GLAnyExtendedContextFreeGrammar phi t r rr -> Name ->+ Q Type -> + Q [Dec]+liftGrammar gram name grammarType =+ let sig = do t <- grammarType+ return $ SigD name t+ fundef = liftGrammar' gram name [|ref|] [|manyRef|] [|many1Ref|]+ in do s <- sig+ f <- fundef+ return [s,f]++-- | Lift a given grammar to Template Haskell and replace recursion and loops with +-- infinite-tree style recursive calls to the grammar itself. This allows GHC to do+-- a much better optimization (x20 speed-ups in one realistic test, compared with+-- result of 'liftGrammar').+unfoldAndLiftGrammar :: forall phi t r rr. (FoldFam phi, LiftFam phi, Token t) =>+ GLAnyExtendedContextFreeGrammar phi t r rr -> Name ->+ Q Type -> + Q [Dec]+unfoldAndLiftGrammar gram name gramType =+ let refQ = return $ VarE name+ manyRefQ = return $ AppE (AppE (VarE '(.)) (VarE 'manyInf)) $ VarE name+ many1RefQ = return $ AppE (AppE (VarE '(.)) (VarE 'many1Inf)) $ (VarE name)+ sig = do t <- gramType+ return $ SigD name t+ fundef = liftGrammar' gram name refQ manyRefQ many1RefQ+ in do s <- sig+ d <- fundef+ return [s,d]
+ Text/GrammarCombinators/Utils/MemoizeGrammar.hs view
@@ -0,0 +1,45 @@+{- Copyright 2010 Dominique Devriese++ This file is part of the grammar-combinators library.++ The grammar-combinators library is free software: you can+ redistribute it and/or modify it under the terms of the GNU+ Lesser General Public License as published by the Free+ Software Foundation, either version 3 of the License, or (at+ your option) any later version.++ Foobar is distributed in the hope that it will be useful, but+ WITHOUT ANY WARRANTY; without even the implied warranty of+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+ GNU Lesser General Public License for more details.++ You should have received a copy of the GNU Lesser General+ Public License along with Foobar. If not, see+ <http://www.gnu.org/licenses/>.+-}+{-# LANGUAGE RankNTypes #-}++module Text.GrammarCombinators.Utils.MemoizeGrammar (+ memoizeGrammarR,+ memoizeGrammar,+ memoizeGrammarE+ ) where++import Text.GrammarCombinators.Base++newtype WrapCFGR p rr ix = WCFGR { unWCFGR :: p (rr ix) }++-- | Memoize the production rules of a regular grammar. Currently not sure if this is ever useful.+memoizeGrammarR :: (MemoFam phi) => + GRegularGrammar phi t r rr -> GRegularGrammar phi t r rr+memoizeGrammarR gram idx = unWCFGR (memoFamily (\idx' -> WCFGR (gram idx')) idx)++-- | Memoize the production rules of a grammar. Currently not sure if this is ever useful.+memoizeGrammar :: (MemoFam phi) => + GContextFreeGrammar phi t r rr -> GContextFreeGrammar phi t r rr+memoizeGrammar gram idx = unWCFGR (memoFamily (\idx' -> WCFGR (gram idx')) idx)++-- | Memoize the production rules of an extended grammar. Currently not sure if this is ever useful.+memoizeGrammarE :: (MemoFam phi) => + GExtendedContextFreeGrammar phi t r rr -> GExtendedContextFreeGrammar phi t r rr+memoizeGrammarE gram idx = unWCFGR (memoFamily (\idx' -> WCFGR (gram idx')) idx)
grammar-combinators.cabal view
@@ -1,5 +1,5 @@ Name: grammar-combinators-Version: 0.2+Version: 0.2.1 Description: The grammar-combinators library is a novel parsing library using an explicit representation of recursion to provide various novel@@ -36,6 +36,7 @@ Text.GrammarCombinators.Base.ProductionRule Text.GrammarCombinators.Base.Processor Text.GrammarCombinators.Base.Token+ Text.GrammarCombinators.Library.Numeric Text.GrammarCombinators.Parser.LL1 Text.GrammarCombinators.Parser.LL1TH Text.GrammarCombinators.Parser.Packrat@@ -69,6 +70,8 @@ Text.GrammarCombinators.Utils.IsDead Text.GrammarCombinators.Utils.IsEpsilon Text.GrammarCombinators.Utils.IsReachable+ Text.GrammarCombinators.Utils.LiftGrammar+ Text.GrammarCombinators.Utils.MemoizeGrammar Text.GrammarCombinators.Utils.PrintGrammar Text.GrammarCombinators.Utils.ToGraph Text.GrammarCombinators.Utils.UnfoldDepthFirst