forked from GitHub/gf-core
command eb for example-based grammar conversion; see 'help eb' and the example in examples/animals/QuestionsI.gfe
This commit is contained in:
12
examples/animals/Animals.gf
Normal file
12
examples/animals/Animals.gf
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
-- The Question grammar specialized to animals.
|
||||||
|
|
||||||
|
abstract Animals = Questions ** {
|
||||||
|
|
||||||
|
flags startcat=Phrase ;
|
||||||
|
|
||||||
|
fun
|
||||||
|
-- a lexicon of animals and actions among them
|
||||||
|
Dog, Cat, Mouse, Lion, Zebra : Entity ;
|
||||||
|
Chase, Eat, See : Action ;
|
||||||
|
}
|
||||||
|
|
||||||
16
examples/animals/AnimalsEng.gf
Normal file
16
examples/animals/AnimalsEng.gf
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
--# -path=.:present:prelude
|
||||||
|
--resource/english:resource/abstract:resource/../prelude
|
||||||
|
|
||||||
|
concrete AnimalsEng of Animals = QuestionsEng **
|
||||||
|
open LangEng, ParadigmsEng, IrregEng in {
|
||||||
|
|
||||||
|
lin
|
||||||
|
Dog = regN "dog" ;
|
||||||
|
Cat = regN "cat" ;
|
||||||
|
Mouse = mk2N "mouse" "mice" ;
|
||||||
|
Lion = regN "lion" ;
|
||||||
|
Zebra = regN "zebra" ;
|
||||||
|
Chase = dirV2 (regV "chase") ;
|
||||||
|
Eat = dirV2 eat_V ;
|
||||||
|
See = dirV2 see_V ;
|
||||||
|
}
|
||||||
15
examples/animals/AnimalsFre.gf
Normal file
15
examples/animals/AnimalsFre.gf
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
--# -path=.:present:prelude
|
||||||
|
|
||||||
|
concrete AnimalsFre of Animals = QuestionsFre **
|
||||||
|
open LangFre, ParadigmsFre, IrregFre in {
|
||||||
|
|
||||||
|
lin
|
||||||
|
Dog = regN "chien" ;
|
||||||
|
Cat = regN "chat" ;
|
||||||
|
Mouse = regGenN "souris" feminine ;
|
||||||
|
Lion = regN "lion" ;
|
||||||
|
Zebra = regGenN "zèbre" masculine ;
|
||||||
|
Chase = dirV2 (regV "chasser") ;
|
||||||
|
Eat = dirV2 (regV "manger") ;
|
||||||
|
See = voir_V2 ;
|
||||||
|
}
|
||||||
15
examples/animals/AnimalsSwe.gf
Normal file
15
examples/animals/AnimalsSwe.gf
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
--# -path=.:present:prelude
|
||||||
|
|
||||||
|
concrete AnimalsSwe of Animals = QuestionsSwe **
|
||||||
|
open LangSwe, ParadigmsSwe, IrregSwe in {
|
||||||
|
|
||||||
|
lin
|
||||||
|
Dog = regN "hund" ;
|
||||||
|
Cat = mk2N "katt" "katter" ;
|
||||||
|
Mouse = mkN "mus" "musen" "möss" "mössen" ;
|
||||||
|
Lion = mk2N "lejon" "lejon" ;
|
||||||
|
Zebra = regN "zebra" ;
|
||||||
|
Chase = dirV2 (regV "jaga") ;
|
||||||
|
Eat = dirV2 äta_V ;
|
||||||
|
See = dirV2 se_V ;
|
||||||
|
}
|
||||||
10
examples/animals/Questions.gf
Normal file
10
examples/animals/Questions.gf
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
-- Simple questions and answers, in present tense.
|
||||||
|
|
||||||
|
abstract Questions = {
|
||||||
|
cat
|
||||||
|
Phrase ; Entity ; Action ;
|
||||||
|
fun
|
||||||
|
Who : Action -> Entity -> Phrase ; -- who chases X
|
||||||
|
Whom : Entity -> Action -> Phrase ; -- whom does X chase
|
||||||
|
Answer : Entity -> Action -> Entity -> Phrase ; -- X chases Y
|
||||||
|
}
|
||||||
2
examples/animals/QuestionsEng.gf
Normal file
2
examples/animals/QuestionsEng.gf
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
concrete QuestionsEng of Questions = QuestionsI with
|
||||||
|
(Lang = LangEng) ;
|
||||||
2
examples/animals/QuestionsFre.gf
Normal file
2
examples/animals/QuestionsFre.gf
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
concrete QuestionsFre of Questions = QuestionsI with
|
||||||
|
(Lang = LangFre) ;
|
||||||
27
examples/animals/QuestionsI.gf
Normal file
27
examples/animals/QuestionsI.gf
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
-- to compile: echo "eb -file=QuestionsI.gfe" | gf $GF_LIB_PATH/present/LangEng.gfo
|
||||||
|
-- or use directly gf <mkAnimals.gfs
|
||||||
|
|
||||||
|
incomplete concrete QuestionsI of Questions = open Lang in {
|
||||||
|
lincat
|
||||||
|
Phrase = Utt ;
|
||||||
|
Entity = N ;
|
||||||
|
Action = V2 ;
|
||||||
|
|
||||||
|
lin
|
||||||
|
Who love_V2 man_N = (
|
||||||
|
UttQS (UseQCl (TTAnt TPres ASimul) PPos (QuestVP whoSg_IP (ComplSlash (SlashV2a love_V2) (DetCN (DetQuant IndefArt NumPl) (UseN man_N)))))
|
||||||
|
)
|
||||||
|
;
|
||||||
|
Whom man_N love_V2 = (
|
||||||
|
UttQS (UseQCl (TTAnt TPres ASimul) PPos (QuestSlash whoPl_IP (SlashVP (DetCN (DetQuant DefArt NumSg) (UseN man_N)) (SlashV2a love_V2))))
|
||||||
|
--- UttQS (UseQCl (TTAnt TPres ASimul) PPos (QuestSlash whoSg_IP (SlashVP (DetCN (DetQuant DefArt NumSg) (UseN man_N)) (SlashV2a love_V2))))
|
||||||
|
)
|
||||||
|
;
|
||||||
|
Answer woman_N love_V2 man_N = (
|
||||||
|
UttNP (DetCN (DetQuant DefArt NumSg) (ApposCN (ApposCN (UseN woman_N) (DetCN (DetQuant IndefArt NumPl) (UseN love_N))) (DetCN (DetQuant IndefArt NumPl) (UseN man_N))))
|
||||||
|
--- UttNP (DetCN (DetQuant DefArt NumSg) (ApposCN (UseN woman_N) (DetCN (DetQuant IndefArt NumPl) (ApposCN (UseN love_N) (DetCN (DetQuant IndefArt NumPl) (UseN man_N))))))
|
||||||
|
--- UttS (UseCl (TTAnt TPres ASimul) PPos (PredVP (DetCN (DetQuant DefArt NumSg) (UseN woman_N)) (ComplSlash (SlashV2a love_V2) (DetCN (DetQuant IndefArt NumPl) (UseN man_N)))))
|
||||||
|
)
|
||||||
|
;
|
||||||
|
|
||||||
|
}
|
||||||
15
examples/animals/QuestionsI.gfe
Normal file
15
examples/animals/QuestionsI.gfe
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
-- to compile: echo "eb -file=QuestionsI.gfe" | gf $GF_LIB_PATH/present/LangEng.gfo
|
||||||
|
-- or use directly gf <mkAnimals.gfs
|
||||||
|
|
||||||
|
incomplete concrete QuestionsI of Questions = open Lang in {
|
||||||
|
lincat
|
||||||
|
Phrase = Utt ;
|
||||||
|
Entity = N ;
|
||||||
|
Action = V2 ;
|
||||||
|
|
||||||
|
lin
|
||||||
|
Who love_V2 man_N = %ex Utt "who loves men" ;
|
||||||
|
Whom man_N love_V2 = %ex Utt "whom does the man love" ;
|
||||||
|
Answer woman_N love_V2 man_N = %ex Utt "the woman loves men" ;
|
||||||
|
|
||||||
|
}
|
||||||
2
examples/animals/QuestionsSwe.gf
Normal file
2
examples/animals/QuestionsSwe.gf
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
concrete QuestionsSwe of Questions = QuestionsI with
|
||||||
|
(Lang = LangSwe) ;
|
||||||
@@ -23,6 +23,7 @@ import PGF.Printer
|
|||||||
import PGF.Probabilistic -- (getProbsFromFile,prProbabilities,defaultProbabilities)
|
import PGF.Probabilistic -- (getProbsFromFile,prProbabilities,defaultProbabilities)
|
||||||
import PGF.Generate (genRandomProb) ----
|
import PGF.Generate (genRandomProb) ----
|
||||||
import GF.Compile.Export
|
import GF.Compile.Export
|
||||||
|
import GF.Compile.ExampleBased
|
||||||
import GF.Infra.Option (noOptions, readOutputFormat, Encoding(..))
|
import GF.Infra.Option (noOptions, readOutputFormat, Encoding(..))
|
||||||
import GF.Infra.UseIO
|
import GF.Infra.UseIO
|
||||||
import GF.Data.ErrM ----
|
import GF.Data.ErrM ----
|
||||||
@@ -231,6 +232,33 @@ allCommands cod env@(pgf, mos) = Map.fromList [
|
|||||||
longname = "empty",
|
longname = "empty",
|
||||||
synopsis = "empty the environment"
|
synopsis = "empty the environment"
|
||||||
}),
|
}),
|
||||||
|
("eb", emptyCommandInfo {
|
||||||
|
longname = "example_based",
|
||||||
|
syntax = "eb (-probs=FILE | -lang=LANG)* -file=FILE.gfe",
|
||||||
|
synopsis = "converts .gfe files to .gf files by parsing examples to trees",
|
||||||
|
explanation = unlines [
|
||||||
|
"Reads FILE.gfe and writes FILE.gf. Each expression of form",
|
||||||
|
"'%ex CAT QUOTEDSTRING' in FILE.gfe is replaced by a syntax tree.",
|
||||||
|
"This tree is the first one returned by the parser; a biased ranking",
|
||||||
|
"can be used to regulate the order. If there are more than one parses",
|
||||||
|
"the rest are shown in comments, with probabilities if the order is biased.",
|
||||||
|
"The probabilities flag and configuration file is similar to the commands",
|
||||||
|
"gr and rt. Notice that the command doesn't change the environment,",
|
||||||
|
"but the resulting .gf file must be imported separately."
|
||||||
|
],
|
||||||
|
flags = [
|
||||||
|
("file","the file to be converted (suffix .gfe must be given)"),
|
||||||
|
("lang","the language in which to parse"),
|
||||||
|
("probs","file with probabilities to rank the parses")
|
||||||
|
],
|
||||||
|
exec = \opts _ -> do
|
||||||
|
let file = optFile opts
|
||||||
|
mprobs <- optProbs opts pgf
|
||||||
|
let conf = configureExBased pgf mprobs (optLang opts)
|
||||||
|
file' <- parseExamplesInGrammar conf file
|
||||||
|
return (fromString ("wrote " ++ file')),
|
||||||
|
needsTypeCheck = False
|
||||||
|
}),
|
||||||
("gr", emptyCommandInfo {
|
("gr", emptyCommandInfo {
|
||||||
longname = "generate_random",
|
longname = "generate_random",
|
||||||
synopsis = "generate random trees in the current abstract syntax",
|
synopsis = "generate random trees in the current abstract syntax",
|
||||||
@@ -871,6 +899,8 @@ allCommands cod env@(pgf, mos) = Map.fromList [
|
|||||||
-- putStrLn $ prProbabilities ps
|
-- putStrLn $ prProbabilities ps
|
||||||
return $ Just ps
|
return $ Just ps
|
||||||
|
|
||||||
|
optFile opts = valStrOpts "file" "_gftmp" opts
|
||||||
|
|
||||||
optType opts =
|
optType opts =
|
||||||
let str = valStrOpts "cat" (showCId $ lookStartCat pgf) opts
|
let str = valStrOpts "cat" (showCId $ lookStartCat pgf) opts
|
||||||
in case readType str of
|
in case readType str of
|
||||||
@@ -988,3 +1018,4 @@ prMorphoAnalysis (w,lps) =
|
|||||||
|
|
||||||
morphoMissing :: Morpho -> [String] -> [String]
|
morphoMissing :: Morpho -> [String] -> [String]
|
||||||
morphoMissing mo ws = [w | w <- ws, null (lookupMorpho mo w)]
|
morphoMissing mo ws = [w | w <- ws, null (lookupMorpho mo w)]
|
||||||
|
|
||||||
|
|||||||
59
src/compiler/GF/Compile/ExampleBased.hs
Normal file
59
src/compiler/GF/Compile/ExampleBased.hs
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
module GF.Compile.ExampleBased (parseExamplesInGrammar,configureExBased) where
|
||||||
|
|
||||||
|
import PGF
|
||||||
|
import PGF.Probabilistic
|
||||||
|
|
||||||
|
parseExamplesInGrammar :: ExConfiguration -> FilePath -> IO FilePath
|
||||||
|
parseExamplesInGrammar conf file = do
|
||||||
|
src <- readFile file -- .gfe
|
||||||
|
let file' = take (length file - 3) file ++ "gf" -- .gf
|
||||||
|
convertFile conf src file'
|
||||||
|
return file'
|
||||||
|
|
||||||
|
convertFile :: ExConfiguration -> String -> FilePath -> IO ()
|
||||||
|
convertFile conf src file = do
|
||||||
|
writeFile file "" -- "-- created by example-based grammar writing in GF\n"
|
||||||
|
conv src
|
||||||
|
where
|
||||||
|
conv s = do
|
||||||
|
(cex,end) <- findExample s
|
||||||
|
if null end then return () else do
|
||||||
|
convEx cex
|
||||||
|
conv end
|
||||||
|
findExample s = case s of
|
||||||
|
'%':'e':'x':cs -> return $ getExample cs
|
||||||
|
c:cs -> appf [c] >> findExample cs
|
||||||
|
_ -> return (undefined,s)
|
||||||
|
getExample s =
|
||||||
|
let
|
||||||
|
(cat,exend) = break (=='"') s
|
||||||
|
(ex, end) = break (=='"') (tail exend)
|
||||||
|
in ((unwords (words cat),ex), tail end) -- quotes ignored
|
||||||
|
pgf = resource_pgf conf
|
||||||
|
lang = language conf
|
||||||
|
convEx (cat,ex) = do
|
||||||
|
appn "("
|
||||||
|
let typ = maybe (error "no valid cat") id $ readType cat
|
||||||
|
let ts = rank $ parse pgf lang typ ex
|
||||||
|
case ts of
|
||||||
|
[] -> appv ("WARNING: cannot parse example " ++ ex)
|
||||||
|
t:tt -> appn t >> mapM_ (appn . (" --- " ++)) tt
|
||||||
|
appn ")"
|
||||||
|
rank ts = case probs conf of
|
||||||
|
Just probs -> [showExpr [] t ++ " -- " ++ show p | (t,p) <- rankTreesByProbs probs ts]
|
||||||
|
_ -> map (showExpr []) ts
|
||||||
|
appf = appendFile file
|
||||||
|
appn s = appf s >> appf "\n"
|
||||||
|
appv s = appn s >> putStrLn s
|
||||||
|
|
||||||
|
data ExConfiguration = ExConf {
|
||||||
|
resource_file :: FilePath,
|
||||||
|
resource_pgf :: PGF,
|
||||||
|
probs :: Maybe Probabilities,
|
||||||
|
verbose :: Bool,
|
||||||
|
language :: Language
|
||||||
|
}
|
||||||
|
|
||||||
|
configureExBased :: PGF -> Maybe Probabilities -> Language -> ExConfiguration
|
||||||
|
configureExBased pgf mprobs lang = ExConf [] pgf mprobs False lang
|
||||||
|
|
||||||
Reference in New Issue
Block a user