Merge branch 'recursive_indirect' into LALR
This commit is contained in:
commit
6f44ab1196
4 changed files with 26 additions and 4 deletions
|
|
@ -11,6 +11,8 @@ struct HCFStack_ {
|
||||||
int count;
|
int count;
|
||||||
int cap;
|
int cap;
|
||||||
HCFChoice *last_completed; // Last completed choice.
|
HCFChoice *last_completed; // Last completed choice.
|
||||||
|
// XXX is last_completed still needed?
|
||||||
|
HCFChoice *prealloc; // If not NULL, will be used for the outermost choice.
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef UNUSED
|
#ifndef UNUSED
|
||||||
|
|
@ -25,11 +27,13 @@ static HCFStack* h_cfstack_new(HAllocator *mm__) {
|
||||||
stack->count = 0;
|
stack->count = 0;
|
||||||
stack->cap = 4;
|
stack->cap = 4;
|
||||||
stack->stack = h_new(HCFChoice*, stack->cap);
|
stack->stack = h_new(HCFChoice*, stack->cap);
|
||||||
|
stack->prealloc = NULL;
|
||||||
return stack;
|
return stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void h_cfstack_free(HAllocator *mm__, HCFStack *stk__) UNUSED;
|
static void h_cfstack_free(HAllocator *mm__, HCFStack *stk__) UNUSED;
|
||||||
static void h_cfstack_free(HAllocator *mm__, HCFStack *stk__) {
|
static void h_cfstack_free(HAllocator *mm__, HCFStack *stk__) {
|
||||||
|
h_free(stk__->prealloc);
|
||||||
h_free(stk__->stack);
|
h_free(stk__->stack);
|
||||||
h_free(stk__);
|
h_free(stk__);
|
||||||
}
|
}
|
||||||
|
|
@ -56,7 +60,9 @@ static inline void h_cfstack_add_to_seq(HAllocator *mm__, HCFStack *stk__, HCFCh
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline HCFChoice* h_cfstack_new_choice_raw(HAllocator *mm__, HCFStack *stk__) {
|
static inline HCFChoice* h_cfstack_new_choice_raw(HAllocator *mm__, HCFStack *stk__) {
|
||||||
HCFChoice *ret = h_new(HCFChoice, 1);
|
HCFChoice *ret = stk__->prealloc? stk__->prealloc : h_new(HCFChoice, 1);
|
||||||
|
stk__->prealloc = NULL;
|
||||||
|
|
||||||
ret->reshape = NULL;
|
ret->reshape = NULL;
|
||||||
ret->action = NULL;
|
ret->action = NULL;
|
||||||
ret->pred = NULL;
|
ret->pred = NULL;
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,11 @@ HCFChoice *h_desugar(HAllocator *mm__, HCFStack *stk__, const HParser *parser) {
|
||||||
if (nstk__ == NULL) {
|
if (nstk__ == NULL) {
|
||||||
nstk__ = h_cfstack_new(mm__);
|
nstk__ = h_cfstack_new(mm__);
|
||||||
}
|
}
|
||||||
|
if(nstk__->prealloc == NULL)
|
||||||
|
nstk__->prealloc = h_new(HCFChoice, 1);
|
||||||
// we're going to do something naughty and cast away the const to memoize
|
// we're going to do something naughty and cast away the const to memoize
|
||||||
|
((HParser *)parser)->desugared = nstk__->prealloc;
|
||||||
parser->vtable->desugar(mm__, nstk__, parser->env);
|
parser->vtable->desugar(mm__, nstk__, parser->env);
|
||||||
((HParser *)parser)->desugared = nstk__->last_completed;
|
|
||||||
if (stk__ == NULL)
|
if (stk__ == NULL)
|
||||||
h_cfstack_free(mm__, nstk__);
|
h_cfstack_free(mm__, nstk__);
|
||||||
} else if (stk__ != NULL) {
|
} else if (stk__ != NULL) {
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ static bool indirect_isValidCF(void *env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void desugar_indirect(HAllocator *mm__, HCFStack *stk__, void *env) {
|
static void desugar_indirect(HAllocator *mm__, HCFStack *stk__, void *env) {
|
||||||
HCFS_DESUGAR( (HParser*)env );
|
HCFS_DESUGAR( (HParser *)env );
|
||||||
}
|
}
|
||||||
|
|
||||||
static const HParserVtable indirect_vt = {
|
static const HParserVtable indirect_vt = {
|
||||||
|
|
|
||||||
|
|
@ -407,7 +407,7 @@ static void test_not(gconstpointer backend) {
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
static void test_leftrec(gconstpointer backend) {
|
static void test_leftrec(gconstpointer backend) {
|
||||||
const HParser *a_ = h_ch('a');
|
HParser *a_ = h_ch('a');
|
||||||
|
|
||||||
HParser *lr_ = h_indirect();
|
HParser *lr_ = h_indirect();
|
||||||
h_bind_indirect(lr_, h_choice(h_sequence(lr_, a_, NULL), a_, NULL));
|
h_bind_indirect(lr_, h_choice(h_sequence(lr_, a_, NULL), a_, NULL));
|
||||||
|
|
@ -417,6 +417,17 @@ static void test_leftrec(gconstpointer backend) {
|
||||||
g_check_parse_ok(lr_, (HParserBackend)GPOINTER_TO_INT(backend), "aaa", 3, "((u0x61 u0x61) u0x61)");
|
g_check_parse_ok(lr_, (HParserBackend)GPOINTER_TO_INT(backend), "aaa", 3, "((u0x61 u0x61) u0x61)");
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
static void test_rightrec(gconstpointer backend) {
|
||||||
|
HParser *a_ = h_ch('a');
|
||||||
|
|
||||||
|
HParser *rr_ = h_indirect();
|
||||||
|
h_bind_indirect(rr_, h_choice(h_sequence(a_, rr_, NULL), h_epsilon_p(), NULL));
|
||||||
|
|
||||||
|
g_check_parse_ok(rr_, (HParserBackend)GPOINTER_TO_INT(backend), "a", 1, "(u0x61)");
|
||||||
|
g_check_parse_ok(rr_, (HParserBackend)GPOINTER_TO_INT(backend), "aa", 2, "(u0x61 (u0x61))");
|
||||||
|
g_check_parse_ok(rr_, (HParserBackend)GPOINTER_TO_INT(backend), "aaa", 3, "(u0x61 (u0x61 (u0x61)))");
|
||||||
|
}
|
||||||
|
|
||||||
void register_parser_tests(void) {
|
void register_parser_tests(void) {
|
||||||
g_test_add_data_func("/core/parser/packrat/token", GINT_TO_POINTER(PB_PACKRAT), test_token);
|
g_test_add_data_func("/core/parser/packrat/token", GINT_TO_POINTER(PB_PACKRAT), test_token);
|
||||||
g_test_add_data_func("/core/parser/packrat/ch", GINT_TO_POINTER(PB_PACKRAT), test_ch);
|
g_test_add_data_func("/core/parser/packrat/ch", GINT_TO_POINTER(PB_PACKRAT), test_ch);
|
||||||
|
|
@ -460,6 +471,7 @@ void register_parser_tests(void) {
|
||||||
g_test_add_data_func("/core/parser/packrat/not", GINT_TO_POINTER(PB_PACKRAT), test_not);
|
g_test_add_data_func("/core/parser/packrat/not", GINT_TO_POINTER(PB_PACKRAT), test_not);
|
||||||
g_test_add_data_func("/core/parser/packrat/ignore", GINT_TO_POINTER(PB_PACKRAT), test_ignore);
|
g_test_add_data_func("/core/parser/packrat/ignore", GINT_TO_POINTER(PB_PACKRAT), test_ignore);
|
||||||
// g_test_add_data_func("/core/parser/packrat/leftrec", GINT_TO_POINTER(PB_PACKRAT), test_leftrec);
|
// g_test_add_data_func("/core/parser/packrat/leftrec", GINT_TO_POINTER(PB_PACKRAT), test_leftrec);
|
||||||
|
g_test_add_data_func("/core/parser/packrat/rightrec", GINT_TO_POINTER(PB_PACKRAT), test_rightrec);
|
||||||
|
|
||||||
g_test_add_data_func("/core/parser/llk/token", GINT_TO_POINTER(PB_LLk), test_token);
|
g_test_add_data_func("/core/parser/llk/token", GINT_TO_POINTER(PB_LLk), test_token);
|
||||||
g_test_add_data_func("/core/parser/llk/ch", GINT_TO_POINTER(PB_LLk), test_ch);
|
g_test_add_data_func("/core/parser/llk/ch", GINT_TO_POINTER(PB_LLk), test_ch);
|
||||||
|
|
@ -496,6 +508,8 @@ void register_parser_tests(void) {
|
||||||
g_test_add_data_func("/core/parser/llk/epsilon_p", GINT_TO_POINTER(PB_LLk), test_epsilon_p);
|
g_test_add_data_func("/core/parser/llk/epsilon_p", GINT_TO_POINTER(PB_LLk), test_epsilon_p);
|
||||||
g_test_add_data_func("/core/parser/llk/attr_bool", GINT_TO_POINTER(PB_LLk), test_attr_bool);
|
g_test_add_data_func("/core/parser/llk/attr_bool", GINT_TO_POINTER(PB_LLk), test_attr_bool);
|
||||||
g_test_add_data_func("/core/parser/llk/ignore", GINT_TO_POINTER(PB_LLk), test_ignore);
|
g_test_add_data_func("/core/parser/llk/ignore", GINT_TO_POINTER(PB_LLk), test_ignore);
|
||||||
|
//g_test_add_data_func("/core/parser/llk/leftrec", GINT_TO_POINTER(PB_LLk), test_leftrec);
|
||||||
|
g_test_add_data_func("/core/parser/llk/rightrec", GINT_TO_POINTER(PB_LLk), test_rightrec);
|
||||||
|
|
||||||
g_test_add_data_func("/core/parser/regex/token", GINT_TO_POINTER(PB_REGULAR), test_token);
|
g_test_add_data_func("/core/parser/regex/token", GINT_TO_POINTER(PB_REGULAR), test_token);
|
||||||
g_test_add_data_func("/core/parser/regex/ch", GINT_TO_POINTER(PB_REGULAR), test_ch);
|
g_test_add_data_func("/core/parser/regex/ch", GINT_TO_POINTER(PB_REGULAR), test_ch);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue