forked from GitHub/gf-core
cleanup in the python export
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
-- |
|
||||||
-- Module : PGFtoPython
|
-- Module : PGFtoPython
|
||||||
-- Maintainer : Peter Ljunglöf
|
-- Maintainer : Peter Ljunglöf
|
||||||
--
|
--
|
||||||
@@ -11,6 +12,8 @@ import PGF.CId
|
|||||||
import PGF.Data
|
import PGF.Data
|
||||||
import qualified PGF.Macros as M
|
import qualified PGF.Macros as M
|
||||||
|
|
||||||
|
import GF.Data.Operations
|
||||||
|
|
||||||
import qualified Data.Array.IArray as Array
|
import qualified Data.Array.IArray as Array
|
||||||
import qualified Data.Set as Set
|
import qualified Data.Set as Set
|
||||||
import qualified Data.Map as Map
|
import qualified Data.Map as Map
|
||||||
@@ -18,91 +21,96 @@ import qualified Data.IntMap as IntMap
|
|||||||
import Data.List (intersperse)
|
import Data.List (intersperse)
|
||||||
|
|
||||||
pgf2python :: PGF -> String
|
pgf2python :: PGF -> String
|
||||||
pgf2python pgf = "# -*- coding: UTF-8 -*-\n" ++
|
pgf2python pgf = ("# -*- coding: UTF-8 -*-" ++++
|
||||||
"# This file was automatically generated by GF\n\n" ++
|
"# This file was automatically generated by GF" +++++
|
||||||
showCId name ++ " = " ++ grammar ++ "\n"
|
showCId name +++ "=" +++
|
||||||
|
pyDict 1 pyStr id [
|
||||||
|
("flags", pyDict 2 pyCId pyLiteral (Map.assocs (gflags pgf))),
|
||||||
|
("abstract", pyDict 2 pyStr id [
|
||||||
|
("name", pyCId name),
|
||||||
|
("start", pyCId start),
|
||||||
|
("flags", pyDict 3 pyCId pyLiteral (Map.assocs (aflags abs))),
|
||||||
|
("funs", pyDict 3 pyCId pyAbsdef (Map.assocs (funs abs)))
|
||||||
|
]),
|
||||||
|
("concretes", pyDict 2 pyCId pyConcrete (Map.assocs cncs))
|
||||||
|
] ++ "\n")
|
||||||
where
|
where
|
||||||
name = absname pgf
|
name = absname pgf
|
||||||
start = M.lookStartCat pgf
|
start = M.lookStartCat pgf
|
||||||
abs = abstract pgf
|
abs = abstract pgf
|
||||||
cncs = concretes pgf
|
cncs = concretes pgf
|
||||||
grammar = pyDict 1 [(qs "abstract", pyDict 2 [(qs "name", qcid name),
|
|
||||||
(qs "start", qcid start),
|
|
||||||
(qs "flags", pyDict 0 [(qcid k, lit2py v) |
|
|
||||||
(k, v) <- Map.toList (aflags abs)]),
|
|
||||||
(qs "funs", pyDict 3 [(qcid f, absdef2py def) |
|
|
||||||
(f, def) <- Map.assocs (funs abs)])]),
|
|
||||||
(qs "concretes", pyDict 2 [(qcid cname, concrete2py cnc) |
|
|
||||||
(cname, cnc) <- Map.assocs cncs])]
|
|
||||||
|
|
||||||
absdef2py :: (Type, Int, Maybe [Equation], Double) -> String
|
pyAbsdef :: (Type, Int, Maybe [Equation], Double) -> String
|
||||||
absdef2py (typ, _, _, _) = pyTuple 0 [qcid cat, pyList 0 (map qcid args)]
|
pyAbsdef (typ, _, _, _) = pyTuple 0 id [pyCId cat, pyTuple 0 pyCId args]
|
||||||
where (args, cat) = M.catSkeleton typ
|
where (args, cat) = M.catSkeleton typ
|
||||||
|
|
||||||
lit2py :: Literal -> String
|
pyLiteral :: Literal -> String
|
||||||
lit2py (LStr s) = qs s
|
pyLiteral (LStr s) = pyStr s
|
||||||
lit2py (LInt n) = show n
|
pyLiteral (LInt n) = show n
|
||||||
lit2py (LFlt d) = show d
|
pyLiteral (LFlt d) = show d
|
||||||
|
|
||||||
concrete2py :: Concr -> String
|
pyConcrete :: Concr -> String
|
||||||
concrete2py cnc = pyDict 3 [(qs "flags", pyDict 0 [(qcid k, lit2py v) | (k, v) <- Map.toList (cflags cnc)]),
|
pyConcrete cnc = pyDict 3 pyStr id [
|
||||||
(qs "prods", pyDict 4 [(show cat, pyList 0 (map frule2py (Set.toList set))) |
|
("flags", pyDict 0 pyCId pyLiteral (Map.assocs (cflags cnc))),
|
||||||
(cat, set) <- IntMap.toList (productions cnc)]),
|
("printnames", pyDict 4 pyCId pyStr (Map.assocs (printnames cnc))),
|
||||||
(qs "cfuns", pyList 4 [ffun2py f | f <- Array.elems (cncfuns cnc)]),
|
("lindefs", pyDict 4 pyCat (pyTuple 0 pyFun) (IntMap.assocs (lindefs cnc))),
|
||||||
(qs "seqs", pyList 4 [seq2py s | s <- Array.elems (sequences cnc)]),
|
("productions", pyDict 4 pyCat pyProds (IntMap.assocs (productions cnc))),
|
||||||
(qs "ccats", pyDict 4 [(qcid cat, pyTuple 0 [show start, show end]) |
|
("cncfuns", pyDict 4 pyFun pyCncFun (Array.assocs (cncfuns cnc))),
|
||||||
(cat, CncCat start end _) <- Map.assocs (cnccats cnc)]),
|
("sequences", pyDict 4 pySeq pySymbols (Array.assocs (sequences cnc))),
|
||||||
(qs "size", show (totalCats cnc))]
|
("cnccats", pyDict 4 pyCId pyCncCat (Map.assocs (cnccats cnc))),
|
||||||
|
("size", show (totalCats cnc))
|
||||||
|
]
|
||||||
|
where pyProds prods = pyTuple 5 pyProduction (Set.toList prods)
|
||||||
|
pyCncCat (CncCat start end _) = pyTuple 0 pyCat [start..end]
|
||||||
|
pyCncFun (CncFun f lins) = pyTuple 0 id [pyTuple 0 pySeq (Array.elems lins), pyCId f]
|
||||||
|
pySymbols syms = pyTuple 0 pySymbol (Array.elems syms)
|
||||||
|
|
||||||
frule2py :: Production -> String
|
pyProduction :: Production -> String
|
||||||
frule2py (PApply funid args) = pyTuple 0 [show funid, pyList 0 (map parg2py args)]
|
pyProduction (PCoerce arg) = pyTuple 0 id [pyStr "", pyTuple 0 pyCat [arg]]
|
||||||
frule2py (PCoerce arg) = show arg
|
pyProduction (PApply funid args) = pyTuple 0 id [pyFun funid, pyTuple 0 pyPArg args]
|
||||||
|
where pyPArg (PArg [] fid) = pyCat fid
|
||||||
|
pyPArg (PArg hypos fid) = pyTuple 0 pyCat (fid : map snd hypos)
|
||||||
|
|
||||||
parg2py :: PArg -> String
|
pySymbol :: Symbol -> String
|
||||||
parg2py (PArg [] fid) = show fid
|
pySymbol (SymCat n l) = pyTuple 0 show [n, l]
|
||||||
parg2py (PArg hypos fid) = pyTuple 0 (show fid : map (show . snd) hypos)
|
pySymbol (SymLit n l) = pyDict 0 pyStr id [("lit", pyTuple 0 show [n, l])]
|
||||||
|
pySymbol (SymVar n l) = pyDict 0 pyStr id [("var", pyTuple 0 show [n, l])]
|
||||||
ffun2py :: CncFun -> String
|
pySymbol (SymKS ts) = prTList "," (map pyStr ts)
|
||||||
ffun2py (CncFun f lins) = pyTuple 0 [pyList 0 (map show (Array.elems lins)), qcid f]
|
pySymbol (SymKP ts alts) = pyDict 0 pyStr id [("pre", pyTuple 0 pyStr ts), ("alts", pyTuple 0 alt2py alts)]
|
||||||
|
where alt2py (Alt ps ts) = pyTuple 0 (pyTuple 0 pyStr) [ps, ts]
|
||||||
seq2py :: Array.Array DotPos Symbol -> String
|
|
||||||
seq2py seq = pyList 0 [sym2py s | s <- Array.elems seq]
|
|
||||||
|
|
||||||
sym2py :: Symbol -> String
|
|
||||||
sym2py (SymCat n l) = pyTuple 0 [show n, show l]
|
|
||||||
sym2py (SymLit n l) = pyDict 0 [(qs "lit", pyTuple 0 [show n, show l])]
|
|
||||||
sym2py (SymVar n l) = pyDict 0 [(qs "var", pyTuple 0 [show n, show l])]
|
|
||||||
sym2py (SymKS ts) = join "," (map qs ts)
|
|
||||||
sym2py (SymKP ts alts) = pyDict 0 [(qs "pre", pyList 0 (map show ts)),
|
|
||||||
(qs "alts", pyList 0 (map alt2py alts))]
|
|
||||||
where alt2py (Alt ps ts) = pyTuple 0 [pyList 0 (map show ps), pyList 0 (map show ts)]
|
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
-- python helpers
|
-- python helpers
|
||||||
|
|
||||||
pyDict :: Int -> [(String, String)] -> String
|
pyDict :: Int -> (k -> String) -> (v -> String) -> [(k, v)] -> String
|
||||||
pyDict n xys = "{" ++ indent n ++ join ("," ++ indent n) [x ++ ":" ++ y | (x, y) <- xys] ++ indent n ++ "}"
|
pyDict n pk pv [] = "{}"
|
||||||
|
pyDict n pk pv kvlist = prCurly (pyIndent n ++ prTList ("," ++ pyIndent n) (map pyKV kvlist) ++ pyIndent n)
|
||||||
|
where pyKV (k, v) = pk k ++ ":" ++ pv v
|
||||||
|
|
||||||
pyList :: Int -> [String] -> String
|
pyList :: Int -> (v -> String) -> [v] -> String
|
||||||
pyList n xs = "[" ++ indent n ++ join ("," ++ indent n) xs ++ indent n ++ "]"
|
pyList n pv [] = "[]"
|
||||||
|
pyList n pv xs = prBracket (pyIndent n ++ prTList ("," ++ pyIndent n) (map pv xs) ++ pyIndent n)
|
||||||
|
|
||||||
pyTuple :: Int -> [String] -> String
|
pyTuple :: Int -> (v -> String) -> [v] -> String
|
||||||
pyTuple n [x] = "(" ++ indent n ++ x ++ "," ++ indent n ++ ")"
|
pyTuple n pv [] = "()"
|
||||||
pyTuple n xs = "(" ++ indent n ++ join ("," ++ indent n) xs ++ indent n ++ ")"
|
pyTuple n pv [x] = prParenth (pyIndent n ++ pv x ++ "," ++ pyIndent n)
|
||||||
|
pyTuple n pv xs = prParenth (pyIndent n ++ prTList ("," ++ pyIndent n) (map pv xs) ++ pyIndent n)
|
||||||
|
|
||||||
qs :: String -> String
|
pyCat :: Int -> String
|
||||||
qs s = "u\"" ++ qs' s
|
pyCat n = pyStr ('C' : show n)
|
||||||
where qs' ('"':s) = "\\\"" ++ qs' s
|
|
||||||
qs' ('\\':s) = "\\\\" ++ qs' s
|
|
||||||
qs' (c:s) = c : qs' s
|
|
||||||
qs' [] = "\""
|
|
||||||
|
|
||||||
qcid :: CId -> String
|
pyFun :: Int -> String
|
||||||
qcid = qs . showCId
|
pyFun n = pyStr ('F' : show n)
|
||||||
|
|
||||||
indent :: Int -> String
|
pySeq :: Int -> String
|
||||||
indent n | n > 0 = "\n" ++ replicate n ' '
|
pySeq n = pyStr ('S' : show n)
|
||||||
| otherwise = ""
|
|
||||||
|
|
||||||
join :: String -> [String] -> String
|
pyStr :: String -> String
|
||||||
join a bs = concat (intersperse a bs)
|
pyStr s = 'u' : prQuotedString s
|
||||||
|
|
||||||
|
pyCId :: CId -> String
|
||||||
|
pyCId = pyStr . showCId
|
||||||
|
|
||||||
|
pyIndent :: Int -> String
|
||||||
|
pyIndent n | n > 0 = "\n" ++ replicate n ' '
|
||||||
|
| otherwise = ""
|
||||||
|
|||||||
Reference in New Issue
Block a user