mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-04-23 19:42:50 -06:00
the C runtime now supports the same customizations for GraphViz as the Haskell runtime
This commit is contained in:
@@ -509,21 +509,21 @@ pgfCommands = Map.fromList [
|
|||||||
exec = needPGF $ \opts arg env@(pgf, concs) ->
|
exec = needPGF $ \opts arg env@(pgf, concs) ->
|
||||||
do let es = toExprs arg
|
do let es = toExprs arg
|
||||||
let concs = optConcs env opts
|
let concs = optConcs env opts
|
||||||
{-
|
|
||||||
let gvOptions=H.GraphvizOptions {H.noLeaves = isOpt "noleaves" opts && not (isOpt "showleaves" opts),
|
let gvOptions=graphvizDefaults{noLeaves = isOpt "noleaves" opts && not (isOpt "showleaves" opts),
|
||||||
H.noFun = isOpt "nofun" opts || not (isOpt "showfun" opts),
|
noFun = isOpt "nofun" opts || not (isOpt "showfun" opts),
|
||||||
H.noCat = isOpt "nocat" opts && not (isOpt "showcat" opts),
|
noCat = isOpt "nocat" opts && not (isOpt "showcat" opts),
|
||||||
H.nodeFont = valStrOpts "nodefont" "" opts,
|
nodeFont = valStrOpts "nodefont" "" opts,
|
||||||
H.leafFont = valStrOpts "leaffont" "" opts,
|
leafFont = valStrOpts "leaffont" "" opts,
|
||||||
H.nodeColor = valStrOpts "nodecolor" "" opts,
|
nodeColor = valStrOpts "nodecolor" "" opts,
|
||||||
H.leafColor = valStrOpts "leafcolor" "" opts,
|
leafColor = valStrOpts "leafcolor" "" opts,
|
||||||
H.nodeEdgeStyle = valStrOpts "nodeedgestyle" "solid" opts,
|
nodeEdgeStyle = valStrOpts "nodeedgestyle" "solid" opts,
|
||||||
H.leafEdgeStyle = valStrOpts "leafedgestyle" "dashed" opts
|
leafEdgeStyle = valStrOpts "leafedgestyle" "dashed" opts
|
||||||
}
|
}
|
||||||
-}
|
|
||||||
let grph= if null es || null concs
|
let grph= if null es || null concs
|
||||||
then []
|
then []
|
||||||
else graphvizParseTree (snd (head concs)) (cExpr (head es))
|
else graphvizParseTree (snd (head concs)) gvOptions (cExpr (head es))
|
||||||
if isFlag "view" opts || isFlag "format" opts then do
|
if isFlag "view" opts || isFlag "format" opts then do
|
||||||
let file s = "_grph." ++ s
|
let file s = "_grph." ++ s
|
||||||
let view = optViewGraph opts
|
let view = optViewGraph opts
|
||||||
@@ -534,31 +534,27 @@ pgfCommands = Map.fromList [
|
|||||||
return void
|
return void
|
||||||
else return $ fromString grph,
|
else return $ fromString grph,
|
||||||
examples = [
|
examples = [
|
||||||
mkEx "p -lang=Eng \"John walks\" | vp -- generate a tree and show parse tree as .dot script"--,
|
mkEx "p -lang=Eng \"John walks\" | vp -- generate a tree and show parse tree as .dot script",
|
||||||
-- mkEx "gr | vp -view=\"open\" -- generate a tree and display parse tree on a Mac"
|
mkEx "gr | vp -view=\"open\" -- generate a tree and display parse tree on a Mac"
|
||||||
],
|
],
|
||||||
options = [
|
options = [
|
||||||
{-
|
|
||||||
("showcat","show categories in the tree nodes (default)"),
|
("showcat","show categories in the tree nodes (default)"),
|
||||||
("nocat","don't show categories"),
|
("nocat","don't show categories"),
|
||||||
("showfun","show function names in the tree nodes"),
|
("showfun","show function names in the tree nodes"),
|
||||||
("nofun","don't show function names (default)"),
|
("nofun","don't show function names (default)"),
|
||||||
("showleaves","show the leaves of the tree (default)"),
|
("showleaves","show the leaves of the tree (default)"),
|
||||||
("noleaves","don't show the leaves of the tree (i.e., only the abstract tree)")
|
("noleaves","don't show the leaves of the tree (i.e., only the abstract tree)")
|
||||||
-}
|
|
||||||
],
|
],
|
||||||
flags = [
|
flags = [
|
||||||
("lang","the language to visualize"),
|
("lang","the language to visualize"),
|
||||||
("format","format of the visualization file (default \"png\")"),
|
("format","format of the visualization file (default \"png\")"),
|
||||||
("view","program to open the resulting file (default \"open\")")--,
|
("view","program to open the resulting file (default \"open\")"),
|
||||||
{-
|
|
||||||
("nodefont","font for tree nodes (default: Times -- graphviz standard font)"),
|
("nodefont","font for tree nodes (default: Times -- graphviz standard font)"),
|
||||||
("leaffont","font for tree leaves (default: nodefont)"),
|
("leaffont","font for tree leaves (default: nodefont)"),
|
||||||
("nodecolor","color for tree nodes (default: black -- graphviz standard color)"),
|
("nodecolor","color for tree nodes (default: black -- graphviz standard color)"),
|
||||||
("leafcolor","color for tree leaves (default: nodecolor)"),
|
("leafcolor","color for tree leaves (default: nodecolor)"),
|
||||||
("nodeedgestyle","edge style between tree nodes (solid/dashed/dotted/bold, default: solid)"),
|
("nodeedgestyle","edge style between tree nodes (solid/dashed/dotted/bold, default: solid)"),
|
||||||
("leafedgestyle","edge style for links to leaves (solid/dashed/dotted/bold, default: dashed)")
|
("leafedgestyle","edge style for links to leaves (solid/dashed/dotted/bold, default: dashed)")
|
||||||
-}
|
|
||||||
]
|
]
|
||||||
}),
|
}),
|
||||||
|
|
||||||
@@ -584,9 +580,13 @@ pgfCommands = Map.fromList [
|
|||||||
mapM_ putStrLn ss
|
mapM_ putStrLn ss
|
||||||
return void
|
return void
|
||||||
else do
|
else do
|
||||||
-- let funs = not (isOpt "nofun" opts)
|
let gvOptions=graphvizDefaults{noFun = isOpt "nofun" opts,
|
||||||
-- let cats = not (isOpt "nocat" opts)
|
noCat = isOpt "nocat" opts,
|
||||||
let grph = unlines (map (graphvizAbstractTree pgf . cExpr) es)
|
nodeFont = valStrOpts "nodefont" "" opts,
|
||||||
|
nodeColor = valStrOpts "nodecolor" "" opts,
|
||||||
|
nodeEdgeStyle = valStrOpts "nodeedgestyle" "solid" opts
|
||||||
|
}
|
||||||
|
let grph = unlines (map (graphvizAbstractTree pgf gvOptions . cExpr) es)
|
||||||
if isFlag "view" opts || isFlag "format" opts then do
|
if isFlag "view" opts || isFlag "format" opts then do
|
||||||
let file s = "_grph." ++ s
|
let file s = "_grph." ++ s
|
||||||
let view = optViewGraph opts
|
let view = optViewGraph opts
|
||||||
@@ -601,14 +601,17 @@ pgfCommands = Map.fromList [
|
|||||||
mkEx "p \"hello\" | vt -view=\"open\" -- parse a string and display trees on a Mac"
|
mkEx "p \"hello\" | vt -view=\"open\" -- parse a string and display trees on a Mac"
|
||||||
],
|
],
|
||||||
options = [
|
options = [
|
||||||
("api", "show the tree with function names converted to 'mkC' with value cats C")--,
|
("api", "show the tree with function names converted to 'mkC' with value cats C"),
|
||||||
-- ("mk", "similar to -api, deprecated"),
|
-- ("mk", "similar to -api, deprecated"),
|
||||||
-- ("nofun","don't show functions but only categories"),
|
("nofun","don't show functions but only categories"),
|
||||||
-- ("nocat","don't show categories but only functions")
|
("nocat","don't show categories but only functions")
|
||||||
],
|
],
|
||||||
flags = [
|
flags = [
|
||||||
("format","format of the visualization file (default \"png\")"),
|
("format","format of the visualization file (default \"png\")"),
|
||||||
("view","program to open the resulting file (default \"open\")")
|
("view","program to open the resulting file (default \"open\")"),
|
||||||
|
("nodefont","font for tree nodes (default: Times -- graphviz standard font)"),
|
||||||
|
("nodecolor","color for tree nodes (default: black -- graphviz standard color)"),
|
||||||
|
("nodeedgestyle","edge style between tree nodes (solid/dashed/dotted/bold, default: solid)")
|
||||||
]
|
]
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,12 @@
|
|||||||
#include "graphviz.h"
|
#include "graphviz.h"
|
||||||
#include "linearizer.h"
|
#include "linearizer.h"
|
||||||
|
|
||||||
|
PgfGraphvizOptions pgf_default_graphviz_options[1] =
|
||||||
|
{ {0, 0, 0, 1, NULL, NULL, NULL, NULL, NULL, NULL} } ;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pgf_graphviz_abstract_tree_(PgfExpr expr, int *pid,
|
pgf_graphviz_abstract_tree_(PgfPGF* pgf, PgfExpr expr, int *pid,
|
||||||
|
PgfGraphvizOptions* opts,
|
||||||
GuOut* out, GuExn* err)
|
GuOut* out, GuExn* err)
|
||||||
{
|
{
|
||||||
int id = -1;
|
int id = -1;
|
||||||
@@ -15,9 +19,16 @@ pgf_graphviz_abstract_tree_(PgfExpr expr, int *pid,
|
|||||||
break;
|
break;
|
||||||
case PGF_EXPR_APP: {
|
case PGF_EXPR_APP: {
|
||||||
PgfExprApp* app = ei.data;
|
PgfExprApp* app = ei.data;
|
||||||
id = pgf_graphviz_abstract_tree_(app->fun, pid, out, err);
|
id = pgf_graphviz_abstract_tree_(pgf, app->fun, pid, opts, out, err);
|
||||||
int arg_id = pgf_graphviz_abstract_tree_(app->arg, pid, out, err);
|
int arg_id = pgf_graphviz_abstract_tree_(pgf, app->arg, pid, opts, out, err);
|
||||||
gu_printf(out, err, "n%d -- n%d [style = \"solid\"]\n", id, arg_id);
|
gu_printf(out, err, "n%d -- n%d", id, arg_id);
|
||||||
|
if (opts->nodeEdgeStyle != NULL && *opts->nodeEdgeStyle && opts->nodeColor != NULL && *opts->nodeColor)
|
||||||
|
gu_printf(out, err, " [style = \"%s\", color = \"%s\"]", opts->nodeEdgeStyle, opts->nodeColor);
|
||||||
|
else if (opts->nodeEdgeStyle != NULL && *opts->nodeEdgeStyle)
|
||||||
|
gu_printf(out, err, " [style = \"%s\"]", opts->nodeEdgeStyle);
|
||||||
|
else if (opts->nodeColor != NULL && *opts->nodeColor)
|
||||||
|
gu_printf(out, err, " [color = \"%s\"]", opts->nodeColor);
|
||||||
|
gu_printf(out, err, "\n", id, arg_id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PGF_EXPR_LIT: {
|
case PGF_EXPR_LIT: {
|
||||||
@@ -58,9 +69,24 @@ pgf_graphviz_abstract_tree_(PgfExpr expr, int *pid,
|
|||||||
case PGF_EXPR_FUN: {
|
case PGF_EXPR_FUN: {
|
||||||
PgfExprFun* fun = ei.data;
|
PgfExprFun* fun = ei.data;
|
||||||
id = (*pid)++;
|
id = (*pid)++;
|
||||||
gu_printf(out, err, "n%d[label = \"", id);
|
if (opts->noFun && opts->noCat) {
|
||||||
gu_string_write(fun->fun, out, err);
|
gu_printf(out, err, "n%d[shape = \"point\"]\n", id);
|
||||||
gu_puts("\", style = \"solid\", shape = \"plaintext\"]\n", out, err);
|
} else {
|
||||||
|
gu_printf(out, err, "n%d[label = \"", id);
|
||||||
|
PgfType* ty = (opts->noCat) ? NULL : pgf_function_type(pgf, fun->fun);
|
||||||
|
if (!opts->noFun)
|
||||||
|
gu_string_write(fun->fun, out, err);
|
||||||
|
if (!opts->noFun && ty != NULL)
|
||||||
|
gu_puts(" : ", out,err);
|
||||||
|
if (ty != NULL)
|
||||||
|
gu_string_write(ty->cid, out, err);
|
||||||
|
gu_puts("\", shape = \"plaintext\", style = \"solid\"", out, err);
|
||||||
|
if (opts->nodeColor != NULL && *opts->nodeColor)
|
||||||
|
gu_printf(out, err, ", fontcolor = \"%s\"", opts->nodeColor);
|
||||||
|
if (opts->nodeFont != NULL && *opts->nodeFont)
|
||||||
|
gu_printf(out, err, ", fontname = \"%s\"", opts->nodeFont);
|
||||||
|
gu_puts("]\n", out, err);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PGF_EXPR_VAR:
|
case PGF_EXPR_VAR:
|
||||||
@@ -68,12 +94,12 @@ pgf_graphviz_abstract_tree_(PgfExpr expr, int *pid,
|
|||||||
break;
|
break;
|
||||||
case PGF_EXPR_TYPED: {
|
case PGF_EXPR_TYPED: {
|
||||||
PgfExprTyped* typed = ei.data;
|
PgfExprTyped* typed = ei.data;
|
||||||
id = pgf_graphviz_abstract_tree_(typed->expr, pid, out, err);
|
id = pgf_graphviz_abstract_tree_(pgf, typed->expr, pid, opts, out, err);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PGF_EXPR_IMPL_ARG: {
|
case PGF_EXPR_IMPL_ARG: {
|
||||||
PgfExprImplArg* implarg = ei.data;
|
PgfExprImplArg* implarg = ei.data;
|
||||||
id = pgf_graphviz_abstract_tree_(implarg->expr, pid, out, err);
|
id = pgf_graphviz_abstract_tree_(pgf, implarg->expr, pid, opts, out, err);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -84,12 +110,12 @@ pgf_graphviz_abstract_tree_(PgfExpr expr, int *pid,
|
|||||||
}
|
}
|
||||||
|
|
||||||
PGF_API void
|
PGF_API void
|
||||||
pgf_graphviz_abstract_tree(PgfPGF* pgf, PgfExpr expr, GuOut* out, GuExn* err)
|
pgf_graphviz_abstract_tree(PgfPGF* pgf, PgfExpr expr, PgfGraphvizOptions* opts, GuOut* out, GuExn* err)
|
||||||
{
|
{
|
||||||
int id = 0;
|
int id = 0;
|
||||||
|
|
||||||
gu_puts("graph {\n", out, err);
|
gu_puts("graph {\n", out, err);
|
||||||
pgf_graphviz_abstract_tree_(expr, &id, out, err);
|
pgf_graphviz_abstract_tree_(pgf, expr, &id, opts, out, err);
|
||||||
gu_puts("}", out, err);
|
gu_puts("}", out, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,6 +124,7 @@ typedef struct PgfParseNode PgfParseNode;
|
|||||||
struct PgfParseNode {
|
struct PgfParseNode {
|
||||||
int id;
|
int id;
|
||||||
PgfParseNode* parent;
|
PgfParseNode* parent;
|
||||||
|
GuString fun;
|
||||||
GuString label;
|
GuString label;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -107,7 +134,7 @@ typedef struct {
|
|||||||
GuPool* pool;
|
GuPool* pool;
|
||||||
GuOut* out;
|
GuOut* out;
|
||||||
GuExn* err;
|
GuExn* err;
|
||||||
|
|
||||||
PgfParseNode* parent;
|
PgfParseNode* parent;
|
||||||
size_t level;
|
size_t level;
|
||||||
GuBuf* internals;
|
GuBuf* internals;
|
||||||
@@ -122,6 +149,7 @@ pgf_bracket_lzn_symbol_token(PgfLinFuncs** funcs, PgfToken tok)
|
|||||||
PgfParseNode* node = gu_new(PgfParseNode, state->pool);
|
PgfParseNode* node = gu_new(PgfParseNode, state->pool);
|
||||||
node->id = 100000 + gu_buf_length(state->leaves);
|
node->id = 100000 + gu_buf_length(state->leaves);
|
||||||
node->parent = state->parent;
|
node->parent = state->parent;
|
||||||
|
node->fun = NULL;
|
||||||
node->label = tok;
|
node->label = tok;
|
||||||
gu_buf_push(state->leaves, PgfParseNode*, node);
|
gu_buf_push(state->leaves, PgfParseNode*, node);
|
||||||
}
|
}
|
||||||
@@ -156,6 +184,7 @@ pgf_bracket_lzn_begin_phrase(PgfLinFuncs** funcs, PgfCId cat, int fid, int linde
|
|||||||
PgfParseNode* node = gu_new(PgfParseNode, state->pool);
|
PgfParseNode* node = gu_new(PgfParseNode, state->pool);
|
||||||
node->id = fid;
|
node->id = fid;
|
||||||
node->parent = state->parent;
|
node->parent = state->parent;
|
||||||
|
node->fun = fun;
|
||||||
node->label = cat;
|
node->label = cat;
|
||||||
gu_buf_push(level, PgfParseNode*, node);
|
gu_buf_push(level, PgfParseNode*, node);
|
||||||
|
|
||||||
@@ -182,6 +211,7 @@ pgf_bracket_lzn_symbol_meta(PgfLinFuncs** funcs, PgfMetaId meta_id)
|
|||||||
PgfParseNode* node = gu_new(PgfParseNode, state->pool);
|
PgfParseNode* node = gu_new(PgfParseNode, state->pool);
|
||||||
node->id = 100000 + gu_buf_length(state->leaves);
|
node->id = 100000 + gu_buf_length(state->leaves);
|
||||||
node->parent = state->parent;
|
node->parent = state->parent;
|
||||||
|
node->fun = NULL;
|
||||||
node->label = "?";
|
node->label = "?";
|
||||||
gu_buf_push(state->leaves, PgfParseNode*, node);
|
gu_buf_push(state->leaves, PgfParseNode*, node);
|
||||||
}
|
}
|
||||||
@@ -197,7 +227,7 @@ static PgfLinFuncs pgf_bracket_lin_funcs = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pgf_graphviz_parse_level(GuBuf* level, GuOut* out, GuExn* err)
|
pgf_graphviz_parse_level(GuBuf* level, PgfGraphvizOptions* opts, GuOut* out, GuExn* err)
|
||||||
{
|
{
|
||||||
gu_puts("\n subgraph {rank=same;\n", out, err);
|
gu_puts("\n subgraph {rank=same;\n", out, err);
|
||||||
|
|
||||||
@@ -208,9 +238,32 @@ pgf_graphviz_parse_level(GuBuf* level, GuOut* out, GuExn* err)
|
|||||||
|
|
||||||
for (size_t i = 0; i < len; i++) {
|
for (size_t i = 0; i < len; i++) {
|
||||||
PgfParseNode* node = gu_buf_get(level, PgfParseNode*, i);
|
PgfParseNode* node = gu_buf_get(level, PgfParseNode*, i);
|
||||||
gu_printf(out, err, " n%d[label=\"", node->id);
|
if (node->fun != NULL) {
|
||||||
gu_string_write(node->label, out, err);
|
gu_printf(out, err, " n%d[label=\"", node->id);
|
||||||
gu_puts("\"]\n", out, err);
|
if (!opts->noFun)
|
||||||
|
gu_string_write(node->fun, out, err);
|
||||||
|
if (!opts->noFun && !opts->noCat)
|
||||||
|
gu_puts(" : ", out, err);
|
||||||
|
if (!opts->noCat)
|
||||||
|
gu_string_write(node->label, out, err);
|
||||||
|
gu_puts("\"", out, err);
|
||||||
|
if (opts->nodeColor != NULL && *opts->nodeColor)
|
||||||
|
gu_printf(out, err, ", fontcolor = \"%s\"", opts->nodeColor);
|
||||||
|
if (opts->nodeFont != NULL && *opts->nodeFont)
|
||||||
|
gu_printf(out, err, ", fontname = \"%s\"", opts->nodeFont);
|
||||||
|
gu_puts("]\n", out, err);
|
||||||
|
} else {
|
||||||
|
if (opts->noLeaves)
|
||||||
|
gu_printf(out, err, " n%d[label=\"\"]\n", node->id);
|
||||||
|
else {
|
||||||
|
gu_printf(out, err, " n%d[label=\"%s\"", node->id, node->label);
|
||||||
|
if (opts->leafColor != NULL && *opts->leafColor)
|
||||||
|
gu_printf(out, err, ", fontcolor = \"%s\"", opts->leafColor);
|
||||||
|
if (opts->leafFont != NULL && *opts->leafFont)
|
||||||
|
gu_printf(out, err, ", fontname = \"%s\"", opts->leafFont);
|
||||||
|
gu_puts("]\n", out, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len > 1) {
|
if (len > 1) {
|
||||||
@@ -227,13 +280,32 @@ pgf_graphviz_parse_level(GuBuf* level, GuOut* out, GuExn* err)
|
|||||||
|
|
||||||
for (size_t i = 0; i < len; i++) {
|
for (size_t i = 0; i < len; i++) {
|
||||||
PgfParseNode* node = gu_buf_get(level, PgfParseNode*, i);
|
PgfParseNode* node = gu_buf_get(level, PgfParseNode*, i);
|
||||||
if (node->parent != NULL)
|
if (node->parent != NULL) {
|
||||||
gu_printf(out, err, " n%d -- n%d\n", node->parent->id, node->id);
|
gu_printf(out, err, " n%d -- n%d", node->parent->id, node->id);
|
||||||
|
|
||||||
|
GuString edgeStyle, color;
|
||||||
|
if (node->fun == NULL) {
|
||||||
|
edgeStyle = opts->leafEdgeStyle;
|
||||||
|
color = opts->leafColor;
|
||||||
|
} else {
|
||||||
|
edgeStyle = opts->nodeEdgeStyle;
|
||||||
|
color = opts->nodeColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (edgeStyle != NULL && *edgeStyle && color != NULL && *color)
|
||||||
|
gu_printf(out, err, " [style = \"%s\", color = \"%s\"]", edgeStyle, color);
|
||||||
|
else if (edgeStyle != NULL && *edgeStyle)
|
||||||
|
gu_printf(out, err, " [style = \"%s\"]", edgeStyle);
|
||||||
|
else if (color != NULL && *color)
|
||||||
|
gu_printf(out, err, " [color = \"%s\"]", color);
|
||||||
|
|
||||||
|
gu_putc('\n', out, err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PGF_API void
|
PGF_API void
|
||||||
pgf_graphviz_parse_tree(PgfConcr* concr, PgfExpr expr, GuOut* out, GuExn* err)
|
pgf_graphviz_parse_tree(PgfConcr* concr, PgfExpr expr, PgfGraphvizOptions* opts, GuOut* out, GuExn* err)
|
||||||
{
|
{
|
||||||
GuPool* tmp_pool = gu_local_pool();
|
GuPool* tmp_pool = gu_local_pool();
|
||||||
|
|
||||||
@@ -266,9 +338,9 @@ pgf_graphviz_parse_tree(PgfConcr* concr, PgfExpr expr, GuOut* out, GuExn* err)
|
|||||||
size_t len = gu_buf_length(state.internals);
|
size_t len = gu_buf_length(state.internals);
|
||||||
for (size_t i = 0; i < len; i++) {
|
for (size_t i = 0; i < len; i++) {
|
||||||
GuBuf* level = gu_buf_get(state.internals, GuBuf*, i);
|
GuBuf* level = gu_buf_get(state.internals, GuBuf*, i);
|
||||||
pgf_graphviz_parse_level(level, out, err);
|
pgf_graphviz_parse_level(level, opts, out, err);
|
||||||
}
|
}
|
||||||
pgf_graphviz_parse_level(state.leaves, out, err);
|
pgf_graphviz_parse_level(state.leaves, opts, out, err);
|
||||||
|
|
||||||
gu_puts("}", out, err);
|
gu_puts("}", out, err);
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,25 @@
|
|||||||
#ifndef PGF_GRAPHVIZ_H_
|
#ifndef PGF_GRAPHVIZ_H_
|
||||||
#define PGF_GRAPHVIZ_H_
|
#define PGF_GRAPHVIZ_H_
|
||||||
|
|
||||||
PGF_API_DECL void
|
typedef struct {
|
||||||
pgf_graphviz_abstract_tree(PgfPGF* pgf, PgfExpr expr, GuOut* out, GuExn* err);
|
int noLeaves;
|
||||||
|
int noFun;
|
||||||
|
int noCat;
|
||||||
|
int noDep;
|
||||||
|
GuString nodeFont;
|
||||||
|
GuString leafFont;
|
||||||
|
GuString nodeColor;
|
||||||
|
GuString leafColor;
|
||||||
|
GuString nodeEdgeStyle;
|
||||||
|
GuString leafEdgeStyle;
|
||||||
|
} PgfGraphvizOptions;
|
||||||
|
|
||||||
|
extern PgfGraphvizOptions pgf_default_graphviz_options[1];
|
||||||
|
|
||||||
PGF_API_DECL void
|
PGF_API_DECL void
|
||||||
pgf_graphviz_parse_tree(PgfConcr* concr, PgfExpr expr, GuOut* out, GuExn* err);
|
pgf_graphviz_abstract_tree(PgfPGF* pgf, PgfExpr expr, PgfGraphvizOptions* opts, GuOut* out, GuExn* err);
|
||||||
|
|
||||||
|
PGF_API_DECL void
|
||||||
|
pgf_graphviz_parse_tree(PgfConcr* concr, PgfExpr expr, PgfGraphvizOptions* opts, GuOut* out, GuExn* err);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -66,7 +66,8 @@ module PGF2 (-- * PGF
|
|||||||
-- ** Morphological Analysis
|
-- ** Morphological Analysis
|
||||||
MorphoAnalysis, lookupMorpho, fullFormLexicon,
|
MorphoAnalysis, lookupMorpho, fullFormLexicon,
|
||||||
-- ** Visualizations
|
-- ** Visualizations
|
||||||
graphvizAbstractTree,graphvizParseTree,
|
GraphvizOptions(..), graphvizDefaults,
|
||||||
|
graphvizAbstractTree, graphvizParseTree,
|
||||||
|
|
||||||
-- * Exceptions
|
-- * Exceptions
|
||||||
PGFError(..),
|
PGFError(..),
|
||||||
@@ -316,30 +317,61 @@ compute (PGF p _) (Expr c_expr touch1) =
|
|||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
-- Graphviz
|
-- Graphviz
|
||||||
|
|
||||||
|
data GraphvizOptions = GraphvizOptions {noLeaves :: Bool,
|
||||||
|
noFun :: Bool,
|
||||||
|
noCat :: Bool,
|
||||||
|
noDep :: Bool,
|
||||||
|
nodeFont :: String,
|
||||||
|
leafFont :: String,
|
||||||
|
nodeColor :: String,
|
||||||
|
leafColor :: String,
|
||||||
|
nodeEdgeStyle :: String,
|
||||||
|
leafEdgeStyle :: String
|
||||||
|
}
|
||||||
|
|
||||||
|
graphvizDefaults = GraphvizOptions False False False True "" "" "" "" "" ""
|
||||||
|
|
||||||
-- | Renders an abstract syntax tree in a Graphviz format.
|
-- | Renders an abstract syntax tree in a Graphviz format.
|
||||||
graphvizAbstractTree :: PGF -> Expr -> String
|
graphvizAbstractTree :: PGF -> GraphvizOptions -> Expr -> String
|
||||||
graphvizAbstractTree p e =
|
graphvizAbstractTree p opts e =
|
||||||
unsafePerformIO $
|
unsafePerformIO $
|
||||||
withGuPool $ \tmpPl ->
|
withGuPool $ \tmpPl ->
|
||||||
do (sb,out) <- newOut tmpPl
|
do (sb,out) <- newOut tmpPl
|
||||||
exn <- gu_new_exn tmpPl
|
exn <- gu_new_exn tmpPl
|
||||||
pgf_graphviz_abstract_tree (pgf p) (expr e) out exn
|
c_opts <- newGraphvizOptions tmpPl opts
|
||||||
|
pgf_graphviz_abstract_tree (pgf p) (expr e) c_opts out exn
|
||||||
touchExpr e
|
touchExpr e
|
||||||
s <- gu_string_buf_freeze sb tmpPl
|
s <- gu_string_buf_freeze sb tmpPl
|
||||||
peekUtf8CString s
|
peekUtf8CString s
|
||||||
|
|
||||||
|
|
||||||
graphvizParseTree :: Concr -> Expr -> String
|
graphvizParseTree :: Concr -> GraphvizOptions -> Expr -> String
|
||||||
graphvizParseTree c e =
|
graphvizParseTree c opts e =
|
||||||
unsafePerformIO $
|
unsafePerformIO $
|
||||||
withGuPool $ \tmpPl ->
|
withGuPool $ \tmpPl ->
|
||||||
do (sb,out) <- newOut tmpPl
|
do (sb,out) <- newOut tmpPl
|
||||||
exn <- gu_new_exn tmpPl
|
exn <- gu_new_exn tmpPl
|
||||||
pgf_graphviz_parse_tree (concr c) (expr e) out exn
|
c_opts <- newGraphvizOptions tmpPl opts
|
||||||
|
pgf_graphviz_parse_tree (concr c) (expr e) c_opts out exn
|
||||||
touchExpr e
|
touchExpr e
|
||||||
s <- gu_string_buf_freeze sb tmpPl
|
s <- gu_string_buf_freeze sb tmpPl
|
||||||
peekUtf8CString s
|
peekUtf8CString s
|
||||||
|
|
||||||
|
newGraphvizOptions :: Ptr GuPool -> GraphvizOptions -> IO (Ptr PgfGraphvizOptions)
|
||||||
|
newGraphvizOptions pool opts = do
|
||||||
|
c_opts <- gu_malloc pool (#size PgfGraphvizOptions)
|
||||||
|
(#poke PgfGraphvizOptions, noLeaves) c_opts (if noLeaves opts then 1 else 0 :: CInt)
|
||||||
|
(#poke PgfGraphvizOptions, noFun) c_opts (if noFun opts then 1 else 0 :: CInt)
|
||||||
|
(#poke PgfGraphvizOptions, noCat) c_opts (if noCat opts then 1 else 0 :: CInt)
|
||||||
|
(#poke PgfGraphvizOptions, noDep) c_opts (if noDep opts then 1 else 0 :: CInt)
|
||||||
|
newUtf8CString (nodeFont opts) pool >>= (#poke PgfGraphvizOptions, nodeFont) c_opts
|
||||||
|
newUtf8CString (leafFont opts) pool >>= (#poke PgfGraphvizOptions, leafFont) c_opts
|
||||||
|
newUtf8CString (nodeColor opts) pool >>= (#poke PgfGraphvizOptions, nodeColor) c_opts
|
||||||
|
newUtf8CString (leafColor opts) pool >>= (#poke PgfGraphvizOptions, leafColor) c_opts
|
||||||
|
newUtf8CString (nodeEdgeStyle opts) pool >>= (#poke PgfGraphvizOptions, nodeEdgeStyle) c_opts
|
||||||
|
newUtf8CString (leafEdgeStyle opts) pool >>= (#poke PgfGraphvizOptions, leafEdgeStyle) c_opts
|
||||||
|
return c_opts
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
-- Functions using Concr
|
-- Functions using Concr
|
||||||
-- Morpho analyses, parsing & linearization
|
-- Morpho analyses, parsing & linearization
|
||||||
|
|||||||
@@ -148,6 +148,7 @@ data PgfCallbacksMap
|
|||||||
data PgfOracleCallback
|
data PgfOracleCallback
|
||||||
data PgfCncTree
|
data PgfCncTree
|
||||||
data PgfLinFuncs
|
data PgfLinFuncs
|
||||||
|
data PgfGraphvizOptions
|
||||||
|
|
||||||
foreign import ccall "pgf/pgf.h pgf_read"
|
foreign import ccall "pgf/pgf.h pgf_read"
|
||||||
pgf_read :: CString -> Ptr GuPool -> Ptr GuExn -> IO (Ptr PgfPGF)
|
pgf_read :: CString -> Ptr GuPool -> Ptr GuExn -> IO (Ptr PgfPGF)
|
||||||
@@ -364,7 +365,7 @@ foreign import ccall "pgf/expr.h pgf_read_type"
|
|||||||
pgf_read_type :: Ptr GuIn -> Ptr GuPool -> Ptr GuExn -> IO PgfType
|
pgf_read_type :: Ptr GuIn -> Ptr GuPool -> Ptr GuExn -> IO PgfType
|
||||||
|
|
||||||
foreign import ccall "pgf/graphviz.h pgf_graphviz_abstract_tree"
|
foreign import ccall "pgf/graphviz.h pgf_graphviz_abstract_tree"
|
||||||
pgf_graphviz_abstract_tree :: Ptr PgfPGF -> PgfExpr -> Ptr GuOut -> Ptr GuExn -> IO ()
|
pgf_graphviz_abstract_tree :: Ptr PgfPGF -> PgfExpr -> Ptr PgfGraphvizOptions -> Ptr GuOut -> Ptr GuExn -> IO ()
|
||||||
|
|
||||||
foreign import ccall "pgf/graphviz.h pgf_graphviz_parse_tree"
|
foreign import ccall "pgf/graphviz.h pgf_graphviz_parse_tree"
|
||||||
pgf_graphviz_parse_tree :: Ptr PgfConcr -> PgfExpr -> Ptr GuOut -> Ptr GuExn -> IO ()
|
pgf_graphviz_parse_tree :: Ptr PgfConcr -> PgfExpr -> Ptr PgfGraphvizOptions -> Ptr GuOut -> Ptr GuExn -> IO ()
|
||||||
|
|||||||
@@ -382,6 +382,7 @@ Java_org_grammaticalframework_pgf_PGF_graphvizAbstractTree(JNIEnv* env, jobject
|
|||||||
|
|
||||||
pgf_graphviz_abstract_tree(get_ref(env,self),
|
pgf_graphviz_abstract_tree(get_ref(env,self),
|
||||||
gu_variant_from_ptr(l2p(get_ref(env,jexpr))),
|
gu_variant_from_ptr(l2p(get_ref(env,jexpr))),
|
||||||
|
pgf_default_graphviz_options,
|
||||||
out, err);
|
out, err);
|
||||||
|
|
||||||
jstring jstr = gu2j_string_buf(env, sbuf);
|
jstring jstr = gu2j_string_buf(env, sbuf);
|
||||||
@@ -1228,6 +1229,7 @@ Java_org_grammaticalframework_pgf_Concr_graphvizParseTree(JNIEnv* env, jobject s
|
|||||||
|
|
||||||
pgf_graphviz_parse_tree(get_ref(env,self),
|
pgf_graphviz_parse_tree(get_ref(env,self),
|
||||||
gu_variant_from_ptr(l2p(get_ref(env,jexpr))),
|
gu_variant_from_ptr(l2p(get_ref(env,jexpr))),
|
||||||
|
pgf_default_graphviz_options,
|
||||||
out, err);
|
out, err);
|
||||||
|
|
||||||
jstring jstr = gu2j_string_buf(env, sbuf);
|
jstring jstr = gu2j_string_buf(env, sbuf);
|
||||||
|
|||||||
@@ -2281,7 +2281,7 @@ Concr_graphvizParseTree(ConcrObject* self, PyObject *args) {
|
|||||||
GuStringBuf* sbuf = gu_new_string_buf(tmp_pool);
|
GuStringBuf* sbuf = gu_new_string_buf(tmp_pool);
|
||||||
GuOut* out = gu_string_buf_out(sbuf);
|
GuOut* out = gu_string_buf_out(sbuf);
|
||||||
|
|
||||||
pgf_graphviz_parse_tree(self->concr, pyexpr->expr, out, err);
|
pgf_graphviz_parse_tree(self->concr, pyexpr->expr, pgf_default_graphviz_options, out, err);
|
||||||
if (!gu_ok(err)) {
|
if (!gu_ok(err)) {
|
||||||
if (gu_exn_caught(err, PgfExn)) {
|
if (gu_exn_caught(err, PgfExn)) {
|
||||||
GuString msg = (GuString) gu_exn_caught_data(err);
|
GuString msg = (GuString) gu_exn_caught_data(err);
|
||||||
@@ -3075,7 +3075,7 @@ PGF_graphvizAbstractTree(PGFObject* self, PyObject *args) {
|
|||||||
GuStringBuf* sbuf = gu_new_string_buf(tmp_pool);
|
GuStringBuf* sbuf = gu_new_string_buf(tmp_pool);
|
||||||
GuOut* out = gu_string_buf_out(sbuf);
|
GuOut* out = gu_string_buf_out(sbuf);
|
||||||
|
|
||||||
pgf_graphviz_abstract_tree(self->pgf, pyexpr->expr, out, err);
|
pgf_graphviz_abstract_tree(self->pgf, pyexpr->expr, pgf_default_graphviz_options, out, err);
|
||||||
if (!gu_ok(err)) {
|
if (!gu_ok(err)) {
|
||||||
PyErr_SetString(PGFError, "The abstract tree cannot be visualized");
|
PyErr_SetString(PGFError, "The abstract tree cannot be visualized");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
@@ -159,8 +159,8 @@ cpgfMain qsem command (t,(pgf,pc)) =
|
|||||||
"c-lookupmorpho"-> out t=<< morpho # from1 % textInput
|
"c-lookupmorpho"-> out t=<< morpho # from1 % textInput
|
||||||
"c-flush" -> out t=<< flush
|
"c-flush" -> out t=<< flush
|
||||||
"c-grammar" -> out t grammar
|
"c-grammar" -> out t grammar
|
||||||
"c-abstrtree" -> outputGraphviz=<< C.graphvizAbstractTree pgf # tree
|
"c-abstrtree" -> outputGraphviz=<< C.graphvizAbstractTree pgf C.graphvizDefaults # tree
|
||||||
"c-parsetree" -> outputGraphviz=<< C.graphvizParseTree . snd # from1 %tree
|
"c-parsetree" -> outputGraphviz=<< (\cnc -> C.graphvizParseTree cnc C.graphvizDefaults) . snd # from1 %tree
|
||||||
"c-wordforword" -> out t =<< wordforword # input % to
|
"c-wordforword" -> out t =<< wordforword # input % to
|
||||||
_ -> badRequest "Unknown command" command
|
_ -> badRequest "Unknown command" command
|
||||||
where
|
where
|
||||||
|
|||||||
Reference in New Issue
Block a user