import System.Directory import System.FilePath import Data.List import Data.Char(toLower) import Control.Monad import qualified Data.Map as Map import PGF2 import SusanneFormat import Parser import Idents main = do gr <- readPGF "ParseEngAbs.pgf" let Just eng = Map.lookup "ParseEng" (languages gr) fs <- getDirectoryContents "data" txts <- (mapM (\f -> readFile ("data" f)) . filter ((/= ".") . take 1)) (sort fs) let ts = (map (convert gr eng) . concatMap filterTree) (readTreebank (lines (concat txts))) writeFile "susanne.gft" (unlines (map show ts)) filterTree w@(Word _ tag _ lemma) | elem tag ["YB","YBL","YBR","YF","YIL","YIR","YTL","YTR", "YO"] = [] | otherwise = [w] filterTree (Phrase tag mods fn idx ts) | tag == "O" = ts' | tag == "Q" = ts' | otherwise = [Phrase tag mods fn idx ts'] where ts' = concatMap filterTree ts convert pgf eng t@(Phrase tag mods fn idx ts) | tag == "S" = case runP pS pgf eng ts of Just ([],x) -> x _ -> Phrase tag mods fn idx ts' | tag == "N" = case runP pNP pgf eng ts of Just ([],x) -> x _ -> Phrase tag mods fn idx ts' | tag == "V" = case runP (pV "V") pgf eng [t] of Just ([],(_,_,_,_,x)) -> x _ -> Phrase tag mods fn idx ts' | tag == "P" = case runP pPP pgf eng ts of Just ([],x) -> x _ -> Phrase tag mods fn idx ts' | tag == "Po"= case runP pPP pgf eng ts of Just ([],x) -> x _ -> Phrase tag mods fn idx ts' | otherwise = Phrase tag mods fn idx ts' where ts' = map (convert pgf eng) ts convert pgf eng t@(Word _ tag _ lemma) | take 2 tag == "NN" = case runP pN pgf eng [t] of Just ([],(_,x)) -> x _ -> t | take 1 tag == "J" = case runP pAP pgf eng [t] of Just ([],x) -> x _ -> t | otherwise = t pS = do mplus pConj (return ()) advs <- many pAdS np <- pSubject (t,p,vp) <- pVP return (foldr ($) (cidUseCl t p (cidPredVP np vp)) advs) `mplus` do mplus pConj (return ()) (t,p,vp) <- pVP return (cidImpVP vp) `mplus` do mplus pConj (return ()) advs <- many pAdS t1 <- match convert "EX" (t,p,vp) <- pVP return (foldr ($) (cidUseCl t p (cidExistNP t1 vp)) advs) pSubject = do insideOpt convert "N:s" pNP `mplus` do insideOpt convert "N:S" pNP `mplus` do match convert "M:s" `mplus` do match convert "M:S" `mplus` do insideOpt convert "Ds:s" $ do det <- pDet return (cidDetNP (det cidNumSg)) `mplus` do insideOpt convert "Dp:s" $ do det <- pDet return (cidDetNP (det cidNumPl)) `mplus` do insideOpt convert "Ds:S" $ do det <- pDet return (cidDetNP (det cidNumSg)) `mplus` do insideOpt convert "Dp:S" $ do det <- pDet return (cidDetNP (det cidNumPl)) pConj = do match convert "CC" return () `mplus` do match convert "CCB" return () pAdS = do adv <- pVPMods match convert "YC" return (\t -> cidExtAdvS adv t) `mplus` do adv <- pVPMods return (\t -> cidAdvS adv t) pVP = do adVs <- many pAdV (t,p,voice,apect,vs) <- pV "VS" advs <- many pVPMods s <- insideOpt convert "F:o" (opt (match convert "CST") >> pS) return (t,p,foldr (\adv t -> cidAdVVP adv t) (foldl (\t adv -> cidAdvVP t adv) (cidComplVS vs s) advs) adVs) `mplus` do adVs <- many pAdV (t,p,voice,apect,vv) <- pV "VV" advs <- many pVPMods (p2,voice,aspect,vp) <- inside "Ti" $ do match convert "s" pVPInf return (t,p,foldr (\adv t -> cidAdVVP adv t) (foldl (\t adv -> cidAdvVP t adv) (cidComplVV vv cidASimul p2 vp) advs) adVs) `mplus` do adVs <- many pAdV (t,p,voice,apect,v2) <- pV "V2" o <- pObject opt (match convert "YC") -- what is this? advs <- many pVPMods return (t,p,foldr (\adv t -> cidAdVVP adv t) (foldl (\t adv -> cidAdvVP t adv) (cidComplSlash (cidSlashV2a v2) o) advs) adVs) `mplus` do adVs <- many pAdV (t,p,voice,apect,v) <- pV "V" advs <- many pVPMods return (t,p,foldr (\adv t -> cidAdVVP adv t) (foldl (\t adv -> cidAdvVP t adv) (cidUseV v) advs) adVs) `mplus` do inside "V" (match convert "VBZ") adVs <- many pAdV p <- pPol comp <- pComp advs <- many pVPMods return (cidTTAnt cidTPres cidASimul,p,foldr (\adv t -> cidAdVVP adv t) (foldl (\t adv -> cidAdvVP t adv) (cidUseComp comp) advs) adVs) pComp = do adv <- insideOpt convert "R:e" pAdv return (cidCompAdv adv) `mplus` do np <- insideOpt convert "N:e" pNP return (cidCompNP np) `mplus` do ap <- pAP return (cidCompAP ap) pAdv = do lemma "RP" "Adv" "s" data Voice = Active | Passive data Aspect = Simple | Progressive pV cat = do inside "V" $ do v <- pVPres cat return (cidTTAnt cidTPres cidASimul,cidPPos,Active,Simple,v) `mplus` do v <- do lemma "VVZi" cat "s VPres" `mplus` do lemma "VVZt" cat "s VPres" `mplus` do lemma "VVZv" cat "s VPres" return (cidTTAnt cidTPres cidASimul,cidPPos,Active,Simple,v) `mplus` do v <- do lemma "VVDi" cat "s VPast" `mplus` do lemma "VVDt" cat "s VPast" `mplus` do lemma "VVDv" cat "s VPast" return (cidTTAnt cidTPast cidASimul,cidPPos,Active,Simple,v) `mplus` do (match convert "VBM" `mplus` match convert "VBR" `mplus` match convert "VBZ") -- am,are,is pol <- pPol (voice,aspect,v) <- pVPart cat return (cidTTAnt cidTPres cidASimul,pol,voice,aspect,v) `mplus` do (match convert "VBDZ" `mplus` match convert "VBDR") -- was,were pol <- pPol (voice,aspect,v) <- pVPart cat return (cidTTAnt cidTPast cidASimul,pol,voice,aspect,v) `mplus` do match convert "VH0" -- have pol <- pPol (voice,aspect,v) <- do v <- pVPastPart cat return (Active,Simple,v) `mplus` do match convert "VBN" -- been pVPart cat return (cidTTAnt cidTPres cidAAnter,pol,voice,aspect,v) `mplus` do match convert "VH0" -- have return (cidTTAnt cidTPres cidAAnter,cidPPos,Active,Simple,cidhave_V2) `mplus` do match convert "VHZ" -- has pol <- pPol (voice,aspect,v) <- do v <- pVPastPart cat return (Active,Simple,v) `mplus` do match convert "VBN" -- been pVPart cat return (cidTTAnt cidTPres cidAAnter,pol,voice,aspect,v) `mplus` do match convert "VHZ" -- has return (cidTTAnt cidTPres cidAAnter,cidPPos,Active,Simple,cidhave_V2) `mplus` do match convert "VHD" -- had pol <- pPol (voice,aspect,v) <- do v <- pVPastPart cat return (Active,Simple,v) `mplus` do match convert "VBN" -- been pVPart cat return (cidTTAnt cidTPast cidAAnter,pol,voice,aspect,v) `mplus` do match convert "VHD" -- had return (cidTTAnt cidTPast cidASimul,cidPPos,Active,Simple,cidhave_V2) `mplus` do w <- word "VMo" -- will guard (w == "will") pol <- pPol (voice,apect,vp) <- pVInf cat return (cidTTAnt cidTFut cidASimul,pol,voice,apect,vp) `mplus` do mplus (match convert "VD0") (match convert "VDZ") -- do,does match convert "XX" vp <- pVPres cat return (cidTTAnt cidTPres cidASimul,cidPNeg,Active,Simple,vp) `mplus` do match convert "VDD" -- did match convert "XX" vp <- pVPres cat return (cidTTAnt cidTPast cidASimul,cidPNeg,Active,Simple,vp) pVPInf = do adVs <- many pAdV (pol,voice,apect,vp) <- do (pol,voice,apect,v2) <- inside "Vi" $ do pol <- pPol match convert "TO" (voice,aspect,v) <- pVInf "V2" return (pol,voice,aspect,v) o <- pObject return (pol,voice,apect,cidComplSlash (cidSlashV2a v2) o) `mplus` do (pol,voice,apect,v2a) <- inside "Vi" $ do pol <- pPol match convert "TO" (voice,aspect,v) <- pVInf "V2A" return (pol,voice,aspect,v) o <- pObject ap <- pAP return (pol,voice,apect,cidComplSlash (cidSlashV2A v2a ap) o) advs <- many pVPMods return (pol,voice,apect, foldr (\adv t -> cidAdVVP adv t) (foldl (\t adv -> cidAdvVP t adv) vp advs) adVs) pVInf cat = do v <- pVPres cat return (Active,Simple,v) `mplus` do match convert "VB0" -- be pVPart cat `mplus` do v <- match convert "VH0" -- have return (Active,Simple,v) pVPart cat = do v <- do lemma "VVGi" cat "s VPresPart" `mplus` do lemma "VVGt" cat "s VPresPart" `mplus` do lemma "VVGv" cat "s VPresPart" return (Active,Progressive,v) `mplus` do v <- pVPastPart cat return (Passive,Simple,v) pVPres cat = do lemma "VV0i" cat "s VInf" `mplus` do lemma "VV0t" cat "s VInf" `mplus` do lemma "VV0v" cat "s VInf" pVPastPart cat = do lemma "VVNi" cat "s VPPart" `mplus` do lemma "VVNt" cat "s VPPart" `mplus` do lemma "VVNv" cat "s VPPart" pPol = do match convert "XX" return cidPNeg `mplus` do return cidPPos pAdV = do insideOpt convert "R:c" $ lemma "RRR" "AdV" "s" `mplus` do insideOpt convert "R:m" $ lemma "RRR" "AdV" "s" pObject = match convert "P:u" `mplus` insideOpt convert "N:o" pNP `mplus` match convert "N:e" `mplus` match convert "M:e" `mplus` do insideOpt convert "Ds:e" $ do det <- pDet return (cidDetNP (det cidNumSg)) `mplus` do insideOpt convert "Dp:e" $ do det <- pDet return (cidDetNP (det cidNumPl)) `mplus` do insideOpt convert "P:e" $ pPP pVPMods = do insideOpt convert "N:t" pTimeNPAdv `mplus` do match convert "N:h" `mplus` do insideOpt convert "P:p" $ pPP `mplus` do insideOpt convert "P:q" $ pPP `mplus` do insideOpt convert "Pb:a" $ do match convert "IIb" np <- insideOpt convert "N" pNP return (cidPrepNP cidby_Prep np) `mplus` do insideOpt convert "P:t" $ pPP `mplus` do insideOpt convert "P:h" $ pPP `mplus` do insideOpt convert "P:m" $ pPP `mplus` do insideOpt convert "P:r" $ pPP `mplus` do insideOpt convert "R:p" $ pAdv `mplus` do insideOpt convert "R:q" $ pAdv `mplus` do insideOpt convert "R:a" $ pAdv `mplus` do insideOpt convert "R:t" $ pAdv `mplus` do insideOpt convert "R:h" $ pAdv `mplus` do insideOpt convert "R:m" $ pAdv `mplus` do insideOpt convert "R:c" $ pAdv `mplus` do insideOpt convert "R:r" $ pAdv `mplus` do match convert "F:p" `mplus` do match convert "F:q" `mplus` do match convert "F:a" `mplus` do match convert "F:t" `mplus` do match convert "F:h" `mplus` do match convert "F:m" `mplus` do match convert "F:r" `mplus` do match convert "W:b" `mplus` do match convert "L:b" pPP = do prep <- do lemma "ICS" "Prep" "s" `mplus` do lemma "ICSk" "Prep" "s" `mplus` do lemma "ICSt" "Prep" "s" `mplus` do lemma "ICSx" "Prep" "s" `mplus` do lemma "IF" "Prep" "s" `mplus` do lemma "II" "Prep" "s" `mplus` do lemma "IIa" "Prep" "s" `mplus` do lemma "IIb" "Prep" "s" `mplus` do lemma "IIg" "Prep" "s" `mplus` do lemma "IIp" "Prep" "s" `mplus` do lemma "IIt" "Prep" "s" `mplus` do lemma "IO" "Prep" "s" `mplus` do lemma "IW" "Prep" "s" `mplus` do insideOpt convert "II=" $ do w1 <- word "II21" w2 <- word "II22" lookupForm "Prep" "s" (unwords [w1,w2]) np <- do insideOpt convert "N" pNP `mplus` do (mb_num,n) <- pN case mb_num of Just num | num == cidNumPl -> return (cidDetCN (cidDetQuant cidIndefArt num) (cidUseN n)) _ -> return (cidMassNP (cidUseN n)) -- we don't know the number return (cidPrepNP prep np) pNP = do np <- pBaseNP match convert "YC" fr <- insideOpt convert "Fr" pRCl return (cidRelNP np fr) `mplus` do pBaseNP pBaseNP = do det <- pDet (mb_num,cn) <- pCN case mb_num of Just num -> return (cidDetCN (det num) cn) Nothing -> mzero -- we don't know the number `mplus` do pn <- pName return (cidUsePN pn) `mplus` do (mb_num,cn) <- pCN case mb_num of Just num | num == cidNumPl -> return (cidDetCN (cidDetQuant cidIndefArt num) cn) _ -> return (cidMassNP cn) -- we don't know the number `mplus` do match convert "PPIS1" return (cidUsePron cidi_Pron) `mplus` do match convert "PPY" return (cidUsePron cidyouSg_Pron) `mplus` do match convert "PPHS1m" return (cidUsePron cidhe_Pron) `mplus` do match convert "PPHS1f" return (cidUsePron cidshe_Pron) `mplus` do match convert "PPH1" return (cidUsePron cidit_Pron) `mplus` do match convert "PPIS2" return (cidUsePron cidwe_Pron) `mplus` do match convert "PPHS2" return (cidUsePron cidthey_Pron) `mplus` do match convert "Nn" pDet = do match convert "DDy" return (\num -> if num == cidNumSg then cidanySg_Det else cidanyPl_Det) `mplus` do det <- lemma "DA2" "Det" "s" return (\num -> det) `mplus` do q <- pQuant ord <- pOrd return (\num -> cidDetQuantOrd q num ord) `mplus` do q <- pQuant return (\num -> cidDetQuant q num) pQuant = do match convert "AT" return cidDefArt `mplus` do match convert "AT1" return cidIndefArt `mplus` do match convert "ATn" return cidno_Quant `mplus` do match convert "APPGi1" return (cidPossPron cidi_Pron) `mplus` do match convert "APPGy" return (cidPossPron cidyouSg_Pron) `mplus` do match convert "APPGm" return (cidPossPron cidhe_Pron) `mplus` do match convert "APPGf" return (cidPossPron cidshe_Pron) `mplus` do match convert "APPGh1" return (cidPossPron cidit_Pron) `mplus` do match convert "APPGi2" return (cidPossPron cidwe_Pron) `mplus` do match convert "APPGh2" return (cidPossPron cidthey_Pron) `mplus` do lemma "DD1a" "Quant" "s True Sg" `mplus` do lemma "DD1i" "Quant" "s True Sg" `mplus` do lemma "DD2a" "Quant" "s True Pl" `mplus` do lemma "DD2i" "Quant" "s True Pl" `mplus` do lemma "DDi" "Quant" "s True Pl" `mplus` insideOpt convert "G" pGenitive pOrd = do a <- lemma "JJT" "A" "s (AAdj Superl Nom)" return (cidOrdSuperl a) pGenitive = do np <- insideOpt convert "N" pNP match convert "GG" return (cidGenNP np) pCN = do pn <- mplus pName (insideOpt convert "Nn" pName) (mb_num,cn) <- pCN return (mb_num,cidNameCN pn cn) `mplus` do (mb_num_n,n) <- mplus pN (inside "N" pCN) (mb_num,cn) <- pCN case mb_num_n of Just num | num == cidNumPl -> return (mb_num,cidCompoundPlCN (cidUseN n) cn) _ -> return (mb_num,cidCompoundSgCN (cidUseN n) cn) -- here we don't really know the number `mplus` do ap <- pAP (mb_num,cn) <- pCN return (mb_num,cidAdjCN ap cn) `mplus` do t <- match convert "NN1u&" mods <- many pCNMods return (Just cidNumSg ,foldl (\t mod -> mod t) t mods) `mplus` do (mb_num,n) <- pN mods <- many pCNMods return (mb_num, foldl (\t mod -> mod t) (cidUseN n) mods) pAP = do a <- lemma "JJ" "A" "s (AAdj Posit Nom)" `mplus` lemma "JA" "A" "s (AAdj Posit Nom)" `mplus` lemma "JB" "A" "s (AAdj Posit Nom)" `mplus` lemma "JBo" "A" "s (AAdj Posit Nom)" `mplus` lemma "DAy" "A" "s (AAdj Posit Nom)" `mplus` lemma "DAz" "A" "s (AAdj Posit Nom)" return (cidPositA a) `mplus` do a <- lemma "JJR" "A" "s (AAdj Compar Nom)" return (cidUseComparA a) `mplus` do vp <- match convert "Tn" return (cidPastPartAP vp) `mplus` do insideOpt convert "J" $ do adas <- many pAdA ap <- pAP mods <- many pAPMods return (foldl (\t ada -> cidAdAP ada t) (foldl (\t mod -> cidAdvAP t mod) ap mods) adas) pAdA = do a <- lemma "RR" "A" "s AAdv" return (cidPositAdAAdj a) pAPMods = do insideOpt convert "P" pPP pN = do n <- lemma "NNn" "N" "s Sg Nom" return (Nothing, n) `mplus` do n <- lemma "NNu" "N" "s Sg Nom" return (Just cidNumPl, n) `mplus` do n <- lemma "NNux" "N" "s Sg Nom" return (Nothing, n) `mplus` do n <- lemma "NN1c" "N" "s Sg Nom" return (Just cidNumSg, n) `mplus` do n <- lemma "NN1m" "N" "s Sg Nom" return (Just cidNumSg, n) `mplus` do n <- lemma "NN1n" "N" "s Sg Nom" return (Just cidNumSg, n) `mplus` do n <- lemma "NN1u" "N" "s Sg Nom" return (Just cidNumSg, n) `mplus` do n <- lemma "NN1ux" "N" "s Sg Nom" return (Just cidNumSg, n) `mplus` do n <- lemma "NN2" "N" "s Pl Nom" return (Just cidNumPl, n) `mplus` do n <- lemma "NNJ1c" "N" "s Sg Nom" return (Just cidNumSg, n) `mplus` do n <- lemma "NNJ1n" "N" "s Sg Nom" return (Just cidNumSg, n) `mplus` do n <- lemma "NNJ2" "N" "s Pl Nom" return (Just cidNumPl, n) `mplus` do n <- lemma "NNLc" "N" "s Sg Nom" return (Nothing, n) `mplus` do n <- lemma "NNL1c" "N" "s Sg Nom" return (Just cidNumSg, n) `mplus` do n <- lemma "NNL1cb" "N" "s Sg Nom" return (Just cidNumSg, n) `mplus` do n <- lemma "NNL1n" "N" "s Sg Nom" return (Just cidNumSg, n) `mplus` do n <- lemma "NNL2" "N" "s Pl Nom" return (Just cidNumPl, n) `mplus` do n <- lemma "NNS1c" "N" "s Sg Nom" return (Just cidNumSg, n) `mplus` do n <- lemma "NNS1n" "N" "s Sg Nom" return (Just cidNumSg, n) `mplus` do n <- lemma "NNS2" "N" "s Pl Nom" return (Just cidNumPl, n) `mplus` do n <- lemma "NNT1h" "N" "s Sg Nom" return (Just cidNumSg, n) `mplus` do n <- lemma "NNT1m" "N" "s Sg Nom" return (Just cidNumSg, n) `mplus` do n <- lemma "NNT1c" "N" "s Sg Nom" return (Just cidNumSg, n) `mplus` do n <- lemma "NNT2" "N" "s Pl Nom" return (Just cidNumPl, n) `mplus` do n <- lemma "NNUc" "N" "s Sg Nom" return (Nothing, n) `mplus` do n <- lemma "NNUn" "N" "s Sg Nom" return (Nothing, n) `mplus` do n <- lemma "NNU1c" "N" "s Sg Nom" return (Just cidNumSg, n) `mplus` do n <- lemma "NNU1n" "N" "s Sg Nom" return (Just cidNumSg, n) `mplus` do n <- lemma "NNU2" "N" "s Pl Nom" return (Just cidNumPl, n) `mplus` do inside "Ns" $ do (mb_num1,n1) <- pN match convert "YH" (mb_num2,n2) <- pN case mb_num1 of Just num | num == cidNumPl -> return (mb_num2,cidDashPlN n1 n2) _ -> return (mb_num2,cidDashSgN n1 n2) -- here we don't really know the number pCNMods = do adv <- insideOpt convert "Po" $ pPP return (\t -> cidAdvCN t adv) `mplus` do adv <- insideOpt convert "P" $ pPP return (\t -> cidAdvCN t adv) `mplus` do adv <- insideOpt convert "Fn" $ do match convert "CST" s <- pS return (cidSubjS cidthat_Subj s) return (\t -> cidAdvCN t adv) `mplus` do fr <- insideOpt convert "Fr" pRCl return (\t -> cidRelCN t fr) pName = do w1 <- word "NP1s" w2 <- word "NNL1cb" return (cidSymbPN (cidMkSymb (Lit (unwords [w1,w2])))) `mplus` do w1 <- word "NPM1" match convert "YH" w2 <- word "NPM1" return (cidSymbPN (cidMkSymb (Lit (unwords [w1,"-",w2])))) `mplus` do w1 <- msum [word "NP1c", word "NP1f", word "NP1g" ,word "NP1j", word "NP1m", word "NP1p" ,word "NP1s", word "NP1t", word "NP1x" ,word "NP1z", word "NP2c", word "NP2f" ,word "NP2g", word "NP2j", word "NP2m" ,word "NP2p", word "NP2s", word "NP2t" ,word "NP2x", word "NP2z"] return (cidSymbPN (cidMkSymb (Lit w1))) pRCl = do rp <- pRP (t,p,vp) <- pVP opt (match convert "YC") return (cidUseRCl t p (cidRelVP rp vp)) `mplus` do (prep,rp) <- inside "Pq" $ do prep <- lemma "II" "Prep" "s" rp <- pRP return (prep,rp) np <- pSubject (t,p,vp) <- pVP opt (match convert "YC") return (cidUseRCl t p (cidRelSlash rp (cidSlashVP np (cidVPSlashPrep vp prep)))) pRP = do inside "Dq" (match convert "DDQr") return cidIdRP pTimeNPAdv = do day <- lemma "NPD1" "Weekday" "s Sg Nom" return (cidweekdayPunctualAdv day)