From 2fb68fa97f096e5bd0f3ff81d31c3bc61719ae8a Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Mon, 14 Dec 2020 22:01:50 -0800 Subject: [PATCH] Moved json code into its own file --- Makefile | 2 +- json.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ json.h | 11 +++++++++++ vm.c | 43 ++----------------------------------------- 4 files changed, 58 insertions(+), 42 deletions(-) create mode 100644 json.c create mode 100644 json.h diff --git a/Makefile b/Makefile index 568421f..d419241 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ CWARN=-Wall -Wpedantic -Wextra -Wno-unknown-pragmas -Wno-missing-field-initializ G ?= O ?= -O3 -CFILES=compiler.c grammar.c utils.c vm.c file_loader.c viz.c +CFILES=compiler.c grammar.c utils.c vm.c file_loader.c viz.c json.c OBJFILES=$(CFILES:.c=.o) all: $(NAME) diff --git a/json.c b/json.c new file mode 100644 index 0000000..d45e79c --- /dev/null +++ b/json.c @@ -0,0 +1,44 @@ +/* + * json.c - Code for printing JSON output of matches. + */ +#include "types.h" + +/* + * Print a match as JSON + */ +static int _json_match(FILE *f, const char *text, match_t *m, int comma, int verbose) +{ + if (!verbose) { + if (m->op->op != VM_REF) { + for (match_t *child = m->child; child; child = child->nextsibling) { + comma |= _json_match(f, text, child, comma, verbose); + } + return comma; + } + } + + if (comma) fprintf(f, ",\n"); + comma = 0; + fprintf(f, "{\"rule\":\""); + for (const char *c = m->op->start; c < m->op->end; c++) { + switch (*c) { + case '"': fprintf(f, "\\\""); break; + case '\\': fprintf(f, "\\\\"); break; + case '\t': fprintf(f, "\\t"); break; + case '\n': fprintf(f, "↵"); break; + default: fprintf(f, "%c", *c); break; + } + } + fprintf(f, "\",\"start\":%ld,\"end\":%ld,\"children\":[", + m->start - text, m->end - text); + for (match_t *child = m->child; child; child = child->nextsibling) { + comma |= _json_match(f, text, child, comma, verbose); + } + fprintf(f, "]}"); + return 1; +} + +void json_match(FILE *f, const char *text, match_t *m, int verbose) +{ + _json_match(f, text, m, 0, verbose); +} diff --git a/json.h b/json.h new file mode 100644 index 0000000..2a5a62a --- /dev/null +++ b/json.h @@ -0,0 +1,11 @@ +/* + * json.h - Header file for JSON output. + */ +#ifndef JSON__H +#define JSON__H + +__attribute__((nonnull)) +void json_match(FILE *f, const char *text, match_t *m, int verbose); + +#endif +// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1 diff --git a/vm.c b/vm.c index e754a62..6d40507 100644 --- a/vm.c +++ b/vm.c @@ -4,9 +4,10 @@ #include -#include "vm.h" #include "grammar.h" +#include "types.h" #include "utils.h" +#include "vm.h" static match_t *match_backref(const char *str, vm_op_t *op, match_t *m, unsigned int flags); static size_t push_backrefs(grammar_t *g, match_t *m); @@ -592,46 +593,6 @@ void print_match(file_t *f, match_t *m, print_options_t options) _print_match(f, m, &state, options); } -/* - * Print a match as JSON - */ -static int _json_match(FILE *f, const char *text, match_t *m, int comma, int verbose) -{ - if (!verbose) { - if (m->op->op != VM_REF) { - for (match_t *child = m->child; child; child = child->nextsibling) { - comma |= _json_match(f, text, child, comma, verbose); - } - return comma; - } - } - - if (comma) fprintf(f, ",\n"); - comma = 0; - fprintf(f, "{\"rule\":\""); - for (const char *c = m->op->start; c < m->op->end; c++) { - switch (*c) { - case '"': fprintf(f, "\\\""); break; - case '\\': fprintf(f, "\\\\"); break; - case '\t': fprintf(f, "\\t"); break; - case '\n': fprintf(f, "↵"); break; - default: fprintf(f, "%c", *c); break; - } - } - fprintf(f, "\",\"start\":%ld,\"end\":%ld,\"children\":[", - m->start - text, m->end - text); - for (match_t *child = m->child; child; child = child->nextsibling) { - comma |= _json_match(f, text, child, comma, verbose); - } - fprintf(f, "]}"); - return 1; -} - -void json_match(FILE *f, const char *text, match_t *m, int verbose) -{ - _json_match(f, text, m, 0, verbose); -} - static match_t *match_backref(const char *str, vm_op_t *op, match_t *cap, unsigned int flags) { check(op->op == VM_BACKREF, "Attempt to match backref against something that's not a backref");