summaryrefslogtreecommitdiff
path: root/src/fspec/ragel/validator.rl
diff options
context:
space:
mode:
Diffstat (limited to 'src/fspec/ragel/validator.rl')
-rw-r--r--src/fspec/ragel/validator.rl96
1 files changed, 96 insertions, 0 deletions
diff --git a/src/fspec/ragel/validator.rl b/src/fspec/ragel/validator.rl
new file mode 100644
index 0000000..90ead21
--- /dev/null
+++ b/src/fspec/ragel/validator.rl
@@ -0,0 +1,96 @@
+#include <fspec/bcode.h>
+#include <fspec/validator.h>
+#include "util/ragel/ragel.h"
+#include "fspec/private/bcode-types.h"
+
+#include <assert.h>
+
+struct stack {
+ union {
+ fspec_num num;
+ fspec_off off;
+ fspec_var var;
+ fspec_strsz strsz;
+ unsigned char b[sizeof(fspec_num)];
+ } u;
+ uint8_t i; // writing index for u.b
+};
+
+struct state {
+ struct ragel ragel;
+ struct stack stack;
+};
+
+%%{
+ machine fspec_validator;
+ variable p state.ragel.p;
+ variable pe state.ragel.pe;
+ variable eof state.ragel.eof;
+ write data noerror nofinal;
+
+# BLT_HEADER = 0;
+# BLT_ADD = 1;
+# BLT_SUB = 2;
+# BLT_MUL = 3;
+# BLT_DIV = 4;
+# BLT_MOD = 5;
+# BLT_BIT_AND = 6;
+# BLT_BIT_OR = 7;
+# BLT_BIT_XOR = 8;
+# BLT_BIT_LEFT = 9;
+# BLT_BIT_RIGHT = 10;
+# BLT_DECLARE = 11;
+# BLT_READ = 12;
+# BLT_GOTO = 13;
+# BLT_FILTER = 14;
+# BLT_VISUAL = 15;
+#
+# builtins = BLT_HEADER |
+# BLT_ADD | BLT_SUB | BLT_MUL | BLT_DIV | BLT_MOD |
+# BLT_BIT_AND | BLT_BIT_OR | BLT_BIT_XOR | BLT_BIT_LEFT | BLT_BIT_RIGHT
+# BLT_DECLARE | BLT_READ | BLT_GOTO | BLT_FILTER | BLT_VISUAL;
+#
+# OP_ARG = 0;
+# OP_REF = 1;
+# OP_BLT = 2 OP_ARG builtins;
+# OP_FUN = 3;
+#
+# arg_ops = OP_REF | OP_FUN | OP_BUILTIN OP_FUN
+#
+# BLT_DECLARE = OP_BUILTIN 10 OP_ARG 2 OP_REF OP_REF;
+# BLT_READ = OP_BUILTIN 11 OP_ARG 1..255 OP_REF (arg_ops)*;
+#
+# pattern = ((BLT_READ | BLT_GOTO) BLT_FILTER* BLT_VISUAL?)* $!pattern_error;
+# main := (BLT_HEADER <: BLT_DECLARE* <: pattern) %check_decls $advance $!syntax_error;
+ main := any*;
+}%%
+
+bool
+fspec_validator_parse(struct fspec_validator *validator, const char *name)
+{
+ int cs;
+ %% write init;
+
+ (void)fspec_validator_en_main;
+ assert(validator);
+ assert(validator->ops.read);
+ assert(validator->mem.input.data && validator->mem.input.len);
+ assert(validator->mem.input.len <= (size_t)~0 && "input storage size exceeds size_t range");
+
+ struct state state = {
+ .ragel.name = name,
+ .ragel.lineno = 1,
+ };
+
+ static_assert(sizeof(state.stack.u) == sizeof(state.stack.u.b), "bytes doesn't represent the largest member in union");
+
+ struct fspec_mem input = validator->mem.input;
+ for (bool eof = false; !state.ragel.error && !eof;) {
+ const size_t bytes = validator->ops.read(validator, input.data, 1, input.len);
+ const struct ragel_mem rl = { .data = input.data, .end = (char*)input.data + bytes, .binary = true };
+ ragel_feed_input(&state.ragel, (eof = (bytes < input.len)), &rl);
+ %% write exec;
+ }
+
+ return !state.ragel.error;
+}