1
0
forked from GitHub/gf-rgl
Files
gf-rgl/src/morphodict/saldo/SaldoGF.hs
2020-03-03 18:10:02 +01:00

98 lines
3.1 KiB
Haskell

import Data.List
import qualified Data.Map as M
-- AR 2020-03-03
-- generating GF from preprocessed SALDO (of type Lex by John Camilleri)
main = do
lexicon <- readFile "saldom.hsdump" >>= return . readLex -- this is the preprocessed file
let gf = map (mkRules . treatNone) $ mkFuns lexicon
writeFile "abs.tmp" $ unlines $ map fst gf -- the generated files need headers
writeFile "cnc.tmp" $ unlines $ map snd gf -- use SaldoGF.header for this
-- JC's datatypes, using String for simplicity
type Lex = M.Map String Entry -- key is lemgram ID
type Table = [(String,String)]
data Entry = E
{ ePOS :: String
, eTable :: Table -- morphological tags to surface form: ("sg def gen" ,"killens")
} deriving (Show, Read)
readLex :: String -> [(String,Entry)]
readLex = read . drop 8
-- new code by AR
mkRules (fun,cat,lin) = (nunwords ["fun",fun,":",cat,";"],nunwords ["lin",fun,"=",lin,";"])
where
-- commenting out functions that still have NONE forms
nunwords ws = unwords ((if elem "\"NONE\"" (words lin) then ["--n"] else []) ++ ws)
-- converting incomplete paradigms to special mkC constructors, defined in SaldoSwe.header
treatNone (f,cat,lin) = case (cat,drop 1 (words lin)) of
("V", "\"NONE\"":"\"NONE\"":v:_) -> (f, "V", unwords ("mkVDep":[v]))
("V", i:d:p:a:b:"\"NONE\"":_) -> (f, "V", unwords ("mkVIntr":[i,d,p,a,b]))
("A", i:"\"NONE\"":p:c:s:_) -> (f, "A", unwords ("mkAUtr":[i,p,c,s]))
("A", i:d:p:"\"NONE\"":"\"NONE\"":_) -> (f, "A", unwords ("mkAComp":[i,d,p]))
("N", "\"NONE\"":d:"\"NONE\"":_) -> (f, "PN", unwords ("mkPNDef":[d])) ---
("N", i:"\"NONE\"":"\"NONE\"":_) -> (f, "PN", unwords ("mkPNIndef":[i]))
("N", i:d:"\"NONE\"":"\"NONE\"":_) -> (f, "N", unwords ("mkNSg":[i,d]))
("N", "\"NONE\"":"\"NONE\"":i:d:_) -> (f, "N", unwords ("mkNPl":[i,d]))
_ -> (f,cat,lin)
--- generating function names for simplicity: the result is fed to ../MkMorphoDict anyway
mkFuns lx = [("w"++show i, cat, lin) | (i,(cat,lin)) <- zip [1000000..] (concatMap (entry2lin . snd) lx)]
entry2lin e =
[(cat, mkLin cat ws) | ws <- manyTables valuess]
where
(cat,forms) = formSpec (ePOS e)
valuess = [nub [v | (t,v) <- eTable e, t == f] | f <- forms]
mkLin c ws = unwords $ ["mk"++c] ++ ["\"" ++ w ++ "\"" | w <- ws]
-- looking for the characteristic forms for each POS
formSpec pos = case pos of
"nn" -> ("N",[
"sg indef nom",
"sg def nom",
"pl indef nom",
"pl def nom"
])
"av" -> ("A",[
"pos indef sg u nom",
"pos indef sg n nom",
"pos indef pl nom",
"komp nom",
"super indef nom"
])
"vb" -> ("V",[
"inf aktiv",
"pres ind aktiv",
"imper",
"pret ind aktiv",
"sup aktiv",
"pret_part indef sg u nom"
])
"ab" -> ("Adv",[
"invar"
---- "pos"
])
"pp" -> ("Prep",[
"invar"
])
_ -> ("NONE++pos",["NONE++pos"]) -- ignoring other POS tags, which are rare anyway
-- trying to generate a small number of tables from sets of variant forms; seems to work well enough
manyTables formss = [
map ((!!i) . pad) formss |
i <- [0..maximum (map length formss)-1],
let pad forms = if null forms then repeat "NONE" else forms ++ repeat (head forms)
]