Conflicts:
	src/backends/llk.c
This commit is contained in:
Meredith L. Patterson 2013-05-24 20:00:41 -07:00
commit 02d68f6d18
36 changed files with 413 additions and 418 deletions

147
src/backends/contextfree.h Normal file
View 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

View file

@ -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");

View file

@ -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);