summaryrefslogtreecommitdiff
path: root/src-3.0/GF/OldParsing/ConvertFiniteSimple.hs
diff options
context:
space:
mode:
authoraarne <aarne@cs.chalmers.se>2008-05-21 09:26:44 +0000
committeraarne <aarne@cs.chalmers.se>2008-05-21 09:26:44 +0000
commit055c0d0d5a5bb0dc75904fe53df7f2e4f5732a8f (patch)
tree0e63fb68c69c8f6ad0f78893c63420f0a3600e1c /src-3.0/GF/OldParsing/ConvertFiniteSimple.hs
parent915a1de71783ab8446b1af9e72c7ba7dfbc12d3f (diff)
GF/src is now for 2.9, and the new sources are in src-3.0 - keep it this way until the release of GF 3
Diffstat (limited to 'src-3.0/GF/OldParsing/ConvertFiniteSimple.hs')
-rw-r--r--src-3.0/GF/OldParsing/ConvertFiniteSimple.hs121
1 files changed, 121 insertions, 0 deletions
diff --git a/src-3.0/GF/OldParsing/ConvertFiniteSimple.hs b/src-3.0/GF/OldParsing/ConvertFiniteSimple.hs
new file mode 100644
index 000000000..a05092550
--- /dev/null
+++ b/src-3.0/GF/OldParsing/ConvertFiniteSimple.hs
@@ -0,0 +1,121 @@
+----------------------------------------------------------------------
+-- |
+-- Maintainer : PL
+-- Stability : (stable)
+-- Portability : (portable)
+--
+-- > CVS $Date: 2005/04/21 16:22:43 $
+-- > CVS $Author: bringert $
+-- > CVS $Revision: 1.2 $
+--
+-- Calculating the finiteness of each type in a grammar
+-----------------------------------------------------------------------------
+
+module GF.OldParsing.ConvertFiniteSimple
+ (convertGrammar) where
+
+import GF.System.Tracing
+import GF.Printing.PrintParser
+import GF.Printing.PrintSimplifiedTerm
+
+import GF.Data.Operations
+import GF.Infra.Ident (Ident(..))
+import GF.OldParsing.SimpleGFC
+import GF.Data.SortedList
+import GF.Data.Assoc
+import GF.Data.BacktrackM
+
+type CnvMonad a = BacktrackM () a
+
+convertGrammar :: Grammar -> Grammar
+convertGrammar rules = solutions cnvMonad ()
+ where split = calcSplitable rules
+ cnvMonad = member rules >>= convertRule split
+
+convertRule :: Splitable -> Rule -> CnvMonad Rule
+convertRule split (Rule name typing term)
+ = do newTyping <- convertTyping split name typing
+ return $ Rule name newTyping term
+
+convertTyping :: Splitable -> Name -> Typing -> CnvMonad Typing
+convertTyping split name (typ, decls)
+ = case splitableFun split name of
+ Just newCat -> return (newCat :@ [], decls)
+ Nothing -> expandTyping split [] typ decls []
+
+
+expandTyping :: Splitable -> [(Var, Cat)] -> Type -> [Decl] -> [Decl] -> CnvMonad Typing
+expandTyping split env (cat :@ atoms) [] decls
+ = return (substAtoms split env cat atoms [], reverse decls)
+expandTyping split env typ ((x ::: (xcat :@ xatoms)) : declsToDo) declsDone
+ = do env' <- calcNewEnv
+ expandTyping split env' typ declsToDo (decl : declsDone)
+ where decl = x ::: substAtoms split env xcat xatoms []
+ calcNewEnv = case splitableCat split xcat of
+ Just newCats -> do newCat <- member newCats
+ return ((x,newCat) : env)
+ Nothing -> return env
+
+substAtoms :: Splitable -> [(Var, Cat)] -> Cat -> [Atom] -> [Atom] -> Type
+substAtoms split env cat [] atoms = cat :@ reverse atoms
+substAtoms split env cat (atom:atomsToDo) atomsDone
+ = case atomLookup split env atom of
+ Just newCat -> substAtoms split env (mergeArg cat newCat) atomsToDo atomsDone
+ Nothing -> substAtoms split env cat atomsToDo (atom : atomsDone)
+
+atomLookup split env (AVar x) = lookup x env
+atomLookup split env (ACon con) = splitableFun split (constr2name con)
+
+
+----------------------------------------------------------------------
+-- splitable categories (finite, no dependencies)
+-- they should also be used as some dependency
+
+type Splitable = (Assoc Cat [Cat], Assoc Name Cat)
+
+splitableCat :: Splitable -> Cat -> Maybe [Cat]
+splitableCat = lookupAssoc . fst
+
+splitableFun :: Splitable -> Name -> Maybe Cat
+splitableFun = lookupAssoc . snd
+
+calcSplitable :: [Rule] -> Splitable
+calcSplitable rules = (listAssoc splitableCats, listAssoc splitableFuns)
+ where splitableCats = tracePrt "splitableCats" (prtSep " ") $
+ groupPairs $ nubsort
+ [ (cat, mergeFun fun cat) | (cat, fun) <- constantCats ]
+
+ splitableFuns = tracePrt "splitableFuns" (prtSep " ") $
+ nubsort
+ [ (fun, mergeFun fun cat) | (cat, fun) <- constantCats ]
+
+ constantCats = tracePrt "constantCats" (prtSep " ") $
+ [ (cat, fun) |
+ Rule fun (cat :@ [], []) _ <- rules,
+ dependentConstants ?= cat ]
+
+ dependentConstants = listSet $
+ tracePrt "dep consts" prt $
+ dependentCats <\\> funCats
+
+ funCats = tracePrt "fun cats" prt $
+ nubsort [ cat | Rule _ (cat :@ _, decls) _ <- rules,
+ not (null decls) ]
+
+ dependentCats = tracePrt "dep cats" prt $
+ nubsort [ cat | Rule _ (cat :@ [], []) _ <- rules ]
+
+
+----------------------------------------------------------------------
+-- utilities
+
+-- mergeing categories
+mergeCats :: String -> String -> String -> Cat -> Cat -> Cat
+mergeCats before middle after (IC cat) (IC arg)
+ = IC (before ++ cat ++ middle ++ arg ++ after)
+
+mergeFun, mergeArg :: Cat -> Cat -> Cat
+mergeFun = mergeCats "{" ":" "}"
+mergeArg = mergeCats "" "" ""
+
+