mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-04-23 11:42:49 -06:00
embedded mode for GF grammar in Python. Only generation for now
This commit is contained in:
@@ -198,3 +198,10 @@ pgf_concr_add_literal(PgfConcr *concr, PgfCId cat,
|
|||||||
gu_map_put(concr->callbacks, cnccat,
|
gu_map_put(concr->callbacks, cnccat,
|
||||||
PgfLiteralCallback*, callback);
|
PgfLiteralCallback*, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PgfExprProb*
|
||||||
|
pgf_fun_get_ep(void* value)
|
||||||
|
{
|
||||||
|
PgfAbsFun* absfun = *((PgfAbsFun**) value);
|
||||||
|
return &absfun->ep;
|
||||||
|
}
|
||||||
|
|||||||
@@ -189,4 +189,8 @@ void
|
|||||||
pgf_check_type(PgfPGF* gr, PgfType** ty,
|
pgf_check_type(PgfPGF* gr, PgfType** ty,
|
||||||
GuExn* exn, GuPool* pool);
|
GuExn* exn, GuPool* pool);
|
||||||
|
|
||||||
|
// internal
|
||||||
|
PgfExprProb*
|
||||||
|
pgf_fun_get_ep(void* value);
|
||||||
|
|
||||||
#endif // PGF_H_
|
#endif // PGF_H_
|
||||||
|
|||||||
@@ -65,6 +65,9 @@ Expr_initLiteral(ExprObject *self, PyObject *lit);
|
|||||||
static int
|
static int
|
||||||
Expr_initApp(ExprObject *self, const char* fname, PyObject *args);
|
Expr_initApp(ExprObject *self, const char* fname, PyObject *args);
|
||||||
|
|
||||||
|
static ExprObject*
|
||||||
|
Expr_call(ExprObject* e, PyObject* args, PyObject* kw);
|
||||||
|
|
||||||
static PyObject*
|
static PyObject*
|
||||||
Expr_unpack(ExprObject* self, PyObject *args);
|
Expr_unpack(ExprObject* self, PyObject *args);
|
||||||
|
|
||||||
@@ -184,7 +187,7 @@ static PyTypeObject pgf_ExprType = {
|
|||||||
0, /*tp_as_sequence*/
|
0, /*tp_as_sequence*/
|
||||||
0, /*tp_as_mapping*/
|
0, /*tp_as_mapping*/
|
||||||
(hashfunc) Expr_hash, /*tp_hash */
|
(hashfunc) Expr_hash, /*tp_hash */
|
||||||
0, /*tp_call*/
|
(ternaryfunc) Expr_call, /*tp_call*/
|
||||||
(reprfunc) Expr_repr, /*tp_str*/
|
(reprfunc) Expr_repr, /*tp_str*/
|
||||||
(getattrofunc) Expr_getattro,/*tp_getattro*/
|
(getattrofunc) Expr_getattro,/*tp_getattro*/
|
||||||
0, /*tp_setattro*/
|
0, /*tp_setattro*/
|
||||||
@@ -302,6 +305,51 @@ Expr_initApp(ExprObject *self, const char* fname, PyObject *args)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ExprObject*
|
||||||
|
Expr_call(ExprObject* self, PyObject* args, PyObject* kw)
|
||||||
|
{
|
||||||
|
ExprObject* pyexpr = (ExprObject*) pgf_ExprType.tp_alloc(&pgf_ExprType, 0);
|
||||||
|
if (pyexpr == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
size_t n_args = PyTuple_Size(args);
|
||||||
|
|
||||||
|
pyexpr->master = PyTuple_New(n_args+1);
|
||||||
|
if (pyexpr->master == NULL) {
|
||||||
|
Py_DECREF(pyexpr);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyTuple_SetItem(pyexpr->master, 0, (PyObject*) self);
|
||||||
|
Py_INCREF(self);
|
||||||
|
|
||||||
|
pyexpr->pool = gu_new_pool();
|
||||||
|
pyexpr->expr = self->expr;
|
||||||
|
|
||||||
|
for (Py_ssize_t i = 0; i < n_args; i++) {
|
||||||
|
PyObject* obj = PyTuple_GetItem(args, i);
|
||||||
|
if (obj->ob_type != &pgf_ExprType) {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "the arguments must be expressions");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyTuple_SetItem(pyexpr->master, i+1, obj);
|
||||||
|
Py_INCREF(obj);
|
||||||
|
|
||||||
|
PgfExpr fun = pyexpr->expr;
|
||||||
|
PgfExpr arg = ((ExprObject*) obj)->expr;
|
||||||
|
|
||||||
|
PgfExprApp* e =
|
||||||
|
gu_new_variant(PGF_EXPR_APP,
|
||||||
|
PgfExprApp,
|
||||||
|
&pyexpr->expr, pyexpr->pool);
|
||||||
|
e->fun = fun;
|
||||||
|
e->arg = arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pyexpr;
|
||||||
|
}
|
||||||
|
|
||||||
static PyObject*
|
static PyObject*
|
||||||
Expr_unpack(ExprObject* self, PyObject *fargs)
|
Expr_unpack(ExprObject* self, PyObject *fargs)
|
||||||
{
|
{
|
||||||
@@ -2343,6 +2391,56 @@ PGF_graphvizAbstractTree(PGFObject* self, PyObject *args) {
|
|||||||
return pystr;
|
return pystr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pgf_embed_funs(GuMapItor* fn, const void* key, void* value, GuExn* err)
|
||||||
|
{
|
||||||
|
PyPGFClosure* clo = (PyPGFClosure*) fn;
|
||||||
|
|
||||||
|
PgfCId name = (PgfCId) key;
|
||||||
|
|
||||||
|
ExprObject* pyexpr = (ExprObject*) pgf_ExprType.tp_alloc(&pgf_ExprType, 0);
|
||||||
|
if (pyexpr == NULL) {
|
||||||
|
gu_raise(err, PgfExn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pyexpr->expr = pgf_fun_get_ep(value)->expr;
|
||||||
|
|
||||||
|
if (PyModule_AddObject(clo->object, name, (PyObject*) pyexpr) != 0) {
|
||||||
|
gu_raise(err, PgfExn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject*
|
||||||
|
PGF_embed(PGFObject* self, PyObject *args)
|
||||||
|
{
|
||||||
|
PgfCId modname;
|
||||||
|
if (!PyArg_ParseTuple(args, "s", &modname))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
PyObject *m = PyImport_AddModule(modname);
|
||||||
|
if (m == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
GuPool* tmp_pool = gu_local_pool();
|
||||||
|
|
||||||
|
// Create an exception frame that catches all errors.
|
||||||
|
GuExn* err = gu_new_exn(NULL, gu_kind(type), tmp_pool);
|
||||||
|
|
||||||
|
PyPGFClosure clo = { { pgf_embed_funs }, self, m };
|
||||||
|
pgf_iter_functions(self->pgf, &clo.fn, err);
|
||||||
|
if (!gu_ok(err)) {
|
||||||
|
Py_DECREF(m);
|
||||||
|
gu_pool_free(tmp_pool);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
gu_pool_free(tmp_pool);
|
||||||
|
|
||||||
|
Py_INCREF(m);
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
static PyGetSetDef PGF_getseters[] = {
|
static PyGetSetDef PGF_getseters[] = {
|
||||||
{"abstractName",
|
{"abstractName",
|
||||||
(getter)PGF_getAbstractName, NULL,
|
(getter)PGF_getAbstractName, NULL,
|
||||||
@@ -2396,6 +2494,12 @@ static PyMethodDef PGF_methods[] = {
|
|||||||
{"graphvizAbstractTree", (PyCFunction)PGF_graphvizAbstractTree, METH_VARARGS,
|
{"graphvizAbstractTree", (PyCFunction)PGF_graphvizAbstractTree, METH_VARARGS,
|
||||||
"Renders an abstract syntax tree in a Graphviz format"
|
"Renders an abstract syntax tree in a Graphviz format"
|
||||||
},
|
},
|
||||||
|
{"embed", (PyCFunction)PGF_embed, METH_VARARGS,
|
||||||
|
"embed(mod_name) creates a Python module with name mod_name, which "
|
||||||
|
"contains one Python object for every abstract function in the grammar. "
|
||||||
|
"The module can be imported to make it easier to construct abstract "
|
||||||
|
"syntax trees."
|
||||||
|
},
|
||||||
{NULL} /* Sentinel */
|
{NULL} /* Sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user