mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-04-09 04:59:31 -06:00
123 lines
5.0 KiB
Haskell
123 lines
5.0 KiB
Haskell
----------------------------------------------------------------------
|
|
-- |
|
|
-- Module : PGFtoPython
|
|
-- Maintainer : Peter Ljunglöf
|
|
--
|
|
-- exports a GF grammar into a Python module
|
|
-----------------------------------------------------------------------------
|
|
|
|
{-# LANGUAGE FlexibleContexts #-}
|
|
module GF.Compile.PGFtoPython (pgf2python) where
|
|
|
|
import PGF(showCId)
|
|
import PGF.Internal as M
|
|
|
|
import GF.Data.Operations
|
|
|
|
import qualified Data.Array.IArray as Array
|
|
import qualified Data.Set as Set
|
|
import qualified Data.Map as Map
|
|
import qualified Data.IntMap as IntMap
|
|
--import Data.List (intersperse)
|
|
|
|
pgf2python :: PGF -> String
|
|
pgf2python pgf = ("# -*- coding: utf-8 -*-" ++++
|
|
"# This file was automatically generated by GF" +++++
|
|
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
|
|
name = absname pgf
|
|
start = M.lookStartCat pgf
|
|
abs = abstract pgf
|
|
cncs = concretes pgf
|
|
|
|
pyAbsdef :: (Type, Int, Maybe ([Equation], [[M.Instr]]), Double) -> String
|
|
pyAbsdef (typ, _, _, _) = pyTuple 0 id [pyCId cat, pyList 0 pyCId args]
|
|
where (args, cat) = M.catSkeleton typ
|
|
|
|
pyLiteral :: Literal -> String
|
|
pyLiteral (LStr s) = pyStr s
|
|
pyLiteral (LInt n) = show n
|
|
pyLiteral (LFlt d) = show d
|
|
|
|
pyConcrete :: Concr -> String
|
|
pyConcrete cnc = pyDict 3 pyStr id [
|
|
("flags", pyDict 0 pyCId pyLiteral (Map.assocs (cflags cnc))),
|
|
("printnames", pyDict 4 pyCId pyStr (Map.assocs (printnames cnc))),
|
|
("lindefs", pyDict 4 pyCat (pyList 0 pyFun) (IntMap.assocs (lindefs cnc))),
|
|
("productions", pyDict 4 pyCat pyProds (IntMap.assocs (productions cnc))),
|
|
("cncfuns", pyDict 4 pyFun pyCncFun (Array.assocs (cncfuns cnc))),
|
|
("sequences", pyDict 4 pySeq pySymbols (Array.assocs (sequences cnc))),
|
|
("cnccats", pyDict 4 pyCId pyCncCat (Map.assocs (cnccats cnc))),
|
|
("size", show (totalCats cnc))
|
|
]
|
|
where pyProds prods = pyList 5 pyProduction (Set.toList prods)
|
|
pyCncCat (CncCat start end _) = pyList 0 pyCat [start..end]
|
|
pyCncFun (CncFun f lins) = pyTuple 0 id [pyList 0 pySeq (Array.elems lins), pyCId f]
|
|
pySymbols syms = pyList 0 pySymbol (Array.elems syms)
|
|
|
|
pyProduction :: Production -> String
|
|
pyProduction (PCoerce arg) = pyTuple 0 id [pyStr "", pyList 0 pyCat [arg]]
|
|
pyProduction (PApply funid args) = pyTuple 0 id [pyFun funid, pyList 0 pyPArg args]
|
|
where pyPArg (PArg [] fid) = pyCat fid
|
|
pyPArg (PArg hypos fid) = pyTuple 0 pyCat (fid : map snd hypos)
|
|
|
|
pySymbol :: Symbol -> String
|
|
pySymbol (SymCat n l) = pyTuple 0 show [n, l]
|
|
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])]
|
|
pySymbol (SymKS t) = pyStr t
|
|
pySymbol (SymKP ts alts) = pyDict 0 pyStr id [("pre", pyList 0 pySymbol ts), ("alts", pyList 0 alt2py alts)]
|
|
where alt2py (ps,ts) = pyTuple 0 (pyList 0 pyStr) [map pySymbol ps, ts]
|
|
pySymbol SymBIND = pyStr "&+"
|
|
pySymbol SymSOFT_BIND = pyStr "&+"
|
|
pySymbol SymSOFT_SPACE = pyStr "&+"
|
|
pySymbol SymCAPIT = pyStr "&|"
|
|
pySymbol SymALL_CAPIT = pyStr "&|"
|
|
pySymbol SymNE = pyDict 0 pyStr id [("nonExist", pyTuple 0 id [])]
|
|
|
|
----------------------------------------------------------------------
|
|
-- python helpers
|
|
|
|
pyDict :: Int -> (k -> String) -> (v -> String) -> [(k, v)] -> String
|
|
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 -> (v -> String) -> [v] -> String
|
|
pyList n pv [] = "[]"
|
|
pyList n pv xs = prBracket (pyIndent n ++ prTList ("," ++ pyIndent n) (map pv xs) ++ pyIndent n)
|
|
|
|
pyTuple :: Int -> (v -> String) -> [v] -> String
|
|
pyTuple n pv [] = "()"
|
|
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)
|
|
|
|
pyCat :: Int -> String
|
|
pyCat n = pyStr ('C' : show n)
|
|
|
|
pyFun :: Int -> String
|
|
pyFun n = pyStr ('F' : show n)
|
|
|
|
pySeq :: Int -> String
|
|
pySeq n = pyStr ('S' : show n)
|
|
|
|
pyStr :: String -> String
|
|
pyStr s = 'u' : prQuotedString s
|
|
|
|
pyCId :: CId -> String
|
|
pyCId = pyStr . showCId
|
|
|
|
pyIndent :: Int -> String
|
|
pyIndent n | n > 0 = "\n" ++ replicate n ' '
|
|
| otherwise = ""
|