1
0
forked from GitHub/gf-core

More sophisticated python types

This commit is contained in:
jordi.saludes
2010-06-12 20:28:22 +00:00
parent b8bbb57b85
commit b8a022e3a8
2 changed files with 147 additions and 99 deletions

View File

@@ -1,137 +1,185 @@
#define CAT(a,b) XCAT(a,b)
#define XCAT(a,b) a ## b
#include <stdio.h>
#include <stdlib.h>
#include "pgf.h"
#include <Python.h> #include <Python.h>
#include "pgf.h"
#define NEWOBJECT(OBJ, GFTYPE) typedef struct {\
PyObject_HEAD \
GFTYPE obj; \
} OBJ;
#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)
NEWGF(PGFModule,GF_PGF,PGFType,"gf.pgf","PGF module")
NEWGF(Lang,GF_Language,LangType,"gf.lang","language")
NEWGF(gfType,GF_Type,gfTypeType,"gf.type","gf type")
NEWGF(Expr,GF_Expr,ExprType,"gf.expr","gf expression")
static PyObject* static PyObject*
PGF_repr(PGFModule* obj)
{
return PyString_FromFormat("this is a PGF module");
}
static PGFModule*
readPGF(PyObject *self, PyObject *args) readPGF(PyObject *self, PyObject *args)
{ {
char *path; char *path;
PGFModule *pgf;
if (!PyArg_ParseTuple(args, "s", &path)) if (!PyArg_ParseTuple(args, "s", &path))
return NULL; return NULL;
GF_PGF pgf = gf_readPGF(path); pgf = (PGFModule*)PGFType.tp_new(&PGFType,NULL,NULL);
return PyCObject_FromVoidPtr(pgf, gf_freePGF); if (!pgf) return NULL;
pgf->obj = gf_readPGF(path);
return pgf;
} }
static PyObject* static Lang*
readLanguage(PyObject *self, PyObject *args) readLang(PyObject *self, PyObject *args)
{ {
char *module_name; char *langName;
if (!PyArg_ParseTuple(args, "s", &module_name)) Lang *l;
if (!PyArg_ParseTuple(args,"s",&langName))
return NULL; return NULL;
GF_Language lang = gf_readLanguage(module_name); l = (Lang*)LangType.tp_new(&LangType,NULL,NULL);
return PyCObject_FromVoidPtr(lang, gf_freeLanguage); if(!l) return NULL;
l->obj = gf_readLanguage(langName);
return l;
} }
static PyObject* int
showExpr(PyObject *self, PyObject *args) checkType(PyObject* obj, PyTypeObject* tp)
{ {
PyObject *co_exp; int isRight = PyObject_TypeCheck(obj, tp);
GF_Expr exp; if (!isRight)
if (!PyArg_ParseTuple(args, "O", &co_exp)) PyErr_Format(PyExc_TypeError, "Expected a %s", tp->tp_doc);
return NULL; return isRight;
if (!PyCObject_Check(co_exp)) {
PyErr_SetString(PyExc_TypeError, "Expected an expression.");
return NULL;
}
exp = (GF_Expr)PyCObject_AsVoidPtr(co_exp);
char *str = gf_showExpr(exp);
return Py_BuildValue("s",str);
} }
static gfType*
static PyObject* startCategory(PyObject *self, PyObject *args)
startCat(PyObject *self, PyObject *args)
{ {
PyObject *cobj; gfType *cat;
GF_PGF pgf; PyObject *pgf_obj;
if (!PyArg_ParseTuple(args, "O", &cobj)) if (!PyArg_ParseTuple(args,"O",&pgf_obj))
return NULL; return NULL;
if (!PyCObject_Check(cobj)) { if (!checkType(pgf_obj, &PGFType)) return NULL;
PyErr_SetString(PyExc_TypeError, "Expected a pgf object"); cat = (gfType*)gfTypeType.tp_new(&gfTypeType,NULL,NULL);
return NULL; GF_PGF pgf = ((PGFModule*)pgf_obj)->obj;
} cat->obj = gf_startCat(pgf);
pgf = (GF_PGF)PyCObject_AsVoidPtr(cobj); return cat;
GF_Type cat = gf_startCat(pgf);
return PyCObject_FromVoidPtr(cat, gf_freeType);
} }
static PyObject* static PyObject*
parse(PyObject *self, PyObject *args) parse(PyObject *self, PyObject *args)
{ {
PyObject *co_pgf, *co_lang, *co_cat; PyObject *pgf_pyob, *lang_pyob, *cat_pyob;
GF_PGF pgf; GF_PGF pgf;
GF_Language lang; GF_Language lang;
GF_Type cat; GF_Type cat;
char *lexed; char *lexed;
if (!PyArg_ParseTuple(args, "OOOs", &co_pgf, &co_lang, &co_cat, &lexed)) if (!PyArg_ParseTuple(args, "OOOs", &pgf_pyob, &lang_pyob, &cat_pyob, &lexed))
return NULL; return NULL;
if (!PyCObject_Check(co_pgf)) { if (!checkType(pgf_pyob, &PGFType)) return NULL;
PyErr_SetString(PyExc_TypeError, "Expected a PGF object"); if (!checkType(lang_pyob, &LangType)) return NULL;
return NULL; if (!checkType(cat_pyob, &gfTypeType)) return NULL;
} pgf = ((PGFModule*)pgf_pyob)->obj;
if (!PyCObject_Check(co_lang)) { lang = ((Lang*)lang_pyob)->obj;
PyErr_SetString(PyExc_TypeError, "Expected a Language object"); cat = ((gfType*)cat_pyob)->obj;
return NULL; GF_Tree *result = gf_parse(pgf, lang, cat, lexed);
} GF_Tree *p = result;
if (!PyCObject_Check(co_cat)) { PyObject *parsed = PyList_New(0);
PyErr_SetString(PyExc_TypeError, "Expected a Type object"); if (*p) {
return NULL; do {
} Expr* expr;
pgf = (GF_PGF)PyCObject_AsVoidPtr(co_pgf); expr = (Expr*)ExprType.tp_new(&ExprType,NULL,NULL);
lang = (GF_Language)PyCObject_AsVoidPtr(co_lang); expr->obj = *(p++);
cat = (GF_Type)PyCObject_AsVoidPtr(co_cat); PyList_Append(parsed, (PyObject*)expr);
GF_Tree *result = gf_parse(pgf, lang, cat, lexed);
GF_Tree *p = result;
PyObject *parsed = PyList_New(0);
if (*p) {
do {
GF_Expr exp = *(p++);
PyObject *co_exp = PyCObject_FromVoidPtr(exp,gf_freeExpr);
PyList_Append(parsed, co_exp);
/* char *str = gf_showExpr(exp); /* char *str = gf_showExpr(exp);
puts(str); puts(str);
free(str); */ free(str); */
} while (*p); } while (*p);
} }
return parsed; return parsed;
} }
static PyObject*
expr_repr(Expr *self)
{
const char *str = gf_showExpr(self->obj);
return PyString_FromString(str);
}
static PyMethodDef GfMethods[] = { static PyMethodDef gf_methods[] = {
{"read_pgf", readPGF, METH_VARARGS, {"read_pgf", (PyCFunction)readPGF, METH_VARARGS,"Read pgf file."},
"Read pgf file"}, {"read_language", (PyCFunction)readLang, METH_VARARGS,"Get the language."},
{"read_lang", readLanguage, METH_VARARGS, {"startcat", (PyCFunction)startCategory, METH_VARARGS,"Get the start category of a pgf module."},
"Get language from pgf."}, {"parse", (PyCFunction)parse, METH_VARARGS,"parse a string."},
{"startcat", startCat, METH_VARARGS, {NULL, NULL, 0, NULL} /* Sentinel */
"Get start category from pgf."}, };
{"parse", parse, METH_VARARGS,
"Parse string for language and given start category."}, #ifndef PyMODINIT_FUNC/* declarations for DLL import/export */
{"show_expr", showExpr, METH_VARARGS, #define PyMODINIT_FUNC void
"show an expression."}, #endif
{NULL, NULL, 0, NULL}
} ;
PyMODINIT_FUNC PyMODINIT_FUNC
initgf(void) initgf(void)
{ {
PyObject *m = Py_InitModule("gf", GfMethods); PyObject* m;
static char *argv[] = { "gf.so", 0 }, **argv_ = argv; #define READYTYPE(t) t.tp_new = PyType_GenericNew;\
if (PyType_Ready(&t) < 0) return;
PGFType.tp_repr = (reprfunc)PGF_repr;
READYTYPE(PGFType)
READYTYPE(LangType)
READYTYPE(gfTypeType)
ExprType.tp_repr = (reprfunc)expr_repr;
READYTYPE(ExprType)
m = Py_InitModule3("gf", gf_methods,
"Grammatical Framework.");
static char *argv[] = {"gf.so", 0}, **argv_ = argv;
static int argc = 1; static int argc = 1;
gf_init (&argc, &argv_); gf_init (&argc, &argv_);
hs_add_root (CAT (__stginit_, MODULE)); hs_add_root (__stginit_PGFFFI);
printf("Started gf\n");
if (m == NULL) return;
/* gfError = PyErr_NewException("gf.error", NULL, NULL); #define ADDTYPE(t) Py_INCREF(&t);\
Py_INCREF(gfError); PyModule_AddObject(m, "gf", (PyObject *)&t);
PyModule_AddObject(m, "error", gfError);
*/ ADDTYPE(PGFType)
ADDTYPE(LangType)
ADDTYPE(gfTypeType)
ADDTYPE(ExprType)
} }

View File

@@ -1,9 +1,9 @@
#!/usr/bin/env python #!/usr/bin/env python
from gf import * from gf import *
query = read_pgf("Query.pgf") query = read_pgf("Query.pgf")
lang = read_lang('QueryEng') lang = read_language('QueryEng')
cat = startcat(query) cat = startcat(query)
lexed = "is 2 prime" lexed = "is 2 prime"
print "Parsing '%s':" % lexed print "Parsing '%s':" % lexed
for e in parse(query, lang, cat, lexed): for e in parse(query, lang, cat, lexed):
print '\t',show_expr(e) print '\t',e