diff --git a/src/SConscript b/src/SConscript index f060ba129a0f13e3f3f51b4ee6150767a3e41158..cb6469673c973c16c16030485f91e92143a9c17b 100644 --- a/src/SConscript +++ b/src/SConscript @@ -25,7 +25,8 @@ parsers_headers = [ backends_headers = [ 'backends/regex.h', 'backends/contextfree.h', - 'backends/missing.h' + 'backends/missing.h', + 'backends/params.h' ] parsers = ['parsers/%s.c'%s for s in @@ -60,7 +61,7 @@ parsers = ['parsers/%s.c'%s for s in 'seek']] backends = ['backends/%s.c' % s for s in - ['missing', 'packrat', 'llk', 'regex', 'glr', 'lalr', 'lr', 'lr0']] + ['missing', 'packrat', 'llk', 'regex', 'glr', 'lalr', 'lr', 'lr0', 'params']] misc_hammer_parts = [ 'allocator.c', diff --git a/src/backends/glr.c b/src/backends/glr.c index 92ee09c5d12ba3a5f5005350290fd4a304262df6..06ab394bd7ca59ec89ed06fd3b1e8f983135d660 100644 --- a/src/backends/glr.c +++ b/src/backends/glr.c @@ -1,5 +1,6 @@ #include <assert.h> #include "lr.h" +#include "params.h" static bool glr_step(HParseResult **result, HSlist *engines, HLREngine *engine, const HLRAction *action); @@ -244,35 +245,16 @@ HParseResult *h_glr_parse(HAllocator* mm__, const HParser* parser, HInputStream* char * h_glr_get_description(HAllocator *mm__, HParserBackend be, void *param) { const char *format_str = "GLR(%zu) parser backend"; - /* TODO fix the backend */ + const char *generic_descr_format_str = - "GLR(k) parser backend (actually using the param is broken)"; - uintptr_t params_int; - size_t k, len; + "GLR(k) parser backend (default k is %zu)"; + + size_t k; char *descr = NULL; - params_int = (uintptr_t)param; - if (params_int > 0) { - /* A specific k was given */ - k = (size_t)params_int; - /* Measure how big a buffer we need */ - len = snprintf(NULL, 0, format_str, k); - /* Allocate it and do the real snprintf */ - descr = h_new(char, len + 1); - if (descr) { - snprintf(descr, len + 1, format_str, k); - } - } else { - /* - * No specific k; TODO actually have a default and fix the backend - */ - len = strlen(generic_descr_format_str); - /* Allocate and do the real snprintf */ - descr = h_new(char, len + 1); - if (descr) { - strncpy(descr, generic_descr_format_str, len + 1); - } - } + k = h_get_param_k(param); + + descr = h_format_description_with_param_k(mm__, format_str, generic_descr_format_str, k); return descr; } @@ -280,57 +262,21 @@ char * h_glr_get_description(HAllocator *mm__, char * h_glr_get_short_name(HAllocator *mm__, HParserBackend be, void *param) { const char *format_str = "GLR(%zu)", *generic_name = "GLR(k)"; - uintptr_t params_int; - size_t k, len; + + size_t k; char *name = NULL; - params_int = (uintptr_t)param; - if (params_int > 0) { - /* A specific k was given */ - k = (size_t)params_int; - /* Measure how big a buffer we need */ - len = snprintf(NULL, 0, format_str, k); - /* Allocate it and do the real snprintf */ - name = h_new(char, len + 1); - if (name) { - snprintf(name, len + 1, format_str, k); - } - } else { - /* No specific k */ - len = strlen(generic_name); - name = h_new(char, len + 1); - strncpy(name, generic_name, len + 1); - } + k = h_get_param_k(param); + + name = h_format_name_with_param_k(mm__, format_str, generic_name, k); return name; } -/*TODO: better handling of errors?*/ -int h_glr_extract_params(HParserBackendWithParams * be_with_params, backend_with_params_t * be_with_params_t) { - - be_with_params->params = NULL; - - int param_0 = -1; - int success = 0; - uintptr_t param; - size_t expected_params_len = 1; - backend_params_t params_t = be_with_params_t->params; - size_t actual_params_len = params_t.len; - - if(actual_params_len >= expected_params_len) { - backend_param_with_name_t param_t = params_t.params[0]; - uint8_t * param = param_t.param.param; - success = sscanf((char*)param, "%d", ¶m_0); - } - - if(success) { - param = (uintptr_t) param_0; - be_with_params->params = (void *)param; - } - - return success; +int h_glr_extract_params(HParserBackendWithParams * be_with_params, backend_with_params_t * be_with_params_t) { + return h_extract_param_k(be_with_params, be_with_params_t); } HParserBackendVTable h__glr_backend_vtable = { diff --git a/src/backends/lalr.c b/src/backends/lalr.c index e4c00a2e7413e780c1843e2a0df9adcf89bb2edc..473f595a2eb1777e8641dc323f39100eb08ac5b7 100644 --- a/src/backends/lalr.c +++ b/src/backends/lalr.c @@ -1,8 +1,8 @@ #include <assert.h> #include "contextfree.h" #include "lr.h" +#include "params.h" -static const size_t DEFAULT_K = 1; /* LALR-via-SLR grammar transformation */ @@ -275,7 +275,7 @@ HCFChoice *h_desugar_augmented(HAllocator *mm__, HParser *parser) int h_lalr_compile(HAllocator* mm__, HParser* parser, const void* params) { - size_t k = params? (uintptr_t)params : DEFAULT_K; + size_t k = params? (uintptr_t)params : DEFAULT_KMAX; // generate (augmented) CFG from parser // construct LR(0) DFA // build LR(0) table @@ -377,35 +377,15 @@ void h_lalr_free(HParser *parser) char * h_lalr_get_description(HAllocator *mm__, HParserBackend be, void *param) { const char *format_str = "LALR(%zu) parser backend"; - /* TODO fix the backend */ + const char *generic_descr_format_str = - "LALR(k) parser backend (actually using the param is broken)"; - uintptr_t params_int; - size_t k, len; + "LALR(k) parser backend (default k is %zu)"; + size_t k; char *descr = NULL; - params_int = (uintptr_t)param; - if (params_int > 0) { - /* A specific k was given */ - k = (size_t)params_int; - /* Measure how big a buffer we need */ - len = snprintf(NULL, 0, format_str, k); - /* Allocate it and do the real snprintf */ - descr = h_new(char, len + 1); - if (descr) { - snprintf(descr, len + 1, format_str, k); - } - } else { - /* - * No specific k; TODO actually have a default and fix the backend - */ - len = strlen(generic_descr_format_str); - /* Allocate and do the real snprintf */ - descr = h_new(char, len + 1); - if (descr) { - strncpy(descr, generic_descr_format_str, len + 1); - } - } + k = h_get_param_k(param); + + descr = h_format_description_with_param_k(mm__, format_str, generic_descr_format_str, k); return descr; } @@ -413,56 +393,21 @@ char * h_lalr_get_description(HAllocator *mm__, char * h_lalr_get_short_name(HAllocator *mm__, HParserBackend be, void *param) { const char *format_str = "LALR(%zu)", *generic_name = "LALR(k)"; - uintptr_t params_int; - size_t k, len; + + size_t k; char *name = NULL; - params_int = (uintptr_t)param; - if (params_int > 0) { - /* A specific k was given */ - k = (size_t)params_int; - /* Measure how big a buffer we need */ - len = snprintf(NULL, 0, format_str, k); - /* Allocate it and do the real snprintf */ - name = h_new(char, len + 1); - if (name) { - snprintf(name, len + 1, format_str, k); - } - } else { - /* No specific k */ - len = strlen(generic_name); - name = h_new(char, len + 1); - strncpy(name, generic_name, len + 1); - } + k = h_get_param_k(param); + + name = h_format_name_with_param_k(mm__, format_str, generic_name, k); return name; } -/*TODO better error handling*/ -int h_lalr_extract_params(HParserBackendWithParams * be_with_params, backend_with_params_t * be_with_params_t) { - - be_with_params->params = NULL; - - int param_0 = -1; - int success = 0; - uintptr_t param; - - size_t expected_params_len = 1; - backend_params_t params_t = be_with_params_t->params; - size_t actual_params_len = params_t.len; - if(actual_params_len >= expected_params_len) { - backend_param_with_name_t param_t = params_t.params[0]; - uint8_t * param = param_t.param.param; - success = sscanf((char*)param, "%d", ¶m_0); - } - - if(success) { - param = (uintptr_t) param_0; - be_with_params->params = (void *)param; - } +int h_lalr_extract_params(HParserBackendWithParams * be_with_params, backend_with_params_t * be_with_params_t) { - return success; + return h_extract_param_k(be_with_params, be_with_params_t); } diff --git a/src/backends/llk.c b/src/backends/llk.c index 064d859bdefa25595abd4d743788848c5847c383..e0a9fc92167c4532d16fb7e52d3528217967cc39 100644 --- a/src/backends/llk.c +++ b/src/backends/llk.c @@ -2,8 +2,7 @@ #include "../internal.h" #include "../cfgrammar.h" #include "../parsers/parser_internal.h" - -static const size_t DEFAULT_KMAX = 1; +#include "params.h" /* Generating the LL(k) parse table */ @@ -612,33 +611,13 @@ char * h_llk_get_description(HAllocator *mm__, const char *format_str = "LL(%zu) parser backend"; const char *generic_descr_format_str = "LL(k) parser backend (default k is %zu)"; - uintptr_t params_int; + size_t k, len; char *descr = NULL; - params_int = (uintptr_t)param; - if (params_int > 0) { - /* A specific k was given */ - k = (size_t)params_int; - /* Measure how big a buffer we need */ - len = snprintf(NULL, 0, format_str, k); - /* Allocate it and do the real snprintf */ - descr = h_new(char, len + 1); - if (descr) { - snprintf(descr, len + 1, format_str, k); - } - } else { - /* - * No specific k, would use DEFAULT_KMAX. We say what DEFAULT_KMAX - * was compiled in in the description. - */ - len = snprintf(NULL, 0, generic_descr_format_str, DEFAULT_KMAX); - /* Allocate and do the real snprintf */ - descr = h_new(char, len + 1); - if (descr) { - snprintf(descr, len + 1, generic_descr_format_str, DEFAULT_KMAX); - } - } + k = h_get_param_k(param); + + descr = h_format_description_with_param_k(mm__, format_str, generic_descr_format_str, k); return descr; } @@ -646,57 +625,20 @@ char * h_llk_get_description(HAllocator *mm__, char * h_llk_get_short_name(HAllocator *mm__, HParserBackend be, void *param) { const char *format_str = "LL(%zu)", *generic_name = "LL(k)"; - uintptr_t params_int; - size_t k, len; + + size_t k; char *name = NULL; - params_int = (uintptr_t)param; - if (params_int > 0) { - /* A specific k was given */ - k = (size_t)params_int; - /* Measure how big a buffer we need */ - len = snprintf(NULL, 0, format_str, k); - /* Allocate it and do the real snprintf */ - name = h_new(char, len + 1); - if (name) { - snprintf(name, len + 1, format_str, k); - } - } else { - /* No specific k, would use DEFAULT_KMAX */ - len = strlen(generic_name); - name = h_new(char, len + 1); - strncpy(name, generic_name, len + 1); - } + k = h_get_param_k(param); + + name = h_format_name_with_param_k(mm__, format_str, generic_name, k); return name; } -/*TODO better error handling*/ int h_llk_extract_params(HParserBackendWithParams * be_with_params, backend_with_params_t *be_with_params_t) { - be_with_params->params = NULL; - - int param_0 = -1; - int success = 0; - uintptr_t param; - - size_t expected_params_len = 1; - backend_params_t params_t = be_with_params_t->params; - size_t actual_params_len = params_t.len; - - if(actual_params_len >= expected_params_len) { - backend_param_with_name_t param_t = params_t.params[0]; - uint8_t * param = param_t.param.param; - success = sscanf((char*)param, "%d", ¶m_0); - } - - if(success) { - param = (uintptr_t) param_0; - be_with_params->params = (void *)param; - } - - return success; - + return h_extract_param_k(be_with_params, be_with_params_t); } diff --git a/src/hammer.c b/src/hammer.c index 648dbe2773a754103d6e85d750a9e2bf5a367316..e19336760917623ae870cab8f2d1b614c73c60e7 100644 --- a/src/hammer.c +++ b/src/hammer.c @@ -265,7 +265,17 @@ static char * h_get_string_for_backend_with_params__m(HAllocator *mm__, done: return text; } +/* Allocate and return an identifying name for this backend + * with parameters. The caller is responsible for freeing the result. + */ +char * h_get_name_for_backend_with_params__m(HAllocator *mm__, + HParserBackendWithParams *be_with_params) { + return h_get_string_for_backend_with_params__m(mm__, be_with_params, 0); +} +char * h_get_name_for_backend_with_params(HParserBackendWithParams *be_with_params) { + return h_get_name_for_backend_with_params__m(&system_allocator, be_with_params); +} /* * Allocate and return some human-readable descriptive text for this backend * with parameters. The caller is responsible for freeing the result. diff --git a/src/t_names.c b/src/t_names.c index e30a8b070bb75bc214520d57938895e7aa0f0b2c..fc9a012b5d3f51711903c1683e1170cb3c8f2aa3 100644 --- a/src/t_names.c +++ b/src/t_names.c @@ -115,6 +115,44 @@ static void test_tt_get_backend_with_params_by_name(void) { } +static void test_tt_h_get_descriptive_text_for_backend_with_params(void){ + HAllocator *mm__ = &system_allocator; + HParserBackendWithParams *be_with_params = h_get_backend_with_params_by_name("llk(1)"); + char * descr = h_get_descriptive_text_for_backend_with_params(be_with_params); + g_check_maybe_string_eq(descr, "LL(1) parser backend"); + h_free(descr); + h_free_backend_with_params(be_with_params); + be_with_params = h_get_backend_with_params_by_name("lalr(1)"); + descr = h_get_descriptive_text_for_backend_with_params(be_with_params); + g_check_maybe_string_eq(descr, "LALR(1) parser backend"); + h_free(descr); + h_free_backend_with_params(be_with_params); + be_with_params = h_get_backend_with_params_by_name("glr(2)"); + descr = h_get_descriptive_text_for_backend_with_params(be_with_params); + g_check_maybe_string_eq(descr, "GLR(2) parser backend"); + h_free(descr); + h_free_backend_with_params(be_with_params); +} + +static void test_tt_h_get_name_for_backend_with_params(void){ + HAllocator *mm__ = &system_allocator; + HParserBackendWithParams *be_with_params = h_get_backend_with_params_by_name("llk(1)"); + char * descr = h_get_name_for_backend_with_params(be_with_params); + g_check_maybe_string_eq(descr, "LL(1)"); + h_free(descr); + h_free_backend_with_params(be_with_params); + be_with_params = h_get_backend_with_params_by_name("lalr(2)"); + descr = h_get_name_for_backend_with_params(be_with_params); + g_check_maybe_string_eq(descr, "LALR(2)"); + h_free(descr); + h_free_backend_with_params(be_with_params); + be_with_params = h_get_backend_with_params_by_name("glr(1)"); + descr = h_get_name_for_backend_with_params(be_with_params); + g_check_maybe_string_eq(descr, "GLR(1)"); + h_free(descr); + h_free_backend_with_params(be_with_params); +} + /* test that we can request a backend with params from character * and compile a parser using it */ static void test_tt_h_compile_for_backend_with_params(void) { @@ -141,5 +179,9 @@ void register_names_tests(void) { g_test_add_func("/core/names/tt_backend_description", test_tt_backend_description); g_test_add_func("/core/names/tt_query_backend_by_name", test_tt_query_backend_by_name); g_test_add_func("/core/names/tt_get_backend_with_params_by_name", test_tt_get_backend_with_params_by_name); + g_test_add_func("/core/names/tt_test_tt_h_get_descriptive_text_for_backend_with_params", + test_tt_h_get_descriptive_text_for_backend_with_params); + g_test_add_func("/core/names/test_tt_h_get_name_for_backend_with_params", + test_tt_h_get_name_for_backend_with_params); g_test_add_func("/core/names/tt_h_compile_for_backend_with_params", test_tt_h_compile_for_backend_with_params); }