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

This commit is contained in:
aarne
2008-05-21 09:26:44 +00:00
parent b24ca795ca
commit 2bab9286f1
536 changed files with 0 additions and 0 deletions

182
src-3.0/GF/Canon/AbsGFC.hs Normal file
View File

@@ -0,0 +1,182 @@
module GF.Canon.AbsGFC where
import GF.Infra.Ident --H
-- Haskell module generated by the BNF converter, except --H
-- newtype Ident = Ident String deriving (Eq,Ord,Show) --H
data Canon =
MGr [Ident] Ident [Module]
| Gr [Module]
deriving (Eq,Ord,Show)
data Line =
LMulti [Ident] Ident
| LHeader ModType Extend Open
| LFlag Flag
| LDef Def
| LEnd
deriving (Eq,Ord,Show)
data Module =
Mod ModType Extend Open [Flag] [Def]
deriving (Eq,Ord,Show)
data ModType =
MTAbs Ident
| MTCnc Ident Ident
| MTRes Ident
| MTTrans Ident Ident Ident
deriving (Eq,Ord,Show)
data Extend =
Ext [Ident]
| NoExt
deriving (Eq,Ord,Show)
data Open =
Opens [Ident]
| NoOpens
deriving (Eq,Ord,Show)
data Flag =
Flg Ident Ident
deriving (Eq,Ord,Show)
data Def =
AbsDCat Ident [Decl] [CIdent]
| AbsDFun Ident Exp Exp
| AbsDTrans Ident Exp
| ResDPar Ident [ParDef]
| ResDOper Ident CType Term
| CncDCat Ident CType Term Term
| CncDFun Ident CIdent [ArgVar] Term Term
| AnyDInd Ident Status Ident
deriving (Eq,Ord,Show)
data ParDef =
ParD Ident [CType]
deriving (Eq,Ord,Show)
data Status =
Canon
| NonCan
deriving (Eq,Ord,Show)
data CIdent =
CIQ Ident Ident
deriving (Eq,Ord,Show)
data Exp =
EApp Exp Exp
| EProd Ident Exp Exp
| EAbs Ident Exp
| EAtom Atom
| EData
| EEq [Equation]
deriving (Eq,Ord,Show)
data Sort =
SType
deriving (Eq,Ord,Show)
data Equation =
Equ [APatt] Exp
deriving (Eq,Ord,Show)
data APatt =
APC CIdent [APatt]
| APV Ident
| APS String
| API Integer
| APF Double
| APW
deriving (Eq,Ord,Show)
data Atom =
AC CIdent
| AD CIdent
| AV Ident
| AM Integer
| AS String
| AI Integer
| AF Double
| AT Sort
deriving (Eq,Ord,Show)
data Decl =
Decl Ident Exp
deriving (Eq,Ord,Show)
data CType =
RecType [Labelling]
| Table CType CType
| Cn CIdent
| TStr
| TInts Integer
deriving (Eq,Ord,Show)
data Labelling =
Lbg Label CType
deriving (Eq,Ord,Show)
data Term =
Arg ArgVar
| I CIdent
| Par CIdent [Term]
| LI Ident
| R [Assign]
| P Term Label
| T CType [Case]
| V CType [Term]
| S Term Term
| C Term Term
| FV [Term]
| EInt Integer
| EFloat Double
| K Tokn
| E
deriving (Eq,Ord,Show)
data Tokn =
KS String
| KP [String] [Variant]
| KM String
deriving (Eq,Ord,Show)
data Assign =
Ass Label Term
deriving (Eq,Ord,Show)
data Case =
Cas [Patt] Term
deriving (Eq,Ord,Show)
data Variant =
Var [String] [String]
deriving (Eq,Ord,Show)
data Label =
L Ident
| LV Integer
deriving (Eq,Ord,Show)
data ArgVar =
A Ident Integer
| AB Ident Integer Integer
deriving (Eq,Ord,Show)
data Patt =
PC CIdent [Patt]
| PV Ident
| PW
| PR [PattAssign]
| PI Integer
| PF Double
deriving (Eq,Ord,Show)
data PattAssign =
PAss Label Patt
deriving (Eq,Ord,Show)

View File

@@ -0,0 +1,38 @@
module GF.Canon.AbsToBNF where
import GF.Grammar.SGrammar
import GF.Data.Operations
import GF.Infra.Option
import GF.Canon.GFC (CanonGrammar)
-- AR 10/5/2007
abstract2bnf :: CanonGrammar -> String
abstract2bnf = sgrammar2bnf . gr2sgr noOptions emptyProbs
sgrammar2bnf :: SGrammar -> String
sgrammar2bnf = unlines . map (prBNFRule . mkBNF) . allRules
prBNFRule :: BNFRule -> String
prBNFRule = id
type BNFRule = String
mkBNF :: SRule -> BNFRule
mkBNF (pfun,(args,cat)) =
fun ++ "." +++ gfId cat +++ "::=" +++ rhs +++ ";"
where
fun = gfId (snd pfun)
rhs = case args of
[] -> prQuotedString (snd pfun)
_ -> unwords (map gfId args)
-- good for GF
gfId i = i
-- good for BNFC
gfIdd i = case i of
"Int" -> "Integer"
"String" -> i
"Float" -> "Double"
_ -> "G" ++ i ++ "_"

334
src-3.0/GF/Canon/CMacros.hs Normal file
View File

@@ -0,0 +1,334 @@
----------------------------------------------------------------------
-- |
-- Module : CMacros
-- Maintainer : AR
-- Stability : (stable)
-- Portability : (portable)
--
-- > CVS $Date: 2005/11/14 16:03:41 $
-- > CVS $Author: aarne $
-- > CVS $Revision: 1.29 $
--
-- Macros for building and analysing terms in GFC concrete syntax.
--
-- macros for concrete syntax in GFC that do not need lookup in a grammar
-----------------------------------------------------------------------------
module GF.Canon.CMacros where
import GF.Infra.Ident
import GF.Canon.AbsGFC
import GF.Canon.GFC
import qualified GF.Infra.Ident as A ---- no need to qualif? 21/9
import qualified GF.Grammar.Values as V
import qualified GF.Grammar.MMacros as M
import GF.Grammar.PrGrammar
import GF.Data.Str
import GF.Data.Operations
import Data.Char
import Control.Monad
-- | how to mark subtrees, dep. on node, position, whether focus
type JustMarker = V.TrNode -> [Int] -> Bool -> (String, String)
-- | also to process the text (needed for escapes e.g. in XML)
type Marker = (JustMarker, Maybe (String -> String))
defTMarker :: JustMarker -> Marker
defTMarker = flip (curry id) Nothing
markSubtree :: Marker -> V.TrNode -> [Int] -> Bool -> Term -> Term
markSubtree (mk,esc) n is = markSubterm esc . mk n is
escapeMkString :: Marker -> Maybe (String -> String)
escapeMkString = snd
-- | if no marking is wanted, use the following
noMark :: Marker
noMark = defTMarker mk where
mk _ _ _ = ("","")
-- | mark metas with their categories
metaCatMark :: Marker
metaCatMark = defTMarker mk where
mk nod _ _ = case nod of
V.N (_,V.AtM _,val,_,_) -> ("", '+':prt val)
_ -> ("","")
-- | for vanilla brackets, focus, and position, use
markBracket :: Marker
markBracket = defTMarker mk where
mk n p b = if b then ("[*" ++ show p,"*]") else ("[" ++ show p,"]")
-- | for focus only
markFocus :: Marker
markFocus = defTMarker mk where
mk n p b = if b then ("[*","*]") else ("","")
-- | for XML, use
markJustXML :: JustMarker
markJustXML n i b =
if b
then ("<focus" +++ p +++ c ++ s ++ ">", "</focus>")
else ("<subtree" +++ p +++ c ++ s ++ ">", "</subtree>")
where
c = "type=" ++ prt (M.valNode n)
p = "position=" ++ (show $ reverse i)
s = if (null (M.constrsNode n)) then "" else " status=incorrect"
markXML :: Marker
markXML = (markJustXML, Just esc) where
esc s = case s of
'\\':'<':cs -> '\\':'<':esc cs
'\\':'>':cs -> '\\':'>':esc cs
'\\':'\\':cs -> '\\':'\\':esc cs
----- the first 3 needed because marking may revisit; needs to be fixed
'<':cs -> '\\':'<':esc cs
'>':cs -> '\\':'>':esc cs
'\\':cs -> '\\':'\\':esc cs
c :cs -> c :esc cs
_ -> s
-- | for XML in JGF 1, use
markXMLjgf :: Marker
markXMLjgf = defTMarker mk where
mk n p b =
if b
then ("<focus" +++ c ++ ">", "</focus>")
else ("","")
where
c = "type=" ++ prt (M.valNode n)
-- | the marking engine
markSubterm :: Maybe (String -> String) -> (String,String) -> Term -> Term
markSubterm esc (beg, end) t = case t of
R rs -> R $ map markField rs
T ty cs -> T ty [Cas p (mark v) | Cas p v <- cs]
FV ts -> FV $ map mark ts
_ -> foldr1 C (tm beg ++ [mkEscIf t] ++ tm end) -- t : Str guaranteed?
where
mark = markSubterm esc (beg, end)
markField lt@(Ass l t) = if isLinLabel l then (Ass l (mark t)) else lt
tm s = if null s then [] else [tM s]
mkEscIf t = case esc of
Just f -> mkEsc f t
_ -> t
mkEsc f t = case t of
K (KS s) -> K (KS (f s))
C u v -> C (mkEsc f u) (mkEsc f v)
FV ts -> FV (map (mkEsc f) ts)
_ -> t ---- do we need to look at other cases?
tK,tM :: String -> Term
tK = K . KS
tM = K . KM
term2patt :: Term -> Err Patt
term2patt trm = case trm of
Par c aa -> do
aa' <- mapM term2patt aa
return (PC c aa')
R r -> do
let (ll,aa) = unzip [(l,a) | Ass l a <- r]
aa' <- mapM term2patt aa
return (PR (map (uncurry PAss) (zip ll aa')))
LI x -> return $ PV x
EInt i -> return $ PI i
EFloat i -> return $ PF i
FV (t:_) -> term2patt t ----
_ -> prtBad "no pattern corresponds to term" trm
patt2term :: Patt -> Term
patt2term p = case p of
PC x ps -> Par x (map patt2term ps)
PV x -> LI x
PW -> anyTerm ----
PR pas -> R [ Ass lbl (patt2term q) | PAss lbl q <- pas ]
PI i -> EInt i
PF i -> EFloat i
anyTerm :: Term
anyTerm = LI (A.identC "_") --- should not happen
matchPatt :: [Case] -> Term -> Err Term
matchPatt cs0 (FV ts) = liftM FV $ mapM (matchPatt cs0) ts
matchPatt cs0 trm = term2patt trm >>= match cs0 where
match cs t =
case cs of
Cas ps b :_ | elem t ps -> return b
_:cs' -> match cs' t
[] -> Bad $ "pattern not found for" +++ prt t
+++ "among" ++++ unlines (map prt cs0) ---- debug
defLinType :: CType
defLinType = RecType [Lbg (L (A.identC "s")) TStr]
defLindef :: Term
defLindef = R [Ass (L (A.identC "s")) (Arg (A (A.identC "str") 0))]
isDiscontinuousCType :: CType -> Bool
isDiscontinuousCType t = case t of
RecType rs -> length [t | Lbg _ t <- rs, valTableType t == TStr] > 1
_ -> True --- does not occur; would not behave well in lin commands
valTableType :: CType -> CType
valTableType t = case t of
Table _ v -> valTableType v
_ -> t
strsFromTerm :: Term -> Err [Str]
strsFromTerm t = case t of
K (KS s) -> return [str s]
K (KM s) -> return [str s]
K (KP d vs) -> return $ [Str [TN d [(s,v) | Var s v <- vs]]]
C s t -> do
s' <- strsFromTerm s
t' <- strsFromTerm t
return [plusStr x y | x <- s', y <- t']
FV ts -> liftM concat $ mapM strsFromTerm ts
E -> return [str []]
_ -> return [str ("BUG[" ++ prt t ++ "]")] ---- debug
---- _ -> prtBad "cannot get Str from term " t
-- | recursively collect all branches in a table
allInTable :: Term -> [Term]
allInTable t = case t of
T _ ts -> concatMap (\ (Cas _ v) -> allInTable v) ts --- expand ?
_ -> [t]
-- | to gather s-fields; assumes term in normal form, preserves label
allLinFields :: Term -> Err [[(Label,Term)]]
allLinFields trm = case trm of
---- R rs -> return [[(l,t) | (l,(Just ty,t)) <- rs, isStrType ty]] -- good
R rs -> return [[(l,t) | Ass l t <- rs, isLinLabel l]] ---- bad
FV ts -> do
lts <- mapM allLinFields ts
return $ concat lts
T _ ts -> liftM concat $ mapM allLinFields [t | Cas _ t <- ts]
V _ ts -> liftM concat $ mapM allLinFields ts
S t _ -> allLinFields t
_ -> prtBad "fields can only be sought in a record not in" trm
-- | deprecated
isLinLabel :: Label -> Bool
isLinLabel l = case l of
L (A.IC ('s':cs)) | all isDigit cs -> True
-- peb (28/4-04), for MCFG grammars to work:
L (A.IC cs) | null cs || head cs `elem` ".!" -> True
_ -> False
-- | to gather ultimate cases in a table; preserves pattern list
allCaseValues :: Term -> [([Patt],Term)]
allCaseValues trm = case trm of
T _ cs -> [(p:ps, t) | Cas pp t0 <- cs, p <- pp, (ps,t) <- allCaseValues t0]
_ -> [([],trm)]
-- | to gather all linearizations; assumes normal form, preserves label and args
allLinValues :: Term -> Err [[(Label,[([Patt],Term)])]]
allLinValues trm = do
lts <- allLinFields trm
mapM (mapPairsM (return . allCaseValues)) lts
-- | to gather all fields; does not assume s naming of fields;
-- used in Morpho only
allAllLinValues :: Term -> Err [[(Label,[([Patt],Term)])]]
allAllLinValues trm = do
lts <- allFields trm
mapM (mapPairsM (return . allCaseValues)) lts
where
allFields trm = case trm of
R rs -> return [[(l,t) | Ass l t <- rs]]
FV ts -> do
lts <- mapM allFields ts
return $ concat lts
_ -> prtBad "fields can only be sought in a record not in" trm
-- | to gather all linearizations, even from nested records; params ignored
allLinBranches :: Term -> [([Label],Term)]
allLinBranches trm = case trm of
R rs -> [(l:ls,u) | Ass l t <- rs, (ls,u) <- allLinBranches t]
FV ts -> concatMap allLinBranches ts
T _ ts -> concatMap allLinBranches [t | Cas _ t <- ts]
V _ ts -> concatMap allLinBranches ts
_ -> [([],trm)]
redirectIdent :: A.Ident -> CIdent -> CIdent
redirectIdent n f@(CIQ _ c) = CIQ n c
ciq :: A.Ident -> A.Ident -> CIdent
ciq n f = CIQ n f
wordsInTerm :: Term -> [String]
wordsInTerm trm = filter (not . null) $ case trm of
K (KS s) -> [s]
S c _ -> wo c
R rs -> concat [wo t | Ass _ t <- rs]
T _ cs -> concat [wo t | Cas _ t <- cs]
V _ cs -> concat [wo t | t <- cs]
C s t -> wo s ++ wo t
FV ts -> concatMap wo ts
K (KP ss vs) -> ss ++ concat [s | Var s _ <- vs]
P t _ -> wo t --- not needed ?
_ -> []
where wo = wordsInTerm
onTokens :: (String -> String) -> Term -> Term
onTokens f t = case t of
K (KS s) -> K (KS (f s))
K (KP ss vs) -> K (KP (map f ss) [Var (map f x) (map f y) | Var x y <- vs])
_ -> composSafeOp (onTokens f) t
-- | to define compositional term functions
composSafeOp :: (Term -> Term) -> Term -> Term
composSafeOp op trm = case composOp (mkMonadic op) trm of
Ok t -> t
_ -> error "the operation is safe isn't it ?"
where
mkMonadic f = return . f
-- | to define compositional term functions
composOp :: Monad m => (Term -> m Term) -> Term -> m Term
composOp co trm =
case trm of
Par x as ->
do
as' <- mapM co as
return (Par x as')
R as ->
do
let onAss (Ass l t) = liftM (Ass l) (co t)
as' <- mapM onAss as
return (R as')
P a x ->
do
a' <- co a
return (P a' x)
T x as ->
do
let onCas (Cas ps t) = liftM (Cas ps) (co t)
as' <- mapM onCas as
return (T x as')
S a b ->
do
a' <- co a
b' <- co b
return (S a' b')
C a b ->
do
a' <- co a
b' <- co b
return (C a' b')
FV as ->
do
as' <- mapM co as
return (FV as')
V x as ->
do
as' <- mapM co as
return (V x as')
_ -> return trm -- covers Arg, I, LI, K, E

View File

@@ -0,0 +1,45 @@
module GF.Canon.CanonToGFCC where
import GF.Devel.GrammarToGFCC
import GF.Devel.PrintGFCC
import GF.GFCC.CheckGFCC (checkGFCCmaybe)
import GF.GFCC.OptimizeGFCC
import GF.Canon.AbsGFC
import GF.Canon.GFC
import GF.Canon.CanonToGrammar
import GF.Canon.Subexpressions
import GF.Devel.PrintGFCC
import GF.Grammar.PrGrammar
import qualified GF.Infra.Modules as M
import GF.Infra.Option
import GF.Data.Operations
import GF.Text.UTF8
canon2gfccPr opts = printGFCC . canon2gfcc opts
canon2gfcc opts = source2gfcc opts . canon2source ----
canon2source = err error id . canon2sourceGrammar . unSubelimCanon
source2gfcc opts gf =
let
(abs,gfcc) = mkCanon2gfcc opts (gfcabs gf) gf
gfcc1 = maybe undefined id $ checkGFCCmaybe gfcc
in addParsers $ if oElem (iOpt "noopt") opts then gfcc1 else optGFCC gfcc1
gfcabs gfc =
prt $ head $ M.allConcretes gfc $ maybe (error "no abstract") id $
M.greatestAbstract gfc
{-
-- this variant makes utf8 conversion; used in back ends
mkCanon2gfcc :: CanonGrammar -> D.GFCC
mkCanon2gfcc =
-- canon2gfcc . reorder abs . utf8Conv . canon2canon abs
optGFCC . canon2gfcc . reorder . utf8Conv . canon2canon . normalize
-- this variant makes no utf8 conversion; used in ShellState
mkCanon2gfccNoUTF8 :: CanonGrammar -> D.GFCC
mkCanon2gfccNoUTF8 = optGFCC . canon2gfcc . reorder . canon2canon . normalize
-}

View File

@@ -0,0 +1,203 @@
----------------------------------------------------------------------
-- |
-- Module : CanonToGrammar
-- Maintainer : AR
-- Stability : (stable)
-- Portability : (portable)
--
-- > CVS $Date: 2005/06/17 14:15:17 $
-- > CVS $Author: bringert $
-- > CVS $Revision: 1.15 $
--
-- a decompiler. AR 12/6/2003 -- 19/4/2004
-----------------------------------------------------------------------------
module GF.Canon.CanonToGrammar (canon2sourceGrammar, canon2sourceModule, redFlag) where
import GF.Canon.AbsGFC
import GF.Canon.GFC
import GF.Canon.MkGFC
---import CMacros
import qualified GF.Infra.Modules as M
import qualified GF.Infra.Option as O
import qualified GF.Grammar.Grammar as G
import qualified GF.Grammar.Macros as F
import GF.Infra.Ident
import GF.Data.Operations
import Control.Monad
canon2sourceGrammar :: CanonGrammar -> Err G.SourceGrammar
canon2sourceGrammar gr = do
ms' <- mapM canon2sourceModule $ M.modules gr
return $ M.MGrammar ms'
canon2sourceModule :: CanonModule -> Err G.SourceModule
canon2sourceModule (i,mi) = do
i' <- redIdent i
info' <- case mi of
M.ModMod m -> do
(e,os) <- redExtOpen m
flags <- mapM redFlag $ M.flags m
(abstr,mt) <- case M.mtype m of
M.MTConcrete a -> do
a' <- redIdent a
return (a', M.MTConcrete a')
M.MTAbstract -> return (i',M.MTAbstract) --- c' not needed
M.MTResource -> return (i',M.MTResource) --- c' not needed
M.MTTransfer x y -> return (i',M.MTTransfer x y) --- c' not needed
defs <- mapMTree redInfo $ M.jments m
return $ M.ModMod $ M.Module mt (M.mstatus m) flags e os defs
_ -> Bad $ "cannot decompile module type"
return (i',info')
where
redExtOpen m = do
e' <- return $ M.extend m
os' <- mapM (\ (M.OSimple q i) -> liftM (\i -> M.OQualif q i i) (redIdent i)) $
M.opens m
return (e',os')
redInfo :: (Ident,Info) -> Err (Ident,G.Info)
redInfo (c,info) = errIn ("decompiling abstract" +++ show c) $ do
c' <- redIdent c
info' <- case info of
AbsCat cont fs -> do
return $ G.AbsCat (Yes cont) (Yes (map (uncurry G.Q) fs))
AbsFun typ df -> do
return $ G.AbsFun (Yes typ) (Yes df)
AbsTrans t -> do
return $ G.AbsTrans t
ResPar par -> do
par' <- mapM redParam par
return $ G.ResParam (Yes (par',Nothing)) ---- list of values
ResOper pty ptr -> do
ty' <- redCType pty
trm' <- redCTerm ptr
return $ G.ResOper (Yes ty') (Yes trm')
CncCat pty ptr ppr -> do
ty' <- redCType pty
trm' <- redCTerm ptr
ppr' <- redCTerm ppr
return $ G.CncCat (Yes ty') (Yes trm') (Yes ppr')
CncFun (CIQ abstr cat) xx body ppr -> do
xx' <- mapM redArgVar xx
body' <- redCTerm body
ppr' <- redCTerm ppr
cat' <- redIdent cat
return $ G.CncFun (Just (cat', ([],F.typeStr))) -- Nothing
(Yes (F.mkAbs xx' body')) (Yes ppr')
AnyInd b c -> liftM (G.AnyInd b) $ redIdent c
return (c',info')
redQIdent :: CIdent -> Err G.QIdent
redQIdent (CIQ m c) = liftM2 (,) (redIdent m) (redIdent c)
redIdent :: Ident -> Err Ident
redIdent = return
redFlag :: Flag -> Err O.Option
redFlag (Flg f x) = return $ O.Opt (prIdent f,[prIdent x])
redDecl :: Decl -> Err G.Decl
redDecl (Decl x a) = liftM2 (,) (redIdent x) (redTerm a)
redType :: Exp -> Err G.Type
redType = redTerm
redTerm :: Exp -> Err G.Term
redTerm t = return $ trExp t
-- resource
redParam (ParD c cont) = do
c' <- redIdent c
cont' <- mapM redCType cont
return $ (c', [(IW,t) | t <- cont'])
-- concrete syntax
redCType :: CType -> Err G.Type
redCType t = case t of
RecType lbs -> do
let (ls,ts) = unzip [(l,t) | Lbg l t <- lbs]
ls' = map redLabel ls
ts' <- mapM redCType ts
return $ G.RecType $ zip ls' ts'
Table p v -> liftM2 G.Table (redCType p) (redCType v)
Cn mc -> liftM (uncurry G.QC) $ redQIdent mc
TStr -> return $ F.typeStr
TInts i -> return $ F.typeInts (fromInteger i)
redCTerm :: Term -> Err G.Term
redCTerm x = case x of
Arg argvar -> liftM G.Vr $ redArgVar argvar
I cident -> liftM (uncurry G.Q) $ redQIdent cident
Par cident terms -> liftM2 F.mkApp
(liftM (uncurry G.QC) $ redQIdent cident)
(mapM redCTerm terms)
LI id -> liftM G.Vr $ redIdent id
R assigns -> do
let (ls,ts) = unzip [(l,t) | Ass l t <- assigns]
let ls' = map redLabel ls
ts' <- mapM redCTerm ts
return $ G.R [(l,(Nothing,t)) | (l,t) <- zip ls' ts']
P term label -> liftM2 G.P (redCTerm term) (return $ redLabel label)
T ctype cases -> do
ctype' <- redCType ctype
let (ps,ts) = unzip [(p,t) | Cas [p] t <- cases]
ps' <- mapM redPatt ps
ts' <- mapM redCTerm ts
let tinfo = case ps' of
[G.PV _] -> G.TTyped ctype'
_ -> G.TComp ctype'
return $ G.T tinfo $ zip ps' ts'
V ctype ts -> do
ctype' <- redCType ctype
ts' <- mapM redCTerm ts
return $ G.V ctype' ts'
S term0 term -> liftM2 G.S (redCTerm term0) (redCTerm term)
C term0 term -> liftM2 G.C (redCTerm term0) (redCTerm term)
FV terms -> liftM G.FV $ mapM redCTerm terms
K (KS str) -> return $ G.K str
EInt i -> return $ G.EInt i
EFloat i -> return $ G.EFloat i
E -> return $ G.Empty
K (KP d vs) -> return $
G.Alts (tList d,[(tList s, G.Strs $ map G.K v) | Var s v <- vs])
where
tList ss = case ss of --- this should be in Macros
[] -> G.Empty
_ -> foldr1 G.C $ map G.K ss
failure x = Bad $ "not yet" +++ show x ----
redArgVar :: ArgVar -> Err Ident
redArgVar x = case x of
A x i -> return $ IA (prIdent x, fromInteger i)
AB x b i -> return $ IAV (prIdent x, fromInteger b, fromInteger i)
redLabel :: Label -> G.Label
redLabel (L x) = G.LIdent $ prIdent x
redLabel (LV i) = G.LVar $ fromInteger i
redPatt :: Patt -> Err G.Patt
redPatt p = case p of
PV x -> liftM G.PV $ redIdent x
PC mc ps -> do
(m,c) <- redQIdent mc
liftM (G.PP m c) (mapM redPatt ps)
PR rs -> do
let (ls,ts) = unzip [(l,t) | PAss l t <- rs]
ls' = map redLabel ls
ts <- mapM redPatt ts
return $ G.PR $ zip ls' ts
PI i -> return $ G.PInt i
PF i -> return $ G.PFloat i
_ -> Bad $ "cannot recompile pattern" +++ show p

170
src-3.0/GF/Canon/GFC.cf Normal file
View File

@@ -0,0 +1,170 @@
-- top-level grammar
-- Canonical GF. AR 27/4/2003
entrypoints Canon, Line ;
-- old approach: read in a whole grammar
MGr. Canon ::= "grammar" [Ident] "of" Ident ";" [Module] ;
Gr. Canon ::= [Module] ;
-- new approach: read line by line
LMulti. Line ::= "grammar" [Ident] "of" Ident ";" ;
LHeader. Line ::= ModType "=" Extend Open "{" ;
LFlag. Line ::= Flag ";" ;
LDef. Line ::= Def ";" ;
LEnd. Line ::= "}" ;
Mod. Module ::= ModType "=" Extend Open "{" [Flag] [Def] "}" ;
MTAbs. ModType ::= "abstract" Ident ;
MTCnc. ModType ::= "concrete" Ident "of" Ident ;
MTRes. ModType ::= "resource" Ident ;
MTTrans. ModType ::= "transfer" Ident ":" Ident "->" Ident ;
separator Module "" ;
Ext. Extend ::= [Ident] "**" ;
NoExt. Extend ::= ;
Opens. Open ::= "open" [Ident] "in" ;
NoOpens. Open ::= ;
-- judgements
Flg. Flag ::= "flags" Ident "=" Ident ; --- to have the same res word as in GF
AbsDCat. Def ::= "cat" Ident "[" [Decl] "]" "=" [CIdent] ;
AbsDFun. Def ::= "fun" Ident ":" Exp "=" Exp ;
AbsDTrans. Def ::= "transfer" Ident "=" Exp ;
ResDPar. Def ::= "param" Ident "=" [ParDef] ;
ResDOper. Def ::= "oper" Ident ":" CType "=" Term ;
CncDCat. Def ::= "lincat" Ident "=" CType "=" Term ";" Term ;
CncDFun. Def ::= "lin" Ident ":" CIdent "=" "\\" [ArgVar] "->" Term ";" Term ;
AnyDInd. Def ::= Ident Status "in" Ident ;
ParD. ParDef ::= Ident [CType] ;
-- the canonicity of an indirected constant
Canon. Status ::= "data" ;
NonCan. Status ::= ;
-- names originating from resource modules: prefixed by the module name
CIQ. CIdent ::= Ident "." Ident ;
-- types and terms in abstract syntax; no longer type-annotated
EApp. Exp1 ::= Exp1 Exp2 ;
EProd. Exp ::= "(" Ident ":" Exp ")" "->" Exp ;
EAbs. Exp ::= "\\" Ident "->" Exp ;
EAtom. Exp2 ::= Atom ;
EData. Exp2 ::= "data" ;
EEq. Exp ::= "{" [Equation] "}" ; -- list of pattern eqs; primitive notion: []
coercions Exp 2 ;
SType. Sort ::= "Type" ;
Equ. Equation ::= [APatt] "->" Exp ;
APC. APatt ::= "(" CIdent [APatt] ")" ;
APV. APatt ::= Ident ;
APS. APatt ::= String ;
API. APatt ::= Integer ;
APF. APatt ::= Double ;
APW. APatt ::= "_" ;
separator Decl ";" ;
terminator APatt "" ;
terminator Equation ";" ;
AC. Atom ::= CIdent ;
AD. Atom ::= "<" CIdent ">" ;
AV. Atom ::= "$" Ident ;
AM. Atom ::= "?" Integer ;
AS. Atom ::= String ;
AI. Atom ::= Integer ;
AT. Atom ::= Sort ;
Decl. Decl ::= Ident ":" Exp ;
-- types, terms, and patterns in concrete syntax
RecType. CType ::= "{" [Labelling] "}" ;
Table. CType ::= "(" CType "=>" CType ")" ;
Cn. CType ::= CIdent ;
TStr. CType ::= "Str" ;
TInts. CType ::= "Ints" Integer ;
Lbg. Labelling ::= Label ":" CType ;
Arg. Term2 ::= ArgVar ;
I. Term2 ::= CIdent ; -- from resources
Par. Term2 ::= "<" CIdent [Term2] ">" ;
LI. Term2 ::= "$" Ident ; -- from pattern variables
R. Term2 ::= "{" [Assign] "}" ;
P. Term1 ::= Term2 "." Label ;
T. Term1 ::= "table" CType "{" [Case] "}" ;
V. Term1 ::= "table" CType "[" [Term2] "]" ;
S. Term1 ::= Term1 "!" Term2 ;
C. Term ::= Term "++" Term1 ;
FV. Term1 ::= "variants" "{" [Term2] "}" ; --- no separator!
EInt. Term2 ::= Integer ;
EFloat. Term2 ::= Double ;
K. Term2 ::= Tokn ;
E. Term2 ::= "[" "]" ;
KS. Tokn ::= String ;
KP. Tokn ::= "[" "pre" [String] "{" [Variant] "}" "]" ;
internal KM. Tokn ::= String ; -- mark-up
Ass. Assign ::= Label "=" Term ;
Cas. Case ::= [Patt] "=>" Term ;
Var. Variant ::= [String] "/" [String] ;
coercions Term 2 ;
L. Label ::= Ident ;
LV. Label ::= "$" Integer ;
A. ArgVar ::= Ident "@" Integer ; -- no bindings
AB. ArgVar ::= Ident "+" Integer "@" Integer ; -- with a number of bindings
PC. Patt ::= "(" CIdent [Patt] ")" ;
PV. Patt ::= Ident ;
PW. Patt ::= "_" ;
PR. Patt ::= "{" [PattAssign] "}" ;
PI. Patt ::= Integer ;
PF. Patt ::= Double ;
PAss. PattAssign ::= Label "=" Patt ;
--- here we use the new pragmas to generate list rules
terminator Flag ";" ;
terminator Def ";" ;
separator ParDef "|" ;
separator CType "" ;
separator CIdent "" ;
separator Assign ";" ;
separator ArgVar "," ;
separator Labelling ";" ;
separator Case ";" ;
separator Term2 "" ;
separator String "" ;
separator Variant ";" ;
separator PattAssign ";" ;
separator Patt "" ;
separator Ident "," ;

103
src-3.0/GF/Canon/GFC.hs Normal file
View File

@@ -0,0 +1,103 @@
----------------------------------------------------------------------
-- |
-- Module : GFC
-- Maintainer : AR
-- Stability : (stable)
-- Portability : (portable)
--
-- > CVS $Date: 2005/04/21 16:21:22 $
-- > CVS $Author: bringert $
-- > CVS $Revision: 1.12 $
--
-- canonical GF. AR 10\/9\/2002 -- 9\/5\/2003 -- 21\/9
-----------------------------------------------------------------------------
module GF.Canon.GFC (Context,
CanonGrammar,
CanonModInfo,
CanonModule,
CanonAbs,
Info(..),
Printname,
prPrintnamesGrammar,
mapInfoTerms,
setFlag,
flagIncomplete,
isIncompleteCanon,
hasFlagCanon,
flagCanon
) where
import GF.Canon.AbsGFC
import GF.Canon.PrintGFC
import qualified GF.Grammar.Abstract as A
import GF.Infra.Ident
import GF.Infra.Option
import GF.Data.Zipper
import GF.Data.Operations
import qualified GF.Infra.Modules as M
import Data.Char
import Control.Arrow (first)
type Context = [(Ident,Exp)]
type CanonGrammar = M.MGrammar Ident Flag Info
type CanonModInfo = M.ModInfo Ident Flag Info
type CanonModule = (Ident, CanonModInfo)
type CanonAbs = M.Module Ident Option Info
data Info =
AbsCat A.Context [A.Fun]
| AbsFun A.Type A.Term
| AbsTrans A.Term
| ResPar [ParDef]
| ResOper CType Term -- ^ global constant
| CncCat CType Term Printname
| CncFun CIdent [ArgVar] Term Printname
| AnyInd Bool Ident
deriving (Show)
type Printname = Term
mapInfoTerms :: (Term -> Term) -> Info -> Info
mapInfoTerms f i = case i of
ResOper x a -> ResOper x (f a)
CncCat x a y -> CncCat x (f a) y
CncFun x y a z -> CncFun x y (f a) z
_ -> i
setFlag :: String -> String -> [Flag] -> [Flag]
setFlag n v fs = flagCanon n v : [f | f@(Flg (IC n') _) <- fs, n' /= n]
flagIncomplete :: Flag
flagIncomplete = flagCanon "incomplete" "true"
isIncompleteCanon :: CanonModule -> Bool
isIncompleteCanon = hasFlagCanon flagIncomplete
hasFlagCanon :: Flag -> CanonModule -> Bool
hasFlagCanon f (_,M.ModMod mo) = elem f $ M.flags mo
hasFlagCanon f _ = True ---- safe, useless
flagCanon :: String -> String -> Flag
flagCanon f v = Flg (identC f) (identC v)
-- for Ha-Jo 20/2/2005
prPrintnamesGrammar :: CanonGrammar -> String
prPrintnamesGrammar gr = unlines $ filter (not . null) [prPrint j |
(_,M.ModMod m) <- M.modules gr,
M.isModCnc m,
j <- tree2list $ M.jments m
]
where
prPrint j = case j of
(c,CncCat _ _ p) -> "printname cat" +++ A.prt_ c +++ "=" +++ A.prt_ p
(c,CncFun _ _ _ p) -> "printname fun" +++ A.prt_ c +++ "=" +++ A.prt_ p
_ -> []

View File

@@ -0,0 +1,78 @@
----------------------------------------------------------------------
-- |
-- Module : GetGFC
-- Maintainer : AR
-- Stability : (stable)
-- Portability : (portable)
--
-- > CVS $Date: 2005/05/30 18:39:43 $
-- > CVS $Author: aarne $
-- > CVS $Revision: 1.9 $
--
-- (Description of the module)
-----------------------------------------------------------------------------
module GF.Canon.GetGFC (getCanonModule, getCanonGrammar) where
import GF.Data.Operations
import GF.Canon.ParGFC
import GF.Canon.GFC
import GF.Canon.MkGFC
import GF.Infra.Modules
import GF.Infra.UseIO
import System.IO
import System.Directory
import Control.Monad
getCanonModule :: FilePath -> IOE CanonModule
getCanonModule file = do
gr <- getCanonGrammar file
case modules gr of
[m] -> return m
_ -> ioeErr $ Bad "expected exactly one module in a file"
getCanonGrammar :: FilePath -> IOE CanonGrammar
-- getCanonGrammar = getCanonGrammarByLine
getCanonGrammar file = do
s <- ioeIO $ readFileIf file
c <- ioeErr $ pCanon $ myLexer s
return $ canon2grammar c
{-
-- the following surprisingly does not save memory so it is
-- not in use
getCanonGrammarByLine :: FilePath -> IOE CanonGrammar
getCanonGrammarByLine file = do
b <- ioeIO $ doesFileExist file
if not b
then ioeErr $ Bad $ "file" +++ file +++ "does not exist"
else do
ioeIO $ putStrLn ""
hand <- ioeIO $ openFile file ReadMode ---- err
size <- ioeIO $ hFileSize hand
gr <- addNextLine (size,0) 1 hand emptyMGrammar
ioeIO $ hClose hand
return $ MGrammar $ reverse $ modules gr
where
addNextLine (size,act) d hand gr = do
eof <- ioeIO $ hIsEOF hand
if eof
then return gr
else do
s <- ioeIO $ hGetLine hand
let act' = act + toInteger (length s)
-- if isHash act act' then (ioeIO $ putChar '#') else return ()
updGrammar act' d gr $ pLine $ myLexer s
where
updGrammar a d gr (Ok t) = case buildCanonGrammar d gr t of
(gr',d') -> addNextLine (size,a) d' hand gr'
updGrammar _ _ gr (Bad s) = do
ioeIO $ putStrLn s
return emptyMGrammar
isHash a b = a `div` step < b `div` step
step = size `div` 50
-}

346
src-3.0/GF/Canon/LexGFC.hs Normal file
View File

@@ -0,0 +1,346 @@
{-# OPTIONS -fglasgow-exts -cpp #-}
{-# LINE 3 "LexGFC.x" #-}
module GF.Canon.LexGFC where --H
import GF.Data.ErrM --H
import GF.Data.SharedString --H
#if __GLASGOW_HASKELL__ >= 603
#include "ghcconfig.h"
#else
#include "config.h"
#endif
#if __GLASGOW_HASKELL__ >= 503
import Data.Array
import Data.Char (ord)
import Data.Array.Base (unsafeAt)
#else
import Array
import Char (ord)
#endif
#if __GLASGOW_HASKELL__ >= 503
import GHC.Exts
#else
import GlaExts
#endif
alex_base :: AlexAddr
alex_base = AlexA# "\x01\x00\x00\x00\x39\x00\x00\x00\x42\x00\x00\x00\x00\x00\x00\x00\x09\x00\x00\x00\x1d\x00\x00\x00\x0b\x00\x00\x00\x20\x00\x00\x00\x9a\x00\x00\x00\x00\x00\x00\x00\x15\x01\x00\x00\xd3\x00\x00\x00\x35\x00\x00\x00\xe5\x00\x00\x00\x3f\x00\x00\x00\xf0\x00\x00\x00\x1b\x01\x00\x00\x6d\x01\x00\x00"#
alex_table :: AlexAddr
alex_table = AlexA# "\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x02\x00\x02\x00\x02\x00\x02\x00\x02\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x02\x00\x03\x00\x0a\x00\xff\xff\x03\x00\xff\xff\xff\xff\xff\xff\x03\x00\x03\x00\x07\x00\x05\x00\x03\x00\x06\x00\x03\x00\x03\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x03\x00\x03\x00\x03\x00\x04\x00\x03\x00\x03\x00\x03\x00\x02\x00\x02\x00\x02\x00\x02\x00\x02\x00\x03\x00\x03\x00\x03\x00\x03\x00\x02\x00\x02\x00\x02\x00\x02\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x03\x00\x03\x00\x03\x00\xff\xff\x03\x00\xff\xff\x02\x00\x0f\x00\x00\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0e\x00\x0e\x00\x0e\x00\x0e\x00\x0e\x00\x0e\x00\x0e\x00\x0e\x00\x0e\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x03\x00\x03\x00\x03\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x00\x00\x00\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x0a\x00\x00\x00\x00\x00\xff\xff\x08\x00\x0a\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\xff\xff\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x11\x00\x0e\x00\x0e\x00\x0e\x00\x0e\x00\x0e\x00\x0e\x00\x0e\x00\x0e\x00\x0e\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x0b\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x00\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x10\x00\x00\x00\x00\x00\x0e\x00\x0e\x00\x0e\x00\x0e\x00\x0e\x00\x0e\x00\x0e\x00\x0e\x00\x0e\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#
alex_check :: AlexAddr
alex_check = AlexA# "\xff\xff\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x3e\x00\x2b\x00\x3e\x00\x2a\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x20\x00\xff\xff\xff\xff\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x20\x00\x2e\x00\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\x7b\x00\x7c\x00\x7d\x00\x7e\x00\x7f\x00\x80\x00\x81\x00\x82\x00\x83\x00\x84\x00\x85\x00\x86\x00\x87\x00\x88\x00\x89\x00\x8a\x00\x8b\x00\x8c\x00\x8d\x00\x8e\x00\x8f\x00\x90\x00\x91\x00\x92\x00\x93\x00\x94\x00\x95\x00\x96\x00\x97\x00\x98\x00\x99\x00\x9a\x00\x9b\x00\x9c\x00\x9d\x00\x9e\x00\x9f\x00\xa0\x00\xa1\x00\xa2\x00\xa3\x00\xa4\x00\xa5\x00\xa6\x00\xa7\x00\xa8\x00\xa9\x00\xaa\x00\xab\x00\xac\x00\xad\x00\xae\x00\xaf\x00\xb0\x00\xb1\x00\xb2\x00\xb3\x00\xb4\x00\xb5\x00\xb6\x00\xb7\x00\xb8\x00\xb9\x00\xba\x00\xbb\x00\xbc\x00\xbd\x00\xbe\x00\xbf\x00\x27\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xd7\x00\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x22\x00\xff\xff\xff\xff\xf7\x00\x5f\x00\x27\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x0a\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5c\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x22\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x6e\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x74\x00\xff\xff\xff\xff\x65\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\x5c\x00\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x2d\x00\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"#
alex_deflt :: AlexAddr
alex_deflt = AlexA# "\x08\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"#
alex_accept = listArray (0::Int,17) [[],[],[(AlexAccSkip)],[(AlexAcc (alex_action_1))],[(AlexAcc (alex_action_1))],[(AlexAcc (alex_action_1))],[],[],[(AlexAcc (alex_action_2))],[(AlexAcc (alex_action_3))],[],[],[(AlexAcc (alex_action_4))],[(AlexAcc (alex_action_5))],[(AlexAcc (alex_action_5))],[],[],[]]
{-# LINE 32 "LexGFC.x" #-}
tok f p s = f p s
share :: String -> String
share = shareString
data Tok =
TS !String -- reserved words
| TL !String -- string literals
| TI !String -- integer literals
| TV !String -- identifiers
| TD !String -- double precision float literals
| TC !String -- character literals
deriving (Eq,Show,Ord)
data Token =
PT Posn Tok
| Err Posn
deriving (Eq,Show,Ord)
tokenPos (PT (Pn _ l _) _ :_) = "line " ++ show l
tokenPos (Err (Pn _ l _) :_) = "line " ++ show l
tokenPos _ = "end of file"
posLineCol (Pn _ l c) = (l,c)
mkPosToken t@(PT p _) = (posLineCol p, prToken t)
prToken t = case t of
PT _ (TS s) -> s
PT _ (TI s) -> s
PT _ (TV s) -> s
PT _ (TD s) -> s
PT _ (TC s) -> s
_ -> show t
data BTree = N | B String Tok BTree BTree deriving (Show)
eitherResIdent :: (String -> Tok) -> String -> Tok
eitherResIdent tv s = treeFind resWords
where
treeFind N = tv s
treeFind (B a t left right) | s < a = treeFind left
| s > a = treeFind right
| s == a = t
resWords = b "lin" (b "concrete" (b "Type" (b "Str" (b "Ints" N N) N) (b "cat" (b "abstract" N N) N)) (b "fun" (b "flags" (b "data" N N) N) (b "in" (b "grammar" N N) N))) (b "pre" (b "open" (b "of" (b "lincat" N N) N) (b "param" (b "oper" N N) N)) (b "transfer" (b "table" (b "resource" N N) N) (b "variants" N N)))
where b s = B s (TS s)
unescapeInitTail :: String -> String
unescapeInitTail = unesc . tail where
unesc s = case s of
'\\':c:cs | elem c ['\"', '\\', '\''] -> c : unesc cs
'\\':'n':cs -> '\n' : unesc cs
'\\':'t':cs -> '\t' : unesc cs
'"':[] -> []
c:cs -> c : unesc cs
_ -> []
-------------------------------------------------------------------
-- Alex wrapper code.
-- A modified "posn" wrapper.
-------------------------------------------------------------------
data Posn = Pn !Int !Int !Int
deriving (Eq, Show,Ord)
alexStartPos :: Posn
alexStartPos = Pn 0 1 1
alexMove :: Posn -> Char -> Posn
alexMove (Pn a l c) '\t' = Pn (a+1) l (((c+7) `div` 8)*8+1)
alexMove (Pn a l c) '\n' = Pn (a+1) (l+1) 1
alexMove (Pn a l c) _ = Pn (a+1) l (c+1)
type AlexInput = (Posn, -- current position,
Char, -- previous char
String) -- current input string
tokens :: String -> [Token]
tokens str = go (alexStartPos, '\n', str)
where
go :: (Posn, Char, String) -> [Token]
go inp@(pos, _, str) =
case alexScan inp 0 of
AlexEOF -> []
AlexError (pos, _, _) -> fail $ show pos ++ ": lexical error"
AlexSkip inp' len -> go inp'
AlexToken inp' len act -> act pos (take len str) : (go inp')
alexGetChar :: AlexInput -> Maybe (Char,AlexInput)
alexGetChar (p, c, []) = Nothing
alexGetChar (p, _, (c:s)) =
let p' = alexMove p c
in p' `seq` Just (c, (p', c, s))
alexInputPrevChar :: AlexInput -> Char
alexInputPrevChar (p, c, s) = c
alex_action_1 = tok (\p s -> PT p (TS $ share s))
alex_action_2 = tok (\p s -> PT p (eitherResIdent (TV . share) s))
alex_action_3 = tok (\p s -> PT p (TL $ share $ unescapeInitTail s))
alex_action_4 = tok (\p s -> PT p (TI $ share s))
alex_action_5 = tok (\p s -> PT p (TD $ share s))
{-# LINE 1 "GenericTemplate.hs" #-}
{-# LINE 1 "<built-in>" #-}
{-# LINE 1 "<command line>" #-}
{-# LINE 1 "GenericTemplate.hs" #-}
-- -----------------------------------------------------------------------------
-- ALEX TEMPLATE
--
-- This code is in the PUBLIC DOMAIN; you may copy it freely and use
-- it for any purpose whatsoever.
-- -----------------------------------------------------------------------------
-- INTERNALS and main scanner engine
{-# LINE 35 "GenericTemplate.hs" #-}
data AlexAddr = AlexA# Addr#
#if __GLASGOW_HASKELL__ < 503
uncheckedShiftL# = shiftL#
#endif
{-# INLINE alexIndexInt16OffAddr #-}
alexIndexInt16OffAddr (AlexA# arr) off =
#ifdef WORDS_BIGENDIAN
narrow16Int# i
where
i = word2Int# ((high `uncheckedShiftL#` 8#) `or#` low)
high = int2Word# (ord# (indexCharOffAddr# arr (off' +# 1#)))
low = int2Word# (ord# (indexCharOffAddr# arr off'))
off' = off *# 2#
#else
indexInt16OffAddr# arr off
#endif
{-# INLINE alexIndexInt32OffAddr #-}
alexIndexInt32OffAddr (AlexA# arr) off =
#ifdef WORDS_BIGENDIAN
narrow32Int# i
where
i = word2Int# ((b3 `uncheckedShiftL#` 24#) `or#`
(b2 `uncheckedShiftL#` 16#) `or#`
(b1 `uncheckedShiftL#` 8#) `or#` b0)
b3 = int2Word# (ord# (indexCharOffAddr# arr (off' +# 3#)))
b2 = int2Word# (ord# (indexCharOffAddr# arr (off' +# 2#)))
b1 = int2Word# (ord# (indexCharOffAddr# arr (off' +# 1#)))
b0 = int2Word# (ord# (indexCharOffAddr# arr off'))
off' = off *# 4#
#else
indexInt32OffAddr# arr off
#endif
#if __GLASGOW_HASKELL__ < 503
quickIndex arr i = arr ! i
#else
-- GHC >= 503, unsafeAt is available from Data.Array.Base.
quickIndex = unsafeAt
#endif
-- -----------------------------------------------------------------------------
-- Main lexing routines
data AlexReturn a
= AlexEOF
| AlexError !AlexInput
| AlexSkip !AlexInput !Int
| AlexToken !AlexInput !Int a
-- alexScan :: AlexInput -> StartCode -> Maybe (AlexInput,Int,act)
alexScan input (I# (sc))
= alexScanUser undefined input (I# (sc))
alexScanUser user input (I# (sc))
= case alex_scan_tkn user input 0# input sc AlexNone of
(AlexNone, input') ->
case alexGetChar input of
Nothing ->
AlexEOF
Just _ ->
AlexError input'
(AlexLastSkip input len, _) ->
AlexSkip input len
(AlexLastAcc k input len, _) ->
AlexToken input len k
-- Push the input through the DFA, remembering the most recent accepting
-- state it encountered.
alex_scan_tkn user orig_input len input s last_acc =
input `seq` -- strict in the input
case s of
-1# -> (last_acc, input)
_ -> alex_scan_tkn' user orig_input len input s last_acc
alex_scan_tkn' user orig_input len input s last_acc =
let
new_acc = check_accs (alex_accept `quickIndex` (I# (s)))
in
new_acc `seq`
case alexGetChar input of
Nothing -> (new_acc, input)
Just (c, new_input) ->
let
base = alexIndexInt32OffAddr alex_base s
(I# (ord_c)) = ord c
offset = (base +# ord_c)
check = alexIndexInt16OffAddr alex_check offset
new_s = if (offset >=# 0#) && (check ==# ord_c)
then alexIndexInt16OffAddr alex_table offset
else alexIndexInt16OffAddr alex_deflt s
in
alex_scan_tkn user orig_input (len +# 1#) new_input new_s new_acc
where
check_accs [] = last_acc
check_accs (AlexAcc a : _) = AlexLastAcc a input (I# (len))
check_accs (AlexAccSkip : _) = AlexLastSkip input (I# (len))
check_accs (AlexAccPred a pred : rest)
| pred user orig_input (I# (len)) input
= AlexLastAcc a input (I# (len))
check_accs (AlexAccSkipPred pred : rest)
| pred user orig_input (I# (len)) input
= AlexLastSkip input (I# (len))
check_accs (_ : rest) = check_accs rest
data AlexLastAcc a
= AlexNone
| AlexLastAcc a !AlexInput !Int
| AlexLastSkip !AlexInput !Int
data AlexAcc a user
= AlexAcc a
| AlexAccSkip
| AlexAccPred a (AlexAccPred user)
| AlexAccSkipPred (AlexAccPred user)
type AlexAccPred user = user -> AlexInput -> Int -> AlexInput -> Bool
-- -----------------------------------------------------------------------------
-- Predicates on a rule
alexAndPred p1 p2 user in1 len in2
= p1 user in1 len in2 && p2 user in1 len in2
--alexPrevCharIsPred :: Char -> AlexAccPred _
alexPrevCharIs c _ input _ _ = c == alexInputPrevChar input
--alexPrevCharIsOneOfPred :: Array Char Bool -> AlexAccPred _
alexPrevCharIsOneOf arr _ input _ _ = arr ! alexInputPrevChar input
--alexRightContext :: Int -> AlexAccPred _
alexRightContext (I# (sc)) user _ _ input =
case alex_scan_tkn user input 0# input sc AlexNone of
(AlexNone, _) -> False
_ -> True
-- TODO: there's no need to find the longest
-- match when checking the right context, just
-- the first match will do.
-- used by wrappers
iUnbox (I# (i)) = i

132
src-3.0/GF/Canon/LexGFC.x Normal file
View File

@@ -0,0 +1,132 @@
-- -*- haskell -*-
-- This Alex file was machine-generated by the BNF converter
{
module GF.Canon.LexGFC where
import GF.Data.ErrM -- H
import GF.Data.SharedString -- H
}
$l = [a-zA-Z\192 - \255] # [\215 \247] -- isolatin1 letter FIXME
$c = [A-Z\192-\221] # [\215] -- capital isolatin1 letter FIXME
$s = [a-z\222-\255] # [\247] -- small isolatin1 letter FIXME
$d = [0-9] -- digit
$i = [$l $d _ '] -- identifier character
$u = [\0-\255] -- universal: any character
@rsyms = -- reserved words consisting of special symbols
\; | \= | \{ | \} | \: | \- \> | \* \* | \[ | \] | \\ | \. | \( | \) | \_ | \< | \> | \$ | \? | \= \> | \! | \+ \+ | \/ | \@ | \+ | \| | \,
:-
$white+ ;
@rsyms { tok (\p s -> PT p (TS $ share s)) }
$l $i* { tok (\p s -> PT p (eitherResIdent (TV . share) s)) }
\" ([$u # [\" \\ \n]] | (\\ (\" | \\ | \' | n | t)))* \"{ tok (\p s -> PT p (TL $ share $ unescapeInitTail s)) }
$d+ { tok (\p s -> PT p (TI $ share s)) }
{
tok f p s = f p s
share :: String -> String
share = shareString
data Tok =
TS !String -- reserved words
| TL !String -- string literals
| TI !String -- integer literals
| TV !String -- identifiers
| TD !String -- double precision float literals
| TC !String -- character literals
deriving (Eq,Show,Ord)
data Token =
PT Posn Tok
| Err Posn
deriving (Eq,Show,Ord)
tokenPos (PT (Pn _ l _) _ :_) = "line " ++ show l
tokenPos (Err (Pn _ l _) :_) = "line " ++ show l
tokenPos _ = "end of file"
posLineCol (Pn _ l c) = (l,c)
mkPosToken t@(PT p _) = (posLineCol p, prToken t)
prToken t = case t of
PT _ (TS s) -> s
PT _ (TI s) -> s
PT _ (TV s) -> s
PT _ (TD s) -> s
PT _ (TC s) -> s
_ -> show t
data BTree = N | B String Tok BTree BTree deriving (Show)
eitherResIdent :: (String -> Tok) -> String -> Tok
eitherResIdent tv s = treeFind resWords
where
treeFind N = tv s
treeFind (B a t left right) | s < a = treeFind left
| s > a = treeFind right
| s == a = t
resWords = b "lin" (b "concrete" (b "Type" (b "Str" (b "Ints" N N) N) (b "cat" (b "abstract" N N) N)) (b "fun" (b "flags" (b "data" N N) N) (b "in" (b "grammar" N N) N))) (b "pre" (b "open" (b "of" (b "lincat" N N) N) (b "param" (b "oper" N N) N)) (b "transfer" (b "table" (b "resource" N N) N) (b "variants" N N)))
where b s = B s (TS s)
unescapeInitTail :: String -> String
unescapeInitTail = unesc . tail where
unesc s = case s of
'\\':c:cs | elem c ['\"', '\\', '\''] -> c : unesc cs
'\\':'n':cs -> '\n' : unesc cs
'\\':'t':cs -> '\t' : unesc cs
'"':[] -> []
c:cs -> c : unesc cs
_ -> []
-------------------------------------------------------------------
-- Alex wrapper code.
-- A modified "posn" wrapper.
-------------------------------------------------------------------
data Posn = Pn !Int !Int !Int
deriving (Eq, Show,Ord)
alexStartPos :: Posn
alexStartPos = Pn 0 1 1
alexMove :: Posn -> Char -> Posn
alexMove (Pn a l c) '\t' = Pn (a+1) l (((c+7) `div` 8)*8+1)
alexMove (Pn a l c) '\n' = Pn (a+1) (l+1) 1
alexMove (Pn a l c) _ = Pn (a+1) l (c+1)
type AlexInput = (Posn, -- current position,
Char, -- previous char
String) -- current input string
tokens :: String -> [Token]
tokens str = go (alexStartPos, '\n', str)
where
go :: (Posn, Char, String) -> [Token]
go inp@(pos, _, str) =
case alexScan inp 0 of
AlexEOF -> []
AlexError (pos, _, _) -> fail $ show pos ++ ": lexical error"
AlexSkip inp' len -> go inp'
AlexToken inp' len act -> act pos (take len str) : (go inp')
alexGetChar :: AlexInput -> Maybe (Char,AlexInput)
alexGetChar (p, c, []) = Nothing
alexGetChar (p, _, (c:s)) =
let p' = alexMove p c
in p' `seq` Just (c, (p', c, s))
alexInputPrevChar :: AlexInput -> Char
alexInputPrevChar (p, c, s) = c
}

225
src-3.0/GF/Canon/Look.hs Normal file
View File

@@ -0,0 +1,225 @@
----------------------------------------------------------------------
-- |
-- Module : Look
-- Maintainer : AR
-- Stability : (stable)
-- Portability : (portable)
--
-- > CVS $Date: 2005/09/20 09:32:56 $
-- > CVS $Author: aarne $
-- > CVS $Revision: 1.17 $
--
-- lookup in GFC. AR 2003
-----------------------------------------------------------------------------
module GF.Canon.Look (lookupCncInfo,
lookupLin,
lookupLincat,
lookupPrintname,
lookupResInfo,
lookupGlobal,
lookupOptionsCan,
lookupParamValues,
allParamValues,
ccompute
) where
import GF.Canon.AbsGFC
import GF.Canon.GFC
import GF.Grammar.PrGrammar
import GF.Canon.CMacros
----import Values
import GF.Grammar.MMacros
import GF.Grammar.Macros (zIdent)
import qualified GF.Infra.Modules as M
import qualified GF.Canon.CanonToGrammar as CG
import GF.Data.Operations
import GF.Infra.Option
import Control.Monad
import Data.List
-- linearization lookup
lookupCncInfo :: CanonGrammar -> CIdent -> Err Info
lookupCncInfo gr f@(CIQ m c) = do
mt <- M.lookupModule gr m
case mt of
M.ModMod a -> errIn ("module" +++ prt m) $
lookupIdent c $ M.jments a
_ -> prtBad "not concrete module" m
lookupLin :: CanonGrammar -> CIdent -> Err Term
lookupLin gr f = errIn "looking up linearization rule" $ do
info <- lookupCncInfo gr f
case info of
CncFun _ _ t _ -> return t
CncCat _ t _ -> return t
AnyInd _ n -> lookupLin gr $ redirectIdent n f
lookupLincat :: CanonGrammar -> CIdent -> Err CType
lookupLincat gr (CIQ _ c) | elem c [zIdent "String", zIdent "Int", zIdent "Float"] =
return defLinType --- ad hoc; not needed? cf. Grammar.Lookup.lookupLincat
lookupLincat gr f = errIn "looking up linearization type" $ do
info <- lookupCncInfo gr f
case info of
CncCat t _ _ -> return t
AnyInd _ n -> lookupLincat gr $ redirectIdent n f
_ -> prtBad "no lincat found for" f
lookupPrintname :: CanonGrammar -> CIdent -> Err Term
lookupPrintname gr f = errIn "looking up printname" $ do
info <- lookupCncInfo gr f
case info of
CncFun _ _ _ t -> return t
CncCat _ _ t -> return t
AnyInd _ n -> lookupPrintname gr $ redirectIdent n f
lookupResInfo :: CanonGrammar -> CIdent -> Err Info
lookupResInfo gr f@(CIQ m c) = do
mt <- M.lookupModule gr m
case mt of
M.ModMod a -> lookupIdent c $ M.jments a
_ -> prtBad "not resource module" m
lookupGlobal :: CanonGrammar -> CIdent -> Err Term
lookupGlobal gr f = do
info <- lookupResInfo gr f
case info of
ResOper _ t -> return t
AnyInd _ n -> lookupGlobal gr $ redirectIdent n f
_ -> prtBad "cannot find global" f
lookupOptionsCan :: CanonGrammar -> Err Options
lookupOptionsCan gr = do
let fs = M.allFlags gr
os <- mapM CG.redFlag fs
return $ options os
lookupParamValues :: CanonGrammar -> CIdent -> Err [Term]
lookupParamValues gr pt@(CIQ m _) = do
info <- lookupResInfo gr pt
case info of
ResPar ps -> liftM concat $ mapM mkPar ps
AnyInd _ n -> lookupParamValues gr $ redirectIdent n pt
_ -> prtBad "cannot find parameter type" pt
where
mkPar (ParD f co) = do
vs <- liftM combinations $ mapM (allParamValues gr) co
return $ map (Par (CIQ m f)) vs
-- this is needed since param type can also be a record type
allParamValues :: CanonGrammar -> CType -> Err [Term]
allParamValues cnc ptyp = case ptyp of
Cn pc -> lookupParamValues cnc pc
RecType r -> do
let (ls,tys) = unzip [(l,t) | Lbg l t <- r]
tss <- mapM allPV tys
return [R (map (uncurry Ass) (zip ls ts)) | ts <- combinations tss]
TInts n -> return [EInt i | i <- [0..n]]
_ -> prtBad "cannot possibly find parameter values for" ptyp
where
allPV = allParamValues cnc
-- runtime computation on GFC objects
ccompute :: CanonGrammar -> [Term] -> Term -> Err Term
ccompute cnc = vcomp
where
vcomp xs t = do
let xss = variations xs
ts <- mapM (\xx -> comp [] xx t) xss
return $ variants ts
variations xs = combinations [getVariants t | t <- xs]
variants ts = case ts of
[t] -> t
_ -> FV ts
getVariants t = case t of
FV ts -> ts
_ -> [t]
comp g xs t = case t of
Arg (A _ i) -> err (const (return t)) return $ xs !? fromInteger i
Arg (AB _ _ i) -> err (const (return t)) return $ xs !? fromInteger i
I c -> look c
LI c -> lookVar c g
-- short-cut computation of selections: compute the table only if needed
S u v -> do
u' <- compt u
case u' of
T _ [Cas [PW] b] -> compt b
T _ [Cas [PV x] b] -> do
v' <- compt v
comp ((x,v') : g) xs b
T _ cs -> do
v' <- compt v
if noVar v'
then matchPatt cs v' >>= compt
else return $ S u' v'
FV ccs -> do
v' <- compt v
mapM (\c -> compt (S c v')) ccs >>= return . FV
_ -> liftM (S u') $ compt v
P u l -> do
u' <- compt u
case u' of
R rs -> maybe (Bad ("unknown label" +++ prt l +++ "in" +++ prt u'))
return $
lookup l [ (x,y) | Ass x y <- rs]
FV rrs -> do
mapM (\r -> compt (P r l)) rrs >>= return . FV
_ -> return $ P u' l
FV ts -> liftM FV (mapM compt ts)
C E b -> compt b
C a E -> compt a
C a b -> do
a' <- compt a
b' <- compt b
return $ case (a',b') of
(E,_) -> b'
(_,E) -> a'
_ -> C a' b'
R rs -> liftM (R . map (uncurry Ass)) $
mapPairsM compt [(l,r) | Ass l r <- rs]
-- only expand the table when the table is really needed: use expandLin
T ty rs -> liftM (T ty . map (uncurry Cas)) $
mapPairsM compt [(l,r) | Cas l r <- rs]
V ptyp ts -> do
ts' <- mapM compt ts
vs0 <- allParamValues cnc ptyp
vs <- mapM term2patt vs0
let cc = [Cas [p] u | (p,u) <- zip vs ts']
return $ T ptyp cc
Par c xs -> liftM (Par c) $ mapM compt xs
K (KS []) -> return E --- should not be needed
_ -> return t
where
compt = comp g xs
look c = lookupGlobal cnc c >>= compt
lookVar c co = case lookup c co of
Just t -> return t
_ -> return $ LI c --- Bad $ "unknown local variable" +++ prt c ---
noVar v = case v of
LI _ -> False
Arg _ -> False
R rs -> all noVar [t | Ass _ t <- rs]
Par _ ts -> all noVar ts
FV ts -> all noVar ts
S x y -> noVar x && noVar y
P t _ -> noVar t
_ -> True --- other cases that can be values to pattern match?

237
src-3.0/GF/Canon/MkGFC.hs Normal file
View File

@@ -0,0 +1,237 @@
----------------------------------------------------------------------
-- |
-- Module : MkGFC
-- Maintainer : AR
-- Stability : (stable)
-- Portability : (portable)
--
-- > CVS $Date: 2005/09/04 11:45:38 $
-- > CVS $Author: aarne $
-- > CVS $Revision: 1.16 $
--
-- (Description of the module)
-----------------------------------------------------------------------------
module GF.Canon.MkGFC (prCanonModInfo, prCanon, prCanonMGr,
canon2grammar, grammar2canon, -- buildCanonGrammar,
info2mod,info2def,
trExp, rtExp, rtQIdent) where
import GF.Canon.GFC
import GF.Canon.AbsGFC
import qualified GF.Grammar.Abstract as A
import GF.Grammar.PrGrammar
import GF.Infra.Ident
import GF.Data.Operations
import qualified GF.Infra.Modules as M
prCanonModInfo :: CanonModule -> String
prCanonModInfo = prt . info2mod
prCanon :: CanonGrammar -> String
prCanon = unlines . map prCanonModInfo . M.modules
prCanonMGr :: CanonGrammar -> String
prCanonMGr g = header ++++ prCanon g where
header = case M.greatestAbstract g of
Just a -> prt (MGr (M.allConcretes g a) a [])
_ -> []
canon2grammar :: Canon -> CanonGrammar
canon2grammar (MGr _ _ modules) = canon2grammar (Gr modules) ---- ignoring the header
canon2grammar (Gr modules) = M.MGrammar $ map mod2info modules
mod2info m = case m of
Mod mt e os flags defs ->
let defs' = buildTree $ map def2info defs
(a,mt') = case mt of
MTAbs a -> (a,M.MTAbstract)
MTRes a -> (a,M.MTResource)
MTCnc a x -> (a,M.MTConcrete x)
MTTrans a x y -> (a,M.MTTransfer (M.oSimple x) (M.oSimple y))
in (a,M.ModMod (M.Module mt' M.MSComplete flags (ee e) (oo os) defs'))
where
ee (Ext m) = map M.inheritAll m
ee _ = []
oo (Opens ms) = map M.oSimple ms
oo _ = []
grammar2canon :: CanonGrammar -> Canon
grammar2canon (M.MGrammar modules) = Gr $ map info2mod modules
info2mod :: (Ident, M.ModInfo Ident Flag Info) -> Module
info2mod m = case m of
(a, M.ModMod (M.Module mt _ flags me os defs)) ->
let defs' = map info2def $ tree2list defs
mt' = case mt of
M.MTAbstract -> MTAbs a
M.MTResource -> MTRes a
M.MTConcrete x -> MTCnc a x
M.MTTransfer (M.OSimple _ x) (M.OSimple _ y) -> MTTrans a x y
in
Mod mt' (gfcE me) (gfcO os) flags defs'
where
gfcE = ifNull NoExt Ext . map fst
gfcO os = if null os then NoOpens else Opens [m | M.OSimple _ m <- os]
-- these translations are meant to be trivial
defs2infos = sorted2tree . map def2info
def2info d = case d of
AbsDCat c cont fs -> (c,AbsCat (trCont cont) (trFs fs))
AbsDFun c ty df -> (c,AbsFun (trExp ty) (trExp df))
AbsDTrans c t -> (c,AbsTrans (trExp t))
ResDPar c df -> (c,ResPar df)
ResDOper c ty df -> (c,ResOper ty df)
CncDCat c ty df pr -> (c, CncCat ty df pr)
CncDFun f c xs li pr -> (f, CncFun c xs li pr)
AnyDInd c b m -> (c, AnyInd (b == Canon) m)
-- from file to internal
trCont cont = [(x,trExp t) | Decl x t <- cont]
trFs = map trQIdent
trExp :: Exp -> A.Term
trExp t = case t of
EProd x a b -> A.Prod x (trExp a) (trExp b)
EAbs x b -> A.Abs x (trExp b)
EApp f a -> A.App (trExp f) (trExp a)
EEq eqs -> A.Eqs [(map trPt ps, trExp e) | Equ ps e <- eqs]
EData -> A.EData
_ -> trAt t
where
trAt (EAtom t) = case t of
AC c -> (uncurry A.Q) $ trQIdent c
AD c -> (uncurry A.QC) $ trQIdent c
AV v -> A.Vr v
AM i -> A.Meta $ A.MetaSymb $ fromInteger i
AT s -> A.Sort $ prt s
AS s -> A.K s
AI i -> A.EInt $ i
AF i -> A.EFloat $ i
trPt p = case p of
APC mc ps -> let (m,c) = trQIdent mc in A.PP m c (map trPt ps)
APV x -> A.PV x
APS s -> A.PString s
API i -> A.PInt $ i
APF i -> A.PFloat $ i
APW -> A.PW
trQIdent (CIQ m c) = (m,c)
-- from internal to file
infos2defs = map info2def . tree2list
info2def d = case d of
(c,AbsCat cont fs) -> AbsDCat c (rtCont cont) (rtFs fs)
(c,AbsFun ty df) -> AbsDFun c (rtExp ty) (rtExp df)
(c,AbsTrans t) -> AbsDTrans c (rtExp t)
(c,ResPar df) -> ResDPar c df
(c,ResOper ty df) -> ResDOper c ty df
(c,CncCat ty df pr) -> CncDCat c ty df pr
(f,CncFun c xs li pr) -> CncDFun f c xs li pr
(c,AnyInd b m) -> AnyDInd c (if b then Canon else NonCan) m
rtCont cont = [Decl (rtIdent x) (rtExp t) | (x,t) <- cont]
rtFs = map rtQIdent
rtExp :: A.Term -> Exp
rtExp t = case t of
A.Prod x a b -> EProd (rtIdent x) (rtExp a) (rtExp b)
A.Abs x b -> EAbs (rtIdent x) (rtExp b)
A.App f a -> EApp (rtExp f) (rtExp a)
A.Eqs eqs -> EEq [Equ (map rtPt ps) (rtExp e) | (ps,e) <- eqs]
A.EData -> EData
_ -> EAtom $ rtAt t
where
rtAt t = case t of
A.Q m c -> AC $ rtQIdent (m,c)
A.QC m c -> AD $ rtQIdent (m,c)
A.Vr v -> AV v
A.Meta i -> AM $ toInteger $ A.metaSymbInt i
A.Sort "Type" -> AT SType
A.K s -> AS s
A.EInt i -> AI $ toInteger i
_ -> error $ "MkGFC.rt not defined for" +++ show t
rtPt p = case p of
A.PP m c ps -> APC (rtQIdent (m,c)) (map rtPt ps)
A.PV x -> APV x
A.PString s -> APS s
A.PInt i -> API $ toInteger i
A.PW -> APW
_ -> error $ "MkGFC.rt not defined for" +++ show p
rtQIdent :: (Ident, Ident) -> CIdent
rtQIdent (m,c) = CIQ (rtIdent m) (rtIdent c)
rtIdent x
| isWildIdent x = identC "h_" --- needed in declarations
| otherwise = identC $ prt x ---
{-
-- the following is called in GetGFC to read gfc files line
-- by line. It does not save memory, though, and is therefore
-- not used.
buildCanonGrammar :: Int -> CanonGrammar -> Line -> (CanonGrammar,Int)
buildCanonGrammar n gr0 line = mgr $ case line of
-- LMulti ids id
LHeader mt ext op -> newModule mt ext op
LFlag f@(Flg (IC "modulesize") (IC n)) -> initModule f $ read $ tail n
LFlag flag -> newFlag flag
LDef def -> newDef $ def2info def
-- LEnd -> cleanNames
_ -> M.modules gr0
where
newModule mt ext op = mod2info (Mod mt ext op [] []) : mods
initModule f i = case actm of
(name, M.ModMod (M.Module mt com flags ee oo defs)) ->
(name, M.ModMod (M.Module mt com (f:flags) ee oo (newtree i))) : tmods
newFlag f = case actm of
(name, M.ModMod (M.Module mt com flags ee oo defs)) ->
(name, M.ModMod (M.Module mt com (f:flags) ee oo defs)) : tmods
newDef d = case actm of
(name, M.ModMod (M.Module mt com flags ee oo defs)) ->
(name, M.ModMod (M.Module mt com flags ee oo
(upd (padd 8 n) d defs))) : tmods
-- cleanNames = case actm of
-- (name, M.ModMod (M.Module mt com flags ee oo defs)) ->
-- (name, M.ModMod (M.Module mt com (reverse flags) ee oo
-- (mapTree (\ (IC f,t) -> (IC (drop 8 f),t)) defs))) : tmods
actm = head mods -- only used when a new mod has been created
mods = M.modules gr0
tmods = tail mods
mgr ms = (M.MGrammar ms, case line of
LDef _ -> n+1
LEnd -> 1
_ -> n
)
-- create an initial tree with who-cares value
newtree (i :: Int) = emptyBinTree
-- newtree (i :: Int) = sorted2tree [
-- (padd 8 k, ResPar []) |
-- k <- [1..i]] --- padd (length (show i))
padd l k = 0
-- padd l k = let sk = show k in identC (replicate (l - length sk) '0' ++ sk)
upd _ d defs = updateTree d defs
-- upd n d@(f,t) defs = case defs of
-- NT -> BT (merg n f,t) NT NT --- should not happen
-- BT c@(a,_) left right
-- | n < a -> let left' = upd n d left in BT c left' right
-- | n > a -> let right' = upd n d right in BT c left right'
-- | otherwise -> BT (merg n f,t) left right
-- merg (IC n) (IC f) = IC (n ++ f)
-}

2142
src-3.0/GF/Canon/ParGFC.hs Normal file

File diff suppressed because one or more lines are too long

385
src-3.0/GF/Canon/ParGFC.y Normal file
View File

@@ -0,0 +1,385 @@
-- This Happy file was machine-generated by the BNF converter
{
module GF.Canon.ParGFC where
import GF.Canon.AbsGFC
import GF.Canon.LexGFC
import GF.Data.ErrM -- H
import GF.Infra.Ident -- H
}
%name pCanon Canon
%name pLine Line
-- no lexer declaration
%monad { Err } { thenM } { returnM }
%tokentype { Token }
%token
';' { PT _ (TS ";") }
'=' { PT _ (TS "=") }
'{' { PT _ (TS "{") }
'}' { PT _ (TS "}") }
':' { PT _ (TS ":") }
'->' { PT _ (TS "->") }
'**' { PT _ (TS "**") }
'[' { PT _ (TS "[") }
']' { PT _ (TS "]") }
'\\' { PT _ (TS "\\") }
'.' { PT _ (TS ".") }
'(' { PT _ (TS "(") }
')' { PT _ (TS ")") }
'_' { PT _ (TS "_") }
'<' { PT _ (TS "<") }
'>' { PT _ (TS ">") }
'$' { PT _ (TS "$") }
'?' { PT _ (TS "?") }
'=>' { PT _ (TS "=>") }
'!' { PT _ (TS "!") }
'++' { PT _ (TS "++") }
'/' { PT _ (TS "/") }
'@' { PT _ (TS "@") }
'+' { PT _ (TS "+") }
'|' { PT _ (TS "|") }
',' { PT _ (TS ",") }
'Ints' { PT _ (TS "Ints") }
'Str' { PT _ (TS "Str") }
'Type' { PT _ (TS "Type") }
'abstract' { PT _ (TS "abstract") }
'cat' { PT _ (TS "cat") }
'concrete' { PT _ (TS "concrete") }
'data' { PT _ (TS "data") }
'flags' { PT _ (TS "flags") }
'fun' { PT _ (TS "fun") }
'grammar' { PT _ (TS "grammar") }
'in' { PT _ (TS "in") }
'lin' { PT _ (TS "lin") }
'lincat' { PT _ (TS "lincat") }
'of' { PT _ (TS "of") }
'open' { PT _ (TS "open") }
'oper' { PT _ (TS "oper") }
'param' { PT _ (TS "param") }
'pre' { PT _ (TS "pre") }
'resource' { PT _ (TS "resource") }
'table' { PT _ (TS "table") }
'transfer' { PT _ (TS "transfer") }
'variants' { PT _ (TS "variants") }
L_ident { PT _ (TV $$) }
L_quoted { PT _ (TL $$) }
L_integ { PT _ (TI $$) }
L_err { _ }
%%
Ident :: { Ident } : L_ident { identC $1 } -- H
String :: { String } : L_quoted { $1 }
Integer :: { Integer } : L_integ { (read $1) :: Integer }
Canon :: { Canon }
Canon : 'grammar' ListIdent 'of' Ident ';' ListModule { MGr $2 $4 (reverse $6) }
| ListModule { Gr (reverse $1) }
Line :: { Line }
Line : 'grammar' ListIdent 'of' Ident ';' { LMulti $2 $4 }
| ModType '=' Extend Open '{' { LHeader $1 $3 $4 }
| Flag ';' { LFlag $1 }
| Def ';' { LDef $1 }
| '}' { LEnd }
Module :: { Module }
Module : ModType '=' Extend Open '{' ListFlag ListDef '}' { Mod $1 $3 $4 (reverse $6) (reverse $7) }
ModType :: { ModType }
ModType : 'abstract' Ident { MTAbs $2 }
| 'concrete' Ident 'of' Ident { MTCnc $2 $4 }
| 'resource' Ident { MTRes $2 }
| 'transfer' Ident ':' Ident '->' Ident { MTTrans $2 $4 $6 }
ListModule :: { [Module] }
ListModule : {- empty -} { [] }
| ListModule Module { flip (:) $1 $2 }
Extend :: { Extend }
Extend : ListIdent '**' { Ext $1 }
| {- empty -} { NoExt }
Open :: { Open }
Open : 'open' ListIdent 'in' { Opens $2 }
| {- empty -} { NoOpens }
Flag :: { Flag }
Flag : 'flags' Ident '=' Ident { Flg $2 $4 }
Def :: { Def }
Def : 'cat' Ident '[' ListDecl ']' '=' ListCIdent { AbsDCat $2 $4 (reverse $7) }
| 'fun' Ident ':' Exp '=' Exp { AbsDFun $2 $4 $6 }
| 'transfer' Ident '=' Exp { AbsDTrans $2 $4 }
| 'param' Ident '=' ListParDef { ResDPar $2 $4 }
| 'oper' Ident ':' CType '=' Term { ResDOper $2 $4 $6 }
| 'lincat' Ident '=' CType '=' Term ';' Term { CncDCat $2 $4 $6 $8 }
| 'lin' Ident ':' CIdent '=' '\\' ListArgVar '->' Term ';' Term { CncDFun $2 $4 $7 $9 $11 }
| Ident Status 'in' Ident { AnyDInd $1 $2 $4 }
ParDef :: { ParDef }
ParDef : Ident ListCType { ParD $1 (reverse $2) }
Status :: { Status }
Status : 'data' { Canon }
| {- empty -} { NonCan }
CIdent :: { CIdent }
CIdent : Ident '.' Ident { CIQ $1 $3 }
Exp1 :: { Exp }
Exp1 : Exp1 Exp2 { EApp $1 $2 }
| Exp2 { $1 }
Exp :: { Exp }
Exp : '(' Ident ':' Exp ')' '->' Exp { EProd $2 $4 $7 }
| '\\' Ident '->' Exp { EAbs $2 $4 }
| '{' ListEquation '}' { EEq (reverse $2) }
| Exp1 { $1 }
Exp2 :: { Exp }
Exp2 : Atom { EAtom $1 }
| 'data' { EData }
| '(' Exp ')' { $2 }
Sort :: { Sort }
Sort : 'Type' { SType }
Equation :: { Equation }
Equation : ListAPatt '->' Exp { Equ (reverse $1) $3 }
APatt :: { APatt }
APatt : '(' CIdent ListAPatt ')' { APC $2 (reverse $3) }
| Ident { APV $1 }
| String { APS $1 }
| Integer { API $1 }
| '_' { APW }
ListDecl :: { [Decl] }
ListDecl : {- empty -} { [] }
| Decl { (:[]) $1 }
| Decl ';' ListDecl { (:) $1 $3 }
ListAPatt :: { [APatt] }
ListAPatt : {- empty -} { [] }
| ListAPatt APatt { flip (:) $1 $2 }
ListEquation :: { [Equation] }
ListEquation : {- empty -} { [] }
| ListEquation Equation ';' { flip (:) $1 $2 }
Atom :: { Atom }
Atom : CIdent { AC $1 }
| '<' CIdent '>' { AD $2 }
| '$' Ident { AV $2 }
| '?' Integer { AM $2 }
| String { AS $1 }
| Integer { AI $1 }
| Sort { AT $1 }
Decl :: { Decl }
Decl : Ident ':' Exp { Decl $1 $3 }
CType :: { CType }
CType : '{' ListLabelling '}' { RecType $2 }
| '(' CType '=>' CType ')' { Table $2 $4 }
| CIdent { Cn $1 }
| 'Str' { TStr }
| 'Ints' Integer { TInts $2 }
Labelling :: { Labelling }
Labelling : Label ':' CType { Lbg $1 $3 }
Term2 :: { Term }
Term2 : ArgVar { Arg $1 }
| CIdent { I $1 }
| '<' CIdent ListTerm2 '>' { Par $2 (reverse $3) }
| '$' Ident { LI $2 }
| '{' ListAssign '}' { R $2 }
| Integer { EInt $1 }
| Tokn { K $1 }
| '[' ']' { E }
| '(' Term ')' { $2 }
Term1 :: { Term }
Term1 : Term2 '.' Label { P $1 $3 }
| 'table' CType '{' ListCase '}' { T $2 $4 }
| 'table' CType '[' ListTerm2 ']' { V $2 (reverse $4) }
| Term1 '!' Term2 { S $1 $3 }
| 'variants' '{' ListTerm2 '}' { FV (reverse $3) }
| Term2 { $1 }
Term :: { Term }
Term : Term '++' Term1 { C $1 $3 }
| Term1 { $1 }
Tokn :: { Tokn }
Tokn : String { KS $1 }
| '[' 'pre' ListString '{' ListVariant '}' ']' { KP (reverse $3) $5 }
Assign :: { Assign }
Assign : Label '=' Term { Ass $1 $3 }
Case :: { Case }
Case : ListPatt '=>' Term { Cas (reverse $1) $3 }
Variant :: { Variant }
Variant : ListString '/' ListString { Var (reverse $1) (reverse $3) }
Label :: { Label }
Label : Ident { L $1 }
| '$' Integer { LV $2 }
ArgVar :: { ArgVar }
ArgVar : Ident '@' Integer { A $1 $3 }
| Ident '+' Integer '@' Integer { AB $1 $3 $5 }
Patt :: { Patt }
Patt : '(' CIdent ListPatt ')' { PC $2 (reverse $3) }
| Ident { PV $1 }
| '_' { PW }
| '{' ListPattAssign '}' { PR $2 }
| Integer { PI $1 }
PattAssign :: { PattAssign }
PattAssign : Label '=' Patt { PAss $1 $3 }
ListFlag :: { [Flag] }
ListFlag : {- empty -} { [] }
| ListFlag Flag ';' { flip (:) $1 $2 }
ListDef :: { [Def] }
ListDef : {- empty -} { [] }
| ListDef Def ';' { flip (:) $1 $2 }
ListParDef :: { [ParDef] }
ListParDef : {- empty -} { [] }
| ParDef { (:[]) $1 }
| ParDef '|' ListParDef { (:) $1 $3 }
ListCType :: { [CType] }
ListCType : {- empty -} { [] }
| ListCType CType { flip (:) $1 $2 }
ListCIdent :: { [CIdent] }
ListCIdent : {- empty -} { [] }
| ListCIdent CIdent { flip (:) $1 $2 }
ListAssign :: { [Assign] }
ListAssign : {- empty -} { [] }
| Assign { (:[]) $1 }
| Assign ';' ListAssign { (:) $1 $3 }
ListArgVar :: { [ArgVar] }
ListArgVar : {- empty -} { [] }
| ArgVar { (:[]) $1 }
| ArgVar ',' ListArgVar { (:) $1 $3 }
ListLabelling :: { [Labelling] }
ListLabelling : {- empty -} { [] }
| Labelling { (:[]) $1 }
| Labelling ';' ListLabelling { (:) $1 $3 }
ListCase :: { [Case] }
ListCase : {- empty -} { [] }
| Case { (:[]) $1 }
| Case ';' ListCase { (:) $1 $3 }
ListTerm2 :: { [Term] }
ListTerm2 : {- empty -} { [] }
| ListTerm2 Term2 { flip (:) $1 $2 }
ListString :: { [String] }
ListString : {- empty -} { [] }
| ListString String { flip (:) $1 $2 }
ListVariant :: { [Variant] }
ListVariant : {- empty -} { [] }
| Variant { (:[]) $1 }
| Variant ';' ListVariant { (:) $1 $3 }
ListPattAssign :: { [PattAssign] }
ListPattAssign : {- empty -} { [] }
| PattAssign { (:[]) $1 }
| PattAssign ';' ListPattAssign { (:) $1 $3 }
ListPatt :: { [Patt] }
ListPatt : {- empty -} { [] }
| ListPatt Patt { flip (:) $1 $2 }
ListIdent :: { [Ident] }
ListIdent : {- empty -} { [] }
| Ident { (:[]) $1 }
| Ident ',' ListIdent { (:) $1 $3 }
{
returnM :: a -> Err a
returnM = return
thenM :: Err a -> (a -> Err b) -> Err b
thenM = (>>=)
happyError :: [Token] -> Err a
happyError ts =
Bad $ "syntax error at " ++ tokenPos ts ++ if null ts then [] else (" before " ++ unwords (map prToken (take 4 ts)))
myLexer = tokens
}

46
src-3.0/GF/Canon/PrExp.hs Normal file
View File

@@ -0,0 +1,46 @@
----------------------------------------------------------------------
-- |
-- Module : PrExp
-- Maintainer : AR
-- Stability : (stable)
-- Portability : (portable)
--
-- > CVS $Date: 2005/04/21 16:21:28 $
-- > CVS $Author: bringert $
-- > CVS $Revision: 1.5 $
--
-- print trees without qualifications
-----------------------------------------------------------------------------
module GF.Canon.PrExp (prExp) where
import GF.Canon.AbsGFC
import GF.Canon.GFC
import GF.Data.Operations
prExp :: Exp -> String
prExp e = case e of
EApp f a -> pr1 f +++ pr2 a
EAbsR x b -> "\\" ++ prtt x +++ "->" +++ prExp b
EAbs x _ b -> prExp $ EAbsR x b
EProd x a b -> "(\\" ++ prtt x +++ ":" +++ prExp a ++ ")" +++ "->" +++ prExp b
EAtomR a -> prAtom a
EAtom a _ -> prAtom a
_ -> prtt e
where
pr1 e = case e of
EAbsR _ _ -> prParenth $ prExp e
EAbs _ _ _ -> prParenth $ prExp e
EProd _ _ _ -> prParenth $ prExp e
_ -> prExp e
pr2 e = case e of
EApp _ _ -> prParenth $ prExp e
_ -> pr1 e
prAtom a = case a of
AC c -> prCIdent c
AD c -> prCIdent c
_ -> prtt a
prCIdent (CIQ _ c) = prtt c

View File

@@ -0,0 +1,376 @@
module GF.Canon.PrintGFC where
-- pretty-printer generated by the BNF converter, except handhacked spacing --H
import GF.Infra.Ident --H
import GF.Canon.AbsGFC
import Data.Char
-- the top-level printing method
printTree :: Print a => a -> String
printTree = render . prt 0
type Doc = [ShowS] -> [ShowS]
doc :: ShowS -> Doc
doc = (:)
docs :: ShowS -> Doc
docs x y = concatD [spc, doc x, spc ] y
spc = doc (showString "&")
render :: Doc -> String
render d = rend 0 (map ($ "") $ d []) "" where
rend i ss = case ss of
"*" :ts -> realnew . rend i ts --H
"&":"&":ts -> showChar ' ' . rend i ts --H
"&" :ts -> rend i ts --H
t :ts -> showString t . rend i ts
_ -> id
realnew = showChar '\n' --H
{-
render :: Doc -> String
render d = rend 0 (map ($ "") $ d []) "" where
rend i ss = case ss of
"*NEW" :ts -> realnew . rend i ts --H
"<" :ts -> showString "<" . rend i ts --H
"$" :ts -> showString "$" . rend i ts --H
"?" :ts -> showString "?" . rend i ts --H
"[" :ts -> showChar '[' . rend i ts
"(" :ts -> showChar '(' . rend i ts
"{" :ts -> showChar '{' . new (i+1) . rend (i+1) ts
"}" : ";":ts -> new (i-1) . showChar '}' . showChar ';' . new (i-1) . rend (i-1) ts
"}" :ts -> new (i-1) . showChar '}' . new (i-1) . rend (i-1) ts
";" :ts -> showChar ';' . new i . rend i ts
t : "@" :ts -> showString t . showChar '@' . rend i ts
t : "," :ts -> showString t . showChar ',' . rend i ts
t : ")" :ts -> showString t . showChar ')' . rend i ts
t : "]" :ts -> showString t . showChar ']' . rend i ts
t : ">" :ts -> showString t . showChar '>' . rend i ts --H
t : "." :ts -> showString t . showChar '.' . rend i ts --H
t@"=>" :ts -> showString t . rend i ts --H
t@"->" :ts -> showString t . rend i ts --H
t :ts -> realspace t . rend i ts --H
_ -> id
space t = showString t . showChar ' ' -- H
realspace t = showString t . (\s -> if null s then "" else (' ':s)) -- H
new i s = s -- H
realnew = showChar '\n' --H
-}
parenth :: Doc -> Doc
parenth ss = doc (showChar '(') . ss . doc (showChar ')')
concatS :: [ShowS] -> ShowS
concatS = foldr (.) id
concatD :: [Doc] -> Doc
concatD = foldr (.) id
replicateS :: Int -> ShowS -> ShowS
replicateS n f = concatS (replicate n f)
-- the printer class does the job
class Print a where
prt :: Int -> a -> Doc
prtList :: [a] -> Doc
prtList = concatD . map (prt 0)
instance Print a => Print [a] where
prt _ = prtList
instance Print Char where
prt _ s = doc (showChar '\'' . mkEsc '\'' s . showChar '\'')
prtList s = doc (showChar '"' . concatS (map (mkEsc '"') s) . showChar '"')
mkEsc :: Char -> Char -> ShowS
mkEsc q s = case s of
_ | s == q -> showChar '\\' . showChar s
'\\'-> showString "\\\\"
'\n' -> showString "\\n"
'\t' -> showString "\\t"
_ -> showChar s
prPrec :: Int -> Int -> Doc -> Doc
prPrec i j = if j<i then parenth else id
instance Print Integer where
prt _ x = docs (shows x)
instance Print Double where
prt _ x = docs (shows x)
instance Print Ident where
prt _ i = docs (showString $ prIdent i) -- H
prtList es = case es of
[] -> (concatD [])
[x] -> (concatD [prt 0 x])
x:xs -> (concatD [prt 0 x , doc (showString ",") , prt 0 xs])
instance Print Canon where
prt i e = case e of
MGr ids id modules -> prPrec i 0 (concatD [spc, doc (showString "grammar") , spc, prt 0 ids , spc , doc (showString "of") , spc, prt 0 id , doc (showString ";") , prt 0 modules])
Gr modules -> prPrec i 0 (concatD [prt 0 modules])
instance Print Line where
prt i e = case e of
LMulti ids id -> prPrec i 0 (concatD [spc, doc (showString "grammar") , spc, prt 0 ids , spc, doc (showString "of") , spc, prt 0 id , doc (showString ";")])
LHeader modtype extend open -> prPrec i 0 (concatD [prt 0 modtype , doc (showString "=") , prt 0 extend , prt 0 open , doc (showString "{")])
LFlag flag -> prPrec i 0 (concatD [prt 0 flag , doc (showString ";")])
LDef def -> prPrec i 0 (concatD [prt 0 def , doc (showString ";")])
LEnd -> prPrec i 0 (concatD [doc (showString "}")])
instance Print Module where
prt i e = case e of
Mod modtype extend open flags defs -> prPrec i 0 (concatD [prt 0 modtype , doc (showString "=") , prt 0 extend , prt 0 open , doc (showString "{") , prt 0 flags , prt 0 defs , doc (showString "}")])
prtList es = case es of
[] -> (concatD [])
x:xs -> (concatD [prt 0 x , prt 0 xs])
instance Print ModType where
prt i e = case e of
MTAbs id -> prPrec i 0 (concatD [spc, doc (showString "abstract") , spc , prt 0 id])
MTCnc id0 id -> prPrec i 0 (concatD [spc, doc (showString "concrete") , spc, prt 0 id0 , spc, doc (showString "of") , spc, prt 0 id])
MTRes id -> prPrec i 0 (concatD [spc, doc (showString "resource") , spc, prt 0 id])
MTTrans id0 id1 id -> prPrec i 0 (concatD [spc, doc (showString "transfer") , spc, prt 0 id0 , doc (showString ":") , prt 0 id1 , doc (showString "->") , prt 0 id])
instance Print Extend where
prt i e = case e of
Ext ids -> prPrec i 0 (concatD [prt 0 ids , doc (showString "**")])
NoExt -> prPrec i 0 (concatD [])
instance Print Open where
prt i e = case e of
Opens ids -> prPrec i 0 (concatD [spc, doc (showString "open") , spc, prt 0 ids , docs (showString "in")])
NoOpens -> prPrec i 0 (concatD [])
instance Print Flag where
prt i e = case e of
Flg id0 id -> prPrec i 0 (concatD [spc, doc (showString "flags") , spc, prt 0 id0 , doc (showString "=") , prt 0 id])
prtList es = case es of
[] -> (concatD [])
x:xs -> (concatD [prt 0 x , doc (showString ";") , prt 0 xs])
instance Print Def where
prt i e = case e of
AbsDCat id decls cidents -> prPrec i 0 (concatD [docs (showString "cat") , prt 0 id , doc (showString "[") , prt 0 decls , doc (showString "]") , doc (showString "=") , prt 0 cidents])
AbsDFun id exp0 exp -> prPrec i 0 (concatD [docs (showString "fun") , prt 0 id , doc (showString ":") , prt 0 exp0 , doc (showString "=") , prt 0 exp])
AbsDTrans id exp -> prPrec i 0 (concatD [docs (showString "transfer") , prt 0 id , doc (showString "=") , prt 0 exp])
ResDPar id pardefs -> prPrec i 0 (concatD [docs (showString "param") , prt 0 id , doc (showString "=") , prt 0 pardefs])
ResDOper id ctype term -> prPrec i 0 (concatD [docs (showString "oper") , prt 0 id , doc (showString ":") , prt 0 ctype , doc (showString "=") , prt 0 term])
CncDCat id ctype term0 term -> prPrec i 0 (concatD [docs (showString "lincat") , prt 0 id , doc (showString "=") , prt 0 ctype , doc (showString "=") , prt 0 term0 , doc (showString ";") , prt 0 term])
CncDFun id cident argvars term0 term -> prPrec i 0 (concatD [docs (showString "lin") , prt 0 id , doc (showString ":") , prt 0 cident , doc (showString "=") , doc (showString "\\") , prt 0 argvars , doc (showString "->") , prt 0 term0 , doc (showString ";") , prt 0 term])
AnyDInd id0 status id -> prPrec i 0 (concatD [prt 0 id0 , prt 0 status , docs (showString "in") , prt 0 id])
prtList es = case es of
[] -> (concatD [])
x:xs -> (concatD [prt 0 x , doc (showString ";"), doc (showString "*") , prt 0 xs]) -- H
instance Print ParDef where
prt i e = case e of
ParD id ctypes -> prPrec i 0 (concatD [prt 0 id , prt 0 ctypes])
prtList es = case es of
[] -> (concatD [])
[x] -> (concatD [prt 0 x])
x:xs -> (concatD [prt 0 x , doc (showString "|") , prt 0 xs])
instance Print Status where
prt i e = case e of
Canon -> prPrec i 0 (concatD [docs (showString "data")])
NonCan -> prPrec i 0 (concatD [])
instance Print CIdent where
prt i e = case e of
CIQ id0 id -> prPrec i 0 (concatD [prt 0 id0 , doc (showString ".") , prt 0 id])
prtList es = case es of
[] -> (concatD [])
x:xs -> (concatD [prt 0 x , prt 0 xs])
instance Print Exp where
prt i e = case e of
EApp exp0 exp -> prPrec i 1 (concatD [prt 1 exp0 , prt 2 exp])
EProd id exp0 exp -> prPrec i 0 (concatD [doc (showString "(") , prt 0 id , doc (showString ":") , prt 0 exp0 , doc (showString ")") , doc (showString "->") , prt 0 exp])
EAbs id exp -> prPrec i 0 (concatD [doc (showString "\\") , prt 0 id , doc (showString "->") , prt 0 exp])
EAtom atom -> prPrec i 2 (concatD [prt 0 atom])
EData -> prPrec i 2 (concatD [docs (showString "data")])
EEq equations -> prPrec i 0 (concatD [doc (showString "{") , prt 0 equations , doc (showString "}")])
instance Print Sort where
prt i e = case e of
SType -> prPrec i 0 (concatD [docs (showString "Type")])
instance Print Equation where
prt i e = case e of
Equ apatts exp -> prPrec i 0 (concatD [prt 0 apatts , doc (showString "->") , prt 0 exp])
prtList es = case es of
[] -> (concatD [])
x:xs -> (concatD [prt 0 x , doc (showString ";") , prt 0 xs])
instance Print APatt where
prt i e = case e of
APC cident apatts -> prPrec i 0 (concatD [doc (showString "(") , prt 0 cident , prt 0 apatts , doc (showString ")")])
APV id -> prPrec i 0 (concatD [prt 0 id])
APS str -> prPrec i 0 (concatD [prt 0 str])
API n -> prPrec i 0 (concatD [prt 0 n])
APF n -> prPrec i 0 (concatD [prt 0 n])
APW -> prPrec i 0 (concatD [doc (showString "_")])
prtList es = case es of
[] -> (concatD [])
x:xs -> (concatD [prt 0 x , prt 0 xs])
instance Print Atom where
prt i e = case e of
AC cident -> prPrec i 0 (concatD [prt 0 cident])
AD cident -> prPrec i 0 (concatD [doc (showString "<") , prt 0 cident , doc (showString ">")])
AV id -> prPrec i 0 (concatD [doc (showString "$") , prt 0 id])
AM n -> prPrec i 0 (concatD [doc (showString "?") , prt 0 n])
AS str -> prPrec i 0 (concatD [prt 0 str])
AI n -> prPrec i 0 (concatD [prt 0 n])
AT sort -> prPrec i 0 (concatD [prt 0 sort])
instance Print Decl where
prt i e = case e of
Decl id exp -> prPrec i 0 (concatD [prt 0 id , doc (showString ":") , prt 0 exp])
prtList es = case es of
[] -> (concatD [])
[x] -> (concatD [prt 0 x])
x:xs -> (concatD [prt 0 x , doc (showString ";") , prt 0 xs])
instance Print CType where
prt i e = case e of
RecType labellings -> prPrec i 0 (concatD [doc (showString "{") , prt 0 labellings , doc (showString "}")])
Table ctype0 ctype -> prPrec i 0 (concatD [doc (showString "(") , prt 0 ctype0 , doc (showString "=>") , prt 0 ctype , doc (showString ")")])
Cn cident -> prPrec i 0 (concatD [prt 0 cident])
TStr -> prPrec i 0 (concatD [docs (showString "Str")])
TInts n -> prPrec i 0 (concatD [docs (showString "Ints") , prt 0 n])
prtList es = case es of
[] -> (concatD [])
x:xs -> (concatD [prt 0 x , prt 0 xs])
instance Print Labelling where
prt i e = case e of
Lbg label ctype -> prPrec i 0 (concatD [prt 0 label , doc (showString ":") , prt 0 ctype])
prtList es = case es of
[] -> (concatD [])
[x] -> (concatD [prt 0 x])
x:xs -> (concatD [prt 0 x , doc (showString ";") , prt 0 xs])
instance Print Term where
prt i e = case e of
Arg argvar -> prPrec i 2 (concatD [prt 0 argvar])
I cident -> prPrec i 2 (concatD [prt 0 cident])
Par cident terms -> prPrec i 2 (concatD [doc (showString "<") , prt 0 cident , prt 2 terms , doc (showString ">")])
LI id -> prPrec i 2 (concatD [doc (showString "$") , prt 0 id])
R assigns -> prPrec i 2 (concatD [doc (showString "{") , prt 0 assigns , doc (showString "}")])
P term label -> prPrec i 1 (concatD [prt 2 term , doc (showString ".") , prt 0 label])
T ctype cases -> prPrec i 1 (concatD [docs (showString "table") , prt 0 ctype , doc (showString "{") , prt 0 cases , doc (showString "}")])
V ctype terms -> prPrec i 1 (concatD [docs (showString "table") , prt 0 ctype , doc (showString "[") , prt 2 terms , doc (showString "]")])
S term0 term -> prPrec i 1 (concatD [prt 1 term0 , doc (showString "!") , prt 2 term])
C term0 term -> prPrec i 0 (concatD [prt 0 term0 , doc (showString "++") , prt 1 term])
FV terms -> prPrec i 1 (concatD [docs (showString "variants") , doc (showString "{") , prt 2 terms , doc (showString "}")])
EInt n -> prPrec i 2 (concatD [prt 0 n])
EFloat n -> prPrec i 2 (concatD [prt 0 n])
K tokn -> prPrec i 2 (concatD [prt 0 tokn])
E -> prPrec i 2 (concatD [doc (showString "[") , doc (showString "]")])
prtList es = case es of
[] -> (concatD [])
x:xs -> (concatD [prt 2 x , prt 2 xs])
instance Print Tokn where
prt i e = case e of
KS str -> prPrec i 0 (concatD [prt 0 str])
KP strs variants -> prPrec i 0 (concatD [doc (showString "[") , docs (showString "pre") , prt 0 strs , doc (showString "{") , prt 0 variants , doc (showString "}") , doc (showString "]")])
KM str -> prPrec i 0 (concatD [prt 0 str])
instance Print Assign where
prt i e = case e of
Ass label term -> prPrec i 0 (concatD [prt 0 label , doc (showString "=") , prt 0 term])
prtList es = case es of
[] -> (concatD [])
[x] -> (concatD [prt 0 x])
x:xs -> (concatD [prt 0 x , doc (showString ";") , prt 0 xs])
instance Print Case where
prt i e = case e of
Cas patts term -> prPrec i 0 (concatD [prt 0 patts , doc (showString "=>") , prt 0 term])
prtList es = case es of
[] -> (concatD [])
[x] -> (concatD [prt 0 x])
x:xs -> (concatD [prt 0 x , doc (showString ";") , prt 0 xs])
instance Print Variant where
prt i e = case e of
Var strs0 strs -> prPrec i 0 (concatD [prt 0 strs0 , doc (showString "/") , prt 0 strs])
prtList es = case es of
[] -> (concatD [])
[x] -> (concatD [prt 0 x])
x:xs -> (concatD [prt 0 x , doc (showString ";") , prt 0 xs])
instance Print Label where
prt i e = case e of
L id -> prPrec i 0 (concatD [prt 0 id])
LV n -> prPrec i 0 (concatD [doc (showString "$") , prt 0 n])
instance Print ArgVar where
prt i e = case e of
A id n -> prPrec i 0 (concatD [prt 0 id , doc (showString "@") , prt 0 n])
AB id n0 n -> prPrec i 0 (concatD [prt 0 id , doc (showString "+") , prt 0 n0 , doc (showString "@") , prt 0 n])
prtList es = case es of
[] -> (concatD [])
[x] -> (concatD [prt 0 x])
x:xs -> (concatD [prt 0 x , doc (showString ",") , prt 0 xs])
instance Print Patt where
prt i e = case e of
PC cident patts -> prPrec i 0 (concatD [doc (showString "(") , prt 0 cident , prt 0 patts , doc (showString ")")])
PV id -> prPrec i 0 (concatD [prt 0 id])
PW -> prPrec i 0 (concatD [docs (showString "_")])
PR pattassigns -> prPrec i 0 (concatD [doc (showString "{") , prt 0 pattassigns , doc (showString "}")])
PI n -> prPrec i 0 (concatD [prt 0 n])
PF n -> prPrec i 0 (concatD [prt 0 n])
prtList es = case es of
[] -> (concatD [])
x:xs -> (concatD [prt 0 x , prt 0 xs])
instance Print PattAssign where
prt i e = case e of
PAss label patt -> prPrec i 0 (concatD [prt 0 label , doc (showString "=") , prt 0 patt])
prtList es = case es of
[] -> (concatD [])
[x] -> (concatD [prt 0 x])
x:xs -> (concatD [prt 0 x , doc (showString ";") , prt 0 xs])

147
src-3.0/GF/Canon/Share.hs Normal file
View File

@@ -0,0 +1,147 @@
----------------------------------------------------------------------
-- |
-- Module : Share
-- Maintainer : AR
-- Stability : (stable)
-- Portability : (portable)
--
-- > CVS $Date: 2005/06/17 14:15:18 $
-- > CVS $Author: bringert $
-- > CVS $Revision: 1.12 $
--
-- Optimizations on GFC code: sharing, parametrization, value sets.
--
-- optimization: sharing branches in tables. AR 25\/4\/2003.
-- following advice of Josef Svenningsson
-----------------------------------------------------------------------------
module GF.Canon.Share (shareModule, OptSpec, shareOpt, paramOpt, valOpt, allOpt) where
import GF.Canon.AbsGFC
import GF.Infra.Ident
import GF.Canon.GFC
import qualified GF.Canon.CMacros as C
import GF.Grammar.PrGrammar (prt)
import GF.Data.Operations
import Data.List
import qualified GF.Infra.Modules as M
type OptSpec = [Integer] ---
doOptFactor opt = elem 2 opt
doOptValues opt = elem 3 opt
shareOpt :: OptSpec
shareOpt = []
paramOpt :: OptSpec
paramOpt = [2]
valOpt :: OptSpec
valOpt = [3]
allOpt :: OptSpec
allOpt = [2,3]
shareModule :: OptSpec -> (Ident, CanonModInfo) -> (Ident, CanonModInfo)
shareModule opt (i,m) = case m of
M.ModMod (M.Module mt st fs me ops js) ->
(i,M.ModMod (M.Module mt st fs me ops (mapTree (shareInfo opt) js)))
_ -> (i,m)
shareInfo opt (c, CncCat ty t m) = (c, CncCat ty (shareOptim opt c t) m)
shareInfo opt (c, CncFun k xs t m) = (c, CncFun k xs (shareOptim opt c t) m)
shareInfo _ i = i
-- | the function putting together optimizations
shareOptim :: OptSpec -> Ident -> Term -> Term
shareOptim opt c
| doOptFactor opt && doOptValues opt = values . factor c 0
| doOptFactor opt = share . factor c 0
| doOptValues opt = values
| otherwise = share
-- | we need no counter to create new variable names, since variables are
-- local to tables
share :: Term -> Term
share t = case t of
T ty cs -> shareT ty [(p, share v) | Cas ps v <- cs, p <- ps] -- only substant.
R lts -> R [Ass l (share t) | Ass l t <- lts]
P t l -> P (share t) l
S t a -> S (share t) (share a)
C t a -> C (share t) (share a)
FV ts -> FV (map share ts)
_ -> t -- including D, which is always born shared
where
shareT ty = finalize ty . groupC . sortC
sortC :: [(Patt,Term)] -> [(Patt,Term)]
sortC = sortBy $ \a b -> compare (snd a) (snd b)
groupC :: [(Patt,Term)] -> [[(Patt,Term)]]
groupC = groupBy $ \a b -> snd a == snd b
finalize :: CType -> [[(Patt,Term)]] -> Term
finalize ty css = T ty [Cas (map fst ps) t | ps@((_,t):_) <- css]
-- | do even more: factor parametric branches
factor :: Ident -> Int -> Term -> Term
factor c i t = case t of
T _ [_] -> t
T _ [] -> t
T ty cs -> T ty $ factors i [Cas [p] (factor c (i+1) v) | Cas ps v <- cs, p <- ps]
R lts -> R [Ass l (factor c i t) | Ass l t <- lts]
P t l -> P (factor c i t) l
S t a -> S (factor c i t) (factor c i a)
C t a -> C (factor c i t) (factor c i a)
FV ts -> FV (map (factor c i) ts)
_ -> t
where
factors i psvs = -- we know psvs has at least 2 elements
let p = pIdent c i
vs' = map (mkFun p) psvs
in if allEqs vs'
then mkCase p vs'
else psvs
mkFun p (Cas [patt] val) = replace (C.patt2term patt) (LI p) val
allEqs (v:vs) = all (==v) vs
mkCase p (v:_) = [Cas [PV p] v]
pIdent c i = identC ("p_" ++ prt c ++ "__" ++ show i)
-- | we need to replace subterms
replace :: Term -> Term -> Term -> Term
replace old new trm = case trm of
T ty cs -> T ty [Cas p (repl v) | Cas p v <- cs]
P t l -> P (repl t) l
S t a -> S (repl t) (repl a)
C t a -> C (repl t) (repl a)
FV ts -> FV (map repl ts)
-- these are the important cases, since they can correspond to patterns
Par c ts | trm == old -> new
Par c ts -> Par c (map repl ts)
R _ | isRec && trm == old -> new
R lts -> R [Ass l (repl t) | Ass l t <- lts]
_ -> trm
where
repl = replace old new
isRec = case trm of
R _ -> True
_ -> False
values :: Term -> Term
values t = case t of
T ty [c] -> T ty [Cas p (values t) | Cas p t <- [c]] -- preserve parametrization
T ty cs -> V ty [values t | Cas _ t <- cs] -- assumes proper order
_ -> C.composSafeOp values t

217
src-3.0/GF/Canon/SkelGFC.hs Normal file
View File

@@ -0,0 +1,217 @@
module GF.Canon.SkelGFC where
-- Haskell module generated by the BNF converter
import GF.Canon.AbsGFC
import GF.Data.ErrM
import GF.Infra.Ident
type Result = Err String
failure :: Show a => a -> Result
failure x = Bad $ "Undefined case: " ++ show x
transIdent :: Ident -> Result
transIdent x = case x of
Ident str -> failure x
transCanon :: Canon -> Result
transCanon x = case x of
MGr ids id modules -> failure x
Gr modules -> failure x
transLine :: Line -> Result
transLine x = case x of
LMulti ids id -> failure x
LHeader modtype extend open -> failure x
LFlag flag -> failure x
LDef def -> failure x
LEnd -> failure x
transModule :: Module -> Result
transModule x = case x of
Mod modtype extend open flags defs -> failure x
transModType :: ModType -> Result
transModType x = case x of
MTAbs id -> failure x
MTCnc id0 id -> failure x
MTRes id -> failure x
MTTrans id0 id1 id -> failure x
transExtend :: Extend -> Result
transExtend x = case x of
Ext ids -> failure x
NoExt -> failure x
transOpen :: Open -> Result
transOpen x = case x of
Opens ids -> failure x
NoOpens -> failure x
transFlag :: Flag -> Result
transFlag x = case x of
Flg id0 id -> failure x
transDef :: Def -> Result
transDef x = case x of
AbsDCat id decls cidents -> failure x
AbsDFun id exp0 exp -> failure x
AbsDTrans id exp -> failure x
ResDPar id pardefs -> failure x
ResDOper id ctype term -> failure x
CncDCat id ctype term0 term -> failure x
CncDFun id cident argvars term0 term -> failure x
AnyDInd id0 status id -> failure x
transParDef :: ParDef -> Result
transParDef x = case x of
ParD id ctypes -> failure x
transStatus :: Status -> Result
transStatus x = case x of
Canon -> failure x
NonCan -> failure x
transCIdent :: CIdent -> Result
transCIdent x = case x of
CIQ id0 id -> failure x
transExp :: Exp -> Result
transExp x = case x of
EApp exp0 exp -> failure x
EProd id exp0 exp -> failure x
EAbs id exp -> failure x
EAtom atom -> failure x
EData -> failure x
EEq equations -> failure x
transSort :: Sort -> Result
transSort x = case x of
SType -> failure x
transEquation :: Equation -> Result
transEquation x = case x of
Equ apatts exp -> failure x
transAPatt :: APatt -> Result
transAPatt x = case x of
APC cident apatts -> failure x
APV id -> failure x
APS str -> failure x
API n -> failure x
APW -> failure x
transAtom :: Atom -> Result
transAtom x = case x of
AC cident -> failure x
AD cident -> failure x
AV id -> failure x
AM n -> failure x
AS str -> failure x
AI n -> failure x
AT sort -> failure x
transDecl :: Decl -> Result
transDecl x = case x of
Decl id exp -> failure x
transCType :: CType -> Result
transCType x = case x of
RecType labellings -> failure x
Table ctype0 ctype -> failure x
Cn cident -> failure x
TStr -> failure x
TInts n -> failure x
transLabelling :: Labelling -> Result
transLabelling x = case x of
Lbg label ctype -> failure x
transTerm :: Term -> Result
transTerm x = case x of
Arg argvar -> failure x
I cident -> failure x
Par cident terms -> failure x
LI id -> failure x
R assigns -> failure x
P term label -> failure x
T ctype cases -> failure x
V ctype terms -> failure x
S term0 term -> failure x
C term0 term -> failure x
FV terms -> failure x
EInt n -> failure x
K tokn -> failure x
E -> failure x
transTokn :: Tokn -> Result
transTokn x = case x of
KS str -> failure x
KP strs variants -> failure x
KM str -> failure x
transAssign :: Assign -> Result
transAssign x = case x of
Ass label term -> failure x
transCase :: Case -> Result
transCase x = case x of
Cas patts term -> failure x
transVariant :: Variant -> Result
transVariant x = case x of
Var strs0 strs -> failure x
transLabel :: Label -> Result
transLabel x = case x of
L id -> failure x
LV n -> failure x
transArgVar :: ArgVar -> Result
transArgVar x = case x of
A id n -> failure x
AB id n0 n -> failure x
transPatt :: Patt -> Result
transPatt x = case x of
PC cident patts -> failure x
PV id -> failure x
PW -> failure x
PR pattassigns -> failure x
PI n -> failure x
transPattAssign :: PattAssign -> Result
transPattAssign x = case x of
PAss label patt -> failure x

View File

@@ -0,0 +1,170 @@
----------------------------------------------------------------------
-- |
-- Module : Subexpressions
-- Maintainer : AR
-- Stability : (stable)
-- Portability : (portable)
--
-- > CVS $Date: 2005/09/20 09:32:56 $
-- > CVS $Author: aarne $
-- > CVS $Revision: 1.4 $
--
-- Common subexpression elimination.
-- all tables. AR 18\/9\/2005.
-----------------------------------------------------------------------------
module GF.Canon.Subexpressions (
elimSubtermsMod, prSubtermStat, unSubelimCanon, unSubelimModule
) where
import GF.Canon.AbsGFC
import GF.Infra.Ident
import GF.Canon.GFC
import GF.Canon.Look
import GF.Grammar.PrGrammar
import GF.Canon.CMacros as C
import GF.Data.Operations
import qualified GF.Infra.Modules as M
import Control.Monad
import Data.Map (Map)
import qualified Data.Map as Map
import Data.List
{-
This module implements a simple common subexpression elimination
for gfc grammars, to factor out shared subterms in lin rules.
It works in three phases:
(1) collectSubterms collects recursively all subterms of forms table and (P x..y)
from lin definitions (experience shows that only these forms
tend to get shared) and counts how many times they occur
(2) addSubexpConsts takes those subterms t that occur more than once
and creates definitions of form "oper A''n = t" where n is a
fresh number; notice that we assume no ids of this form are in
scope otherwise
(3) elimSubtermsMod goes through lins and the created opers by replacing largest
possible subterms by the newly created identifiers
The optimization is invoked in gf by the flag i -subs.
If an application does not support GFC opers, the effect of this
optimization can be undone by the function unSubelimCanon.
The function unSubelimCanon can be used to diagnostisize how much
cse is possible in the grammar. It is used by the flag pg -printer=subs.
-}
-- exported functions
elimSubtermsMod :: (Ident,CanonModInfo) -> Err (Ident, CanonModInfo)
elimSubtermsMod (mo,m) = case m of
M.ModMod (M.Module mt st fs me ops js) -> do
(tree,_) <- appSTM (getSubtermsMod mo (tree2list js)) (Map.empty,0)
js2 <- liftM buildTree $ addSubexpConsts mo tree $ tree2list js
return (mo,M.ModMod (M.Module mt st fs me ops js2))
_ -> return (mo,m)
prSubtermStat :: CanonGrammar -> String
prSubtermStat gr = unlines [prt mo ++++ expsIn mo js | (mo,js) <- mos] where
mos = [(i, tree2list (M.jments m)) | (i, M.ModMod m) <- M.modules gr, M.isModCnc m]
expsIn mo js = err id id $ do
(tree,_) <- appSTM (getSubtermsMod mo js) (Map.empty,0)
let list0 = Map.toList tree
let list1 = sortBy (\ (_,(m,_)) (_,(n,_)) -> compare n m) list0
return $ unlines [show n ++ "\t" ++ prt trm | (trm,(n,_)) <- list1]
unSubelimCanon :: CanonGrammar -> CanonGrammar
unSubelimCanon gr@(M.MGrammar modules) =
M.MGrammar $ map unSubelimModule modules
unSubelimModule :: CanonModule -> CanonModule
unSubelimModule mo@(i,m) = case m of
M.ModMod (M.Module mt@(M.MTConcrete _) st fs me ops js) | hasSub ljs ->
(i, M.ModMod (M.Module mt st fs me ops
(rebuild (map unparInfo ljs))))
where ljs = tree2list js
_ -> (i,m)
where
-- perform this iff the module has opers
hasSub ljs = not $ null [c | (c,ResOper _ _) <- ljs]
unparInfo (c,info) = case info of
CncFun k xs t m -> [(c, CncFun k xs (unparTerm t) m)]
ResOper _ _ -> []
_ -> [(c,info)]
unparTerm t = case t of
I c -> errVal t $ liftM unparTerm $ lookupGlobal gr c
_ -> C.composSafeOp unparTerm t
gr = M.MGrammar [mo]
rebuild = buildTree . concat
-- implementation
type TermList = Map Term (Int,Int) -- number of occs, id
type TermM a = STM (TermList,Int) a
addSubexpConsts :: Ident -> Map Term (Int,Int) -> [(Ident,Info)] -> Err [(Ident,Info)]
addSubexpConsts mo tree lins = do
let opers = [oper id trm | (trm,(_,id)) <- list]
mapM mkOne $ opers ++ lins
where
mkOne (f,def) = case def of
CncFun ci xs trm pn -> do
trm' <- recomp f trm
return (f,CncFun ci xs trm' pn)
ResOper ty trm -> do
trm' <- recomp f trm
return (f,ResOper ty trm')
_ -> return (f,def)
recomp f t = case Map.lookup t tree of
Just (_,id) | ident id /= f -> return $ I $ cident mo id
_ -> composOp (recomp f) t
list = Map.toList tree
oper id trm = (ident id, ResOper TStr trm) --- type TStr does not matter
getSubtermsMod :: Ident -> [(Ident,Info)] -> TermM (Map Term (Int,Int))
getSubtermsMod mo js = do
mapM (getInfo (collectSubterms mo)) js
(tree0,_) <- readSTM
return $ Map.filter (\ (nu,_) -> nu > 1) tree0
where
getInfo get fi@(f,i) = case i of
CncFun ci xs trm pn -> do
get trm
return $ fi
ResOper ty trm -> do
get trm
return $ fi
_ -> return fi
collectSubterms :: Ident -> Term -> TermM Term
collectSubterms mo t = case t of
Par _ (_:_) -> add t
T ty cs -> do
let (ps,ts) = unzip [(p,t) | Cas p t <- cs]
mapM (collectSubterms mo) ts
add t
V ty ts -> do
mapM (collectSubterms mo) ts
add t
K (KP _ _) -> add t
_ -> composOp (collectSubterms mo) t
where
add t = do
(ts,i) <- readSTM
let
((count,id),next) = case Map.lookup t ts of
Just (nu,id) -> ((nu+1,id), i)
_ -> ((1, i ), i+1)
writeSTM (Map.insert t (count,id) ts, next)
return t --- only because of composOp
ident :: Int -> Ident
ident i = identC ("A''" ++ show i) ---
cident :: Ident -> Int -> CIdent
cident mo = CIQ mo . ident

View File

@@ -0,0 +1,58 @@
-- automatically generated by BNF Converter
module Main where
import IO ( stdin, hGetContents )
import System ( getArgs, getProgName )
import GF.Canon.LexGFC
import GF.Canon.ParGFC
import GF.Canon.SkelGFC
import GF.Canon.PrintGFC
import GF.Canon.AbsGFC
import GF.Infra.Ident
import GF.Data.ErrM
type ParseFun a = [Token] -> Err a
myLLexer = myLexer
type Verbosity = Int
putStrV :: Verbosity -> String -> IO ()
putStrV v s = if v > 1 then putStrLn s else return ()
runFile :: (Print a, Show a) => Verbosity -> ParseFun a -> FilePath -> IO ()
runFile v p f = putStrLn f >> readFile f >>= run v p
run :: (Print a, Show a) => Verbosity -> ParseFun a -> String -> IO ()
run v p s = let ts = myLLexer s in case p ts of
Bad s -> do putStrLn "\nParse Failed...\n"
putStrV v "Tokens:"
putStrV v $ show ts
putStrLn s
Ok tree -> do putStrLn "\nParse Successful!"
showTree v tree
showTree :: (Show a, Print a) => Int -> a -> IO ()
showTree v tree
= do
putStrV v $ "\n[Abstract Syntax]\n\n" ++ show tree
putStrV v $ "\n[Linearized tree]\n\n" ++ printTree tree
main :: IO ()
main = do args <- getArgs
case args of
[] -> hGetContents stdin >>= run 2 pCanon
"-s":fs -> mapM_ (runFile 0 pCanon) fs
fs -> mapM_ (runFile 2 pCanon) fs

49
src-3.0/GF/Canon/Unlex.hs Normal file
View File

@@ -0,0 +1,49 @@
----------------------------------------------------------------------
-- |
-- Module : Unlex
-- Maintainer : AR
-- Stability : (stable)
-- Portability : (portable)
--
-- > CVS $Date: 2005/04/21 16:21:32 $
-- > CVS $Author: bringert $
-- > CVS $Revision: 1.8 $
--
-- elementary text postprocessing. AR 21/11/2001
-----------------------------------------------------------------------------
module GF.Canon.Unlex (formatAsText, unlex, performBinds) where
import GF.Data.Operations
import GF.Data.Str
import Data.Char
import Data.List (isPrefixOf)
formatAsText :: String -> String
formatAsText = unwords . format . cap . words where
format ws = case ws of
w : c : ww | major c -> (w ++ c) : format (cap ww)
w : c : ww | minor c -> (w ++ c) : format ww
c : ww | para c -> "\n\n" : format ww
w : ww -> w : format ww
[] -> []
cap (p:(c:cs):ww) | para p = p : (toUpper c : cs) : ww
cap ((c:cs):ww) = (toUpper c : cs) : ww
cap [] = []
major = flip elem (map (:[]) ".!?")
minor = flip elem (map (:[]) ",:;")
para = (=="&-")
unlex :: [Str] -> String
unlex = formatAsText . performBinds . concat . map sstr . take 1 ----
-- | modified from GF/src/Text by adding hyphen
performBinds :: String -> String
performBinds = unwords . format . words where
format ws = case ws of
w : "-" : u : ws -> format ((w ++ "-" ++ u) : ws)
w : "&+" : u : ws -> format ((w ++ u) : ws)
w : ws -> w : format ws
[] -> []

View File

@@ -0,0 +1,63 @@
----------------------------------------------------------------------
-- |
-- Module : Unparametrize
-- Maintainer : AR
-- Stability : (stable)
-- Portability : (portable)
--
-- > CVS $Date: 2005/09/14 16:26:21 $
-- > CVS $Author: aarne $
-- > CVS $Revision: 1.1 $
--
-- Taking away parameters from a canonical grammar. All param
-- types are replaced by {}, and only one branch is left in
-- all tables. AR 14\/9\/2005.
-----------------------------------------------------------------------------
module GF.Canon.Unparametrize (unparametrizeCanon) where
import GF.Canon.AbsGFC
import GF.Infra.Ident
import GF.Canon.GFC
import qualified GF.Canon.CMacros as C
import GF.Data.Operations
import qualified GF.Infra.Modules as M
unparametrizeCanon :: CanonGrammar -> CanonGrammar
unparametrizeCanon (M.MGrammar modules) =
M.MGrammar $ map unparModule modules where
unparModule (i,m) = case m of
M.ModMod (M.Module mt@(M.MTConcrete _) st fs me ops js) ->
let me' = [(unparIdent j,incl) | (j,incl) <- me] in
(unparIdent i, M.ModMod (M.Module mt st fs me' ops (mapTree unparInfo js)))
_ -> (i,m)
unparInfo (c,info) = case info of
CncCat ty t m -> (c, CncCat (unparCType ty) (unparTerm t) m)
CncFun k xs t m -> (c, CncFun k xs (unparTerm t) m)
AnyInd b i -> (c, AnyInd b (unparIdent i))
_ -> (c,info)
unparCType ty = case ty of
RecType ls -> RecType [Lbg lab (unparCType t) | Lbg lab t <- ls]
Table _ v -> unparCType v --- Table unitType (unparCType v)
Cn _ -> unitType
_ -> ty
unparTerm t = case t of
Par _ _ -> unitTerm
T _ cs -> unparTerm (head [t | Cas _ t <- cs])
V _ ts -> unparTerm (head ts)
S t _ -> unparTerm t
{-
T _ cs -> V unitType [unparTerm (head [t | Cas _ t <- cs])]
V _ ts -> V unitType [unparTerm (head ts)]
S t _ -> S (unparTerm t) unitTerm
-}
_ -> C.composSafeOp unparTerm t
unitType = RecType []
unitTerm = R []
unparIdent (IC s) = IC $ "UP_" ++ s

20
src-3.0/GF/Canon/log.txt Normal file
View File

@@ -0,0 +1,20 @@
GFCC, 6/9/2006
66661 24 Par remaining to be sent to GFC
66662 0 not covered by mkTerm
66663 36 label not in numeric format in mkTerm
66664 2 label not found in symbol table
66665 36 projection from deeper than just arg var: NP.agr.n
66667 0 parameter value not found in symbol table
66668 1 variable in parameter argument
66664 2
66665 125 missing: (VP.s!vf).fin
66668 1
66661/3 24 same lines:
66664 2
66668 1