packages feed

FM-SBLEX-3.0: src/lib/GeneralIO.hs

----------------------------------------------------------------------
-- |
-- Module      : GeneralIO
-- Maintainer  : Markus Forsberg
-- Stability   : 
-- Portability : 
--
-- Top-level functions: 
-- * reading/writing morphology databases
-- * writing Lexicon, Tables, GF, XFST, Latex 
-- * analysis/synthesis (Trie)
--
-----------------------------------------------------------------------------
module GeneralIO where

import Print
import Dict.GetDict(getEntry)
import DictToDictionary
import General
import Dictionary
import IO
import Command (Comp(..))
import qualified Data.Set as Set
import qualified Data.Map as Map
import Frontend
import List (nub,sort,intersperse)
import Maybe(fromJust)
import Char
import Dict.ErrM
import Util
import Compound
import Monad(when)
import qualified CTrie

type Stem      = String
type Id        = String

analysis :: Language a => a -> Comp -> Maybe CompDesc -> ((String,String) -> [(String,String)]) -> String -> [[String]]
analysis l mc f sandhi s =  post_filter mc $ map (map snd) $ CTrie.decompose f sandhi s
    where f' = if mc == None then Just [[One (word_attr l)]] else f

post_filter Min xs = case sort_length Set.empty xs of
                              ys@(r:_) -> let n = length r in takeWhile (\s -> length s == n) ys
                              _         -> []
post_filter Max xs = case sort_length_rev Set.empty xs of
                       ys@(r:_) -> let n = length r in takeWhile (\s -> length s == n) ys
                       _         -> []
post_filter _           xs = xs -- all, or default



--       post_filter (Length n) xs  = filter (\s -> and (map (fun n) s)) xs
-- [x | x <- xs, and $ map (fun n) x]
--       fun n x = case words x of
--                   (x:_) -> length x >= n
--                   _     -> False

lookupId :: String -> [String]
lookupId s = nub $ [identifier xs | xs <-  map snd (CTrie.trie_lookup False s)]
   where identifier ('\"':'i':'d':'\"':':':'\"':xs) = case span (/='\"') xs of
                                                        (i,_) -> i
         identifier (x:xs) = identifier xs
         identifier []     = []

synthesiser :: Language a => a -> IO String
synthesiser l =  
    do s <- getContents
       return $ unlines $ map f (lines s)
 where f line =
        case(lookupId line) of
	 [] -> "{\"" ++ line ++ "\":\"-Unknown-\"}"
	 xs -> "{\"" ++ line ++ "\":{\n" ++ (concat  
              (concat [format x (reverse (map snd (CTrie.trie_lookup False x))) | x <- xs])) ++ "}\n"
       format :: String -> [String] -> [String]
       format s xs  =  ("\"" ++ s ++ "\":[\n") : (intersperse ",\n" xs) ++ ["\n]\n"]

imode :: Language a => a  -> IO String
imode l =  do s <- getContents
              return $ unlines $ map f (lines s)
  where f s = case getEntry s of
                Bad s -> []
                Ok  e -> 
                    case parseCommand l emptyParadigmErrors e of
		      (Right _) -> []
		      (Left e)  -> unlines  ["[", 
				             (concat (intersperse ",\n" (lines (prJSON (dictionary [e]))))) ++"\n]"]

tester :: (PositiveTests,NegativeTests) -> [TestInput] -> IO ()
tester (pos,neg) rs = 
  do prStd $ "Testbench (" ++ show (length pos) ++ " positive tests, " ++ show (length neg) ++ " negative tests)" 
     case (tester' pos rs [], tester' neg rs []) of
       ([],[]) -> prStd " All tests succeeded!\n"
       (xs,ys) -> do prStd $ (prFailed xs "positive")  ++ "\n" ++ (prFailed ys "negative")
                     prStd "\n"
 where
   prFailed [] s = " All " ++ s ++ " tests succeeded!"
   prFailed xs s = " "  ++ s ++ " tests failed... \n\n" ++ unlines [n ++ ". " ++ r ++ "\n" | (r,n) <- zip xs (map show [1..])] 
   tester' :: [(TestInput -> Maybe String)] -> [TestInput] -> [String] -> [String]
   tester' _    [] xs = xs
   tester' test (s:xs) rs = tester' test xs (test_it test s rs)
   test_it :: [(TestInput -> Maybe String)] -> TestInput -> [String] -> [String]
   test_it [] _     rs = rs
   test_it (f:fs) s rs  = case f s of
                             Nothing       -> test_it fs s rs
                             Just message  -> test_it fs s (message:rs)