aboutsummaryrefslogtreecommitdiff
path: root/flatcc/src/compiler/parser.h
diff options
context:
space:
mode:
Diffstat (limited to 'flatcc/src/compiler/parser.h')
-rw-r--r--flatcc/src/compiler/parser.h213
1 files changed, 213 insertions, 0 deletions
diff --git a/flatcc/src/compiler/parser.h b/flatcc/src/compiler/parser.h
new file mode 100644
index 0000000..ef2ecc1
--- /dev/null
+++ b/flatcc/src/compiler/parser.h
@@ -0,0 +1,213 @@
+#ifndef PARSER_H
+#define PARSER_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "../../config/config.h"
+#include "flatcc/flatcc.h"
+#include "symbols.h"
+
+#define ELEM_BUFSIZ (64 * 1024)
+#define ERROR_BUFSIZ 200
+
+#define REVERT_LIST(TYPE, FIELD, HEAD) \
+ do { \
+ TYPE *tmp__next, *tmp__prev = 0, *tmp__link = *(HEAD); \
+ while (tmp__link) { \
+ tmp__next = tmp__link->FIELD; \
+ tmp__link->FIELD = tmp__prev; \
+ tmp__prev = tmp__link; \
+ tmp__link = tmp__next; \
+ } \
+ *(HEAD) = tmp__prev; \
+ } while (0)
+
+typedef struct fb_parser fb_parser_t;
+typedef flatcc_options_t fb_options_t;
+
+typedef void (*fb_error_fun)(void *err_ctx, const char *buf, size_t len);
+
+void __flatcc_fb_default_error_out(void *err_ctx, const char *buf, size_t len);
+#define fb_default_error_out __flatcc_fb_default_error_out
+
+int __flatcc_fb_print_error(fb_parser_t *P, const char * format, ...);
+#define fb_print_error __flatcc_fb_print_error
+
+struct fb_parser {
+ fb_parser_t *dependencies;
+ fb_parser_t *inverse_dependencies;
+ fb_error_fun error_out;
+ void *error_ctx;
+
+ const char *managed_input;
+
+ fb_token_t *ts, *te;
+ int tcapacity;
+ int doc_mode;
+ fb_doc_t *doc;
+ fb_token_t *token;
+
+ size_t elem_end;
+ void *elem_buffers;
+ size_t elem;
+ size_t offset_size;
+
+ const char *line;
+ long linenum;
+
+ /* Internal id (not a pointer into token stream). */
+ fb_token_t t_none;
+ fb_token_t t_ubyte;
+
+ int failed;
+
+ unsigned char *tmp_field_marker;
+ fb_symbol_t **tmp_field_index;
+ int nesting_level;
+
+ int has_schema;
+ fb_options_t opts;
+ fb_schema_t schema;
+ fb_scope_t *current_scope;
+ char *path;
+ char *referer_path;
+};
+
+static inline void checkmem(const void *p)
+{
+ if (!p) {
+ fprintf(stderr, "error: out of memory, aborting...\n");
+ exit(1);
+ }
+}
+
+static inline void *new_elem(fb_parser_t *P, size_t size)
+{
+ size_t elem;
+ void *buf;
+
+ size = (size + 15) & ~(size_t)15;
+ elem = P->elem;
+ if (elem + size > P->elem_end) {
+ buf = calloc(ELEM_BUFSIZ, 1);
+ checkmem(buf);
+ *(void**)buf = P->elem_buffers;
+ P->elem_buffers = buf;
+ elem = P->elem = (size_t)buf + 16;
+ P->elem_end = (size_t)buf + ELEM_BUFSIZ;
+ }
+ P->elem += size;
+ return (void*)elem;
+}
+
+int __flatcc_fb_print_error(fb_parser_t *P, const char * format, ...);
+#define fb_print_error __flatcc_fb_print_error
+
+const char *__flatcc_error_find_file_of_token(fb_parser_t *P, fb_token_t *t);
+#define error_find_file_of_token __flatcc_error_find_file_of_token
+
+/*
+ * This is the primary error reporting function.
+ * The parser is flagged as failed and error count incremented.
+ *
+ * If s is not null, then s, len replaces the token text of `t` but
+ * still reports the location of t. `peer` is optional and prints the
+ * token location and text and the end of the message.
+ * `msg` may be the only non-zero argument besides `P`.
+ *
+ * Various helper functions are available for the various cases.
+ *
+ * `fb_print_error` may be called instead to generate text to the error
+ * output that is not counted as an error.
+ */
+void __flatcc_error_report(fb_parser_t *P, fb_token_t *t, const char *msg, fb_token_t *peer, const char *s, size_t len);
+#define error_report __flatcc_error_report
+
+static void error_tok_2(fb_parser_t *P, fb_token_t *t, const char *msg, fb_token_t *peer)
+{
+ error_report(P, t, msg, peer, 0, 0);
+}
+
+static inline void error_tok(fb_parser_t *P, fb_token_t *t, const char *msg)
+{
+ error_tok_2(P, t, msg, 0);
+}
+
+/* Only use the token location. */
+static inline void error_tok_as_string(fb_parser_t *P, fb_token_t *t, const char *msg, char *s, size_t len)
+{
+ error_report(P, t, msg, 0, s, len);
+}
+
+static inline void error(fb_parser_t *P, const char *msg)
+{
+ error_tok(P, 0, msg);
+}
+
+static inline void error_name(fb_parser_t *P, fb_name_t *name, const char *msg)
+{
+ if (!name) {
+ error(P, msg);
+ } else {
+ error_report(P, 0, msg, 0, name->name.s.s, (size_t)name->name.s.len);
+ }
+}
+
+static inline void error_sym(fb_parser_t *P, fb_symbol_t *s, const char *msg)
+{
+ error_tok(P, s->ident, msg);
+}
+
+static inline void error_sym_2(fb_parser_t *P, fb_symbol_t *s, const char *msg, fb_symbol_t *s2)
+{
+ error_tok_2(P, s->ident, msg, s2->ident);
+}
+
+static inline void error_sym_tok(fb_parser_t *P, fb_symbol_t *s, const char *msg, fb_token_t *t2)
+{
+ error_tok_2(P, s->ident, msg, t2);
+}
+
+void error_ref_sym(fb_parser_t *P, fb_ref_t *ref, const char *msg, fb_symbol_t *s2);
+
+static inline void error_ref(fb_parser_t *P, fb_ref_t *ref, const char *msg)
+{
+ error_ref_sym(P, ref, msg, 0);
+}
+
+/*
+ * If `opts` is null, defaults options are being used, otherwise opts is
+ * copied into the parsers options. The name may be path, the basename
+ * without default extension will be extracted. The `error_out` funciton is
+ * optional, otherwise output is printed to stderr, truncated to a
+ * reasoanble size per error. `error_ctx` is provided as argument to
+ * `error_out` if non-zero, and otherwise ignored.
+ *
+ * This api only deals with a single schema file so a parent level
+ * driver must handle file inclusion and update P->dependencies but
+ * order is not significant (parse order is, but this is handled by
+ * updating the `include_index` in the root schema).
+ *
+ * P->dependencies must be cleared by callee in any order but once one
+ * is cleared the entire structure should be taken down because symbols
+ * trees point everywhere. For parses without file inclusion
+ * dependencies will be null. Dependencies are not handled at this
+ * level. P->inverse_dependencies is just the reverse list.
+ *
+ * The file at the head of the dependencies list is the root and the
+ * one that provides the root schema. Other root schemas are not used.
+ */
+int __flatcc_fb_init_parser(fb_parser_t *P, fb_options_t *opts, const char *name,
+ fb_error_fun error_out, void *error_ctx, fb_root_schema_t *rs);
+#define fb_init_parser __flatcc_fb_init_parser
+
+int __flatcc_fb_parse(fb_parser_t *P, const char *input, size_t len, int own_buffer);
+#define fb_parse __flatcc_fb_parse
+
+void __flatcc_fb_clear_parser(fb_parser_t *P);
+#define fb_clear_parser __flatcc_fb_clear_parser
+
+#endif /* PARSER_H */