From a663eda2690602d82584d6f74bdab48ebbe0d31b Mon Sep 17 00:00:00 2001 From: krasimir Date: Tue, 16 Sep 2008 15:35:15 +0000 Subject: [PATCH] build parsers on demand if they aren't in the PGF file --- GF.cabal | 5 ++++- src/PGF/Raw/Convert.hs | 40 +++++++++++++++++++++++++++------------- 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/GF.cabal b/GF.cabal index 14af3bdec..4ddccb11a 100644 --- a/GF.cabal +++ b/GF.cabal @@ -584,7 +584,10 @@ library GF.Data.Assoc GF.Data.ErrM GF.Text.UTF8 - +-- needed only for the on demand generation of PMCFG + GF.Data.BacktrackM + GF.Compile.GenerateFCFG + GF.Compile.GeneratePMCFG executable gf build-depends: base, diff --git a/src/PGF/Raw/Convert.hs b/src/PGF/Raw/Convert.hs index 8e429660a..0c9338012 100644 --- a/src/PGF/Raw/Convert.hs +++ b/src/PGF/Raw/Convert.hs @@ -5,6 +5,8 @@ import PGF.Data import PGF.Raw.Abstract import PGF.BuildParser (buildParserInfo) import PGF.Parsing.FCFG.Utilities +import qualified GF.Compile.GenerateFCFG as FCFG +import qualified GF.Compile.GeneratePMCFG as PMCFG import qualified Data.Array as Array import qualified Data.Map as Map @@ -24,7 +26,7 @@ toPGF (Grm [ App "cat" cts ]), App "concrete" ccs - ]) = PGF { + ]) = let pgf = PGF { absname = mkCId a, cncnames = [mkCId c | App c [] <- cs], gflags = Map.fromAscList [(mkCId f,v) | App f [AStr v] <- gfs], @@ -38,21 +40,27 @@ toPGF (Grm [ catfuns = Map.fromAscList [(cat,[f | (f, (DTyp _ c _,_)) <- lfuns, c==cat]) | (cat,_) <- lcats] in Abstr aflags funs cats catfuns, - concretes = Map.fromAscList [(mkCId lang, toConcr ts) | App lang ts <- ccs] + concretes = Map.fromAscList [(mkCId lang, toConcr pgf ts) | App lang ts <- ccs] } + in pgf where -toConcr :: [RExp] -> Concr -toConcr = foldl add (Concr { - cflags = Map.empty, - lins = Map.empty, - opers = Map.empty, - lincats = Map.empty, - lindefs = Map.empty, - printnames = Map.empty, - paramlincats = Map.empty, - parser = Nothing - }) +toConcr :: PGF -> [RExp] -> Concr +toConcr pgf rexp = + let cnc = foldl add (Concr {cflags = Map.empty, + lins = Map.empty, + opers = Map.empty, + lincats = Map.empty, + lindefs = Map.empty, + printnames = Map.empty, + paramlincats = Map.empty, + parser = Just (buildParserOnDemand cnc) -- This thunk will be overwritten if there is a parser + -- compiled in the PGF file. We use lazy evaluation here + -- to make sure that buildParserOnDemand is called only + -- if it is needed. + + }) rexp + in cnc where add :: Concr -> RExp -> Concr add cnc (App "flags" ts) = cnc { cflags = Map.fromAscList [(mkCId f,v) | App f [AStr v] <- ts] } @@ -64,6 +72,12 @@ toConcr = foldl add (Concr { add cnc (App "param" ts) = cnc { paramlincats = mkTermMap ts } add cnc (App "parser" ts) = cnc { parser = Just (toPInfo ts) } + buildParserOnDemand cnc = buildParserInfo fcfg + where + fcfg + | Map.lookup (mkCId "erasing") (cflags cnc) == Just "on" = PMCFG.convertConcrete (abstract pgf) cnc + | otherwise = FCFG.convertConcrete (abstract pgf) cnc + toPInfo :: [RExp] -> ParserInfo toPInfo [App "rules" rs, App "startupcats" cs] = buildParserInfo (rules, cats) where