From e9beb1c292f945ee9cfedfaabf5b9ec5bbaaf0cc Mon Sep 17 00:00:00 2001 From: tovjemam Date: Mon, 23 Dec 2024 14:40:58 +0100 Subject: [PATCH] gv export --- .gitignore | 3 +- lex.c | 16 --- lex.h | 4 - main.c | 21 +++- math_functions.c | 8 +- ps_graph.c | 2 +- tree.c | 292 ++++++++++++++++++----------------------------- tree.h | 7 +- 8 files changed, 140 insertions(+), 213 deletions(-) diff --git a/.gitignore b/.gitignore index dbce466..beab05e 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,5 @@ build/ *.dot *.png *.svg -*.ps \ No newline at end of file +*.ps +*.pdf diff --git a/lex.c b/lex.c index 90e23d5..5006e94 100644 --- a/lex.c +++ b/lex.c @@ -212,19 +212,3 @@ const char *lex_token_str(enum token_type token) { default: return ""; } } - -#ifdef LEX_DEBUG - -void lex_debug_print_token(const struct token *tok) { - printf("%-20s ", lex_token_str(tok->type)); - - if (tok->type == TOK_NUMBER) - printf("%.2f\n", tok->val.num); - else if (tok->type == TOK_FUNCTION) { - printf("%s\n", fns_get()[tok->val.fn_idx].name); - } - else - printf("\n"); -} - -#endif /* LEX_DEBUG */ diff --git a/lex.h b/lex.h index ba76136..6f130ac 100644 --- a/lex.h +++ b/lex.h @@ -114,8 +114,4 @@ const char *lex_get_error_text(const struct lexer *lex); */ const char *lex_token_str(enum token_type token); -#ifdef LEX_DEBUG -void lex_debug_print_token(const struct token *tok); -#endif /* LEX_DEBUG */ - #endif /* LEX_H */ \ No newline at end of file diff --git a/main.c b/main.c index faf41c5..1821085 100644 --- a/main.c +++ b/main.c @@ -58,6 +58,21 @@ static enum error_code export_to_file(const struct expr_node *node, const struct return ERR_NO_ERR; } +#ifdef ENABLE_GRAPHVIZ_EXPORT +static void export_gv(const struct expr_node *node, const char *out_name) { + FILE *file; + + if (!(file = fopen(out_name, "w"))) { + fprintf(stderr, "GV: Cannot open \"%s\" for writing!\n", out_name); + return; + } + + node_debug_print_gv(node, file); + + fclose(file); +} +#endif /* ENABLE_GRAPHVIZ_EXPORT */ + int main(int argc, char *argv[]) { enum error_code err; struct parser parser; @@ -91,9 +106,9 @@ int main(int argc, char *argv[]) { err = export_to_file(node, &range, argv[2]); - /* file = fopen("graph.dot", "w"); - node_debug_print_gv(node, file); - fclose(file); */ +#ifdef ENABLE_GRAPHVIZ_EXPORT + export_gv(node, "graph.dot"); +#endif /* ENABLE_GRAPHVIZ_EXPORT */ node_free(node); diff --git a/math_functions.c b/math_functions.c index a3af5f2..48670c5 100644 --- a/math_functions.c +++ b/math_functions.c @@ -28,7 +28,7 @@ MAKE_FUNCTION_1_ARG(tanh) MAKE_FUNCTION_1_ARG(floor) MAKE_FUNCTION_1_ARG(ceil) -static double mf_sgn(double *y, const double *args) { +static enum eval_result mf_sgn(double *y, const double *args) { if (args[0] < 0.0) *y = -1.0; else if (args[0] > 0.0) @@ -39,7 +39,7 @@ static double mf_sgn(double *y, const double *args) { return EVAL_OK; } -static double mf_min(double *y, const double *args) { +static enum eval_result mf_min(double *y, const double *args) { if (args[0] < args[1]) *y = args[0]; else @@ -48,7 +48,7 @@ static double mf_min(double *y, const double *args) { return EVAL_OK; } -static double mf_max(double *y, const double *args) { +static enum eval_result mf_max(double *y, const double *args) { if (args[0] > args[1]) *y = args[0]; else @@ -57,7 +57,7 @@ static double mf_max(double *y, const double *args) { return EVAL_OK; } -static double mf_mod(double *y, const double *args) { +static enum eval_result mf_mod(double *y, const double *args) { errno = 0; *y = fmod(args[0], args[1]); diff --git a/ps_graph.c b/ps_graph.c index 30a0caa..0476e55 100644 --- a/ps_graph.c +++ b/ps_graph.c @@ -35,7 +35,7 @@ void ps_export_graph(FILE *file, const struct expr_node *node, const struct grap /* popisky */ fprintf(file, "/Arial findfont\n" - "12 scalefont\n" + "10 scalefont\n" "setfont\n" ); diff --git a/tree.c b/tree.c index 51dfffb..1da684a 100644 --- a/tree.c +++ b/tree.c @@ -75,187 +75,6 @@ struct expr_node *node_create_fn(size_t fn_idx, struct expr_node **args) { return node; } -void node_free(struct expr_node *node) { - if (!node) return; - - switch (node->type) { - case EXPR_ADD: - case EXPR_SUB: - case EXPR_MULT: - case EXPR_DIV: - case EXPR_POW: - node_free(node->vals.binop.left); - node_free(node->vals.binop.right); - break; - - case EXPR_NEG: - node_free(node->vals.unop); - break; - - case EXPR_FN: - { - size_t i, num_args = fns_get()[node->vals.fn.fn_idx].num_args; - for (i = 0; i < num_args; ++i) { - node_free(node->vals.fn.args[i]); - } - } - break; - - default: - break; - } - - free(node); -} - -static void debug_indent(int indent) { - int i; - for (i = 0; i < indent; ++i) - printf(" "); -} - -static void debug_print(struct expr_node *node, int indent); - -static void debug_print_binop(struct expr_node *node, const char* name, int indent) { - debug_indent(indent); printf("[%s]\n", name); - debug_print(node->vals.binop.left, indent + 1); - debug_print(node->vals.binop.right, indent + 1); -} - -static void debug_print(struct expr_node *node, int indent) { - - switch (node->type) { - case EXPR_ADD: - debug_print_binop(node, "ADD", indent); - break; - - case EXPR_SUB: - debug_print_binop(node, "SUB", indent); - break; - - case EXPR_MULT: - debug_print_binop(node, "MULT", indent); - break; - - case EXPR_DIV: - debug_print_binop(node, "DIV", indent); - break; - - case EXPR_POW: - debug_print_binop(node, "POW", indent); - break; - - case EXPR_NEG: - debug_indent(indent); printf("[NEG]\n"); - debug_print(node->vals.unop, indent + 1); - break; - - case EXPR_CONST: - debug_indent(indent); printf("[CONST] %.2f\n", node->vals.num); - break; - - case EXPR_X: - debug_indent(indent); printf("[X]\n"); - - break; - - case EXPR_FN: - { - size_t i; - const struct math_function *fn = &fns_get()[node->vals.fn.fn_idx]; - debug_indent(indent); printf("[FN] %s\n", fn->name); - - for (i = 0; i < fn->num_args; ++i) { - debug_print(node->vals.fn.args[i], indent + 1); - } - - break; - } - - default: - break; - } -} - - -void node_debug_print(struct expr_node *node) { - debug_print(node, 0); -} - -static void debug_print_gv(const struct expr_node *node, FILE *output); - -static void debug_print_binop_gv(const struct expr_node *node, FILE *output, const char *name) { - fprintf(output, "node%p [label=\"%s\"]\n", (void*)node, name); - debug_print_gv(node->vals.binop.left, output); - debug_print_gv(node->vals.binop.right, output); - fprintf(output, "node%p -> node%p [label=left]\n", (void*)node, (void*)node->vals.binop.left); - fprintf(output, "node%p -> node%p [label=right]\n", (void*)node, (void*)node->vals.binop.right); -} - -static void debug_print_gv(const struct expr_node *node, FILE *output) { - - switch (node->type) { - case EXPR_ADD: - debug_print_binop_gv(node, output, "ADD"); - break; - - case EXPR_SUB: - debug_print_binop_gv(node, output, "SUB"); - break; - - case EXPR_MULT: - debug_print_binop_gv(node, output, "MULT"); - break; - - case EXPR_DIV: - debug_print_binop_gv(node, output, "DIV"); - break; - - case EXPR_POW: - debug_print_binop_gv(node, output, "POW"); - break; - - case EXPR_NEG: - fprintf(output, "node%p [label=\"NEG\"]\n", (void*)node); - debug_print_gv(node->vals.unop, output); - fprintf(output, "node%p -> node%p [label=unop]\n", (void*)node, (void*)node->vals.unop); - break; - - case EXPR_CONST: - fprintf(output, "node%p [label=\"CONST: %.2f\"]\n", (void*)node, node->vals.num); - break; - - case EXPR_X: - fprintf(output, "node%p [label=\"X\"]\n", (void*)node); - break; - - case EXPR_FN: - { - size_t i; - const struct math_function *fn = &fns_get()[node->vals.fn.fn_idx]; - - fprintf(output, "node%p [label=\"FN: %s\"]\n", (void*)node, fn->name); - - for (i = 0; i < fn->num_args; ++i) { - struct expr_node *arg = node->vals.fn.args[i]; - debug_print_gv(arg, output); - fprintf(output, "node%p -> node%p [label=arg%d]\n", (void*)node, (void*)arg, (int)i + 1); - } - - break; - } - - default: - break; - } -} - -void node_debug_print_gv(const struct expr_node *node, FILE *output) { - fprintf(output, "digraph G {\n"); - debug_print_gv(node, output); - fprintf(output, "}\n"); -} - #define INF (1.0e256) static int is_real(double x) { @@ -346,3 +165,114 @@ enum eval_result node_eval(const struct expr_node *node, double x, double *y) { return 0.0; } + +#ifdef ENABLE_GRAPHVIZ_EXPORT + +static void debug_print_gv(const struct expr_node *node, FILE *output); + +static void debug_print_binop_gv(const struct expr_node *node, FILE *output, const char *name) { + fprintf(output, "node%p [label=\"%s\"]\n", (void*)node, name); + debug_print_gv(node->vals.binop.left, output); + debug_print_gv(node->vals.binop.right, output); + fprintf(output, "node%p -> node%p [label=left]\n", (void*)node, (void*)node->vals.binop.left); + fprintf(output, "node%p -> node%p [label=right]\n", (void*)node, (void*)node->vals.binop.right); +} + +static void debug_print_gv(const struct expr_node *node, FILE *output) { + + switch (node->type) { + case EXPR_ADD: + debug_print_binop_gv(node, output, "ADD"); + break; + + case EXPR_SUB: + debug_print_binop_gv(node, output, "SUB"); + break; + + case EXPR_MULT: + debug_print_binop_gv(node, output, "MULT"); + break; + + case EXPR_DIV: + debug_print_binop_gv(node, output, "DIV"); + break; + + case EXPR_POW: + debug_print_binop_gv(node, output, "POW"); + break; + + case EXPR_NEG: + fprintf(output, "node%p [label=\"NEG\"]\n", (void*)node); + debug_print_gv(node->vals.unop, output); + fprintf(output, "node%p -> node%p [label=unop]\n", (void*)node, (void*)node->vals.unop); + break; + + case EXPR_CONST: + fprintf(output, "node%p [label=\"CONST: %.2f\"]\n", (void*)node, node->vals.num); + break; + + case EXPR_X: + fprintf(output, "node%p [label=\"X\"]\n", (void*)node); + break; + + case EXPR_FN: + { + size_t i; + const struct math_function *fn = &fns_get()[node->vals.fn.fn_idx]; + + fprintf(output, "node%p [label=\"FN: %s\"]\n", (void*)node, fn->name); + + for (i = 0; i < fn->num_args; ++i) { + struct expr_node *arg = node->vals.fn.args[i]; + debug_print_gv(arg, output); + fprintf(output, "node%p -> node%p [label=arg%d]\n", (void*)node, (void*)arg, (int)i + 1); + } + + break; + } + + default: + break; + } +} + +void node_debug_print_gv(const struct expr_node *node, FILE *output) { + fprintf(output, "digraph G {\n"); + debug_print_gv(node, output); + fprintf(output, "}\n"); +} + +#endif /* ENABLE_GRAPHVIZ_EXPORT */ + +void node_free(struct expr_node *node) { + if (!node) return; + + switch (node->type) { + case EXPR_ADD: + case EXPR_SUB: + case EXPR_MULT: + case EXPR_DIV: + case EXPR_POW: + node_free(node->vals.binop.left); + node_free(node->vals.binop.right); + break; + + case EXPR_NEG: + node_free(node->vals.unop); + break; + + case EXPR_FN: + { + size_t i, num_args = fns_get()[node->vals.fn.fn_idx].num_args; + for (i = 0; i < num_args; ++i) { + node_free(node->vals.fn.args[i]); + } + } + break; + + default: + break; + } + + free(node); +} diff --git a/tree.h b/tree.h index 3abc821..78523d7 100644 --- a/tree.h +++ b/tree.h @@ -115,9 +115,6 @@ struct expr_node *node_create_x(void); */ struct expr_node *node_create_fn(size_t fn_idx, struct expr_node **args); -void node_debug_print(struct expr_node *node); -void node_debug_print_gv(const struct expr_node *node, FILE *output); - /** * @brief Vyhodnotí uzel * @@ -128,6 +125,10 @@ void node_debug_print_gv(const struct expr_node *node, FILE *output); */ enum eval_result node_eval(const struct expr_node *node, double x, double *y); +#ifdef ENABLE_GRAPHVIZ_EXPORT +void node_debug_print_gv(const struct expr_node *node, FILE *output); +#endif /* ENABLE_GRAPHVIZ_EXPORT */ + /** * @brief Uvolní uzel *