treba vsecgngo voe
This commit is contained in:
parent
5c0b36a419
commit
88c476e052
8
.gitignore
vendored
Normal file
8
.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
.vs/
|
||||||
|
.vscode/
|
||||||
|
build/
|
||||||
|
*.cppcheck
|
||||||
|
*.dot
|
||||||
|
*.png
|
||||||
|
*.svg
|
||||||
|
*.ps
|
||||||
@ -24,6 +24,9 @@ else()
|
|||||||
target_compile_options(Graph PRIVATE -Wall -Wextra -pedantic)
|
target_compile_options(Graph PRIVATE -Wall -Wextra -pedantic)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# link math
|
||||||
|
target_link_libraries(Graph PRIVATE m)
|
||||||
|
|
||||||
# Optionally, set the output directory for the executable
|
# Optionally, set the output directory for the executable
|
||||||
# set_target_properties(Graph PROPERTIES
|
# set_target_properties(Graph PROPERTIES
|
||||||
# RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
|
# RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
|
||||||
|
|||||||
16
lex.c
16
lex.c
@ -130,7 +130,7 @@ struct token *lex_token(struct lexer *lex) {
|
|||||||
return &lex->tok;
|
return &lex->tok;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lex_print_position(struct lexer *lex) {
|
void lex_print_position(const struct lexer *lex) {
|
||||||
int i;
|
int i;
|
||||||
int pos = lex->prev_p - lex->start;
|
int pos = lex->prev_p - lex->start;
|
||||||
|
|
||||||
@ -146,7 +146,7 @@ void lex_print_position(struct lexer *lex) {
|
|||||||
|
|
||||||
#ifdef LEX_DEBUG
|
#ifdef LEX_DEBUG
|
||||||
|
|
||||||
void lex_debug_print_token(struct token *tok) {
|
void lex_debug_print_token(const struct token *tok) {
|
||||||
static const char *token_str[] = {
|
static const char *token_str[] = {
|
||||||
"TOK_EOF",
|
"TOK_EOF",
|
||||||
"TOK_ERROR",
|
"TOK_ERROR",
|
||||||
@ -162,6 +162,12 @@ void lex_debug_print_token(struct token *tok) {
|
|||||||
"TOK_RIGHT_PAREN"
|
"TOK_RIGHT_PAREN"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
printf("%-20s ", token_str[tok->type]);
|
||||||
|
|
||||||
|
if (tok->type == TOK_NUMBER)
|
||||||
|
printf("%.2f\n", tok->val.num);
|
||||||
|
else if (tok->type == TOK_FUNCTION) {
|
||||||
static const char *fn_str[] = {
|
static const char *fn_str[] = {
|
||||||
"FN_ABS",
|
"FN_ABS",
|
||||||
"FN_EXP",
|
"FN_EXP",
|
||||||
@ -178,12 +184,8 @@ void lex_debug_print_token(struct token *tok) {
|
|||||||
"FN_TANH"
|
"FN_TANH"
|
||||||
};
|
};
|
||||||
|
|
||||||
printf("%-20s ", token_str[tok->type]);
|
|
||||||
|
|
||||||
if (tok->type == TOK_NUMBER)
|
|
||||||
printf("%.2f\n", tok->val.num);
|
|
||||||
else if (tok->type == TOK_FUNCTION)
|
|
||||||
printf("%s\n", fn_str[tok->val.fn]);
|
printf("%s\n", fn_str[tok->val.fn]);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|||||||
4
lex.h
4
lex.h
@ -51,11 +51,11 @@ extern void lex_free(struct lexer *lex);
|
|||||||
extern void lex_next(struct lexer *lex);
|
extern void lex_next(struct lexer *lex);
|
||||||
extern struct token *lex_token(struct lexer *lex);
|
extern struct token *lex_token(struct lexer *lex);
|
||||||
|
|
||||||
extern void lex_print_position(struct lexer *lex);
|
extern void lex_print_position(const struct lexer *lex);
|
||||||
|
|
||||||
|
|
||||||
#ifdef LEX_DEBUG
|
#ifdef LEX_DEBUG
|
||||||
extern void lex_debug_print_token(struct token *tok);
|
extern void lex_debug_print_token(const struct token *tok);
|
||||||
#endif /* LEX_DEBUG */
|
#endif /* LEX_DEBUG */
|
||||||
|
|
||||||
#endif /* LEX_H */
|
#endif /* LEX_H */
|
||||||
7
main.c
7
main.c
@ -32,9 +32,14 @@ int main(int argc, char *argv[]) {
|
|||||||
file = fopen("out.ps", "w");
|
file = fopen("out.ps", "w");
|
||||||
ps_export_graph(file, node, &graph);
|
ps_export_graph(file, node, &graph);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
}
|
|
||||||
|
file = fopen("graph.dot", "w");
|
||||||
|
node_debug_print_gv(node, file);
|
||||||
|
fclose(file);
|
||||||
|
|
||||||
node_free(node);
|
node_free(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
10
parser.c
10
parser.c
@ -84,8 +84,8 @@ static struct expr_node* parse_bracketed(struct lexer* lex) {
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct expr_node* parse_base(struct lexer* lex) {
|
static struct expr_node *parse_base(struct lexer *lex) {
|
||||||
struct expr_node* inner;
|
struct expr_node *node, *inner;
|
||||||
|
|
||||||
if (token_is(lex, TOK_NUMBER)) {
|
if (token_is(lex, TOK_NUMBER)) {
|
||||||
double val = token_num(lex);
|
double val = token_num(lex);
|
||||||
@ -104,7 +104,11 @@ static struct expr_node* parse_base(struct lexer* lex) {
|
|||||||
if (!(inner = parse_bracketed(lex)))
|
if (!(inner = parse_bracketed(lex)))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return node_create_fn(fn, inner);
|
if (!(node = node_create_fn(fn, inner))) {
|
||||||
|
node_free(inner);
|
||||||
|
}
|
||||||
|
|
||||||
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (token_is(lex, TOK_LEFT_PAREN)) {
|
if (token_is(lex, TOK_LEFT_PAREN)) {
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
#define HALF_GRAPH_SIZE (GRAPH_SIZE / 2)
|
#define HALF_GRAPH_SIZE (GRAPH_SIZE / 2)
|
||||||
#define GRID_STEP (GRAPH_SIZE / 10)
|
#define GRID_STEP (GRAPH_SIZE / 10)
|
||||||
|
|
||||||
void ps_export_graph(FILE *file, struct expr_node *node, struct graph_range *range) {
|
void ps_export_graph(FILE *file, const struct expr_node *node, const struct graph_range *range) {
|
||||||
int i;
|
int i;
|
||||||
double x;
|
double x;
|
||||||
int first = 1;
|
int first = 1;
|
||||||
|
|||||||
@ -10,6 +10,6 @@ struct graph_range {
|
|||||||
double step;
|
double step;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern void ps_export_graph(FILE *file, struct expr_node *node, struct graph_range *range);
|
extern void ps_export_graph(FILE *file, const struct expr_node *node, const struct graph_range *range);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
74
tree.c
74
tree.c
@ -112,8 +112,7 @@ static void debug_print_binop(struct expr_node *node, const char* name, int inde
|
|||||||
debug_print(node->vals.binop.right, indent + 1);
|
debug_print(node->vals.binop.right, indent + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void debug_print(struct expr_node *node, int indent) {
|
static const char* fn_str[] = {
|
||||||
static const char* fn_str[] = {
|
|
||||||
"FN_ABS",
|
"FN_ABS",
|
||||||
"FN_EXP",
|
"FN_EXP",
|
||||||
"FN_LN",
|
"FN_LN",
|
||||||
@ -127,7 +126,9 @@ static void debug_print(struct expr_node *node, int indent) {
|
|||||||
"FN_SINH",
|
"FN_SINH",
|
||||||
"FN_COSH",
|
"FN_COSH",
|
||||||
"FN_TANH"
|
"FN_TANH"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void debug_print(struct expr_node *node, int indent) {
|
||||||
|
|
||||||
switch (node->type) {
|
switch (node->type) {
|
||||||
case EXPR_ADD:
|
case EXPR_ADD:
|
||||||
@ -181,7 +182,72 @@ void node_debug_print(struct expr_node *node) {
|
|||||||
debug_print(node, 0);
|
debug_print(node, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
double node_eval(struct expr_node *node, double x) {
|
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:
|
||||||
|
fprintf(output, "node%p [label=\"FN: %s\"]\n", (void*)node, fn_str[node->vals.fn.fn]);
|
||||||
|
debug_print_gv(node->vals.fn.arg, output);
|
||||||
|
fprintf(output, "node%p -> node%p [label=arg]\n", (void*)node, (void*)node->vals.fn.arg);
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
double node_eval(const struct expr_node *node, double x) {
|
||||||
switch (node->type) {
|
switch (node->type) {
|
||||||
case EXPR_CONST:
|
case EXPR_CONST:
|
||||||
return node->vals.num;
|
return node->vals.num;
|
||||||
|
|||||||
3
tree.h
3
tree.h
@ -42,8 +42,9 @@ extern struct expr_node *node_create_x(void);
|
|||||||
extern struct expr_node *node_create_fn(enum math_fn fn, struct expr_node *arg);
|
extern struct expr_node *node_create_fn(enum math_fn fn, struct expr_node *arg);
|
||||||
|
|
||||||
extern void node_debug_print(struct expr_node *node);
|
extern void node_debug_print(struct expr_node *node);
|
||||||
|
extern void node_debug_print_gv(const struct expr_node *node, FILE *output);
|
||||||
|
|
||||||
extern double node_eval(struct expr_node *node, double x);
|
extern double node_eval(const struct expr_node *node, double x);
|
||||||
|
|
||||||
extern void node_free(struct expr_node *node);
|
extern void node_free(struct expr_node *node);
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user