aboutsummaryrefslogtreecommitdiff
path: root/grammar.c
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2020-09-12 18:20:13 -0700
committerBruce Hill <bruce@bruce-hill.com>2020-09-12 18:20:13 -0700
commitc18eb4c9968289c4808d70f7124c0b6bed5eb022 (patch)
tree97fdbee687e2e83f83403161365b90c99c102ee6 /grammar.c
parentc0125378b9ec96149aed3107bff719cd8a01b16d (diff)
Added backrefs
Diffstat (limited to 'grammar.c')
-rw-r--r--grammar.c48
1 files changed, 41 insertions, 7 deletions
diff --git a/grammar.c b/grammar.c
index 2be7cd5..61c82c9 100644
--- a/grammar.c
+++ b/grammar.c
@@ -9,20 +9,20 @@
grammar_t *new_grammar(void)
{
grammar_t *g = calloc(sizeof(grammar_t), 1);
- g->definitions = calloc(sizeof(def_t), (g->capacity = 128));
+ g->definitions = calloc(sizeof(def_t), (g->defcapacity = 128));
return g;
}
void add_def(grammar_t *g, const char *src, const char *name, vm_op_t *op)
{
- if (g->size >= g->capacity) {
- g->definitions = realloc(g->definitions, (g->capacity += 32));
+ if (g->defcount >= g->defcapacity) {
+ g->definitions = realloc(g->definitions, sizeof(&g->definitions[0])*(g->defcapacity += 32));
}
- int i = g->size;
+ int i = g->defcount;
g->definitions[i].source = src;
g->definitions[i].name = name;
g->definitions[i].op = op;
- ++g->size;
+ ++g->defcount;
}
/*
@@ -54,11 +54,45 @@ vm_op_t *load_grammar(grammar_t *g, const char *src)
vm_op_t *lookup(grammar_t *g, const char *name)
{
- // Search backwards so newer defs take precedence
- for (int i = g->size-1; i >= 0; i--) {
+ // Search backwards so newer backrefs/defs take precedence
+ for (int i = (int)g->backrefcount-1; i >= 0; i--) {
+ if (streq(g->backrefs[i].name, name)) {
+ return g->backrefs[i].op;
+ }
+ }
+ for (int i = g->defcount-1; i >= 0; i--) {
if (streq(g->definitions[i].name, name)) {
return g->definitions[i].op;
}
}
return NULL;
}
+
+void push_backref(grammar_t *g, const char *name, match_t *capture)
+{
+ check(capture, "No capture provided");
+ if (g->backrefcount >= g->backrefcapacity) {
+ g->backrefs = realloc(g->backrefs, sizeof(g->backrefs[0])*(g->backrefcapacity += 32));
+ }
+ size_t i = g->backrefcount++;
+ g->backrefs[i].name = name;
+ g->backrefs[i].capture = capture;
+ vm_op_t *op = calloc(sizeof(vm_op_t), 1);
+ op->op = VM_BACKREF;
+ op->start = capture->start;
+ op->end = capture->end;
+ op->len = -1; // TODO: maybe calculate this?
+ op->args.backref = (void*)capture;
+ g->backrefs[i].op = op;
+}
+
+void pop_backrefs(grammar_t *g, size_t count)
+{
+ check(count <= g->backrefcount, "Attempt to pop %ld backrefs when there are only %ld", count, g->backrefcount);
+ for ( ; count > 0; count--) {
+ //free(g->backrefs[i].op); // TODO: memory leak problem??
+ int i = (int)g->backrefcount - 1;
+ memset(&g->backrefs[i], 0, sizeof(g->backrefs[i]));
+ --g->backrefcount;
+ }
+}