From 7b04ab8d9de37b7ced1b5038565821082fa42285 Mon Sep 17 00:00:00 2001 From: "Sven M. Hallberg" Date: Fri, 14 Jun 2013 12:27:35 +0200 Subject: [PATCH 1/3] pre-allocate h_desugar's result to squelch recursive calls --- src/backends/contextfree.h | 7 ++++++- src/desugar.c | 4 +++- src/parsers/indirect.c | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/backends/contextfree.h b/src/backends/contextfree.h index 9c2ec45..3f01d70 100644 --- a/src/backends/contextfree.h +++ b/src/backends/contextfree.h @@ -11,6 +11,7 @@ struct HCFStack_ { int count; int cap; HCFChoice *last_completed; // Last completed choice. + HCFChoice *prealloc; // If not NULL, will serve as outermost choice. }; #ifndef UNUSED @@ -25,11 +26,13 @@ static HCFStack* h_cfstack_new(HAllocator *mm__) { stack->count = 0; stack->cap = 4; stack->stack = h_new(HCFChoice*, stack->cap); + stack->prealloc = NULL; return stack; } static void h_cfstack_free(HAllocator *mm__, HCFStack *stk__) UNUSED; static void h_cfstack_free(HAllocator *mm__, HCFStack *stk__) { + h_free(stk__->prealloc); h_free(stk__->stack); h_free(stk__); } @@ -56,7 +59,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__) { - HCFChoice *ret = h_new(HCFChoice, 1); + HCFChoice *ret = stk__->prealloc? stk__->prealloc : h_new(HCFChoice, 1); + stk__->prealloc = NULL; + ret->reshape = NULL; ret->action = NULL; ret->pred = NULL; diff --git a/src/desugar.c b/src/desugar.c index ce87ca3..46176ea 100644 --- a/src/desugar.c +++ b/src/desugar.c @@ -8,9 +8,11 @@ HCFChoice *h_desugar(HAllocator *mm__, HCFStack *stk__, const HParser *parser) { if (nstk__ == NULL) { 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 + ((HParser *)parser)->desugared = nstk__->prealloc; parser->vtable->desugar(mm__, nstk__, parser->env); - ((HParser *)parser)->desugared = nstk__->last_completed; if (stk__ == NULL) h_cfstack_free(mm__, nstk__); } else if (stk__ != NULL) { diff --git a/src/parsers/indirect.c b/src/parsers/indirect.c index 746f1a9..2217a20 100644 --- a/src/parsers/indirect.c +++ b/src/parsers/indirect.c @@ -10,7 +10,7 @@ static bool indirect_isValidCF(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 = { From dfe4c3ad4730f85f5645bb723dd02fd461e2d2de Mon Sep 17 00:00:00 2001 From: "Sven M. Hallberg" Date: Fri, 14 Jun 2013 12:42:55 +0200 Subject: [PATCH 2/3] add right-recursion test for packrat and llk --- src/t_parser.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/t_parser.c b/src/t_parser.c index 8aab7bb..fa19151 100644 --- a/src/t_parser.c +++ b/src/t_parser.c @@ -407,7 +407,7 @@ static void test_not(gconstpointer backend) { } /* static void test_leftrec(gconstpointer backend) { - const HParser *a_ = h_ch('a'); + HParser *a_ = h_ch('a'); HParser *lr_ = h_indirect(); 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)"); } */ +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) { 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); @@ -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/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/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/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/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/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/ch", GINT_TO_POINTER(PB_REGULAR), test_ch); From f65b0ae82a0f192ceb58c9f03df1ef830b09e9e0 Mon Sep 17 00:00:00 2001 From: "Sven M. Hallberg" Date: Fri, 14 Jun 2013 12:50:39 +0200 Subject: [PATCH 3/3] commentation --- src/backends/contextfree.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/backends/contextfree.h b/src/backends/contextfree.h index 3f01d70..b387e55 100644 --- a/src/backends/contextfree.h +++ b/src/backends/contextfree.h @@ -11,7 +11,8 @@ struct HCFStack_ { int count; int cap; HCFChoice *last_completed; // Last completed choice. - HCFChoice *prealloc; // If not NULL, will serve as outermost choice. + // XXX is last_completed still needed? + HCFChoice *prealloc; // If not NULL, will be used for the outermost choice. }; #ifndef UNUSED