mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-04-23 19:42:50 -06:00
GF.Infra.Modules: keep the modules of a grammar in a finite map instead of a list
This speeds up the compilation of PhrasebookFin.pgf by 12%, mosly by speeding up calls to lookupModule in calls from lookupParamValues, in calls from allParamValues. The invariant "modules are stored in dependency order" is no longer respected! But the type MGrammar is now abstract, making it easier to maintain this or other invariants in the future.
This commit is contained in:
@@ -69,8 +69,8 @@ batchCompile opts files = do
|
|||||||
|
|
||||||
-- to compile a set of modules, e.g. an old GF or a .cf file
|
-- to compile a set of modules, e.g. an old GF or a .cf file
|
||||||
compileSourceGrammar :: Options -> SourceGrammar -> IOE SourceGrammar
|
compileSourceGrammar :: Options -> SourceGrammar -> IOE SourceGrammar
|
||||||
compileSourceGrammar opts gr@(MGrammar ms) = do
|
compileSourceGrammar opts gr = do
|
||||||
(_,gr',_) <- foldM compOne (0,emptySourceGrammar,Map.empty) ms
|
(_,gr',_) <- foldM compOne (0,emptySourceGrammar,Map.empty) (modules gr)
|
||||||
return gr'
|
return gr'
|
||||||
where
|
where
|
||||||
compOne env mo = do
|
compOne env mo = do
|
||||||
@@ -215,19 +215,19 @@ generateModuleCode opts file minfo = do
|
|||||||
|
|
||||||
-- auxiliaries
|
-- auxiliaries
|
||||||
|
|
||||||
reverseModules (MGrammar ms) = MGrammar $ reverse ms
|
--reverseModules (MGrammar ms) = MGrammar $ reverse ms
|
||||||
|
|
||||||
emptyCompileEnv :: CompileEnv
|
emptyCompileEnv :: CompileEnv
|
||||||
emptyCompileEnv = (0,emptyMGrammar,Map.empty)
|
emptyCompileEnv = (0,emptyMGrammar,Map.empty)
|
||||||
|
|
||||||
extendCompileEnvInt (_,MGrammar ss,menv) k mfile sm = do
|
extendCompileEnvInt (_,gr,menv) k mfile sm = do
|
||||||
let (mod,imps) = importsOfModule sm
|
let (mod,imps) = importsOfModule sm
|
||||||
menv2 <- case mfile of
|
menv2 <- case mfile of
|
||||||
Just file -> do
|
Just file -> do
|
||||||
t <- ioeIO $ getModificationTime file
|
t <- ioeIO $ getModificationTime file
|
||||||
return $ Map.insert mod (t,imps) menv
|
return $ Map.insert mod (t,imps) menv
|
||||||
_ -> return menv
|
_ -> return menv
|
||||||
return (k,MGrammar (sm:ss),menv2) --- reverse later
|
return (k,mGrammar (sm:modules gr),menv2) --- reverse later
|
||||||
|
|
||||||
extendCompileEnv e@(k,_,_) file sm = extendCompileEnvInt e k (Just file) sm
|
extendCompileEnv e@(k,_,_) file sm = extendCompileEnvInt e k (Just file) sm
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ checkModule :: [SourceModule] -> SourceModule -> Check SourceModule
|
|||||||
checkModule ms m@(name,mo) = checkIn (text "checking module" <+> ppIdent name) $ do
|
checkModule ms m@(name,mo) = checkIn (text "checking module" <+> ppIdent name) $ do
|
||||||
checkRestrictedInheritance ms m
|
checkRestrictedInheritance ms m
|
||||||
m <- case mtype mo of
|
m <- case mtype mo of
|
||||||
MTConcrete a -> do let gr = MGrammar (m:ms)
|
MTConcrete a -> do let gr = mGrammar (m:ms)
|
||||||
abs <- checkErr $ lookupModule gr a
|
abs <- checkErr $ lookupModule gr a
|
||||||
checkCompleteGrammar gr (a,abs) m
|
checkCompleteGrammar gr (a,abs) m
|
||||||
_ -> return m
|
_ -> return m
|
||||||
@@ -221,7 +221,7 @@ checkInfo ms (m,mo) c info = do
|
|||||||
|
|
||||||
_ -> return info
|
_ -> return info
|
||||||
where
|
where
|
||||||
gr = MGrammar ((m,mo) : ms)
|
gr = mGrammar ((m,mo) : ms)
|
||||||
chIn loc cat = checkIn (text "Happened in" <+> text cat <+> ppIdent c <+> ppPosition m loc <> colon)
|
chIn loc cat = checkIn (text "Happened in" <+> text cat <+> ppIdent c <+> ppPosition m loc <> colon)
|
||||||
|
|
||||||
mkPar (L loc (f,co)) =
|
mkPar (L loc (f,co)) =
|
||||||
|
|||||||
@@ -44,10 +44,13 @@ mkCanon2pgf opts cnc gr = (canon2pgf opts gr . reorder abs) gr
|
|||||||
|
|
||||||
-- Generate PGF from grammar.
|
-- Generate PGF from grammar.
|
||||||
|
|
||||||
canon2pgf :: Options -> SourceGrammar -> SourceGrammar -> IO D.PGF
|
type AbsConcsGrammar = (IdModInfo,[IdModInfo]) -- (abstract,concretes)
|
||||||
canon2pgf opts gr cgr@(M.MGrammar (am:cms)) = do
|
type IdModInfo = (Ident,SourceModInfo)
|
||||||
|
|
||||||
|
canon2pgf :: Options -> SourceGrammar -> AbsConcsGrammar -> IO D.PGF
|
||||||
|
canon2pgf opts gr (am,cms) = do
|
||||||
if dump opts DumpCanon
|
if dump opts DumpCanon
|
||||||
then putStrLn (render (vcat (map (ppModule Qualified) (M.modules cgr))))
|
then putStrLn (render (vcat (map (ppModule Qualified) (am:cms))))
|
||||||
else return ()
|
else return ()
|
||||||
(an,abs) <- mkAbstr am
|
(an,abs) <- mkAbstr am
|
||||||
cncs <- mapM (mkConcr am) cms
|
cncs <- mapM (mkConcr am) cms
|
||||||
@@ -148,12 +151,12 @@ compilePatt eqs = whilePP eqs Map.empty
|
|||||||
|
|
||||||
-- return just one module per language
|
-- return just one module per language
|
||||||
|
|
||||||
reorder :: Ident -> SourceGrammar -> SourceGrammar
|
reorder :: Ident -> SourceGrammar -> AbsConcsGrammar
|
||||||
reorder abs cg =
|
reorder abs cg =
|
||||||
M.MGrammar $
|
-- M.MGrammar $
|
||||||
(abs, M.ModInfo M.MTAbstract M.MSComplete aflags [] Nothing [] [] adefs):
|
((abs, M.ModInfo M.MTAbstract M.MSComplete aflags [] Nothing [] [] adefs),
|
||||||
[(cnc, M.ModInfo (M.MTConcrete abs) M.MSComplete cflags [] Nothing [] [] cdefs)
|
[(cnc, M.ModInfo (M.MTConcrete abs) M.MSComplete cflags [] Nothing [] [] cdefs)
|
||||||
| cnc <- M.allConcretes cg abs, let (cflags,cdefs) = concr cnc]
|
| cnc <- M.allConcretes cg abs, let (cflags,cdefs) = concr cnc])
|
||||||
where
|
where
|
||||||
aflags =
|
aflags =
|
||||||
concatOptions (reverse [M.flags mo | (_,mo) <- M.modules cg, M.isModAbs mo])
|
concatOptions (reverse [M.flags mo | (_,mo) <- M.modules cg, M.isModAbs mo])
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ evalInfo opts ms m c info = do
|
|||||||
|
|
||||||
_ -> return info
|
_ -> return info
|
||||||
where
|
where
|
||||||
gr = MGrammar (m : ms)
|
gr = mGrammar (m : ms)
|
||||||
optim = flag optOptimizations opts
|
optim = flag optOptimizations opts
|
||||||
param = OptParametrize `Set.member` optim
|
param = OptParametrize `Set.member` optim
|
||||||
eIn cat = errIn (render (text "Error optimizing" <+> cat <+> ppIdent c <+> colon))
|
eIn cat = errIn (render (text "Error optimizing" <+> cat <+> ppIdent c <+> colon))
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ refreshEquation pst = err Bad (return . fst) (appSTM (refr pst) initIdState) whe
|
|||||||
-- for concrete and resource in grammar, before optimizing
|
-- for concrete and resource in grammar, before optimizing
|
||||||
|
|
||||||
refreshGrammar :: SourceGrammar -> Err SourceGrammar
|
refreshGrammar :: SourceGrammar -> Err SourceGrammar
|
||||||
refreshGrammar = liftM (MGrammar . snd) . foldM refreshModule (0,[]) . modules
|
refreshGrammar = liftM (mGrammar . snd) . foldM refreshModule (0,[]) . modules
|
||||||
|
|
||||||
refreshModule :: (Int,[SourceModule]) -> SourceModule -> Err (Int,[SourceModule])
|
refreshModule :: (Int,[SourceModule]) -> SourceModule -> Err (Int,[SourceModule])
|
||||||
refreshModule (k,ms) mi@(i,mo)
|
refreshModule (k,ms) mi@(i,mo)
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ renameSourceJudgement g m (i,t) = do
|
|||||||
renameModule :: [SourceModule] -> SourceModule -> Check SourceModule
|
renameModule :: [SourceModule] -> SourceModule -> Check SourceModule
|
||||||
renameModule ms (name,mo) = checkIn (text "renaming module" <+> ppIdent name) $ do
|
renameModule ms (name,mo) = checkIn (text "renaming module" <+> ppIdent name) $ do
|
||||||
let js1 = jments mo
|
let js1 = jments mo
|
||||||
status <- buildStatus (MGrammar ms) name mo
|
status <- buildStatus (mGrammar ms) name mo
|
||||||
js2 <- checkMap (renameInfo status name) js1
|
js2 <- checkMap (renameInfo status name) js1
|
||||||
return (name, mo {opens = map forceQualif (opens mo), jments = js2})
|
return (name, mo {opens = map forceQualif (opens mo), jments = js2})
|
||||||
|
|
||||||
@@ -128,7 +128,7 @@ tree2status o = case o of
|
|||||||
|
|
||||||
buildStatus :: SourceGrammar -> Ident -> SourceModInfo -> Check Status
|
buildStatus :: SourceGrammar -> Ident -> SourceModInfo -> Check Status
|
||||||
buildStatus gr c mo = let mo' = self2status c mo in do
|
buildStatus gr c mo = let mo' = self2status c mo in do
|
||||||
let gr1 = MGrammar ((c,mo) : modules gr)
|
let gr1 = mGrammar ((c,mo) : modules gr)
|
||||||
ops = [OSimple e | e <- allExtends gr1 c] ++ opens mo
|
ops = [OSimple e | e <- allExtends gr1 c] ++ opens mo
|
||||||
mods <- checkErr $ mapM (lookupModule gr1 . openedModule) ops
|
mods <- checkErr $ mapM (lookupModule gr1 . openedModule) ops
|
||||||
let sts = map modInfo2status $ zip ops mods
|
let sts = map modInfo2status $ zip ops mods
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ unsubexpModule sm@(i,mo)
|
|||||||
Q (m,c) | isOperIdent c -> --- name convention of subexp opers
|
Q (m,c) | isOperIdent c -> --- name convention of subexp opers
|
||||||
errVal t $ liftM unparTerm $ lookupResDef gr (m,c)
|
errVal t $ liftM unparTerm $ lookupResDef gr (m,c)
|
||||||
_ -> C.composSafeOp unparTerm t
|
_ -> C.composSafeOp unparTerm t
|
||||||
gr = M.MGrammar [sm]
|
gr = M.mGrammar [sm]
|
||||||
rebuild = buildTree . concat
|
rebuild = buildTree . concat
|
||||||
|
|
||||||
-- implementation
|
-- implementation
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ instance Binary Ident where
|
|||||||
else return (identC bs)
|
else return (identC bs)
|
||||||
|
|
||||||
instance Binary a => Binary (MGrammar a) where
|
instance Binary a => Binary (MGrammar a) where
|
||||||
put (MGrammar ms) = put ms
|
put = put . modules
|
||||||
get = fmap MGrammar get
|
get = fmap mGrammar get
|
||||||
|
|
||||||
instance Binary a => Binary (ModInfo a) where
|
instance Binary a => Binary (ModInfo a) where
|
||||||
put mi = do put (mtype mi,mstatus mi,flags mi,extend mi,mwith mi,opens mi,mexdeps mi,jments mi)
|
put mi = do put (mtype mi,mstatus mi,flags mi,extend mi,mwith mi,opens mi,mexdeps mi,jments mi)
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ type CFFun = String
|
|||||||
--------------------------
|
--------------------------
|
||||||
|
|
||||||
cf2gf :: String -> CF -> SourceGrammar
|
cf2gf :: String -> CF -> SourceGrammar
|
||||||
cf2gf name cf = MGrammar [
|
cf2gf name cf = mGrammar [
|
||||||
(aname, addFlag (modifyFlags (\fs -> fs{optStartCat = Just cat}))
|
(aname, addFlag (modifyFlags (\fs -> fs{optStartCat = Just cat}))
|
||||||
(emptyModInfo{mtype = MTAbstract, jments = abs})),
|
(emptyModInfo{mtype = MTAbstract, jments = abs})),
|
||||||
(cname, emptyModInfo{mtype = MTConcrete aname, jments = cnc})
|
(cname, emptyModInfo{mtype = MTConcrete aname, jments = cnc})
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
|
|
||||||
module GF.Grammar.Grammar (SourceGrammar,
|
module GF.Grammar.Grammar (SourceGrammar,
|
||||||
emptySourceGrammar,
|
emptySourceGrammar,mGrammar,
|
||||||
SourceModInfo,
|
SourceModInfo,
|
||||||
SourceModule,
|
SourceModule,
|
||||||
mapSourceModule,
|
mapSourceModule,
|
||||||
@@ -56,7 +56,7 @@ import qualified Data.ByteString.Char8 as BS
|
|||||||
-- | grammar as presented to the compiler
|
-- | grammar as presented to the compiler
|
||||||
type SourceGrammar = MGrammar Info
|
type SourceGrammar = MGrammar Info
|
||||||
|
|
||||||
emptySourceGrammar = MGrammar []
|
emptySourceGrammar = mGrammar []
|
||||||
|
|
||||||
type SourceModInfo = ModInfo Info
|
type SourceModInfo = ModInfo Info
|
||||||
|
|
||||||
|
|||||||
@@ -15,12 +15,12 @@
|
|||||||
--
|
--
|
||||||
-- The same structure will be used in both source code and canonical.
|
-- The same structure will be used in both source code and canonical.
|
||||||
-- The parameters tell what kind of data is involved.
|
-- The parameters tell what kind of data is involved.
|
||||||
-- Invariant: modules are stored in dependency order
|
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
|
|
||||||
module GF.Infra.Modules (
|
module GF.Infra.Modules (
|
||||||
MGrammar(..), ModInfo(..), ModuleType(..),
|
MGrammar, ModInfo(..), ModuleType(..),
|
||||||
MInclude (..),
|
MInclude (..),
|
||||||
|
mGrammar,modules,
|
||||||
extends, isInherited,inheritAll,
|
extends, isInherited,inheritAll,
|
||||||
updateMGrammar, updateModule, replaceJudgements, addFlag,
|
updateMGrammar, updateModule, replaceJudgements, addFlag,
|
||||||
addOpenQualif, flagsModule, allFlags, mapModules,
|
addOpenQualif, flagsModule, allFlags, mapModules,
|
||||||
@@ -28,7 +28,8 @@ module GF.Infra.Modules (
|
|||||||
ModuleStatus(..),
|
ModuleStatus(..),
|
||||||
openedModule, depPathModule, allDepsModule, partOfGrammar,
|
openedModule, depPathModule, allDepsModule, partOfGrammar,
|
||||||
allExtends, allExtendSpecs, allExtendsPlus, allExtensions,
|
allExtends, allExtendSpecs, allExtendsPlus, allExtensions,
|
||||||
searchPathModule, addModule,
|
searchPathModule,
|
||||||
|
-- addModule,
|
||||||
emptyMGrammar, emptyModInfo,
|
emptyMGrammar, emptyModInfo,
|
||||||
abstractOfConcrete, abstractModOfConcrete,
|
abstractOfConcrete, abstractModOfConcrete,
|
||||||
lookupModule, lookupModuleType, lookupInfo,
|
lookupModule, lookupModuleType, lookupInfo,
|
||||||
@@ -50,10 +51,16 @@ import Text.PrettyPrint
|
|||||||
|
|
||||||
-- The same structure will be used in both source code and canonical.
|
-- The same structure will be used in both source code and canonical.
|
||||||
-- The parameters tell what kind of data is involved.
|
-- The parameters tell what kind of data is involved.
|
||||||
-- Invariant: modules are stored in dependency order
|
-- No longer maintained invariant (TH 2011-08-30):
|
||||||
|
-- modules are stored in dependency order
|
||||||
|
|
||||||
newtype MGrammar a = MGrammar {modules :: [(Ident,ModInfo a)]}
|
--mGrammar = MGrammar
|
||||||
|
--newtype MGrammar a = MGrammar {modules :: [(Ident,ModInfo a)]}
|
||||||
|
|
||||||
|
newtype MGrammar a = MGrammar {moduleMap :: Map.Map Ident (ModInfo a)}
|
||||||
deriving Show
|
deriving Show
|
||||||
|
modules = Map.toList . moduleMap
|
||||||
|
mGrammar = MGrammar . Map.fromList
|
||||||
|
|
||||||
data ModInfo a = ModInfo {
|
data ModInfo a = ModInfo {
|
||||||
mtype :: ModuleType,
|
mtype :: ModuleType,
|
||||||
@@ -94,9 +101,9 @@ inheritAll i = (i,MIAll)
|
|||||||
|
|
||||||
-- destructive update
|
-- destructive update
|
||||||
|
|
||||||
-- | dep order preserved since old cannot depend on new
|
-- | dep order preserved since old cannot depend on new (not anymore TH 2011-08-30)
|
||||||
updateMGrammar :: MGrammar a -> MGrammar a -> MGrammar a
|
updateMGrammar :: MGrammar a -> MGrammar a -> MGrammar a
|
||||||
updateMGrammar old new = MGrammar $
|
updateMGrammar old new = mGrammar $
|
||||||
[(i,m) | (i,m) <- os, notElem i (map fst ns)] ++ ns
|
[(i,m) | (i,m) <- os, notElem i (map fst ns)] ++ ns
|
||||||
where
|
where
|
||||||
os = modules old
|
os = modules old
|
||||||
@@ -121,7 +128,8 @@ allFlags :: MGrammar a -> Options
|
|||||||
allFlags gr = concatOptions [flags m | (_,m) <- modules gr]
|
allFlags gr = concatOptions [flags m | (_,m) <- modules gr]
|
||||||
|
|
||||||
mapModules :: (ModInfo a -> ModInfo a) -> MGrammar a -> MGrammar a
|
mapModules :: (ModInfo a -> ModInfo a) -> MGrammar a -> MGrammar a
|
||||||
mapModules f (MGrammar ms) = MGrammar (map (onSnd f) ms)
|
--mapModules f (MGrammar ms) = MGrammar (map (onSnd f) ms)
|
||||||
|
mapModules f (MGrammar ms) = MGrammar (fmap f ms)
|
||||||
|
|
||||||
data OpenSpec =
|
data OpenSpec =
|
||||||
OSimple Ident
|
OSimple Ident
|
||||||
@@ -159,7 +167,7 @@ allDepsModule gr m = iterFix add os0 where
|
|||||||
|
|
||||||
-- | select just those modules that a given one depends on, including itself
|
-- | select just those modules that a given one depends on, including itself
|
||||||
partOfGrammar :: MGrammar a -> (Ident,ModInfo a) -> MGrammar a
|
partOfGrammar :: MGrammar a -> (Ident,ModInfo a) -> MGrammar a
|
||||||
partOfGrammar gr (i,m) = MGrammar [mo | mo@(j,_) <- mods, elem j modsFor]
|
partOfGrammar gr (i,m) = mGrammar [mo | mo@(j,_) <- mods, elem j modsFor]
|
||||||
where
|
where
|
||||||
mods = modules gr
|
mods = modules gr
|
||||||
modsFor = (i:) $ map openedModule $ allDepsModule gr m
|
modsFor = (i:) $ map openedModule $ allDepsModule gr m
|
||||||
@@ -208,12 +216,15 @@ allExtensions gr i =
|
|||||||
searchPathModule :: ModInfo a -> [Ident]
|
searchPathModule :: ModInfo a -> [Ident]
|
||||||
searchPathModule m = [i | OSimple i <- depPathModule m]
|
searchPathModule m = [i | OSimple i <- depPathModule m]
|
||||||
|
|
||||||
|
{-
|
||||||
-- | a new module can safely be added to the end, since nothing old can depend on it
|
-- | a new module can safely be added to the end, since nothing old can depend on it
|
||||||
addModule :: MGrammar a -> Ident -> ModInfo a -> MGrammar a
|
addModule :: MGrammar a -> Ident -> ModInfo a -> MGrammar a
|
||||||
addModule gr name mi = MGrammar $ (modules gr ++ [(name,mi)])
|
--addModule gr name mi = MGrammar $ (modules gr ++ [(name,mi)])
|
||||||
|
addModule gr name mi = MGrammar $ Map.insert name mi (moduleMap gr)
|
||||||
|
-}
|
||||||
|
|
||||||
emptyMGrammar :: MGrammar a
|
emptyMGrammar :: MGrammar a
|
||||||
emptyMGrammar = MGrammar []
|
emptyMGrammar = mGrammar []
|
||||||
|
|
||||||
emptyModInfo :: ModInfo a
|
emptyModInfo :: ModInfo a
|
||||||
emptyModInfo = ModInfo MTResource MSComplete noOptions [] Nothing [] [] emptyBinTree
|
emptyModInfo = ModInfo MTResource MSComplete noOptions [] Nothing [] [] emptyBinTree
|
||||||
@@ -238,7 +249,8 @@ abstractModOfConcrete gr c = do
|
|||||||
--- canonFileName s = prt s ++ ".gfc"
|
--- canonFileName s = prt s ++ ".gfc"
|
||||||
|
|
||||||
lookupModule :: MGrammar a -> Ident -> Err (ModInfo a)
|
lookupModule :: MGrammar a -> Ident -> Err (ModInfo a)
|
||||||
lookupModule gr m = case lookup m (modules gr) of
|
--lookupModule gr m = case lookup m (modules gr) of
|
||||||
|
lookupModule gr m = case Map.lookup m (moduleMap gr) of
|
||||||
Just i -> return i
|
Just i -> return i
|
||||||
Nothing -> Bad $ render (text "unknown module" <+> ppIdent m <+> text "among" <+> hsep (map (ppIdent . fst) (modules gr)))
|
Nothing -> Bad $ render (text "unknown module" <+> ppIdent m <+> text "among" <+> hsep (map (ppIdent . fst) (modules gr)))
|
||||||
|
|
||||||
|
|||||||
@@ -365,7 +365,7 @@ data GFEnv = GFEnv {
|
|||||||
|
|
||||||
emptyGFEnv :: GFEnv
|
emptyGFEnv :: GFEnv
|
||||||
emptyGFEnv =
|
emptyGFEnv =
|
||||||
GFEnv emptySourceGrammar{modules=[(identW,emptyModInfo)]} (mkCommandEnv emptyPGF) [] {-0-}
|
GFEnv (mGrammar [(identW,emptyModInfo)]) (mkCommandEnv emptyPGF) [] {-0-}
|
||||||
|
|
||||||
wordCompletion gfenv (left,right) = do
|
wordCompletion gfenv (left,right) = do
|
||||||
case wc_type (reverse left) of
|
case wc_type (reverse left) of
|
||||||
|
|||||||
Reference in New Issue
Block a user