Skip to content

Commit

Permalink
added Graphviz visualizations
Browse files Browse the repository at this point in the history
  • Loading branch information
krangelov committed Apr 15, 2024
1 parent ef659f3 commit 876e3c7
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 7 deletions.
6 changes: 6 additions & 0 deletions src/runtime/c/pgf/pgf.h
Original file line number Diff line number Diff line change
Expand Up @@ -878,6 +878,12 @@ typedef struct {
const char *leafEdgeStyle;
} PgfGraphvizOptions;

PGF_API_DECL PgfText *
pgf_graphviz_abstract_tree(PgfDB *db, PgfRevision revision,
PgfExpr expr, PgfMarshaller *m,
PgfGraphvizOptions* opts,
PgfExn *err);

PGF_API_DECL PgfText *
pgf_graphviz_parse_tree(PgfDB *db, PgfConcrRevision revision,
PgfExpr expr, PgfPrintContext *ctxt,
Expand Down
32 changes: 29 additions & 3 deletions src/runtime/python/pgf.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ class PGF:
"""
...

def generateRandom(cat : Type, depth : int = 5) -> tuple[Expr,float]:
def generateRandom(self, cat : Type, depth : int = 5) -> tuple[Expr,float]:
"""
Generates a random abstract syntax trees of the given type.
The depth parameter specifies the maximal distance between
Expand All @@ -123,6 +123,16 @@ class PGF:
"""
...

def graphvizAbstractTree(self, e: Expr,
noFun:bool=False, noCat:bool=False,
nodeFont:str="",
nodeColor:str="",
nodeEdgeStyle:str="") -> str:
"""
Renders an abstract syntax tree in a Graphviz format
"""
...

def newTransaction(self) -> Transaction:
"""
Starts a new transaction which makes it possible to update
Expand Down Expand Up @@ -208,11 +218,11 @@ class Concr:
"""The name of the concrete syntax"""
...

def linearize(e: Expr) -> str:
def linearize(self, e: Expr) -> str:
"""Linearizes the abstract expression and returns as string"""
...

def bracketedLinearize(e: Expr) -> list[Any]:
def bracketedLinearize(self, e: Expr) -> list[Any]:
"""
Produces a bracketed linearization where syntactic phrases
are represented as objects of type Bracket and terminal tokens
Expand All @@ -221,6 +231,22 @@ class Concr:
"""
...

def hasLinearization(self, fun: Str) -> bool:
"""
Returns true if the given function has linearization in the concrete syntax
"""
...

def graphvizParseTree(self, e: Expr,
noLeaves:bool=False, noFun:bool=False, noCat:bool=False,
nodeFont:str="", leafFont:str="",
nodeColor:str="", leafColor:str="",
nodeEdgeStyle:str="", leafEdgeStyle:str="") -> str:
"""
Renders an abstract syntax tree as a parse tree in Graphviz format
"""
...

class PGFError:
"""
This is the exception that several functions throw
Expand Down
84 changes: 81 additions & 3 deletions src/runtime/python/pypgf.c
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,47 @@ Concr_hasLinearization(ConcrObject* self, PyObject *args)
Py_RETURN_FALSE;
}

static PyObject*
Concr_graphvizParseTree(ConcrObject* self, PyObject *args, PyObject *kwargs)
{
PgfGraphvizOptions opts;
memset(&opts, 0, sizeof(opts));

char *kwds[] = {"","noLeaves","noFun","noCat",
"nodeFont","leafFont",
"nodeColor","leafColor",
"nodeEdgeStyle","leafEdgeStyle",
NULL};

ExprObject* pyexpr;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!|pppssssss", kwds,
&pgf_ExprType, &pyexpr,
&opts.noLeaves,
&opts.noFun,
&opts.noCat,
&opts.nodeFont,
&opts.leafFont,
&opts.nodeColor,
&opts.leafColor,
&opts.nodeEdgeStyle,
&opts.leafEdgeStyle))
return NULL;

PgfExn err;
PgfText *text =
pgf_graphviz_parse_tree(self->grammar->db, self->concr,
(PgfExpr) pyexpr, NULL, &marshaller,
&opts, &err);
if (handleError(err) != PGF_EXN_NONE) {
return NULL;
}

PyObject* pystr = PyUnicode_FromStringAndSize(text->text, text->size);
free(text);

return pystr;
}

typedef struct {
PgfMorphoCallback fn;
PyObject* analyses;
Expand Down Expand Up @@ -519,10 +560,10 @@ static PyMethodDef Concr_methods[] = {
},*/
{"hasLinearization", (PyCFunction)Concr_hasLinearization, METH_VARARGS,
"hasLinearization(f) returns true if the function f has linearization in the concrete syntax"
},/*
{"graphvizParseTree", (PyCFunction)Concr_graphvizParseTree, METH_VARARGS,
},
{"graphvizParseTree", (PyCFunction)Concr_graphvizParseTree, METH_VARARGS | METH_KEYWORDS,
"Renders an abstract syntax tree as a parse tree in Graphviz format"
},*/
},
{"lookupMorpho", (PyCFunction)Concr_lookupMorpho, METH_VARARGS,
"Looks up a word in the lexicon of the grammar"
},/*
Expand Down Expand Up @@ -993,6 +1034,40 @@ PGF_generateRandom(PGFObject *self, PyObject *args, PyObject *keywds)
return res;
}

static PyObject*
PGF_graphvizAbstractTree(PGFObject* self, PyObject *args, PyObject *kwargs) {
PgfGraphvizOptions opts;
memset(&opts, 0, sizeof(opts));

char *kwds[] = {"","noFun","noCat",
"nodeFont", "nodeColor", "nodeEdgeStyle",
NULL};

ExprObject* pyexpr;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!|ppsss", kwds,
&pgf_ExprType, &pyexpr,
&opts.noFun,
&opts.noCat,
&opts.nodeFont,
&opts.nodeColor,
&opts.nodeEdgeStyle))
return NULL;

PgfExn err;
PgfText *text =
pgf_graphviz_abstract_tree(self->db, self->revision,
(PgfExpr) pyexpr, &marshaller,
&opts, &err);
if (handleError(err) != PGF_EXN_NONE) {
return NULL;
}

PyObject* pystr = PyUnicode_FromStringAndSize(text->text, text->size);
free(text);

return pystr;
}

static PyObject *
PGF_categoryProbability(PGFObject *self, PyObject *args)
{
Expand Down Expand Up @@ -1537,6 +1612,9 @@ static PyMethodDef PGF_methods[] = {
{"generateRandom", (PyCFunction)PGF_generateRandom, METH_VARARGS | METH_KEYWORDS,
"Generates a random abstract syntax trees of the given type"
},
{"graphvizAbstractTree", (PyCFunction)PGF_graphvizAbstractTree, METH_VARARGS | METH_KEYWORDS,
"Renders an abstract syntax tree in a Graphviz format"
},
{"categoryProbability", (PyCFunction)PGF_categoryProbability, METH_VARARGS,
"Returns the probability of a category"
},
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/python/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@

setup(
name = 'pgf-majestic',
version = '2.8',
version = '2.9',
description = 'Python bindings to the Grammatical Framework\'s PGF runtime',
long_description="""\
Grammatical Framework (GF) is a programming language for multilingual grammar applications.
Expand Down

0 comments on commit 876e3c7

Please sign in to comment.