diff options
| author | kr.angelov <kr.angelov@gmail.com> | 2012-10-01 08:33:43 +0000 |
|---|---|---|
| committer | kr.angelov <kr.angelov@gmail.com> | 2012-10-01 08:33:43 +0000 |
| commit | 6daeecb6d9278528266b42e324b136689624914b (patch) | |
| tree | 583ead4ee116351d95e82135af2f360ae369f56b /treebanks/talbanken/MonadSP.hs | |
| parent | 00490c07dd13c2efeff44fb88c7d8255e8e5a05a (diff) | |
added the GF version of Talbanken which was imported by Malin
Diffstat (limited to 'treebanks/talbanken/MonadSP.hs')
| -rw-r--r-- | treebanks/talbanken/MonadSP.hs | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/treebanks/talbanken/MonadSP.hs b/treebanks/talbanken/MonadSP.hs new file mode 100644 index 000000000..ceddddfe5 --- /dev/null +++ b/treebanks/talbanken/MonadSP.hs @@ -0,0 +1,193 @@ +{-# LANGUAGE FlexibleInstances, + MultiParamTypeClasses, + ScopedTypeVariables, + FlexibleContexts, + UndecidableInstances #-} +module MonadSP ( Rule(..), Grammar, grammar + , P, parse + , cat, word, word2, lemma, inside, insideSuff, transform + , many, many1, opt + , optEat, consume, wordlookup,write + ) where +import Data.Tree +import Data.Char +import Data.List +import qualified Data.Map as Map +import Control.Monad +import Control.Monad.State +import Control.Monad.Writer +import PGF hiding (Tree,parse) + + +infix 1 :-> + + +data Rule m t e = t :-> P t e m e +type Grammar m t e = t -> PGF -> Morpho -> [Tree t] -> m e + +instance Show t => Show (Rule m t e) where + show (t :-> x) = show t + + +grammar :: (MonadWriter [String] m,MonadState s m,Ord t,Show t,Show e) + => ([e] -> e) -> [Rule m t e] -> Grammar m t e +grammar def rules = gr + where + gr = \tag -> do + + let retry = \pgf m ts -> case ts of + [Node w []] -> return (def []) + trs -> def `liftM` sequence [ gr tag pgf m trs' + | Node tag trs' <- trs] + + case Map.lookup tag pmap of + Just f -> \pgf m ts -> do + stored <- get + r <- unP f gr pgf m ts + case r of + Just (e,[]) -> return e + Just (e,xs) -> tell ["Rest parse"] >> retry pgf m ts -- use xs here? + Nothing -> put stored >> retry pgf m ts + Nothing -> retry + + -- If many rules match, try all of them (mplus) + pmap = Map.fromListWith mplus (map (\(t :-> r) -> (t,r)) rules) + +newtype P t e m a = P {unP :: Grammar m t e -> PGF -> Morpho -> [Tree t] -> m (Maybe (a,[Tree t]))} + +instance Monad m => Monad (P t e m) where + return x = P $ \gr pgf m ts -> return (Just (x,ts)) + f >>= g = P $ \gr pgf m ts -> unP f gr pgf m ts >>= \r -> case r of + Just (x,ts') -> unP (g x) gr pgf m ts' + Nothing -> return Nothing + +instance MonadState s m => MonadPlus (P t e m) where + mzero = P $ \gr pgf m ts -> return Nothing + mplus f g = P $ \gr pgf m ts -> do + store <- get + res <- unP f gr pgf m ts + case res of + Just x -> return (Just x) + Nothing -> put store >> unP g gr pgf m ts + +instance MonadState s m => MonadState s (P t e m) where + put s = P $ \gr pgf m ts -> put s >> return (Just ((),ts)) + get = P $ \gr pgf m ts -> get >>= \s -> return (Just (s,ts)) + +instance MonadWriter w m => MonadWriter w (P t e m) where + tell w = P $ \gr pgf m ts -> tell w >> return (Just ((),ts)) + listen = error "listen not implemented for P" + pass = error "pass not implemented for P" + +-- write x = tell [x] +write :: MonadWriter [w] m => w -> P t e m () +write = tell . return + +instance MonadTrans (P t e) where + lift m = P $ \gr p morpho ts -> m >>= \r -> return (Just (r,ts)) + +parse :: Monad m => Grammar m t e -> PGF -> Morpho -> Tree t -> m e +parse gr pgf morpho (Node tag ts) = gr tag pgf morpho ts + +silent m = (m,[]) +speak s (m,w) = (m,s:w) +speaks s (m,w) = (m,s++w) +addS s m = (m,s) +add s m = (m,[s]) + + +cat :: (Monad m,Eq t,Show t) => [t] -> P [t] e m e +cat tag = P $ \gr pgf morpho ts -> + case ts of + Node tag1 ts1 : ts | tag `isPrefixOf` tag1 + -> gr tag1 pgf morpho ts1 >>= \r -> return (Just (r,ts)) + _ -> return Nothing + +word :: (Monad m,Show t,Eq t) => [t] -> P [t] e m [t] +word tag = P $ \gr pgf morpho ts -> return $ + case ts of + (Node tag1 [Node w []] : ts) | tag `isPrefixOf` tag1 + -> Just (w,ts) + _ -> Nothing + + +word2 :: (Monad m,Eq t) => t -> P t e m t +word2 tag = P $ \gr pgf morpho ts -> return $ + case ts of + (Node tag1 [Node tag2 [Node w []]] : ts) | tag == tag1 -> Just (w,ts) + _ -> Nothing + + +inside, insideSuff :: (MonadWriter [String] m,Eq t,Show t)=> [t] -> P [t] e m a -> P [t] e m a +insideSuff = inside' isSuffixOf +inside = inside' isPrefixOf + +inside' :: (MonadWriter [String] m,Eq t,Show t)=> + ([t] -> [t] -> Bool) -> [t] -> P [t] e m a -> P [t] e m a +inside' isEq tag f = P $ \gr pgf morpho ts -> + case ts of + Node tag1 ts1 : ts | tag `isEq` tag1 -> do + tell [show tag++" "++show tag1] + unP f gr pgf morpho ts1 >>= \r -> case r of + Just (x,[]) -> return (Just (x,ts)) + Just (x,xs) -> tell ["inside fail "++show xs] >> return Nothing + Nothing -> return Nothing + _ -> return Nothing + + +magicLookup :: String -> String -> String -> Morpho -> PGF -> [Lemma] +magicLookup w cat0 an0 morpho pgf = [ lem + | (lem, an1) <- lookupMorpho morpho (map toLower w) + , let cat1 = maybe "" (showType []) (functionType pgf lem) + , cat0 == cat1 && an0 == an1 + ] + +wordlookup :: MonadWriter [String] m => String -> String -> String -> P String e m CId +wordlookup w cat0 an0 = P $ \gr pgf morpho ts -> do + tell ["wordlookup: " ++ w ++ show ts ++ show cat0] + let wds = magicLookup w cat0 an0 morpho pgf + tell [show wds] + case wds of + (wd:_) -> return $ Just (wd,ts) + [] -> return Nothing + + +lemma :: MonadWriter [String] m => String -> String -> P String e m CId +lemma cat = liftM head . lemmas cat + +lemmas :: MonadWriter [String] m => String -> String -> P String e m [CId] +lemmas cat0 an0 = P $ \gr pgf morpho ts -> do + tell ["lemma: "++show ts++show cat0] + case ts of + Node w [] : ts -> case magicLookup w cat0 an0 morpho pgf of + (id:ids) -> tell ["lemma ok"] >> return (Just (id:ids,ts)) + _ -> tell ["no word "++w++cat0++an0] >> return Nothing + _ -> tell ["tried to lemma a tag"] >> return Nothing + + +transform :: Monad m => ([Tree t] -> [Tree t]) -> P t e m () +transform f = P $ \gr pgf morpho ts -> return (Just ((),f ts)) + +many :: MonadState s m => P t e m a -> P t e m [a] +many f = many1 f + `mplus` + return [] + +many1 :: MonadState s m => P t e m a -> P t e m [a] +many1 f = do x <- f + xs <- many f + return (x:xs) + +opt :: MonadState s m => P t e m a -> a -> P t e m a +opt f x = mplus f (return x) + +optEat :: MonadState s m => P t e m a -> a -> P t e m a +optEat f x = mplus f (consume >> return x) + + +consume :: Monad m => P t e m () +consume = P $ \gr pgf morpho ts -> + case ts of + Node x w:ws -> return (Just ((),ws)) + [] -> return (Just ((),[])) + |
