mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-05-07 18:22:50 -06:00
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:
182
src-3.0/GF/Canon/AbsGFC.hs
Normal file
182
src-3.0/GF/Canon/AbsGFC.hs
Normal 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)
|
||||
|
||||
38
src-3.0/GF/Canon/AbsToBNF.hs
Normal file
38
src-3.0/GF/Canon/AbsToBNF.hs
Normal 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
334
src-3.0/GF/Canon/CMacros.hs
Normal 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
|
||||
45
src-3.0/GF/Canon/CanonToGFCC.hs
Normal file
45
src-3.0/GF/Canon/CanonToGFCC.hs
Normal 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
|
||||
-}
|
||||
|
||||
203
src-3.0/GF/Canon/CanonToGrammar.hs
Normal file
203
src-3.0/GF/Canon/CanonToGrammar.hs
Normal 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
170
src-3.0/GF/Canon/GFC.cf
Normal 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
103
src-3.0/GF/Canon/GFC.hs
Normal 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
|
||||
_ -> []
|
||||
78
src-3.0/GF/Canon/GetGFC.hs
Normal file
78
src-3.0/GF/Canon/GetGFC.hs
Normal 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
346
src-3.0/GF/Canon/LexGFC.hs
Normal 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
132
src-3.0/GF/Canon/LexGFC.x
Normal 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
225
src-3.0/GF/Canon/Look.hs
Normal 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
237
src-3.0/GF/Canon/MkGFC.hs
Normal 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
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
385
src-3.0/GF/Canon/ParGFC.y
Normal 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
46
src-3.0/GF/Canon/PrExp.hs
Normal 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
|
||||
376
src-3.0/GF/Canon/PrintGFC.hs
Normal file
376
src-3.0/GF/Canon/PrintGFC.hs
Normal 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
147
src-3.0/GF/Canon/Share.hs
Normal 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
217
src-3.0/GF/Canon/SkelGFC.hs
Normal 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
|
||||
|
||||
|
||||
|
||||
170
src-3.0/GF/Canon/Subexpressions.hs
Normal file
170
src-3.0/GF/Canon/Subexpressions.hs
Normal 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
|
||||
58
src-3.0/GF/Canon/TestGFC.hs
Normal file
58
src-3.0/GF/Canon/TestGFC.hs
Normal 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
49
src-3.0/GF/Canon/Unlex.hs
Normal 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
|
||||
[] -> []
|
||||
|
||||
63
src-3.0/GF/Canon/Unparametrize.hs
Normal file
63
src-3.0/GF/Canon/Unparametrize.hs
Normal 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
20
src-3.0/GF/Canon/log.txt
Normal 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
|
||||
Reference in New Issue
Block a user