mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-05-28 04:08:55 -06:00
Add flag and stubs for compiling to LPGF format
This commit is contained in:
1
gf.cabal
1
gf.cabal
@@ -184,6 +184,7 @@ Library
|
|||||||
GF.Compile.Export
|
GF.Compile.Export
|
||||||
GF.Compile.GenerateBC
|
GF.Compile.GenerateBC
|
||||||
GF.Compile.GeneratePMCFG
|
GF.Compile.GeneratePMCFG
|
||||||
|
GF.Compile.GrammarToLPGF
|
||||||
GF.Compile.GrammarToPGF
|
GF.Compile.GrammarToPGF
|
||||||
GF.Compile.Multi
|
GF.Compile.Multi
|
||||||
GF.Compile.Optimize
|
GF.Compile.Optimize
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
module GF.Compile (compileToPGF, link, batchCompile, srcAbsName) where
|
module GF.Compile (compileToPGF, link, linkl, batchCompile, srcAbsName) where
|
||||||
|
|
||||||
import GF.Compile.GrammarToPGF(mkCanon2pgf)
|
import GF.Compile.GrammarToPGF(mkCanon2pgf)
|
||||||
|
import GF.Compile.GrammarToLPGF(mkCanon2lpgf)
|
||||||
import GF.Compile.ReadFiles(ModEnv,getOptionsFromFile,getAllFiles,
|
import GF.Compile.ReadFiles(ModEnv,getOptionsFromFile,getAllFiles,
|
||||||
importsOfModule)
|
importsOfModule)
|
||||||
import GF.CompileOne(compileOne)
|
import GF.CompileOne(compileOne)
|
||||||
@@ -39,9 +40,16 @@ link opts (cnc,gr) =
|
|||||||
pgf <- mkCanon2pgf opts gr abs
|
pgf <- mkCanon2pgf opts gr abs
|
||||||
probs <- liftIO (maybe (return . defaultProbabilities) readProbabilitiesFromFile (flag optProbsFile opts) pgf)
|
probs <- liftIO (maybe (return . defaultProbabilities) readProbabilitiesFromFile (flag optProbsFile opts) pgf)
|
||||||
when (verbAtLeast opts Normal) $ putStrE "OK"
|
when (verbAtLeast opts Normal) $ putStrE "OK"
|
||||||
return $ setProbabilities probs
|
return $ setProbabilities probs
|
||||||
$ if flag optOptimizePGF opts then optimizePGF pgf else pgf
|
$ if flag optOptimizePGF opts then optimizePGF pgf else pgf
|
||||||
|
|
||||||
|
linkl :: Options -> (ModuleName,Grammar) -> IOE PGF
|
||||||
|
linkl opts (cnc,gr) =
|
||||||
|
putPointE Normal opts "linking ... " $ do
|
||||||
|
let abs = srcAbsName gr cnc
|
||||||
|
lpgf <- mkCanon2lpgf opts gr abs
|
||||||
|
return lpgf
|
||||||
|
|
||||||
-- | Returns the name of the abstract syntax corresponding to the named concrete syntax
|
-- | Returns the name of the abstract syntax corresponding to the named concrete syntax
|
||||||
srcAbsName gr cnc = err (const cnc) id $ abstractOfConcrete gr cnc
|
srcAbsName gr cnc = err (const cnc) id $ abstractOfConcrete gr cnc
|
||||||
|
|
||||||
|
|||||||
308
src/compiler/GF/Compile/GrammarToLPGF.hs
Normal file
308
src/compiler/GF/Compile/GrammarToLPGF.hs
Normal file
@@ -0,0 +1,308 @@
|
|||||||
|
{-# LANGUAGE BangPatterns, FlexibleContexts #-}
|
||||||
|
module GF.Compile.GrammarToLPGF (mkCanon2lpgf) where
|
||||||
|
|
||||||
|
--import GF.Compile.Export
|
||||||
|
import GF.Compile.GeneratePMCFG
|
||||||
|
import GF.Compile.GenerateBC
|
||||||
|
|
||||||
|
import PGF(CId,mkCId,utf8CId)
|
||||||
|
import PGF.Internal(fidInt,fidFloat,fidString,fidVar)
|
||||||
|
import PGF.Internal(updateProductionIndices)
|
||||||
|
import qualified PGF.Internal as C
|
||||||
|
import qualified PGF.Internal as D
|
||||||
|
import GF.Grammar.Predef
|
||||||
|
import GF.Grammar.Grammar
|
||||||
|
import qualified GF.Grammar.Lookup as Look
|
||||||
|
import qualified GF.Grammar as A
|
||||||
|
import qualified GF.Grammar.Macros as GM
|
||||||
|
|
||||||
|
import GF.Infra.Ident
|
||||||
|
import GF.Infra.Option
|
||||||
|
import GF.Infra.UseIO (IOE)
|
||||||
|
import GF.Data.Operations
|
||||||
|
|
||||||
|
import Data.List
|
||||||
|
import qualified Data.Set as Set
|
||||||
|
import qualified Data.Map as Map
|
||||||
|
import qualified Data.IntMap as IntMap
|
||||||
|
import Data.Array.IArray
|
||||||
|
|
||||||
|
|
||||||
|
mkCanon2lpgf :: Options -> SourceGrammar -> ModuleName -> IOE D.PGF
|
||||||
|
mkCanon2lpgf opts gr am = do
|
||||||
|
(an,abs) <- mkAbstr am
|
||||||
|
cncs <- mapM mkConcr (allConcretes gr am)
|
||||||
|
return $ updateProductionIndices (D.PGF Map.empty an abs (Map.fromList cncs))
|
||||||
|
where
|
||||||
|
cenv = resourceValues opts gr
|
||||||
|
|
||||||
|
mkAbstr am = return (mi2i am, D.Abstr flags funs cats)
|
||||||
|
where
|
||||||
|
aflags = err (const noOptions) mflags (lookupModule gr am)
|
||||||
|
|
||||||
|
adefs =
|
||||||
|
[((cPredefAbs,c), AbsCat (Just (L NoLoc []))) | c <- [cFloat,cInt,cString]] ++
|
||||||
|
Look.allOrigInfos gr am
|
||||||
|
|
||||||
|
flags = Map.fromList [(mkCId f,x) | (f,x) <- optionsPGF aflags]
|
||||||
|
|
||||||
|
funs = Map.fromList [(i2i f, (mkType [] ty, arity, mkDef gr arity mdef, 0)) |
|
||||||
|
((m,f),AbsFun (Just (L _ ty)) ma mdef _) <- adefs,
|
||||||
|
let arity = mkArity ma mdef ty]
|
||||||
|
|
||||||
|
cats = Map.fromList [(i2i c, (snd (mkContext [] cont),catfuns c, 0)) |
|
||||||
|
((m,c),AbsCat (Just (L _ cont))) <- adefs]
|
||||||
|
|
||||||
|
catfuns cat =
|
||||||
|
[(0,i2i f) | ((m,f),AbsFun (Just (L _ ty)) _ _ (Just True)) <- adefs, snd (GM.valCat ty) == cat]
|
||||||
|
|
||||||
|
mkConcr cm = do
|
||||||
|
let cflags = err (const noOptions) mflags (lookupModule gr cm)
|
||||||
|
ciCmp | flag optCaseSensitive cflags = compare
|
||||||
|
| otherwise = C.compareCaseInsensitve
|
||||||
|
|
||||||
|
(ex_seqs,cdefs) <- addMissingPMCFGs
|
||||||
|
Map.empty
|
||||||
|
([((cPredefAbs,c), CncCat (Just (L NoLoc GM.defLinType)) Nothing Nothing Nothing Nothing) | c <- [cInt,cFloat,cString]] ++
|
||||||
|
Look.allOrigInfos gr cm)
|
||||||
|
|
||||||
|
let flags = Map.fromList [(mkCId f,x) | (f,x) <- optionsPGF cflags]
|
||||||
|
|
||||||
|
seqs = (mkArray . C.sortNubBy ciCmp . concat) $
|
||||||
|
(Map.keys ex_seqs : [maybe [] elems (mseqs mi) | (m,mi) <- allExtends gr cm])
|
||||||
|
|
||||||
|
ex_seqs_arr = mkMapArray ex_seqs :: Array SeqId Sequence
|
||||||
|
|
||||||
|
!(!fid_cnt1,!cnccats) = genCncCats gr am cm cdefs
|
||||||
|
!(!fid_cnt2,!productions,!lindefs,!linrefs,!cncfuns)
|
||||||
|
= genCncFuns gr am cm ex_seqs_arr ciCmp seqs cdefs fid_cnt1 cnccats
|
||||||
|
|
||||||
|
printnames = genPrintNames cdefs
|
||||||
|
return (mi2i cm, D.Concr flags
|
||||||
|
printnames
|
||||||
|
cncfuns
|
||||||
|
lindefs
|
||||||
|
linrefs
|
||||||
|
seqs
|
||||||
|
productions
|
||||||
|
IntMap.empty
|
||||||
|
Map.empty
|
||||||
|
cnccats
|
||||||
|
IntMap.empty
|
||||||
|
fid_cnt2)
|
||||||
|
where
|
||||||
|
-- if some module was compiled with -no-pmcfg, then
|
||||||
|
-- we have to create the PMCFG code just before linking
|
||||||
|
addMissingPMCFGs seqs [] = return (seqs,[])
|
||||||
|
addMissingPMCFGs seqs (((m,id), info):is) = do
|
||||||
|
(seqs,info) <- addPMCFG opts gr cenv Nothing am cm seqs id info
|
||||||
|
(seqs,is ) <- addMissingPMCFGs seqs is
|
||||||
|
return (seqs, ((m,id), info) : is)
|
||||||
|
|
||||||
|
i2i :: Ident -> CId
|
||||||
|
i2i = utf8CId . ident2utf8
|
||||||
|
|
||||||
|
mi2i :: ModuleName -> CId
|
||||||
|
mi2i (MN i) = i2i i
|
||||||
|
|
||||||
|
mkType :: [Ident] -> A.Type -> C.Type
|
||||||
|
mkType scope t =
|
||||||
|
case GM.typeForm t of
|
||||||
|
(hyps,(_,cat),args) -> let (scope',hyps') = mkContext scope hyps
|
||||||
|
in C.DTyp hyps' (i2i cat) (map (mkExp scope') args)
|
||||||
|
|
||||||
|
mkExp :: [Ident] -> A.Term -> C.Expr
|
||||||
|
mkExp scope t =
|
||||||
|
case t of
|
||||||
|
Q (_,c) -> C.EFun (i2i c)
|
||||||
|
QC (_,c) -> C.EFun (i2i c)
|
||||||
|
Vr x -> case lookup x (zip scope [0..]) of
|
||||||
|
Just i -> C.EVar i
|
||||||
|
Nothing -> C.EMeta 0
|
||||||
|
Abs b x t-> C.EAbs b (i2i x) (mkExp (x:scope) t)
|
||||||
|
App t1 t2-> C.EApp (mkExp scope t1) (mkExp scope t2)
|
||||||
|
EInt i -> C.ELit (C.LInt (fromIntegral i))
|
||||||
|
EFloat f -> C.ELit (C.LFlt f)
|
||||||
|
K s -> C.ELit (C.LStr s)
|
||||||
|
Meta i -> C.EMeta i
|
||||||
|
_ -> C.EMeta 0
|
||||||
|
|
||||||
|
mkPatt scope p =
|
||||||
|
case p of
|
||||||
|
A.PP (_,c) ps->let (scope',ps') = mapAccumL mkPatt scope ps
|
||||||
|
in (scope',C.PApp (i2i c) ps')
|
||||||
|
A.PV x -> (x:scope,C.PVar (i2i x))
|
||||||
|
A.PAs x p -> let (scope',p') = mkPatt scope p
|
||||||
|
in (x:scope',C.PAs (i2i x) p')
|
||||||
|
A.PW -> ( scope,C.PWild)
|
||||||
|
A.PInt i -> ( scope,C.PLit (C.LInt (fromIntegral i)))
|
||||||
|
A.PFloat f -> ( scope,C.PLit (C.LFlt f))
|
||||||
|
A.PString s -> ( scope,C.PLit (C.LStr s))
|
||||||
|
A.PImplArg p-> let (scope',p') = mkPatt scope p
|
||||||
|
in (scope',C.PImplArg p')
|
||||||
|
A.PTilde t -> ( scope,C.PTilde (mkExp scope t))
|
||||||
|
|
||||||
|
mkContext :: [Ident] -> A.Context -> ([Ident],[C.Hypo])
|
||||||
|
mkContext scope hyps = mapAccumL (\scope (bt,x,ty) -> let ty' = mkType scope ty
|
||||||
|
in if x == identW
|
||||||
|
then ( scope,(bt,i2i x,ty'))
|
||||||
|
else (x:scope,(bt,i2i x,ty'))) scope hyps
|
||||||
|
|
||||||
|
mkDef gr arity (Just eqs) = Just ([C.Equ ps' (mkExp scope' e) | L _ (ps,e) <- eqs, let (scope',ps') = mapAccumL mkPatt [] ps]
|
||||||
|
,generateByteCode gr arity eqs
|
||||||
|
)
|
||||||
|
mkDef gr arity Nothing = Nothing
|
||||||
|
|
||||||
|
mkArity (Just a) _ ty = a -- known arity, i.e. defined function
|
||||||
|
mkArity Nothing (Just _) ty = 0 -- defined function with no arity - must be an axiom
|
||||||
|
mkArity Nothing _ ty = let (ctxt, _, _) = GM.typeForm ty -- constructor
|
||||||
|
in length ctxt
|
||||||
|
|
||||||
|
genCncCats gr am cm cdefs =
|
||||||
|
let (index,cats) = mkCncCats 0 cdefs
|
||||||
|
in (index, Map.fromList cats)
|
||||||
|
where
|
||||||
|
mkCncCats index [] = (index,[])
|
||||||
|
mkCncCats index (((m,id),CncCat (Just (L _ lincat)) _ _ _ _):cdefs)
|
||||||
|
| id == cInt =
|
||||||
|
let cc = pgfCncCat gr lincat fidInt
|
||||||
|
(index',cats) = mkCncCats index cdefs
|
||||||
|
in (index', (i2i id,cc) : cats)
|
||||||
|
| id == cFloat =
|
||||||
|
let cc = pgfCncCat gr lincat fidFloat
|
||||||
|
(index',cats) = mkCncCats index cdefs
|
||||||
|
in (index', (i2i id,cc) : cats)
|
||||||
|
| id == cString =
|
||||||
|
let cc = pgfCncCat gr lincat fidString
|
||||||
|
(index',cats) = mkCncCats index cdefs
|
||||||
|
in (index', (i2i id,cc) : cats)
|
||||||
|
| otherwise =
|
||||||
|
let cc@(C.CncCat _s e _) = pgfCncCat gr lincat index
|
||||||
|
(index',cats) = mkCncCats (e+1) cdefs
|
||||||
|
in (index', (i2i id,cc) : cats)
|
||||||
|
mkCncCats index (_ :cdefs) = mkCncCats index cdefs
|
||||||
|
|
||||||
|
genCncFuns :: Grammar
|
||||||
|
-> ModuleName
|
||||||
|
-> ModuleName
|
||||||
|
-> Array SeqId Sequence
|
||||||
|
-> (Sequence -> Sequence -> Ordering)
|
||||||
|
-> Array SeqId Sequence
|
||||||
|
-> [(QIdent, Info)]
|
||||||
|
-> FId
|
||||||
|
-> Map.Map CId D.CncCat
|
||||||
|
-> (FId,
|
||||||
|
IntMap.IntMap (Set.Set D.Production),
|
||||||
|
IntMap.IntMap [FunId],
|
||||||
|
IntMap.IntMap [FunId],
|
||||||
|
Array FunId D.CncFun)
|
||||||
|
genCncFuns gr am cm ex_seqs ciCmp seqs cdefs fid_cnt cnccats =
|
||||||
|
let (fid_cnt1,funs_cnt1,funs1,lindefs,linrefs) = mkCncCats cdefs fid_cnt 0 [] IntMap.empty IntMap.empty
|
||||||
|
(fid_cnt2,funs_cnt2,funs2,prods) = mkCncFuns cdefs fid_cnt1 funs_cnt1 funs1 lindefs Map.empty IntMap.empty
|
||||||
|
in (fid_cnt2,prods,lindefs,linrefs,array (0,funs_cnt2-1) funs2)
|
||||||
|
where
|
||||||
|
mkCncCats [] fid_cnt funs_cnt funs lindefs linrefs =
|
||||||
|
(fid_cnt,funs_cnt,funs,lindefs,linrefs)
|
||||||
|
mkCncCats (((m,id),CncCat _ _ _ _ (Just (PMCFG prods0 funs0))):cdefs) fid_cnt funs_cnt funs lindefs linrefs =
|
||||||
|
let !funs_cnt' = let (s_funid, e_funid) = bounds funs0
|
||||||
|
in funs_cnt+(e_funid-s_funid+1)
|
||||||
|
lindefs' = foldl' (toLinDef (am,id) funs_cnt) lindefs prods0
|
||||||
|
linrefs' = foldl' (toLinRef (am,id) funs_cnt) linrefs prods0
|
||||||
|
funs' = foldl' (toCncFun funs_cnt (m,mkLinDefId id)) funs (assocs funs0)
|
||||||
|
in mkCncCats cdefs fid_cnt funs_cnt' funs' lindefs' linrefs'
|
||||||
|
mkCncCats (_ :cdefs) fid_cnt funs_cnt funs lindefs linrefs =
|
||||||
|
mkCncCats cdefs fid_cnt funs_cnt funs lindefs linrefs
|
||||||
|
|
||||||
|
mkCncFuns [] fid_cnt funs_cnt funs lindefs crc prods =
|
||||||
|
(fid_cnt,funs_cnt,funs,prods)
|
||||||
|
mkCncFuns (((m,id),CncFun _ _ _ (Just (PMCFG prods0 funs0))):cdefs) fid_cnt funs_cnt funs lindefs crc prods =
|
||||||
|
let ---Ok ty_C = fmap GM.typeForm (Look.lookupFunType gr am id)
|
||||||
|
ty_C = err error (\x -> x) $ fmap GM.typeForm (Look.lookupFunType gr am id)
|
||||||
|
!funs_cnt' = let (s_funid, e_funid) = bounds funs0
|
||||||
|
in funs_cnt+(e_funid-s_funid+1)
|
||||||
|
!(fid_cnt',crc',prods')
|
||||||
|
= foldl' (toProd lindefs ty_C funs_cnt)
|
||||||
|
(fid_cnt,crc,prods) prods0
|
||||||
|
funs' = foldl' (toCncFun funs_cnt (m,id)) funs (assocs funs0)
|
||||||
|
in mkCncFuns cdefs fid_cnt' funs_cnt' funs' lindefs crc' prods'
|
||||||
|
mkCncFuns (_ :cdefs) fid_cnt funs_cnt funs lindefs crc prods =
|
||||||
|
mkCncFuns cdefs fid_cnt funs_cnt funs lindefs crc prods
|
||||||
|
|
||||||
|
toProd lindefs (ctxt_C,res_C,_) offs st (Production fid0 funid0 args0) =
|
||||||
|
let !((fid_cnt,crc,prods),args) = mapAccumL mkArg st (zip ctxt_C args0)
|
||||||
|
set0 = Set.fromList (map (C.PApply (offs+funid0)) (sequence args))
|
||||||
|
fid = mkFId res_C fid0
|
||||||
|
!prods' = case IntMap.lookup fid prods of
|
||||||
|
Just set -> IntMap.insert fid (Set.union set0 set) prods
|
||||||
|
Nothing -> IntMap.insert fid set0 prods
|
||||||
|
in (fid_cnt,crc,prods')
|
||||||
|
where
|
||||||
|
mkArg st@(fid_cnt,crc,prods) ((_,_,ty),fid0s ) =
|
||||||
|
case fid0s of
|
||||||
|
[fid0] -> (st,map (flip C.PArg (mkFId arg_C fid0)) ctxt)
|
||||||
|
fid0s -> case Map.lookup fids crc of
|
||||||
|
Just fid -> (st,map (flip C.PArg fid) ctxt)
|
||||||
|
Nothing -> let !crc' = Map.insert fids fid_cnt crc
|
||||||
|
!prods' = IntMap.insert fid_cnt (Set.fromList (map C.PCoerce fids)) prods
|
||||||
|
in ((fid_cnt+1,crc',prods'),map (flip C.PArg fid_cnt) ctxt)
|
||||||
|
where
|
||||||
|
(hargs_C,arg_C) = GM.catSkeleton ty
|
||||||
|
ctxt = mapM (mkCtxt lindefs) hargs_C
|
||||||
|
fids = map (mkFId arg_C) fid0s
|
||||||
|
|
||||||
|
mkLinDefId id = prefixIdent "lindef " id
|
||||||
|
|
||||||
|
toLinDef res offs lindefs (Production fid0 funid0 args) =
|
||||||
|
if args == [[fidVar]]
|
||||||
|
then IntMap.insertWith (++) fid [offs+funid0] lindefs
|
||||||
|
else lindefs
|
||||||
|
where
|
||||||
|
fid = mkFId res fid0
|
||||||
|
|
||||||
|
toLinRef res offs linrefs (Production fid0 funid0 [fargs]) =
|
||||||
|
if fid0 == fidVar
|
||||||
|
then foldr (\fid -> IntMap.insertWith (++) fid [offs+funid0]) linrefs fids
|
||||||
|
else linrefs
|
||||||
|
where
|
||||||
|
fids = map (mkFId res) fargs
|
||||||
|
|
||||||
|
mkFId (_,cat) fid0 =
|
||||||
|
case Map.lookup (i2i cat) cnccats of
|
||||||
|
Just (C.CncCat s e _) -> s+fid0
|
||||||
|
Nothing -> error ("GrammarToPGF.mkFId: missing category "++showIdent cat)
|
||||||
|
|
||||||
|
mkCtxt lindefs (_,cat) =
|
||||||
|
case Map.lookup (i2i cat) cnccats of
|
||||||
|
Just (C.CncCat s e _) -> [(C.fidVar,fid) | fid <- [s..e], Just _ <- [IntMap.lookup fid lindefs]]
|
||||||
|
Nothing -> error "GrammarToPGF.mkCtxt failed"
|
||||||
|
|
||||||
|
toCncFun offs (m,id) funs (funid0,lins0) =
|
||||||
|
let mseqs = case lookupModule gr m of
|
||||||
|
Ok (ModInfo{mseqs=Just mseqs}) -> mseqs
|
||||||
|
_ -> ex_seqs
|
||||||
|
in (offs+funid0,C.CncFun (i2i id) (amap (newIndex mseqs) lins0)):funs
|
||||||
|
where
|
||||||
|
newIndex mseqs i = binSearch (mseqs ! i) seqs (bounds seqs)
|
||||||
|
|
||||||
|
binSearch v arr (i,j)
|
||||||
|
| i <= j = case ciCmp v (arr ! k) of
|
||||||
|
LT -> binSearch v arr (i,k-1)
|
||||||
|
EQ -> k
|
||||||
|
GT -> binSearch v arr (k+1,j)
|
||||||
|
| otherwise = error "binSearch"
|
||||||
|
where
|
||||||
|
k = (i+j) `div` 2
|
||||||
|
|
||||||
|
genPrintNames cdefs =
|
||||||
|
Map.fromAscList [(i2i id, name) | ((m,id),info) <- cdefs, name <- prn info]
|
||||||
|
where
|
||||||
|
prn (CncFun _ _ (Just (L _ tr)) _) = [flatten tr]
|
||||||
|
prn (CncCat _ _ _ (Just (L _ tr)) _) = [flatten tr]
|
||||||
|
prn _ = []
|
||||||
|
|
||||||
|
flatten (K s) = s
|
||||||
|
flatten (Alts x _) = flatten x
|
||||||
|
flatten (C x y) = flatten x +++ flatten y
|
||||||
|
|
||||||
|
mkArray lst = listArray (0,length lst-1) lst
|
||||||
|
mkMapArray map = array (0,Map.size map-1) [(v,k) | (k,v) <- Map.toList map]
|
||||||
@@ -3,7 +3,7 @@ module GF.Compiler (mainGFC, linkGrammars, writePGF, writeOutputs) where
|
|||||||
import PGF
|
import PGF
|
||||||
import PGF.Internal(concretes,optimizePGF,unionPGF)
|
import PGF.Internal(concretes,optimizePGF,unionPGF)
|
||||||
import PGF.Internal(putSplitAbs,encodeFile,runPut)
|
import PGF.Internal(putSplitAbs,encodeFile,runPut)
|
||||||
import GF.Compile as S(batchCompile,link,srcAbsName)
|
import GF.Compile as S(batchCompile,link,linkl,srcAbsName)
|
||||||
import GF.CompileInParallel as P(parallelBatchCompile)
|
import GF.CompileInParallel as P(parallelBatchCompile)
|
||||||
import GF.Compile.Export
|
import GF.Compile.Export
|
||||||
import GF.Compile.ConcreteToHaskell(concretes2haskell)
|
import GF.Compile.ConcreteToHaskell(concretes2haskell)
|
||||||
@@ -11,7 +11,8 @@ import GF.Compile.GrammarToCanonical--(concretes2canonical)
|
|||||||
import GF.Compile.CFGtoPGF
|
import GF.Compile.CFGtoPGF
|
||||||
import GF.Compile.GetGrammar
|
import GF.Compile.GetGrammar
|
||||||
import GF.Grammar.BNFC
|
import GF.Grammar.BNFC
|
||||||
import GF.Grammar.CFG
|
import GF.Grammar.CFG hiding (Grammar)
|
||||||
|
import GF.Grammar.Grammar (Grammar, ModuleName)
|
||||||
|
|
||||||
--import GF.Infra.Ident(showIdent)
|
--import GF.Infra.Ident(showIdent)
|
||||||
import GF.Infra.UseIO
|
import GF.Infra.UseIO
|
||||||
@@ -23,6 +24,7 @@ import GF.Text.Pretty(render,render80)
|
|||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
import qualified Data.Map as Map
|
import qualified Data.Map as Map
|
||||||
import qualified Data.Set as Set
|
import qualified Data.Set as Set
|
||||||
|
import Data.Time(UTCTime)
|
||||||
import qualified Data.ByteString.Lazy as BSL
|
import qualified Data.ByteString.Lazy as BSL
|
||||||
import GF.Grammar.CanonicalJSON (encodeJSON)
|
import GF.Grammar.CanonicalJSON (encodeJSON)
|
||||||
import System.FilePath
|
import System.FilePath
|
||||||
@@ -47,7 +49,7 @@ mainGFC opts fs = do
|
|||||||
extensionIs ext = (== ext) . takeExtension
|
extensionIs ext = (== ext) . takeExtension
|
||||||
|
|
||||||
compileSourceFiles :: Options -> [FilePath] -> IOE ()
|
compileSourceFiles :: Options -> [FilePath] -> IOE ()
|
||||||
compileSourceFiles opts fs =
|
compileSourceFiles opts fs =
|
||||||
do output <- batchCompile opts fs
|
do output <- batchCompile opts fs
|
||||||
exportCanonical output
|
exportCanonical output
|
||||||
unless (flag optStopAfterPhase opts == Compile) $
|
unless (flag optStopAfterPhase opts == Compile) $
|
||||||
@@ -93,6 +95,12 @@ compileSourceFiles opts fs =
|
|||||||
-- If a @.pgf@ file by the same name already exists and it is newer than the
|
-- If a @.pgf@ file by the same name already exists and it is newer than the
|
||||||
-- source grammar files (as indicated by the 'UTCTime' argument), it is not
|
-- source grammar files (as indicated by the 'UTCTime' argument), it is not
|
||||||
-- recreated. Calls 'writePGF' and 'writeOutputs'.
|
-- recreated. Calls 'writePGF' and 'writeOutputs'.
|
||||||
|
linkGrammars :: Options -> (UTCTime,[(ModuleName, Grammar)]) -> IOE ()
|
||||||
|
linkGrammars opts (_,cnc_grs) | FmtLPGF `elem` flag optOutputFormats opts = do
|
||||||
|
pgfs <- mapM (linkl opts) cnc_grs
|
||||||
|
let pgf0 = foldl1 unionPGF pgfs
|
||||||
|
writePGF opts pgf0
|
||||||
|
putStrLn "LPGF"
|
||||||
linkGrammars opts (t_src,~cnc_grs@(~(cnc,gr):_)) =
|
linkGrammars opts (t_src,~cnc_grs@(~(cnc,gr):_)) =
|
||||||
do let abs = render (srcAbsName gr cnc)
|
do let abs = render (srcAbsName gr cnc)
|
||||||
pgfFile = outputPath opts (grammarName' opts abs<.>"pgf")
|
pgfFile = outputPath opts (grammarName' opts abs<.>"pgf")
|
||||||
@@ -155,7 +163,7 @@ unionPGFFiles opts fs =
|
|||||||
-- Calls 'exportPGF'.
|
-- Calls 'exportPGF'.
|
||||||
writeOutputs :: Options -> PGF -> IOE ()
|
writeOutputs :: Options -> PGF -> IOE ()
|
||||||
writeOutputs opts pgf = do
|
writeOutputs opts pgf = do
|
||||||
sequence_ [writeOutput opts name str
|
sequence_ [writeOutput opts name str
|
||||||
| fmt <- flag optOutputFormats opts,
|
| fmt <- flag optOutputFormats opts,
|
||||||
(name,str) <- exportPGF opts fmt pgf]
|
(name,str) <- exportPGF opts fmt pgf]
|
||||||
|
|
||||||
|
|||||||
@@ -2,13 +2,13 @@ module GF.Infra.Option
|
|||||||
(
|
(
|
||||||
-- ** Command line options
|
-- ** Command line options
|
||||||
-- *** Option types
|
-- *** Option types
|
||||||
Options,
|
Options,
|
||||||
Flags(..),
|
Flags(..),
|
||||||
Mode(..), Phase(..), Verbosity(..),
|
Mode(..), Phase(..), Verbosity(..),
|
||||||
OutputFormat(..),
|
OutputFormat(..),
|
||||||
SISRFormat(..), Optimization(..), CFGTransform(..), HaskellOption(..),
|
SISRFormat(..), Optimization(..), CFGTransform(..), HaskellOption(..),
|
||||||
Dump(..), Pass(..), Recomp(..),
|
Dump(..), Pass(..), Recomp(..),
|
||||||
outputFormatsExpl,
|
outputFormatsExpl,
|
||||||
-- *** Option parsing
|
-- *** Option parsing
|
||||||
parseOptions, parseModuleOptions, fixRelativeLibPaths,
|
parseOptions, parseModuleOptions, fixRelativeLibPaths,
|
||||||
-- *** Option pretty-printing
|
-- *** Option pretty-printing
|
||||||
@@ -47,7 +47,7 @@ import PGF.Internal(Literal(..))
|
|||||||
import qualified Control.Monad.Fail as Fail
|
import qualified Control.Monad.Fail as Fail
|
||||||
|
|
||||||
usageHeader :: String
|
usageHeader :: String
|
||||||
usageHeader = unlines
|
usageHeader = unlines
|
||||||
["Usage: gf [OPTIONS] [FILE [...]]",
|
["Usage: gf [OPTIONS] [FILE [...]]",
|
||||||
"",
|
"",
|
||||||
"How each FILE is handled depends on the file name suffix:",
|
"How each FILE is handled depends on the file name suffix:",
|
||||||
@@ -87,13 +87,14 @@ data Verbosity = Quiet | Normal | Verbose | Debug
|
|||||||
data Phase = Preproc | Convert | Compile | Link
|
data Phase = Preproc | Convert | Compile | Link
|
||||||
deriving (Show,Eq,Ord)
|
deriving (Show,Eq,Ord)
|
||||||
|
|
||||||
data OutputFormat = FmtPGFPretty
|
data OutputFormat = FmtLPGF
|
||||||
|
| FmtPGFPretty
|
||||||
| FmtCanonicalGF
|
| FmtCanonicalGF
|
||||||
| FmtCanonicalJson
|
| FmtCanonicalJson
|
||||||
| FmtJavaScript
|
| FmtJavaScript
|
||||||
| FmtJSON
|
| FmtJSON
|
||||||
| FmtPython
|
| FmtPython
|
||||||
| FmtHaskell
|
| FmtHaskell
|
||||||
| FmtJava
|
| FmtJava
|
||||||
| FmtProlog
|
| FmtProlog
|
||||||
| FmtBNF
|
| FmtBNF
|
||||||
@@ -102,30 +103,30 @@ data OutputFormat = FmtPGFPretty
|
|||||||
| FmtNoLR
|
| FmtNoLR
|
||||||
| FmtSRGS_XML
|
| FmtSRGS_XML
|
||||||
| FmtSRGS_XML_NonRec
|
| FmtSRGS_XML_NonRec
|
||||||
| FmtSRGS_ABNF
|
| FmtSRGS_ABNF
|
||||||
| FmtSRGS_ABNF_NonRec
|
| FmtSRGS_ABNF_NonRec
|
||||||
| FmtJSGF
|
| FmtJSGF
|
||||||
| FmtGSL
|
| FmtGSL
|
||||||
| FmtVoiceXML
|
| FmtVoiceXML
|
||||||
| FmtSLF
|
| FmtSLF
|
||||||
| FmtRegExp
|
| FmtRegExp
|
||||||
| FmtFA
|
| FmtFA
|
||||||
deriving (Eq,Ord)
|
deriving (Eq,Ord)
|
||||||
|
|
||||||
data SISRFormat =
|
data SISRFormat =
|
||||||
-- | SISR Working draft 1 April 2003
|
-- | SISR Working draft 1 April 2003
|
||||||
-- <http://www.w3.org/TR/2003/WD-semantic-interpretation-20030401/>
|
-- <http://www.w3.org/TR/2003/WD-semantic-interpretation-20030401/>
|
||||||
SISR_WD20030401
|
SISR_WD20030401
|
||||||
| SISR_1_0
|
| SISR_1_0
|
||||||
deriving (Show,Eq,Ord)
|
deriving (Show,Eq,Ord)
|
||||||
|
|
||||||
data Optimization = OptStem | OptCSE | OptExpand | OptParametrize
|
data Optimization = OptStem | OptCSE | OptExpand | OptParametrize
|
||||||
deriving (Show,Eq,Ord)
|
deriving (Show,Eq,Ord)
|
||||||
|
|
||||||
data CFGTransform = CFGNoLR
|
data CFGTransform = CFGNoLR
|
||||||
| CFGRegular
|
| CFGRegular
|
||||||
| CFGTopDownFilter
|
| CFGTopDownFilter
|
||||||
| CFGBottomUpFilter
|
| CFGBottomUpFilter
|
||||||
| CFGStartCatOnly
|
| CFGStartCatOnly
|
||||||
| CFGMergeIdentical
|
| CFGMergeIdentical
|
||||||
| CFGRemoveCycles
|
| CFGRemoveCycles
|
||||||
@@ -196,7 +197,7 @@ instance Show Options where
|
|||||||
parseOptions :: ErrorMonad err =>
|
parseOptions :: ErrorMonad err =>
|
||||||
[String] -- ^ list of string arguments
|
[String] -- ^ list of string arguments
|
||||||
-> err (Options, [FilePath])
|
-> err (Options, [FilePath])
|
||||||
parseOptions args
|
parseOptions args
|
||||||
| not (null errs) = errors errs
|
| not (null errs) = errors errs
|
||||||
| otherwise = do opts <- concatOptions `fmap` liftErr (sequence optss)
|
| otherwise = do opts <- concatOptions `fmap` liftErr (sequence optss)
|
||||||
return (opts, files)
|
return (opts, files)
|
||||||
@@ -208,7 +209,7 @@ parseModuleOptions :: ErrorMonad err =>
|
|||||||
-> err Options
|
-> err Options
|
||||||
parseModuleOptions args = do
|
parseModuleOptions args = do
|
||||||
(opts,nonopts) <- parseOptions args
|
(opts,nonopts) <- parseOptions args
|
||||||
if null nonopts
|
if null nonopts
|
||||||
then return opts
|
then return opts
|
||||||
else errors $ map ("Non-option among module options: " ++) nonopts
|
else errors $ map ("Non-option among module options: " ++) nonopts
|
||||||
|
|
||||||
@@ -281,7 +282,7 @@ defaultFlags = Flags {
|
|||||||
optOptimizations = Set.fromList [OptStem,OptCSE,OptExpand,OptParametrize],
|
optOptimizations = Set.fromList [OptStem,OptCSE,OptExpand,OptParametrize],
|
||||||
optOptimizePGF = False,
|
optOptimizePGF = False,
|
||||||
optSplitPGF = False,
|
optSplitPGF = False,
|
||||||
optCFGTransforms = Set.fromList [CFGRemoveCycles, CFGBottomUpFilter,
|
optCFGTransforms = Set.fromList [CFGRemoveCycles, CFGBottomUpFilter,
|
||||||
CFGTopDownFilter, CFGMergeIdentical],
|
CFGTopDownFilter, CFGMergeIdentical],
|
||||||
optLibraryPath = [],
|
optLibraryPath = [],
|
||||||
optStartCat = Nothing,
|
optStartCat = Nothing,
|
||||||
@@ -301,7 +302,7 @@ defaultFlags = Flags {
|
|||||||
-- | Option descriptions
|
-- | Option descriptions
|
||||||
{-# NOINLINE optDescr #-}
|
{-# NOINLINE optDescr #-}
|
||||||
optDescr :: [OptDescr (Err Options)]
|
optDescr :: [OptDescr (Err Options)]
|
||||||
optDescr =
|
optDescr =
|
||||||
[
|
[
|
||||||
Option ['?','h'] ["help"] (NoArg (mode ModeHelp)) "Show help message.",
|
Option ['?','h'] ["help"] (NoArg (mode ModeHelp)) "Show help message.",
|
||||||
Option ['V'] ["version"] (NoArg (mode ModeVersion)) "Display GF version number.",
|
Option ['V'] ["version"] (NoArg (mode ModeVersion)) "Display GF version number.",
|
||||||
@@ -327,44 +328,44 @@ optDescr =
|
|||||||
-- Option ['t'] ["trace"] (NoArg (trace True)) "Trace computations",
|
-- Option ['t'] ["trace"] (NoArg (trace True)) "Trace computations",
|
||||||
-- Option [] ["no-trace"] (NoArg (trace False)) "Don't trace computations",
|
-- Option [] ["no-trace"] (NoArg (trace False)) "Don't trace computations",
|
||||||
Option [] ["gfo-dir"] (ReqArg gfoDir "DIR") "Directory to put .gfo files in (default = '.').",
|
Option [] ["gfo-dir"] (ReqArg gfoDir "DIR") "Directory to put .gfo files in (default = '.').",
|
||||||
Option ['f'] ["output-format"] (ReqArg outFmt "FMT")
|
Option ['f'] ["output-format"] (ReqArg outFmt "FMT")
|
||||||
(unlines ["Output format. FMT can be one of:",
|
(unlines ["Output format. FMT can be one of:",
|
||||||
"Canonical GF grammar: canonical_gf, canonical_json, (and haskell with option --haskell=concrete)",
|
"Canonical GF grammar: canonical_gf, canonical_json, (and haskell with option --haskell=concrete)",
|
||||||
"Multiple concrete: pgf (default), json, js, pgf_pretty, prolog, python, ...", -- gar,
|
"Multiple concrete: pgf (default), lpgf, json, js, pgf_pretty, prolog, python, ...", -- gar,
|
||||||
"Single concrete only: bnf, ebnf, fa, gsl, jsgf, regexp, slf, srgs_xml, srgs_abnf, vxml, ....", -- cf, lbnf,
|
"Single concrete only: bnf, ebnf, fa, gsl, jsgf, regexp, slf, srgs_xml, srgs_abnf, vxml, ....", -- cf, lbnf,
|
||||||
"Abstract only: haskell, ..."]), -- prolog_abs,
|
"Abstract only: haskell, ..."]), -- prolog_abs,
|
||||||
Option [] ["sisr"] (ReqArg sisrFmt "FMT")
|
Option [] ["sisr"] (ReqArg sisrFmt "FMT")
|
||||||
(unlines ["Include SISR tags in generated speech recognition grammars.",
|
(unlines ["Include SISR tags in generated speech recognition grammars.",
|
||||||
"FMT can be one of: old, 1.0"]),
|
"FMT can be one of: old, 1.0"]),
|
||||||
Option [] ["haskell"] (ReqArg hsOption "OPTION")
|
Option [] ["haskell"] (ReqArg hsOption "OPTION")
|
||||||
("Turn on an optional feature when generating Haskell data types. OPTION = "
|
("Turn on an optional feature when generating Haskell data types. OPTION = "
|
||||||
++ concat (intersperse " | " (map fst haskellOptionNames))),
|
++ concat (intersperse " | " (map fst haskellOptionNames))),
|
||||||
Option [] ["lexical"] (ReqArg lexicalCat "CAT[,CAT[...]]")
|
Option [] ["lexical"] (ReqArg lexicalCat "CAT[,CAT[...]]")
|
||||||
"Treat CAT as a lexical category.",
|
"Treat CAT as a lexical category.",
|
||||||
Option [] ["literal"] (ReqArg literalCat "CAT[,CAT[...]]")
|
Option [] ["literal"] (ReqArg literalCat "CAT[,CAT[...]]")
|
||||||
"Treat CAT as a literal category.",
|
"Treat CAT as a literal category.",
|
||||||
Option ['D'] ["output-dir"] (ReqArg outDir "DIR")
|
Option ['D'] ["output-dir"] (ReqArg outDir "DIR")
|
||||||
"Save output files (other than .gfo files) in DIR.",
|
"Save output files (other than .gfo files) in DIR.",
|
||||||
Option [] ["gf-lib-path"] (ReqArg gfLibPath "DIR")
|
Option [] ["gf-lib-path"] (ReqArg gfLibPath "DIR")
|
||||||
"Overrides the value of GF_LIB_PATH.",
|
"Overrides the value of GF_LIB_PATH.",
|
||||||
Option [] ["src","force-recomp"] (NoArg (recomp AlwaysRecomp))
|
Option [] ["src","force-recomp"] (NoArg (recomp AlwaysRecomp))
|
||||||
"Always recompile from source.",
|
"Always recompile from source.",
|
||||||
Option [] ["recomp-if-newer"] (NoArg (recomp RecompIfNewer))
|
Option [] ["recomp-if-newer"] (NoArg (recomp RecompIfNewer))
|
||||||
"(default) Recompile from source if the source is newer than the .gfo file.",
|
"(default) Recompile from source if the source is newer than the .gfo file.",
|
||||||
Option [] ["gfo","no-recomp"] (NoArg (recomp NeverRecomp))
|
Option [] ["gfo","no-recomp"] (NoArg (recomp NeverRecomp))
|
||||||
"Never recompile from source, if there is already .gfo file.",
|
"Never recompile from source, if there is already .gfo file.",
|
||||||
Option [] ["retain"] (NoArg (set $ \o -> o { optRetainResource = True })) "Retain opers.",
|
Option [] ["retain"] (NoArg (set $ \o -> o { optRetainResource = True })) "Retain opers.",
|
||||||
Option [] ["probs"] (ReqArg probsFile "file.probs") "Read probabilities from file.",
|
Option [] ["probs"] (ReqArg probsFile "file.probs") "Read probabilities from file.",
|
||||||
Option ['n'] ["name"] (ReqArg name "NAME")
|
Option ['n'] ["name"] (ReqArg name "NAME")
|
||||||
(unlines ["Use NAME as the name of the output. This is used in the output file names, ",
|
(unlines ["Use NAME as the name of the output. This is used in the output file names, ",
|
||||||
"with suffixes depending on the formats, and, when relevant, ",
|
"with suffixes depending on the formats, and, when relevant, ",
|
||||||
"internally in the output."]),
|
"internally in the output."]),
|
||||||
Option ['i'] [] (ReqArg addLibDir "DIR") "Add DIR to the library search path.",
|
Option ['i'] [] (ReqArg addLibDir "DIR") "Add DIR to the library search path.",
|
||||||
Option [] ["path"] (ReqArg setLibPath "DIR:DIR:...") "Set the library search path.",
|
Option [] ["path"] (ReqArg setLibPath "DIR:DIR:...") "Set the library search path.",
|
||||||
Option [] ["preproc"] (ReqArg preproc "CMD")
|
Option [] ["preproc"] (ReqArg preproc "CMD")
|
||||||
(unlines ["Use CMD to preprocess input files.",
|
(unlines ["Use CMD to preprocess input files.",
|
||||||
"Multiple preprocessors can be used by giving this option multiple times."]),
|
"Multiple preprocessors can be used by giving this option multiple times."]),
|
||||||
Option [] ["coding"] (ReqArg coding "ENCODING")
|
Option [] ["coding"] (ReqArg coding "ENCODING")
|
||||||
("Character encoding of the source grammar, ENCODING = utf8, latin1, cp1251, ..."),
|
("Character encoding of the source grammar, ENCODING = utf8, latin1, cp1251, ..."),
|
||||||
Option [] ["startcat"] (ReqArg startcat "CAT") "Grammar start category.",
|
Option [] ["startcat"] (ReqArg startcat "CAT") "Grammar start category.",
|
||||||
Option [] ["language"] (ReqArg language "LANG") "Set the speech language flag to LANG in the generated grammar.",
|
Option [] ["language"] (ReqArg language "LANG") "Set the speech language flag to LANG in the generated grammar.",
|
||||||
@@ -372,7 +373,7 @@ optDescr =
|
|||||||
Option [] ["unlexer"] (ReqArg unlexer "UNLEXER") "Use unlexer UNLEXER.",
|
Option [] ["unlexer"] (ReqArg unlexer "UNLEXER") "Use unlexer UNLEXER.",
|
||||||
Option [] ["pmcfg"] (NoArg (pmcfg True)) "Generate PMCFG (default).",
|
Option [] ["pmcfg"] (NoArg (pmcfg True)) "Generate PMCFG (default).",
|
||||||
Option [] ["no-pmcfg"] (NoArg (pmcfg False)) "Don't generate PMCFG (useful for libraries).",
|
Option [] ["no-pmcfg"] (NoArg (pmcfg False)) "Don't generate PMCFG (useful for libraries).",
|
||||||
Option [] ["optimize"] (ReqArg optimize "OPT")
|
Option [] ["optimize"] (ReqArg optimize "OPT")
|
||||||
"Select an optimization package. OPT = all | values | parametrize | none",
|
"Select an optimization package. OPT = all | values | parametrize | none",
|
||||||
Option [] ["optimize-pgf"] (NoArg (optimize_pgf True))
|
Option [] ["optimize-pgf"] (NoArg (optimize_pgf True))
|
||||||
"Enable or disable global grammar optimization. This could significantly reduce the size of the final PGF file",
|
"Enable or disable global grammar optimization. This could significantly reduce the size of the final PGF file",
|
||||||
@@ -447,7 +448,7 @@ optDescr =
|
|||||||
optimize x = case lookup x optimizationPackages of
|
optimize x = case lookup x optimizationPackages of
|
||||||
Just p -> set $ \o -> o { optOptimizations = p }
|
Just p -> set $ \o -> o { optOptimizations = p }
|
||||||
Nothing -> fail $ "Unknown optimization package: " ++ x
|
Nothing -> fail $ "Unknown optimization package: " ++ x
|
||||||
|
|
||||||
optimize_pgf x = set $ \o -> o { optOptimizePGF = x }
|
optimize_pgf x = set $ \o -> o { optOptimizePGF = x }
|
||||||
splitPGF x = set $ \o -> o { optSplitPGF = x }
|
splitPGF x = set $ \o -> o { optSplitPGF = x }
|
||||||
|
|
||||||
@@ -471,8 +472,9 @@ outputFormats :: [(String,OutputFormat)]
|
|||||||
outputFormats = map fst outputFormatsExpl
|
outputFormats = map fst outputFormatsExpl
|
||||||
|
|
||||||
outputFormatsExpl :: [((String,OutputFormat),String)]
|
outputFormatsExpl :: [((String,OutputFormat),String)]
|
||||||
outputFormatsExpl =
|
outputFormatsExpl =
|
||||||
[(("pgf_pretty", FmtPGFPretty),"human-readable pgf"),
|
[(("lpgf", FmtLPGF),"Linearisation-only PGF"),
|
||||||
|
(("pgf_pretty", FmtPGFPretty),"Human-readable PGF"),
|
||||||
(("canonical_gf", FmtCanonicalGF),"Canonical GF source files"),
|
(("canonical_gf", FmtCanonicalGF),"Canonical GF source files"),
|
||||||
(("canonical_json", FmtCanonicalJson),"Canonical JSON source files"),
|
(("canonical_json", FmtCanonicalJson),"Canonical JSON source files"),
|
||||||
(("js", FmtJavaScript),"JavaScript (whole grammar)"),
|
(("js", FmtJavaScript),"JavaScript (whole grammar)"),
|
||||||
@@ -504,11 +506,11 @@ instance Read OutputFormat where
|
|||||||
readsPrec = lookupReadsPrec outputFormats
|
readsPrec = lookupReadsPrec outputFormats
|
||||||
|
|
||||||
optimizationPackages :: [(String, Set Optimization)]
|
optimizationPackages :: [(String, Set Optimization)]
|
||||||
optimizationPackages =
|
optimizationPackages =
|
||||||
[("all", Set.fromList [OptStem,OptCSE,OptExpand,OptParametrize]),
|
[("all", Set.fromList [OptStem,OptCSE,OptExpand,OptParametrize]),
|
||||||
("values", Set.fromList [OptStem,OptCSE,OptExpand]),
|
("values", Set.fromList [OptStem,OptCSE,OptExpand]),
|
||||||
("noexpand", Set.fromList [OptStem,OptCSE]),
|
("noexpand", Set.fromList [OptStem,OptCSE]),
|
||||||
|
|
||||||
-- deprecated
|
-- deprecated
|
||||||
("all_subs", Set.fromList [OptStem,OptCSE,OptExpand,OptParametrize]),
|
("all_subs", Set.fromList [OptStem,OptCSE,OptExpand,OptParametrize]),
|
||||||
("parametrize", Set.fromList [OptStem,OptCSE,OptExpand,OptParametrize]),
|
("parametrize", Set.fromList [OptStem,OptCSE,OptExpand,OptParametrize]),
|
||||||
@@ -516,7 +518,7 @@ optimizationPackages =
|
|||||||
]
|
]
|
||||||
|
|
||||||
cfgTransformNames :: [(String, CFGTransform)]
|
cfgTransformNames :: [(String, CFGTransform)]
|
||||||
cfgTransformNames =
|
cfgTransformNames =
|
||||||
[("nolr", CFGNoLR),
|
[("nolr", CFGNoLR),
|
||||||
("regular", CFGRegular),
|
("regular", CFGRegular),
|
||||||
("topdown", CFGTopDownFilter),
|
("topdown", CFGTopDownFilter),
|
||||||
@@ -558,7 +560,7 @@ onOff f def = OptArg g "[on,off]"
|
|||||||
_ -> fail $ "Expected [on,off], got: " ++ show x
|
_ -> fail $ "Expected [on,off], got: " ++ show x
|
||||||
|
|
||||||
readOutputFormat :: Fail.MonadFail m => String -> m OutputFormat
|
readOutputFormat :: Fail.MonadFail m => String -> m OutputFormat
|
||||||
readOutputFormat s =
|
readOutputFormat s =
|
||||||
maybe (fail $ "Unknown output format: " ++ show s) return $ lookup s outputFormats
|
maybe (fail $ "Unknown output format: " ++ show s) return $ lookup s outputFormats
|
||||||
|
|
||||||
-- FIXME: this is a copy of the function in GF.Devel.UseIO.
|
-- FIXME: this is a copy of the function in GF.Devel.UseIO.
|
||||||
@@ -570,7 +572,7 @@ splitInModuleSearchPath s = case break isPathSep s of
|
|||||||
isPathSep :: Char -> Bool
|
isPathSep :: Char -> Bool
|
||||||
isPathSep c = c == ':' || c == ';'
|
isPathSep c = c == ':' || c == ';'
|
||||||
|
|
||||||
--
|
--
|
||||||
-- * Convenience functions for checking options
|
-- * Convenience functions for checking options
|
||||||
--
|
--
|
||||||
|
|
||||||
@@ -592,7 +594,7 @@ isLiteralCat opts c = Set.member c (flag optLiteralCats opts)
|
|||||||
isLexicalCat :: Options -> String -> Bool
|
isLexicalCat :: Options -> String -> Bool
|
||||||
isLexicalCat opts c = Set.member c (flag optLexicalCats opts)
|
isLexicalCat opts c = Set.member c (flag optLexicalCats opts)
|
||||||
|
|
||||||
--
|
--
|
||||||
-- * Convenience functions for setting options
|
-- * Convenience functions for setting options
|
||||||
--
|
--
|
||||||
|
|
||||||
@@ -623,8 +625,8 @@ readMaybe s = case reads s of
|
|||||||
|
|
||||||
toEnumBounded :: (Bounded a, Enum a, Ord a) => Int -> Maybe a
|
toEnumBounded :: (Bounded a, Enum a, Ord a) => Int -> Maybe a
|
||||||
toEnumBounded i = let mi = minBound
|
toEnumBounded i = let mi = minBound
|
||||||
ma = maxBound `asTypeOf` mi
|
ma = maxBound `asTypeOf` mi
|
||||||
in if i >= fromEnum mi && i <= fromEnum ma
|
in if i >= fromEnum mi && i <= fromEnum ma
|
||||||
then Just (toEnum i `asTypeOf` mi)
|
then Just (toEnum i `asTypeOf` mi)
|
||||||
else Nothing
|
else Nothing
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user