forked from GitHub/gf-core
Devel/GF3: experimentally putting together all functionalities for the first time
This commit is contained in:
34
src/GF/Command/Importing.hs
Normal file
34
src/GF/Command/Importing.hs
Normal file
@@ -0,0 +1,34 @@
|
||||
module GF.Command.Importing (importGrammar) where
|
||||
|
||||
import GF.Devel.Compile
|
||||
import GF.Devel.GrammarToGFCC
|
||||
import GF.GFCC.OptimizeGFCC
|
||||
import GF.GFCC.CheckGFCC
|
||||
import GF.GFCC.DataGFCC
|
||||
import GF.GFCC.ParGFCC
|
||||
import GF.GFCC.API
|
||||
import qualified GF.Command.AbsGFShell as C
|
||||
|
||||
import GF.Devel.UseIO
|
||||
import GF.Infra.Option
|
||||
|
||||
import Data.List (nubBy)
|
||||
|
||||
-- import a grammar in an environment where it extends an existing grammar
|
||||
importGrammar :: MultiGrammar -> Options -> [FilePath] -> IO MultiGrammar
|
||||
importGrammar mgr0 opts files = do
|
||||
gfcc2 <- case fileSuffix (last files) of
|
||||
s | elem s ["gf","gfo"] -> do
|
||||
gr <- batchCompile opts files
|
||||
let name = justModuleName (last files)
|
||||
let (abs,gfcc0) = mkCanon2gfcc opts name gr
|
||||
(gfcc1,b) <- checkGFCC gfcc0
|
||||
if b then return () else do
|
||||
putStrLn "Corrupted GFCC"
|
||||
return $ if oElem (iOpt "noopt") opts then gfcc1 else optGFCC gfcc1
|
||||
"gfcc" ->
|
||||
mapM file2gfcc files >>= return . foldl1 unionGFCC
|
||||
let gfcc3 = unionGFCC (gfcc mgr0) gfcc2
|
||||
return $ MultiGrammar gfcc3
|
||||
(nubBy (\ (x,_) (y,_) -> x == y) (gfcc2parsers gfcc3 ++ parsers mgr0))
|
||||
-- later coming parsers override
|
||||
44
src/GF/Devel/GF3.hs
Normal file
44
src/GF/Devel/GF3.hs
Normal file
@@ -0,0 +1,44 @@
|
||||
module Main where
|
||||
|
||||
import GF.Command.Interpreter
|
||||
import GF.Command.Importing
|
||||
import GF.Command.Commands
|
||||
import GF.GFCC.API
|
||||
|
||||
import GF.Infra.Option ---- Haskell's option lib
|
||||
|
||||
import System (getArgs)
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
putStrLn welcome
|
||||
xx <- getArgs
|
||||
env <- importInEnv emptyMultiGrammar xx
|
||||
loop env
|
||||
return ()
|
||||
|
||||
loop :: CommandEnv -> IO CommandEnv
|
||||
loop env = do
|
||||
s <- getLine
|
||||
case words s of
|
||||
"q":_ -> return env
|
||||
"i":args -> do
|
||||
env1 <- importInEnv (multigrammar env) args
|
||||
loop env1
|
||||
_ -> do
|
||||
interpretCommandLine env s
|
||||
loop env
|
||||
|
||||
importInEnv mgr0 xx = do
|
||||
let (opts,files) = getOptions "-" xx
|
||||
mgr1 <- case files of
|
||||
[] -> return mgr0
|
||||
_ -> importGrammar mgr0 opts files
|
||||
let env = CommandEnv mgr1 (allCommands mgr1)
|
||||
putStrLn $ unwords $ "\nLanguages:" : languages mgr1
|
||||
return env
|
||||
|
||||
welcome = unlines [
|
||||
"This is GF version 3.0 alpha.",
|
||||
"Some things may work."
|
||||
]
|
||||
@@ -76,9 +76,10 @@ startCat :: MultiGrammar -> Category
|
||||
|
||||
file2grammar f = do
|
||||
gfcc <- file2gfcc f
|
||||
let fcfgs = convertGrammar gfcc
|
||||
return (MultiGrammar gfcc
|
||||
[(lang, buildFCFPInfo fcfg) | (CId lang,fcfg) <- fcfgs])
|
||||
return (MultiGrammar gfcc (gfcc2parsers gfcc))
|
||||
|
||||
gfcc2parsers gfcc =
|
||||
[(lang, buildFCFPInfo fcfg) | (CId lang,fcfg) <- convertGrammar gfcc]
|
||||
|
||||
file2gfcc f =
|
||||
readFileIf f >>= err (error) (return . mkGFCC) . pGrammar . myLexer
|
||||
@@ -117,6 +118,8 @@ categories mgr = [c | CId c <- Map.keys (cats (abstract (gfcc mgr)))]
|
||||
|
||||
startCat mgr = "S" ----
|
||||
|
||||
emptyMultiGrammar = MultiGrammar emptyGFCC []
|
||||
|
||||
------------ for internal use only
|
||||
|
||||
linearThis = GF.GFCC.API.linearize
|
||||
|
||||
@@ -96,12 +96,22 @@ printGFCC gfcc0 = compactPrintGFCC $ printTree $ Grm
|
||||
-- merge two GFCCs; fails is differens absnames; priority to second arg
|
||||
|
||||
unionGFCC :: GFCC -> GFCC -> GFCC
|
||||
unionGFCC one two =
|
||||
if absname one == absname two
|
||||
then one {
|
||||
unionGFCC one two = case absname one of
|
||||
CId "" -> two -- extending empty grammar
|
||||
n | n == absname two -> one { -- extending grammar with same abstract
|
||||
concretes = Data.Map.union (concretes two) (concretes one),
|
||||
cncnames = Data.List.union (cncnames two) (cncnames one)}
|
||||
else one
|
||||
cncnames = Data.List.union (cncnames two) (cncnames one)
|
||||
}
|
||||
_ -> one -- abstracts don't match ---- print error msg
|
||||
|
||||
emptyGFCC :: GFCC
|
||||
emptyGFCC = GFCC {
|
||||
absname = CId "",
|
||||
cncnames = [] ,
|
||||
abstract = error "empty grammar, no abstract",
|
||||
concretes = empty
|
||||
}
|
||||
|
||||
|
||||
-- default map and filter are for Map here
|
||||
lmap = Prelude.map
|
||||
|
||||
@@ -203,6 +203,11 @@ gfcc:
|
||||
strip gfcc
|
||||
mv gfcc ../bin/
|
||||
|
||||
gf3:
|
||||
$(GHMAKE) $(GHCOPTFLAGS) -o gf3 GF/Devel/GF3.hs
|
||||
strip gf3
|
||||
mv gf3 ../bin/
|
||||
|
||||
gfcc2c:
|
||||
$(MAKE) -C tools/c
|
||||
$(MAKE) -C ../lib/c
|
||||
|
||||
Reference in New Issue
Block a user