Merge branch 'master' of https://github.com/thequux/hammer
Conflicts: src/backends/llk.c
This commit is contained in:
commit
02d68f6d18
36 changed files with 413 additions and 418 deletions
147
src/backends/contextfree.h
Normal file
147
src/backends/contextfree.h
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
// This is an internal header; it provides macros to make desugaring cleaner.
|
||||
#include <assert.h>
|
||||
#include "../internal.h"
|
||||
#ifndef HAMMER_CONTEXTFREE__H
|
||||
#define HAMMER_CONTEXTFREE__H
|
||||
|
||||
|
||||
// HCFStack
|
||||
struct HCFStack_ {
|
||||
HCFChoice **stack;
|
||||
int count;
|
||||
int cap;
|
||||
HCFChoice *last_completed; // Last completed choice.
|
||||
};
|
||||
|
||||
#ifndef UNUSED
|
||||
#define UNUSED __attribute__((unused))
|
||||
#endif
|
||||
|
||||
static inline HCFChoice* h_cfstack_new_choice_raw(HAllocator *mm__, HCFStack *stk__) UNUSED;
|
||||
static inline void h_cfstack_begin_choice(HAllocator *mm__, HCFStack *stk__) UNUSED;
|
||||
static HCFStack* h_cfstack_new(HAllocator *mm__) UNUSED;
|
||||
static HCFStack* h_cfstack_new(HAllocator *mm__) {
|
||||
HCFStack *stack = h_new(HCFStack, 1);
|
||||
stack->count = 0;
|
||||
stack->cap = 4;
|
||||
stack->stack = h_new(HCFChoice*, stack->cap);
|
||||
return stack;
|
||||
}
|
||||
|
||||
static void h_cfstack_free(HAllocator *mm__, HCFStack *stk__) UNUSED;
|
||||
static void h_cfstack_free(HAllocator *mm__, HCFStack *stk__) {
|
||||
h_free(stk__->stack);
|
||||
h_free(stk__);
|
||||
}
|
||||
|
||||
static inline void h_cfstack_add_to_seq(HAllocator *mm__, HCFStack *stk__, HCFChoice *item) UNUSED;
|
||||
static inline void h_cfstack_add_to_seq(HAllocator *mm__, HCFStack *stk__, HCFChoice *item) {
|
||||
HCFChoice *cur_top = stk__->stack[stk__->count-1];
|
||||
assert(cur_top->type == HCF_CHOICE);
|
||||
assert(cur_top->seq[0] != NULL); // There must be at least one sequence...
|
||||
stk__->last_completed = item;
|
||||
for (int i = 0;; i++) {
|
||||
if (cur_top->seq[i+1] == NULL) {
|
||||
assert(cur_top->seq[i]->items != NULL);
|
||||
for (int j = 0;; j++) {
|
||||
if (cur_top->seq[i]->items[j] == NULL) {
|
||||
cur_top->seq[i]->items = mm__->realloc(mm__, cur_top->seq[i]->items, sizeof(HCFChoice*) * (j+2));
|
||||
cur_top->seq[i]->items[j] = item;
|
||||
cur_top->seq[i]->items[j+1] = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline HCFChoice* h_cfstack_new_choice_raw(HAllocator *mm__, HCFStack *stk__) {
|
||||
HCFChoice *ret = h_new(HCFChoice, 1);
|
||||
ret->reshape = NULL;
|
||||
ret->action = NULL;
|
||||
ret->pred = NULL;
|
||||
ret->type = ~0; // invalid type
|
||||
// Add it to the current sequence...
|
||||
if (stk__->count > 0) {
|
||||
h_cfstack_add_to_seq(mm__, stk__, ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void h_cfstack_add_charset(HAllocator *mm__, HCFStack *stk__, HCharset charset) {
|
||||
HCFChoice *ni = h_cfstack_new_choice_raw(mm__, stk__);
|
||||
ni->type = HCF_CHARSET;
|
||||
ni->charset = charset;
|
||||
stk__->last_completed = ni;
|
||||
}
|
||||
|
||||
|
||||
static inline void h_cfstack_add_char(HAllocator *mm__, HCFStack *stk__, uint8_t chr) {
|
||||
HCFChoice *ni = h_cfstack_new_choice_raw(mm__, stk__);
|
||||
ni->type = HCF_CHAR;
|
||||
ni->chr = chr;
|
||||
stk__->last_completed = ni;
|
||||
}
|
||||
|
||||
static inline void h_cfstack_add_end(HAllocator *mm__, HCFStack *stk__) {
|
||||
HCFChoice *ni = h_cfstack_new_choice_raw(mm__, stk__);
|
||||
ni->type = HCF_END;
|
||||
stk__->last_completed = ni;
|
||||
}
|
||||
|
||||
static inline void h_cfstack_begin_choice(HAllocator *mm__, HCFStack *stk__) {
|
||||
HCFChoice *choice = h_cfstack_new_choice_raw(mm__, stk__);
|
||||
choice->type = HCF_CHOICE;
|
||||
choice->seq = h_new(HCFSequence*, 1);
|
||||
choice->seq[0] = NULL;
|
||||
|
||||
if (stk__->count + 1 > stk__->cap) {
|
||||
assert(stk__->cap > 0);
|
||||
stk__->cap *= 2;
|
||||
stk__->stack = mm__->realloc(mm__, stk__->stack, stk__->cap * sizeof(HCFChoice*));
|
||||
}
|
||||
assert(stk__->cap >= 1);
|
||||
stk__->stack[stk__->count++] = choice;
|
||||
}
|
||||
|
||||
static inline void h_cfstack_begin_seq(HAllocator *mm__, HCFStack *stk__) {
|
||||
HCFChoice *top = stk__->stack[stk__->count-1];
|
||||
for (int i = 0;; i++) {
|
||||
if (top->seq[i] == NULL) {
|
||||
top->seq = mm__->realloc(mm__, top->seq, sizeof(HCFSequence*) * (i+2));
|
||||
HCFSequence *seq = top->seq[i] = h_new(HCFSequence, 1);
|
||||
top->seq[i+1] = NULL;
|
||||
seq->items = h_new(HCFChoice*, 1);
|
||||
seq->items[0] = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void h_cfstack_end_seq(HAllocator *mm__, HCFStack *stk__) UNUSED;
|
||||
static inline void h_cfstack_end_seq(HAllocator *mm__, HCFStack *stk__) {
|
||||
// do nothing. You should call this anyway.
|
||||
}
|
||||
|
||||
static inline void h_cfstack_end_choice(HAllocator *mm__, HCFStack *stk__) UNUSED;
|
||||
static inline void h_cfstack_end_choice(HAllocator *mm__, HCFStack *stk__) {
|
||||
assert(stk__->count > 0);
|
||||
stk__->last_completed = stk__->stack[stk__->count-1];
|
||||
stk__->count--;
|
||||
}
|
||||
|
||||
#define HCFS_APPEND(choice) h_cfstack_add_to_seq(mm__, stk__, (choice))
|
||||
#define HCFS_DESUGAR(parser) h_desugar(mm__, stk__, parser)
|
||||
#define HCFS_ADD_CHARSET(charset) h_cfstack_add_charset(mm__, stk__, (charset))
|
||||
#define HCFS_ADD_CHAR(chr) h_cfstack_add_char(mm__, stk__, (chr))
|
||||
#define HCFS_ADD_END() h_cfstack_add_end(mm__, stk__)
|
||||
// The semicolons on BEGIN macros are intentional; pretend that they
|
||||
// are control structures.
|
||||
#define HCFS_BEGIN_CHOICE() h_cfstack_begin_choice(mm__, stk__);
|
||||
#define HCFS_BEGIN_SEQ() h_cfstack_begin_seq(mm__, stk__);
|
||||
#define HCFS_END_CHOICE() h_cfstack_end_choice(mm__, stk__)
|
||||
#define HCFS_END_SEQ() h_cfstack_end_seq(mm__, stk__)
|
||||
#define HCFS_THIS_CHOICE (stk__->stack[stk__->count-1])
|
||||
|
||||
#endif
|
||||
|
|
@ -458,9 +458,9 @@ int test_llk(void)
|
|||
printf("derive epsilon: ");
|
||||
h_pprint_symbolset(stdout, g, g->geneps, 0);
|
||||
printf("first(A) = ");
|
||||
h_pprint_stringset(stdout, h_first(3, g, g->start), 0);
|
||||
//printf("follow(C) = ");
|
||||
//h_pprint_stringset(stdout, h_follow(3, g, h_desugar(&system_allocator, c)), 0);
|
||||
h_pprint_stringset(stdout, g, h_first(2, g, g->start), 0);
|
||||
printf("follow(C) = ");
|
||||
h_pprint_stringset(stdout, g, h_follow(2, g, h_desugar(&system_allocator, NULL, c)), 0);
|
||||
|
||||
if(h_compile(p, PB_LLk, (void *)3)) {
|
||||
fprintf(stderr, "does not compile\n");
|
||||
|
|
|
|||
|
|
@ -354,6 +354,9 @@ static int h_regex_compile(HAllocator *mm__, HParser* parser, const void* params
|
|||
if (!parser->vtable->isValidRegular(parser->env))
|
||||
return 1;
|
||||
HRVMProg *prog = h_new(HRVMProg, 1);
|
||||
prog->length = prog->action_count = 0;
|
||||
prog->insns = NULL;
|
||||
prog->actions = NULL;
|
||||
prog->allocator = mm__;
|
||||
if (!h_compile_regex(prog, parser)) {
|
||||
h_free(prog->insns);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue