diff options
| author | peb <unknown> | 2005-04-11 12:57:45 +0000 |
|---|---|---|
| committer | peb <unknown> | 2005-04-11 12:57:45 +0000 |
| commit | ac00f77dadd4d447803dd7cab5a36f47365325d0 (patch) | |
| tree | 2fd02b19234f8d1fcc20ee67a2367d4d4eebfcd8 /src/GF/OldParsing/ConvertFiniteSimple.hs | |
| parent | f6273f7033b85eea9a8d0cc7d31e9697ba95d5b7 (diff) | |
"Committed_by_peb"
Diffstat (limited to 'src/GF/OldParsing/ConvertFiniteSimple.hs')
| -rw-r--r-- | src/GF/OldParsing/ConvertFiniteSimple.hs | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/src/GF/OldParsing/ConvertFiniteSimple.hs b/src/GF/OldParsing/ConvertFiniteSimple.hs new file mode 100644 index 000000000..7aac39cb2 --- /dev/null +++ b/src/GF/OldParsing/ConvertFiniteSimple.hs @@ -0,0 +1,121 @@ +---------------------------------------------------------------------- +-- | +-- Maintainer : PL +-- Stability : (stable) +-- Portability : (portable) +-- +-- > CVS $Date: 2005/04/11 13:52:52 $ +-- > CVS $Author: peb $ +-- > CVS $Revision: 1.1 $ +-- +-- 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 Operations +import 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 "" "" "" + + |
