|
| 1 | +/* SPDX-License-Identifier: MIT WITH bison-exception */ |
| 2 | +/* Copyright © 2020 Matthew Stern, Benjamin Michalowicz */ |
| 3 | + |
| 4 | +%{ |
| 5 | +#include <topologic/topologic.h> |
| 6 | +void f(int id, struct graph *graph, struct vertex_result *args, void *glbl, void *edge_vars) {} |
| 7 | +int edge_f(int id, void *args, void *glbl, const void *const edge_vars_a, const void *const edge_vars_b) {return 0;} |
| 8 | +void yyerror(struct graph** graph, const char *s); |
| 9 | +extern FILE *yyin; |
| 10 | +int yylex(void); |
| 11 | +%} |
| 12 | + |
| 13 | +%union { |
| 14 | + struct graph *graph; |
| 15 | + int val; |
| 16 | +}; |
| 17 | + |
| 18 | +%parse-param {struct graph** graph} |
| 19 | +%token L_BRACKET |
| 20 | +%token R_BRACKET |
| 21 | +%token GRAPH |
| 22 | +%token COLON |
| 23 | +%token VERTICES_ |
| 24 | +%token EDGE_ |
| 25 | +%token BI_EDGE_ |
| 26 | +%token L_SQUARE |
| 27 | +%token R_SQUARE |
| 28 | +%token COMMA |
| 29 | +%token MAX_STATE |
| 30 | +%token LVL_VERBOSE |
| 31 | +%token LEX_CONTEXT |
| 32 | +%token MEM_OPT |
| 33 | +%token MAX_LOOP |
| 34 | +%token <val> VALUE |
| 35 | + |
| 36 | +%start json |
| 37 | +%% |
| 38 | +json: L_BRACKET GRAPH {*graph = GRAPH_INIT(); if (!(*graph)){fprintf(stderr, "Can't create graph\n"); return -1;}} |
| 39 | + COLON L_BRACKET content R_BRACKET |
| 40 | + R_BRACKET |
| 41 | + ; |
| 42 | +content: params g |
| 43 | + | g |
| 44 | + | params |
| 45 | + | |
| 46 | + ; |
| 47 | +params: verb COMMA params |
| 48 | + | state COMMA params |
| 49 | + | mem_opt COMMA params |
| 50 | + | context COMMA params |
| 51 | + | max_loop COMMA params |
| 52 | + | verb |
| 53 | + | mem_opt |
| 54 | + | context |
| 55 | + | state |
| 56 | + | max_loop |
| 57 | + | |
| 58 | + ; |
| 59 | +state: MAX_STATE COLON VALUE {(*graph)->max_state_changes = $3;} |
| 60 | + ; |
| 61 | +verb: LVL_VERBOSE COLON VALUE {(*graph)->lvl_verbose = $3;} |
| 62 | + ; |
| 63 | +context: LEX_CONTEXT COLON VALUE {(*graph)->context = $3;} |
| 64 | + ; |
| 65 | +mem_opt: MEM_OPT COLON VALUE {(*graph)->mem_option = $3;} |
| 66 | + ; |
| 67 | +max_loop: MAX_LOOP COLON VALUE {(*graph)->max_loop = $3;} |
| 68 | + ; |
| 69 | +g: vs COMMA es COMMA bes |
| 70 | + | vs COMMA bes COMMA es |
| 71 | + | vs COMMA es |
| 72 | + | vs COMMA bes |
| 73 | + | vs |
| 74 | + ; |
| 75 | +vs: VERTICES_ COLON L_SQUARE v R_SQUARE |
| 76 | + ; |
| 77 | +v: /* empty */ |
| 78 | + | VALUE COMMA {if (create_vertex(*graph, f, $1, NULL) < 0) fprintf(stderr, "Failed To Create Vertex %d\n", $1);} |
| 79 | + v |
| 80 | + | VALUE {if (create_vertex(*graph, f, $1, NULL) < 0) fprintf(stderr, "Failed To Create Vertex %d\n", $1);} |
| 81 | + ; |
| 82 | +es: EDGE_ COLON L_BRACKET e R_BRACKET |
| 83 | + ; |
| 84 | +e: /* empty */ |
| 85 | + | VALUE COLON VALUE COMMA {struct vertex *a = find((*graph)->vertices, $1); struct vertex *b = find((*graph)->vertices, $3); if (a && b) {if (create_edge(a, b, edge_f, NULL) == NULL) fprintf(stderr, "Failed to create Edge Between %d and %d\n", a->id, b->id);} else fprintf(stderr, "Invalid Vertices a:%p b:%p\n", a, b);} |
| 86 | + e |
| 87 | + | VALUE COLON VALUE {struct vertex *a = find((*graph)->vertices, $1); struct vertex *b = find((*graph)->vertices, $3); if (a && b) {if (create_edge(a, b, edge_f, NULL) == NULL) fprintf(stderr, "Failed to create Edge Between %d and %d\n", a->id, b->id);} else fprintf(stderr, "Invalid Vertices a:%p b:%p\n", a, b);} |
| 88 | + ; |
| 89 | +bes:BI_EDGE_ COLON L_BRACKET be R_BRACKET |
| 90 | + ; |
| 91 | +be: /* empty */ |
| 92 | + | VALUE COLON VALUE COMMA {int val = 0; struct vertex *a = find((*graph)->vertices, $1); struct vertex *b = find((*graph)->vertices, $3); if (a && b) { if((val = create_bi_edge(a, b, edge_f, NULL, NULL, NULL) < 0)) fprintf(stderr, "%d: Failed to bi create Edge Between %d and %d\n", val, a->id, b->id);} else fprintf(stderr, "Invalid Vertices a:%p(%d) b:%p(%d)\n", a, $1, b, $3);} |
| 93 | + be |
| 94 | + | VALUE COLON VALUE {int val = 0; struct vertex *a = find((*graph)->vertices, $1); struct vertex *b = find((*graph)->vertices, $3); if (a && b) { if((val = create_bi_edge(a, b, edge_f, NULL, NULL, NULL) < 0)) fprintf(stderr, "%d: Failed to bi create Edge Between %d and %d\n", val, a->id, b->id);} else fprintf(stderr, "Invalid Vertices a:%p(%d) b:%p(%d)\n", a, $1, b, $3);} |
| 95 | + ; |
| 96 | +%% |
| 97 | + |
| 98 | +void yyerror(struct graph** graph, const char *s) { |
| 99 | + fprintf(stderr, "yerror: %s\n", s); |
| 100 | + destroy_graph(*graph); |
| 101 | + *graph = NULL; |
| 102 | +} |
| 103 | + |
| 104 | +struct graph *parse_json(const char *path) { |
| 105 | + topologic_debug("%s;%s", "parse_json", path); |
| 106 | + FILE *file = fopen(path, "r"); |
| 107 | + if (!file) { |
| 108 | + topologic_debug("%s;%s;%p", "parse_json", "invalid file", (void *) NULL); |
| 109 | + return NULL; |
| 110 | + } |
| 111 | + yyin = file; |
| 112 | + struct graph *graph = NULL; |
| 113 | + yyparse(&graph); |
| 114 | + yyin = NULL; |
| 115 | + fclose(file); |
| 116 | + topologic_debug("%s;%s;%p", "parse_json", "success", graph); |
| 117 | + return graph; |
| 118 | +} |
0 commit comments