diff options
Diffstat (limited to 'contrib/py-bindings')
| -rw-r--r-- | contrib/py-bindings/Makefile | 37 | ||||
| -rw-r--r-- | contrib/py-bindings/PyGF.hsc | 304 | ||||
| -rw-r--r-- | contrib/py-bindings/example.rst | 147 | ||||
| -rw-r--r-- | contrib/py-bindings/gfmodule.c | 339 | ||||
| -rw-r--r-- | contrib/py-bindings/lgpl-3.0.txt | 165 | ||||
| -rw-r--r-- | contrib/py-bindings/pygf.h | 96 | ||||
| -rw-r--r-- | contrib/py-bindings/test.py | 187 |
7 files changed, 0 insertions, 1275 deletions
diff --git a/contrib/py-bindings/Makefile b/contrib/py-bindings/Makefile deleted file mode 100644 index aff4d909f..000000000 --- a/contrib/py-bindings/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -src=../../src -import=-i$(src)/runtime/haskell:$(src)/compiler -cbind=../c-bindings -pyversion = $(shell python -c 'import sys; print ".".join(`t` for t in sys.version_info[:2])') -pythoninc=/usr/include/python$(pyversion) -debug= #-optc '-DDEBUG=1' -exdir=../../examples/tutorial/embedded - -build: gf.so - -test: - python test.py - -gf.so: PyGF.hs gfmodule.c Query.pgf - ghc $(import) --make -fglasgow-exts -O2 -no-hs-main -c $< - ghc -O2 --make -fglasgow-exts -no-hs-main -optl '-shared' \ - -optc '-DMODULE=$(basename $<)' $(debug) -optc '-I$(pythoninc)' -o $@ \ - $(filter-out %.pgf, $^) - - - -clean: - rm -f *.hi *.o - rm -f *_stub.* - rm -f PyGF.hs - -superclean: - make clean - rm -f Query.pgf - rm -f gf.so - rm -f mtest - -PyGF.hs: PyGF.hsc - hsc2hs -I$(pythoninc) $< - -Query.pgf: - gf --make $(exdir)/QueryEng.gf $(exdir)/QuerySpa.gf diff --git a/contrib/py-bindings/PyGF.hsc b/contrib/py-bindings/PyGF.hsc deleted file mode 100644 index fc827e68f..000000000 --- a/contrib/py-bindings/PyGF.hsc +++ /dev/null @@ -1,304 +0,0 @@ -{-# LANGUAGE ForeignFunctionInterface #-} --- --- GF Python bindings --- Jordi Saludes, upc.edu 2010, 2011 --- - -module PyGF where - -import PGF -import Foreign -import CString -import Foreign.C.Types -import Control.Monad -import Data.Map (keys, (!)) -import Data.Char (isSpace) - -#include "pygf.h" - -freeSp :: String -> Ptr a -> IO () -freeSp tname p = do - --DEBUG putStrLn $ "about to free pointer " ++ tname ++ " at " ++ (show p) - sp <- (#peek PyGF, sp) p - --DEBUG putStrLn "peeked" - freeStablePtr sp - --DEBUG putStrLn $ "freeing " ++ tname ++ " at " ++ (show p) - -instance Storable PGF where - sizeOf _ = (#size PyGF) - alignment _ = alignment (undefined::CInt) - poke p o = do - sp <- newStablePtr o - (#poke PyGF, sp) p sp - peek p = do - sp <- (#peek PyGF, sp) p - deRefStablePtr sp - -instance Storable Type where - sizeOf _ = (#size PyGF) - alignment _ = alignment (undefined::CInt) - poke p o = do - sp <- newStablePtr o - (#poke PyGF, sp) p sp - peek p = do - sp <- (#peek PyGF, sp) p - deRefStablePtr sp - -instance Storable Language where - sizeOf _ = (#size PyGF) - alignment _ = alignment (undefined::CInt) - poke p o = do - sp <- newStablePtr o - (#poke PyGF, sp) p sp - peek p = do - sp <- (#peek PyGF, sp) p - deRefStablePtr sp - -instance Storable Tree where - sizeOf _ = (#size PyGF) - alignment _ = alignment (undefined::CInt) - poke p o = do - sp <- newStablePtr o - (#poke PyGF, sp) p sp - peek p = do - sp <- (#peek PyGF, sp) p - deRefStablePtr sp - --- It is CId the same as Tree? - -{- instance Storable CId where - sizeOf _ = (#size PyGF) - alignment _ = alignment (undefined::CInt) - poke p o = do - sp <- newStablePtr o - (#poke PyGF, sp) p sp - peek p = do - sp <- (#peek PyGF, sp) p - deRefStablePtr sp --} - - -foreign export ccall gf_freePGF :: Ptr PGF -> IO () -foreign export ccall gf_freeType :: Ptr Type -> IO () -foreign export ccall gf_freeLanguage :: Ptr Language -> IO () -foreign export ccall gf_freeTree :: Ptr Tree -> IO () -foreign export ccall gf_freeExpr :: Ptr Expr -> IO () -foreign export ccall gf_freeCId :: Ptr CId -> IO () -gf_freePGF = freeSp "pgf" -gf_freeType = freeSp "type" -gf_freeLanguage = freeSp "language" -gf_freeTree = freeSp "tree" -gf_freeExpr = freeSp "expression" -gf_freeCId = freeSp "CId" - - -{-foreign export ccall gf_printCId :: Ptr CId-> IO CString -gf_printCId p = do - c <- peek p - newCString (showCId c) --} - -foreign export ccall gf_readPGF :: CString -> IO (Ptr PGF) -gf_readPGF path = do - ppgf <- pyPGF - p <- peekCString path - readPGF p >>= poke ppgf - return ppgf - -foreign export ccall gf_readLanguage :: Ptr Language -> CString -> IO Bool -gf_readLanguage pt str = do - s <- (peekCString str) - case (readLanguage s) of - Just x -> do - poke pt x - return True - Nothing -> return False - -foreign export ccall gf_startCat :: Ptr PGF -> IO (Ptr Type) -gf_startCat ppgf = do - pgf <- peek ppgf - pcat <- pyType - poke pcat (startCat pgf) - return pcat - -foreign export ccall gf_parse :: Ptr PGF -> Ptr Language -> Ptr Type -> CString -> IO (Ptr ()) -gf_parse ppgf plang pcat input = do - p <- peek ppgf - c <- peek pcat - i <- peekCString input - l <- peek plang - let parsed = parse p l c i - --DEBUG putStrLn $ (show $ length parsed) ++ " parsings" - listToPy pyTree parsed - -foreign export ccall gf_showExpr :: Ptr Expr -> IO CString -gf_showExpr pexpr = do - e <- peek pexpr - newCString (showExpr [] e) - -listToPy :: Storable a => IO (Ptr a) -> [a] -> IO (Ptr ()) -- opaque -- IO (Ptr (Ptr Language)) -listToPy mk ls = do - pyls <- pyList - mapM_ (mpoke pyls) ls - return pyls - where mpoke pyl l = do - pl <- mk - poke pl l - pyl << pl - - -listToPyStrings :: [String] -> IO (Ptr ()) -listToPyStrings ss = do - pyls <- pyList - mapM_ (mpoke pyls) ss - return pyls - where mpoke pyl s = do - cs <- newCString s - pcs <- pyString cs - pyl << pcs - - -foreign export ccall gf_showLanguage :: Ptr Language -> IO CString -gf_showLanguage plang = do - l <- peek plang - newCString $ showLanguage l - -foreign export ccall gf_showType :: Ptr Type -> IO CString -gf_showType ptp = do - t <- peek ptp - newCString $ showType [] t - -foreign export ccall gf_showPrintName :: Ptr PGF -> Ptr Language -> Ptr CId -> IO CString -gf_showPrintName ppgf plang pcid = do - pgf <- peek ppgf - lang <- peek plang - cid <- peek pcid - newCString (showPrintName pgf lang cid) - -foreign export ccall gf_abstractName :: Ptr PGF -> IO (Ptr Language) -gf_abstractName ppgf = do - pabs <- pyLang - pgf <- peek ppgf - poke pabs $ abstractName pgf - return pabs - -foreign export ccall gf_linearize :: Ptr PGF -> Ptr Language -> Ptr Tree -> IO CString -gf_linearize ppgf plang ptree = do - pgf <- peek ppgf - lang <- peek plang - tree <- peek ptree - newCString $ linearize pgf lang tree - -foreign export ccall gf_languageCode :: Ptr PGF -> Ptr Language -> IO CString -gf_languageCode ppgf plang = do - pgf <- peek ppgf - lang <- peek plang - case languageCode pgf lang of - Just s -> newCString s - Nothing -> return nullPtr - -foreign export ccall gf_languages :: Ptr PGF -> IO (Ptr ()) -- (Ptr (Ptr Language)) -gf_languages ppgf = do - pgf <- peek ppgf - listToPy pyLang $ languages pgf - -foreign export ccall gf_categories :: Ptr PGF -> IO (Ptr ()) -gf_categories ppgf = do - pgf <- peek ppgf - listToPy pyCId $ categories pgf - -foreign export ccall gf_showCId :: Ptr CId -> IO CString -gf_showCId pcid = do - cid <- peek pcid - newCString $ showCId cid - -foreign export ccall gf_unapp :: Ptr Expr -> IO (Ptr ()) -foreign export ccall gf_unint :: Ptr Expr -> IO CInt -foreign export ccall gf_unstr :: Ptr Expr -> IO CString - -gf_unapp pexp = do - exp <- peek pexp - case unApp exp of - Just (f,args) -> do - puexp <- pyList - pf <- pyCId - poke pf f - puexp << pf - mapM_ (\e -> do - pe <- pyExpr - poke pe e - puexp << pe) args - return puexp - Nothing -> return nullPtr -gf_unint pexp = do - exp <- peek pexp - return $ fromIntegral $ case unInt exp of - Just n -> n - _ -> (-9) -gf_unstr pexp = do - exp <- peek pexp - case unStr exp of - Just s -> newCString s - _ -> return nullPtr - -foreign export ccall gf_inferexpr :: Ptr PGF -> Ptr Expr -> IO (Ptr Type) -gf_inferexpr ppgf pexp = do - pgf <- peek ppgf - exp <- peek pexp - case inferExpr pgf exp of - Right (_,t) -> do - ptype <- pyType - poke ptype t - return ptype - Left _ -> return nullPtr - - -foreign export ccall gf_functions :: Ptr PGF -> IO (Ptr ()) -gf_functions ppgf = do - pgf <- peek ppgf - listToPy pyCId $ functions pgf - -foreign export ccall gf_functiontype :: Ptr PGF -> Ptr CId -> IO (Ptr Type) -gf_functiontype ppgf pcid = do - pgf <- peek ppgf - cid <- peek pcid - case functionType pgf cid of - Just t -> do - ptp <- pyType - poke ptp t - return ptp - _ -> return nullPtr - - -foreign export ccall gf_completions :: Ptr PGF -> Ptr Language -> Ptr Type -> CString -> IO (Ptr ()) -gf_completions ppgf plang pcat ctoks = do - pgf <- peek ppgf - lang <- peek plang - cat <- peek pcat - toks <- peekCString ctoks - let (rpre,rs) = break isSpace (reverse toks) - pre = reverse rpre - ws = words (reverse rs) - state0 = initState pgf lang cat - completions = - case loop state0 ws of - Nothing -> [] - Just state -> keys $ getCompletions state pre - listToPyStrings completions - where - loop ps [] = Just ps - loop ps (w:ws) = - case nextState ps (simpleParseInput w) of - Left _ -> Nothing - Right ps -> loop ps ws - - -foreign import ccall "newLang" pyLang :: IO (Ptr Language) -foreign import ccall "newPGF" pyPGF :: IO (Ptr PGF) -foreign import ccall "newTree" pyTree :: IO (Ptr Tree) -foreign import ccall "newgfType" pyType :: IO (Ptr Type) -foreign import ccall "newCId" pyCId :: IO (Ptr CId) -foreign import ccall "newExpr" pyExpr :: IO (Ptr Expr) -foreign import ccall "newList" pyList :: IO (Ptr ()) -foreign import ccall "newString" pyString :: CString -> IO (Ptr ()) -foreign import ccall "append" (<<) :: Ptr () -> Ptr a -> IO () diff --git a/contrib/py-bindings/example.rst b/contrib/py-bindings/example.rst deleted file mode 100644 index 770c6e862..000000000 --- a/contrib/py-bindings/example.rst +++ /dev/null @@ -1,147 +0,0 @@ -Using the GF python bindings -============================ - -This is how to use some of the functionalities of the GF shell inside Python. - -Loading a pgf file ------------------- -First you must import the library: - ->>> import gf - -then load a PGF file, like this tiny example: - ->>> pgf = gf.read_pgf("Query.pgf") - -We could ask for the supported languages: - ->>> pgf.languages() -[QueryEng, QuerySpa] - -The *start category* of the PGF module is: - ->>> pgf.startcat() -Question - -Parsing and linearizing ------------------------ - -Let's us save the languages for later: - ->>> eng,spa = pgf.languages() - -These are opaque objects, not strings: - ->>> type(eng) -<type 'gf.lang'> - -and must be used when parsing: - ->>> pgf.parse(eng, "is 42 prime") -[Prime (Number 42)] - -Yes, I know it should have a '?' at the end, but there is not support for other lexers at this time. - -Notice that parsing returns a list of gf trees. -Let's save it and linearize it in Spanish: - ->>> t = pgf.parse(eng, "is 42 prime") ->>> pgf.linearize(spa, t[0]) -'42 es primo' - -(which is not, but there is a '?' lacking at the end, remember?) - - -Getting parsing completions ---------------------------- -One of the good things of the GF shell is that it suggests you which tokens can continue the line you are composing. - -We got this also in the bindings. -Suppose we have no idea on how to start: - ->>> pgf.complete(eng, "") -['is'] - -so, there is only a sensible thing to put in. Let's continue: - ->>> pgf.complete(eng, "is ") -[] - -Is it important to note the blank space at the end, otherwise we get it again: - ->>> pgf.complete(eng, "is") -['is'] - -But, how come that nothing is suggested at "is "? -At the current point, a literal integer is expected so GF would have to present an infinite list of alternatives. I cannot blame it for refusing to do so. - ->>> pgf.complete(eng, "is 42 ") -['even', 'odd', 'prime'] - -Good. I will go for 'even', just to be in the safe side: - ->>> pgf.complete(eng, "is 42 even ") -[] - -Nothin again, but this time the phrase is complete. Let us check it by parsing: - ->>> pgf.parse(eng, "is 42 even") -[Even (Number 42)] - -Deconstructing gf trees ------------------------ -We store the last result and ask for its type: - ->>> t = pgf.parse(eng, "is 42 even")[0] ->>> type(t) -<type 'gf.tree'> - -What's inside this tree? We use ``unapply`` for that: - ->>> t.unapply() -[Even, Number 42] - -This method returns a list with the head of the **fun** judgement and its arguments: - ->>> map(type, _) -[<type 'gf.cid'>, <type 'gf.expr'>] - - -Notice the argument is again a tree (``gf.tree`` or ``gf.expr``, it is all the same here.) - ->>> t.unapply()[1] -Number 42 - - -We will repeat the trick with it now: - ->>> t.unapply()[1].unapply() -[Number, 42] - -and again, the same structure shows up: - ->>> map(type, _) -[<type 'gf.cid'>, <type 'gf.expr'>] - -One more time, just to get to the bottom of it: - ->>> t.unapply()[1].unapply()[1].unapply() -42 - -but now it is an actual number: - ->>> type(_) -<type 'int'> - -We ended with a full decomposed **fun** judgement. - - -Note ----- - -This file can be used to test the bindings: :: - - python -m doctest example.rst - - - diff --git a/contrib/py-bindings/gfmodule.c b/contrib/py-bindings/gfmodule.c deleted file mode 100644 index 99824fb77..000000000 --- a/contrib/py-bindings/gfmodule.c +++ /dev/null @@ -1,339 +0,0 @@ -// GF Python bindings -// Jordi Saludes, upc.edu 2010, 2011 -// - -#include <Python.h> -#include <sys/stat.h> -#include "pygf.h" - -/* utilities */ - -int -checkType(void* obj, PyTypeObject* tp) -{ - int isRight = PyObject_TypeCheck((PyObject*)obj, tp); - if (!isRight) - PyErr_Format(PyExc_TypeError, "Expecting a %s.", tp->tp_doc); - return isRight; -} - - -/* new types and declarations */ - -NEWGF(CId,GF_CId,CIdType,"gf.cid","identifier") -NEWGF(Lang,GF_Language,LangType,"gf.lang","language") -NEWGF(gfType,GF_Type,gfTypeType,"gf.type","gf type") -NEWGF(PGF,GF_PGF,PGFType,"gf.pgf","PGF module") -NEWGF(Expr,GF_Expr,ExprType,"gf.expr","gf expression") -NEWGF(Tree,GF_Tree,TreeType,"gf.tree","gf tree") - - -/* CId methods, constructor and destructor */ - -DEALLOCFN(CId_dealloc, CId, gf_freeCId, "freeCId") - - - -/* PGF methods, constructor and destructor */ - -DEALLOCFN(PGF_dealloc, PGF, gf_freePGF, "freePGF") - -static PyObject* -pgf_repr(PGF *self) { - Lang* lang = gf_abstractName(self); - char* abs = gf_showLanguage(lang); - Py_DECREF(lang); - PyObject* str = PyString_FromFormat("<gf.pgf with abstract %s>", abs); - free(abs); -return str; -} - -static PyObject* -languageCode(PGF *self, PyObject *args) -{ - Lang *lang; - if (!PyArg_ParseTuple(args, "O", &lang)) - return NULL; - if (!checkType(lang, &LangType)) return NULL; - char* scode = gf_languageCode(self, lang); - if (scode) { - PyObject* result = PyString_FromString(scode); - free(scode); - return result; - } else { - Py_INCREF(Py_None); - return Py_None; - } -} - -static PyObject* -linearize(PGF *self, PyObject *args) -{ - Lang *lang; - Tree *tree; - if (!PyArg_ParseTuple(args, "OO", &lang, &tree)) - return NULL; - if (!checkType(lang,&LangType)) return NULL; - if (!checkType(tree,&TreeType)) return NULL; - char* c_lin = gf_linearize(self, lang, tree); - PyObject* lin = PyString_FromString(c_lin); - free(c_lin); - return lin; -} - -static Lang* -abstractName(PGF *self) -{ - if (!checkType(self,&PGFType)) return NULL; - return gf_abstractName(self); -} - -static PyObject* -printName(PGF *self, PyObject *args) -{ - Lang* lang; - CId* id; - if (!PyArg_ParseTuple(args, "OO", &lang, &id)) - return NULL; - if (!checkType(lang,&LangType)) return NULL; - if (!checkType(id,&CIdType)) return NULL; - char *pname = gf_showPrintName(self, lang, id); - PyObject* result = PyString_FromString(pname); - free(pname); - return result; -} - -static gfType* -functiontype(PGF *self, PyObject* args) -{ - CId* cid; - gfType* gftp; - if (!PyArg_ParseTuple(args, "O", &cid)) - return NULL; - if (!checkType(cid,&CIdType)) { - PyErr_Format(PyExc_TypeError, "Must be a gf identifier."); - return NULL; - } - return gf_functiontype(self, cid); -} - - -static PyObject* -parse(PGF *self, PyObject *args, PyObject *kws) -{ - Lang *lang; - gfType *cat = NULL; - char *lexed; - static char *kwlist[] = {"lang", "lexed", "cat", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kws, "Os|O", kwlist, &lang, &lexed, &cat)) - return NULL; - if (!checkType(self, &PGFType)) return NULL; - if (!checkType(lang, &LangType)) return NULL; - if (cat) { - if (!checkType(cat, &gfTypeType)) return NULL; - } else { - cat = gf_startCat(self); - } - return gf_parse(self, lang, cat, lexed); -} - -static PGF* -readPGF(PyObject *self, PyObject *args) -{ - char *path; - struct stat info; - if (!PyArg_ParseTuple(args, "s", &path)) - return NULL; - if (stat(path, &info) == 0) { - PGF* pgf = gf_readPGF(path); - return pgf; - } else { - PyErr_Format(PyExc_IOError, "No such file: %s", path); - return NULL; - } -} - - -static PyObject* -completions(PGF *self, PyObject *args, PyObject *kws) -{ char *tokens; - Lang *lang; - gfType *cat = NULL; - static char *kwlist[] = {"lang", "tokens", "category", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kws, "Os|O", kwlist, &lang, &tokens, &cat)) - return NULL; - if (!checkType(self, &PGFType)) return NULL; - if (!checkType(lang, &LangType)) return NULL; - if (cat) { - if (!checkType(cat, &gfTypeType)) return NULL; - } else { - cat = gf_startCat(self); - } - return gf_completions(self, lang, cat, tokens); -} - - -static PyMethodDef pgf_methods[] = { - {"parse", (PyCFunction)parse, METH_VARARGS|METH_KEYWORDS, "Parse a string."}, - {"linearize", (PyCFunction)linearize, METH_VARARGS,"Linearize tree."}, - {"lang_code", (PyCFunction)languageCode, METH_VARARGS,"Get the language code."}, - {"print_name", (PyCFunction)printName, METH_VARARGS,"Get the print name for a id."}, - {"fun_type", (PyCFunction)functiontype, METH_VARARGS,"Get the type of a fun expression."}, - {"startcat", (PyCFunction)gf_startCat, METH_NOARGS,"Get the start category."}, - {"categories", (PyCFunction)gf_categories, METH_NOARGS,"Get all categories."}, - {"functions", (PyCFunction)gf_functions, METH_NOARGS,"Get all functions."}, - {"abstract", (PyCFunction)abstractName, METH_NOARGS,"Get the module abstract name."}, - {"languages", (PyCFunction)gf_languages, METH_NOARGS,"Get the module languages."}, - {"complete", (PyCFunction)completions, METH_VARARGS|METH_KEYWORDS, "Get completions for tokens."}, - {NULL, NULL, 0, NULL} /* Sentinel */ -}; - -REPRCB(CId_repr, CId, gf_showCId) - - -/* Language methods, constructor and destructor */ - -REPRCB(lang_repr, Lang, gf_showLanguage) -DEALLOCFN(Lang_dealloc, Lang, gf_freeLanguage, "freeLanguage") - -static Lang* -readLang(PyObject *self, PyObject *args) -{ - char *langName; - Lang *l; - if (!PyArg_ParseTuple(args,"s",&langName)) - return NULL; - l = (Lang*)LangType.tp_new(&LangType,NULL,NULL); - if(!l) return NULL; - gf_readLanguage(l,langName); - return l; -} - - - -/* gf types: methods, constructor and destructor */ - -DEALLOCFN(gfType_dealloc, gfType, gf_freeType, "freeType") -REPRCB(gfType_repr, gfType, gf_showType) - - -/* expression type: methods, destructor */ - -DEALLOCFN(expr_dealloc, Expr, gf_freeExpr, "freeExpr") -REPRCB(expr_repr, Expr, gf_showExpr) - - -static PyObject* -unapp(Expr *self) { - PyObject* obj = gf_unapp(self); - if (!obj) { - char* s = gf_unstr(self); - if (s) { - obj = PyString_FromString(s); - free(s); - } else { - long n = gf_unint(self); - if (n != -9) { - obj = PyInt_FromLong(n); - } else { - PyErr_Format(PyExc_TypeError, "Cannot unapply expr."); - } - } - } - return obj; -} - -static PyObject* -infer_expr(Expr *self, PyObject* args) { - PGF* pgf; - if (!PyArg_ParseTuple(args, "O", &pgf)) - return NULL; - if (!checkType(pgf, &PGFType)) { - PyErr_Format(PyExc_ValueError, "Must be a pgf module."); - return NULL; - } - return gf_inferexpr(pgf, self); -} - - - -/* todo: Is Tree == Expr ? */ - -static PyMethodDef expr_methods[] = { - {"unapply", (PyCFunction)unapp, METH_NOARGS, "Unapply an expression."}, - {"infer", (PyCFunction)infer_expr, METH_VARARGS, "Infer the type of an expression."}, - {NULL, NULL, 0, NULL} /* Sentinel */ -}; - - - -/* tree type: methods, constructor and destructor */ -// Are Expr and Tree equivalent ? - -REPRCB(tree_repr, Tree, gf_showExpr) -DEALLOCFN(Tree_dealloc, Tree, gf_freeTree, "freeTree") - - - - - -/* gf module methods */ - -static PyMethodDef gf_methods[] = { - {"read_pgf", (PyCFunction)readPGF, METH_VARARGS,"Read pgf file."}, - {"read_language", (PyCFunction)readLang, METH_VARARGS,"Get the language."}, - {NULL, NULL, 0, NULL} /* Sentinel */ -}; - - -#ifndef PyMODINIT_FUNC/* declarations for DLL import/export */ -#define PyMODINIT_FUNC void -#endif - -PyMODINIT_FUNC -initgf(void) -{ - PyObject* m; -#define READYTYPE(t,trepr,tdealloc) t.tp_new = PyType_GenericNew; \ - t.tp_repr = (reprfunc)trepr; \ - t.tp_dealloc = (destructor)tdealloc; \ - if (PyType_Ready(&t) < 0) return; - - READYTYPE(CIdType, CId_repr, CId_dealloc) - - PGFType.tp_methods = pgf_methods; - READYTYPE(PGFType, pgf_repr, PGF_dealloc) - - READYTYPE(LangType, lang_repr, Lang_dealloc) - - READYTYPE(gfTypeType, gfType_repr, gfType_dealloc) - - ExprType.tp_methods = expr_methods; - READYTYPE(ExprType, expr_repr, expr_dealloc) - - TreeType.tp_methods = expr_methods; // Tree == Expr ? - READYTYPE(TreeType, tree_repr, Tree_dealloc) - - m = Py_InitModule3("gf", gf_methods, - "Grammatical Framework."); - static char *argv[] = {"gf.so", 0}, **argv_ = argv; - static int argc = 1; - gf_init (&argc, &argv_); - hs_add_root (__stginit_PyGF); - -#define ADDTYPE(t) Py_INCREF(&t);\ -PyModule_AddObject(m, "gf", (PyObject *)&t); - - ADDTYPE(PGFType) - ADDTYPE(LangType) - ADDTYPE(gfTypeType) - ADDTYPE(TreeType) - ADDTYPE(ExprType) -} - - -/* List utilities to be imported by FFI */ - -inline PyObject* newList() { return PyList_New(0); } -inline PyObject* newString(const char *s) { return PyString_FromString(s); } -inline void append(PyObject* l, PyObject* ob) { PyList_Append(l, ob); } diff --git a/contrib/py-bindings/lgpl-3.0.txt b/contrib/py-bindings/lgpl-3.0.txt deleted file mode 100644 index cca7fc278..000000000 --- a/contrib/py-bindings/lgpl-3.0.txt +++ /dev/null @@ -1,165 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. diff --git a/contrib/py-bindings/pygf.h b/contrib/py-bindings/pygf.h deleted file mode 100644 index 04f142bcf..000000000 --- a/contrib/py-bindings/pygf.h +++ /dev/null @@ -1,96 +0,0 @@ -#include <Python.h> -#include "HsFFI.h" - -#ifdef __GLASGOW_HASKELL__ -#include "PyGF_stub.h" - -extern void __stginit_PyGF ( void ); -#endif - -static inline void gf_init(int *argc, char ***argv) -{ - hs_init(argc, argv); -#ifdef __GLASGOW_HASKELL__ - hs_add_root(__stginit_PyGF); -#endif -} - -static inline void gf_exit(void) -{ - hs_exit(); -} - -typedef HsStablePtr GF_PGF; -typedef HsStablePtr GF_CId; -typedef HsStablePtr GF_Language; -typedef HsStablePtr GF_Type; -typedef HsStablePtr GF_Tree; -typedef HsStablePtr GF_Expr; -typedef struct { - PyObject_HEAD; - HsStablePtr sp; -} PyGF; - - -#define NEWOBJECT(OBJ, GFTYPE) typedef struct {\ - PyObject_HEAD \ - GFTYPE obj; \ - } OBJ; - -#define PYTYPE(OBJ) OBJ ## Type -#define NEWCONSTRUCTOR(OBJ) inline OBJ* new ## OBJ () {\ - return (OBJ*)PYTYPE(OBJ).tp_new(&PYTYPE(OBJ),NULL,NULL); } - -#define NEWTYPE(TYPE,NAME,OBJECT,DOC) static PyTypeObject TYPE = {\ - PyObject_HEAD_INIT(NULL)\ - 0, /*ob_size*/\ - NAME, /*tp_name*/\ - sizeof(OBJECT), /*tp_basicsize*/\ - 0, /*tp_itemsize*/\ - 0, /*tp_dealloc*/\ - 0, /*tp_print*/\ - 0, /*tp_getattr*/\ - 0, /*tp_setattr*/\ - 0, /*tp_compare*/\ - 0, /*tp_repr*/\ - 0, /*tp_as_number*/\ - 0, /*tp_as_sequence*/\ - 0, /*tp_as_mapping*/\ - 0, /*tp_hash */\ - 0, /*tp_call*/\ - 0, /*tp_str*/\ - 0, /*tp_getattro*/\ - 0, /*tp_setattro*/\ - 0, /*tp_as_buffer*/\ - Py_TPFLAGS_DEFAULT, /*tp_flags*/\ - DOC, /* tp_doc */\ - }; -#define NEWGF(OBJ,GFTYPE,TYPE,NAME,DOC) NEWOBJECT(OBJ,GFTYPE) \ - NEWTYPE(TYPE,NAME,OBJ,DOC)\ - NEWCONSTRUCTOR(OBJ) - - -// NEWOBJECT(CID, GF_CId) - -#ifdef DEBUG -#define DEALLOCFN(delname,t,cb,cbname) static void \ -delname(t *self){ cb(self);\ - printf("gf_%s has been called for stable pointer 0x%x\n", cbname, self->obj);\ - self->ob_type->tp_free((PyObject*)self); } -#else -#define DEALLOCFN(delname,t,cb,cbname) static void \ -delname(t *self){ cb(self);\ - self->ob_type->tp_free((PyObject*)self); } -#endif - -#ifdef DEBUG -#define REPRCB(cbid,t,gfcb) static PyObject* \ -cbid(t *self) { \ - const char *str = gfcb(self); \ - return PyString_FromFormat("0x%x: %s", self->obj, str); } -#else -#define REPRCB(cbid,t,gfcb) static PyObject* \ -cbid(t *self) { \ - const char *str = gfcb(self); \ - return PyString_FromString(str); } -#endif diff --git a/contrib/py-bindings/test.py b/contrib/py-bindings/test.py deleted file mode 100644 index 9ea6c1f45..000000000 --- a/contrib/py-bindings/test.py +++ /dev/null @@ -1,187 +0,0 @@ -#!/usr/bin/env python -# GF Python bindings -# Jordi Saludes 2010 -# - - -import gf -import unittest - -samples = [ - (['Odd', ['Number', 89]], - {'eng': "is 89 odd", - 'spa': "89 es impar"}), - (['Prime', ['Number', 21]], - {'eng': "is 21 prime", - 'spa': "21 es primo"})] - -def lang2iso(l): - s = rmprefix(l) - assert s[:5]=="Query" - return s[5:].lower() - -def exp2str(e): - def e2s(e,n): - if type(e) == type([2]): - f = e[0] - sr = ' '.join([e2s(arg,n+1) for arg in e[1:]]) - ret =f + ' ' + sr - return n and '('+ret+')' or ret - elif type(e) == type('2'): - return e - elif type(e) == type(2): - return `e` - else: - raise ValueError, "Do not know how to render " + `e` - return e2s(e,0) - - -import re -hexre = re.compile('0x[0-9a-f]+:[ ]*') -def rmprefix(obj): - return `obj` -# s = `obj` -# m = hexre.match(s) -# return m and s[m.end(0):] - -class TestPgfInfo(unittest.TestCase): - def pgf(self, path=None): - path = path or self.path - return gf.read_pgf(path) - def setUp(self): - self.path = 'Query.pgf' - def test_readPgf(self): - pgf = self.pgf() - self.assertNotEqual(pgf,None) - def test_readNonExistent(self): - nopath = 'x' + self.path - self.assertRaises(IOError, self.pgf, nopath) - def test_startcat(self): - pgf = self.pgf() - cat = pgf.startcat() - self.assertEqual(rmprefix(cat),'Question') - def test_categories(self): - pgf = self.pgf() - cats = [`c` for c in pgf.categories()] - self.failUnless('Float' in cats) - self.failUnless('Int' in cats) - self.failUnless('String' in cats) - def test_createLanguage(self): - pgf = self.pgf() - for lang in 'QueryEng QuerySpa'.split(): - l = gf.read_language(lang) - self.assertEqual(rmprefix(l),lang) - def test_functions(self): - pgf = self.pgf() - self.assertTrue('Even' in [`f` for f in pgf.functions()]) - def test_function_types(self): - pgf = self.pgf() - gftypes = dict((`f`,`pgf.fun_type(f)`) for f in pgf.functions()) - for p in "Prime : Object -> Question; Yes : Answer".split(';'): - lhs,rhs = [s.strip() for s in p.split(':')] - self.assertEqual(gftypes[lhs],rhs) - -class TestParsing(unittest.TestCase): - def setUp(self): - self.lexed = samples - self.lang = 'QueryEng' - self.pgf = "Query.pgf" - - def test_parse(self): - pgf = gf.read_pgf(self.pgf) - l = gf.read_language(self.lang) - for abs,cnc in self.lexed: - rabs = exp2str(abs) - ps = pgf.parse(l, cnc['eng']) - self.failUnless(ps) - pt = rmprefix(ps[0]) - self.assertEqual(pt,rabs) - - -class TestLinearize(unittest.TestCase): - def setUp(self): - self.samples = samples - self.pgf = gf.read_pgf('Query.pgf') - self.lang = gf.read_language('QueryEng') - - def test_Linearize(self): - l = self.lang - for abs,cnc in self.samples: - ts = self.pgf.parse(l, cnc['eng']) - self.assertEqual(cnc['eng'],self.pgf.linearize(l,ts[0])) - -class TestTranslate(unittest.TestCase): - def setUp(self): - self.samples = samples - self.pgf = gf.read_pgf('Query.pgf') - self.langs = [(lang2iso(l),l) for l in self.pgf.languages()] - - def test_translate(self): - for abs,cnc in self.samples: - for i,l in self.langs: - for j,m in self.langs: - if i==j: continue - parsed = self.pgf.parse(l, cnc[i]) - assert len(parsed) == 1 - lin = self.pgf.linearize(m,parsed[0]) - self.assertEqual(lin,cnc[j]) - -class TestUnapplyExpr(unittest.TestCase): - def setUp(self): - self.samples = samples - self.pgf = gf.read_pgf('Query.pgf') - self.langs = dict([(lang2iso(l),l) for l in self.pgf.languages()]) - - def deep_unapp(self,exp): - exp = exp.unapply() - if type(exp) == type([2]): - f = exp[0] - return [`f`] + map(self.deep_unapp,exp[1:]) - else: - return exp - - - def test_unapply(self): - lg = 'eng' - lang = self.langs[lg] - for abs,cnc in self.samples: - parsed = self.pgf.parse(lang, cnc[lg]) - uparsed = self.deep_unapp(parsed[0]) - self.assertEqual(abs,uparsed) - - def test_infer(self): - lg = 'eng' - lang = self.langs[lg] - cnc = self.samples[0][1] - parsed = self.pgf.parse(lang, cnc[lg]) - exp = parsed[0] - for t in 'Question Object Int'.split(): - self.assertEqual(`exp.infer(self.pgf)`, t) - uexp = exp.unapply() - if type(uexp) != type(2) and type(uexp) != type('2'): - exp = uexp[1] - - -class TestComplete(unittest.TestCase): - def setUp(self): - self.lexed = samples - self.pgf = gf.read_pgf('Query.pgf') - self.langs = dict([(lang2iso(l),l) for l in self.pgf.languages()]) - - def test_complete(self): - for (_,d) in self.lexed: - for l,text in d.items(): - lang = self.langs[l] - for k in range(len(text)): - if text[k].isdigit() or text[k-1].isdigit(): # No completion for integer literals - continue - comps = self.pgf.complete(lang,text[:k]) - self.assertNotEqual(comps, [], - msg="while completing '%s^%s'" % (text[:k],text[k:])) - - self.assertTrue(any(w in text for w in comps), - msg="None of %s is in '%s'" % (comps,text)) - - -if __name__ == '__main__': - unittest.main() |
