diff --git a/src/backends/glr.c b/src/backends/glr.c index 781b9aeede2f4c2b0d382f600ef3e8819fa5bae6..b91f7c45a9f3daa5b5bd2efdeae11b0a5b5b82f1 100644 --- a/src/backends/glr.c +++ b/src/backends/glr.c @@ -266,11 +266,11 @@ char * h_glr_get_description(HAllocator *mm__, /* * No specific k; TODO actually have a default and fix the backend */ - len = snprintf(NULL, 0, generic_descr_format_str); + len = strlen(generic_descr_format_str); /* Allocate and do the real snprintf */ descr = h_new(char, len + 1); if (descr) { - snprintf(descr, len + 1, generic_descr_format_str); + strncpy(descr, generic_descr_format_str, len + 1); } } @@ -305,6 +305,23 @@ char * h_glr_get_short_name(HAllocator *mm__, return name; } +int h_glr_extract_params(void ** params, char* raw_params) { + + params = NULL; + + int param_0 = -1; + int success = 0; + + success = sscanf(raw_params + 1, "%d", ¶m_0); + + if(success) { + *params = (void *)(unsigned long long) param_0; + } + + return success; + +} + HParserBackendVTable h__glr_backend_vtable = { .compile = h_glr_compile, .parse = h_glr_parse, @@ -317,7 +334,9 @@ HParserBackendVTable h__glr_backend_vtable = { .backend_short_name = "glr", .backend_description = "GLR(k) parser backend", .get_description_with_params = h_glr_get_description, - .get_short_name_with_params = h_glr_get_short_name + .get_short_name_with_params = h_glr_get_short_name, + + .extract_params = h_glr_extract_params }; diff --git a/src/backends/lalr.c b/src/backends/lalr.c index cc7ff36c70963f7056a99276d36969fdaaf79a4e..2f0f27e5caa58cd79c7cc0058e61847721eac75f 100644 --- a/src/backends/lalr.c +++ b/src/backends/lalr.c @@ -397,11 +397,11 @@ char * h_lalr_get_description(HAllocator *mm__, /* * No specific k; TODO actually have a default and fix the backend */ - len = snprintf(NULL, 0, generic_descr_format_str); + len = strlen(generic_descr_format_str); /* Allocate and do the real snprintf */ descr = h_new(char, len + 1); if (descr) { - snprintf(descr, len + 1, generic_descr_format_str); + strncpy(descr, generic_descr_format_str, len + 1); } } @@ -436,6 +436,23 @@ char * h_lalr_get_short_name(HAllocator *mm__, return name; } +int h_lalr_extract_params(void ** params, char* raw_params) { + + params = NULL; + + int param_0 = -1; + int success = 0; + + success = sscanf(raw_params + 1, "%d", ¶m_0); + + if(success) { + *params = (void *)(unsigned long long) param_0; + } + + return success; + +} + HParserBackendVTable h__lalr_backend_vtable = { .compile = h_lalr_compile, .parse = h_lr_parse, @@ -450,7 +467,9 @@ HParserBackendVTable h__lalr_backend_vtable = { .backend_short_name = "lalr", .backend_description = "LALR(k) parser backend", .get_description_with_params = h_lalr_get_description, - .get_short_name_with_params = h_lalr_get_short_name + .get_short_name_with_params = h_lalr_get_short_name, + + .extract_params = h_lalr_extract_params }; // dummy! diff --git a/src/backends/llk.c b/src/backends/llk.c index b2e89e334c127cd2f498d03a612c8cfd199dc24d..cf7e2aba92dc25425526d9943ddc444928fb91d8 100644 --- a/src/backends/llk.c +++ b/src/backends/llk.c @@ -670,6 +670,23 @@ char * h_llk_get_short_name(HAllocator *mm__, return name; } +int h_llk_extract_params(void ** params, char * raw_params) { + + params = NULL; + + int param_0 = -1; + int success = 0; + + success = sscanf(raw_params + 1, "%d", ¶m_0); + + if(success) { + *params = (void *)(unsigned long long) param_0; + } + + return success; + +} + HParserBackendVTable h__llk_backend_vtable = { .compile = h_llk_compile, @@ -687,7 +704,10 @@ HParserBackendVTable h__llk_backend_vtable = { .backend_short_name = "llk", .backend_description = "LL(k) parser backend", .get_description_with_params = h_llk_get_description, - .get_short_name_with_params = h_llk_get_short_name + .get_short_name_with_params = h_llk_get_short_name, + + /*extraction of params from string*/ + .extract_params = h_llk_extract_params }; diff --git a/src/hammer.c b/src/hammer.c index 78279bab8d602ec7dd2f1dd5899ea1e72a0a9750..a67fc7f850408ef8d8382217e64514508852355a 100644 --- a/src/hammer.c +++ b/src/hammer.c @@ -328,6 +328,70 @@ char * h_get_short_name_with_no_params(HAllocator *mm__, return h_get_backend_text_with_no_params(mm__, be, 0); } +HParserBackendWithParams * h_get_backend_with_params_by_name(const char *name_with_params) { + + HParserBackendWithParams *result = NULL; + + HAllocator *mm__ = &system_allocator; + + char *name_with_no_params = NULL; + char *params_as_string = NULL; + + size_t name_len, params_len; + size_t len = strlen(name_with_params); + + params_as_string = strstr(name_with_params, "("); + + if(params_as_string) { + params_len = strlen(params_as_string); + name_len = len - params_len; + } else { + name_len = len; + } + + name_with_no_params = h_new(char, name_len+1); + memset(name_with_no_params, 0, name_len+1); + strncpy(name_with_no_params, name_with_params, name_len); + + HParserBackend backend = h_query_backend_by_name(name_with_no_params); + + result = h_new(HParserBackendWithParams, 1); + + if (result) { + + result->backend = backend; + + result->name = name_with_no_params; + + if(params_as_string) { + //store the raw string containing the param(s) + char * raw_params_string = h_new(char, params_len+1); + memset(name_with_no_params, 0, params_len+1); + strncpy(raw_params_string, params_as_string, params_len); + result->raw_params = raw_params_string; + + //if the backend is one built as part of hammer, use it + if(backend){ + int s = backends[backend]->extract_params(&(result->params), params_as_string); + if (!s) { + /* copy_params() failed */ + h_free(result); + result = NULL; + } + } + + } else { + /* else just ignore it and set it to NULL */ + result->params = NULL; + result->raw_params = NULL; + } + + } + + return result; + +} + #define DEFAULT_ENDIANNESS (BIT_BIG_ENDIAN | BYTE_BIG_ENDIAN) HParseResult* h_parse(const HParser* parser, const uint8_t* input, size_t length) { @@ -373,6 +437,28 @@ bool h_not_regular(HRVMProg *prog, void *env) { return false; } +int h_compile_for_named_backend(HParser* parser, HParserBackendWithParams* be_with_params){ + HAllocator* mm__ = be_with_params->mm__; + + if(mm__ == NULL){ + mm__ = &system_allocator; + } + + return h_compile_for_named_backend__m(mm__, parser, be_with_params); +} + +int h_compile_for_named_backend__m(HAllocator* mm__, HParser* parser, HParserBackendWithParams* be_with_params) { + /*if (parser->backend >= PB_MIN && parser->backend <= PB_MAX && + backends[parser->backend]->free != NULL) { + backends[parser->backend]->free(parser); + } + int ret = backends[be_with_params->backend]->compile(mm__, parser, (const void*) be_with_params->params); + if (!ret) + parser->backend = be_with_params->backend; + return ret;*/ + return h_compile__m(mm__, parser, be_with_params->backend, be_with_params->params); +} + int h_compile(HParser* parser, HParserBackend backend, const void* params) { return h_compile__m(&system_allocator, parser, backend, params); } diff --git a/src/hammer.h b/src/hammer.h index ab5ea080d4f325b88d5c4014de57dc3da5687baf..fc14125b914cbaf7c174a95dd724d11dd59ed767 100644 --- a/src/hammer.h +++ b/src/hammer.h @@ -55,7 +55,9 @@ typedef enum HParserBackend_ { } HParserBackend; typedef struct HParserBackendWithParams_ { - /* The backend */ + /* Name of backend (for loading backends from modules */ + char *name; + /* The backend (if backend is to be loaded from an external module set to invalid (?))*/ HParserBackend backend; /* * Backend-specific parameters - if this needs to be freed, the backend @@ -64,6 +66,8 @@ typedef struct HParserBackendWithParams_ { * and PB_GLR take an integer cast to void * */ void *params; + /*raw substring the params were extracted from*/ + char *raw_params; /* Allocator to use to free this (and the params if necessary) */ HAllocator *mm__; } HParserBackendWithParams; @@ -349,6 +353,21 @@ HAMMER_FN_DECL(char *, h_get_descriptive_text_for_backend_with_params, HParserBackend h_query_backend_by_name(const char *name); +/** + * Get a Hammer Backend with params from a string of the form + * backend_name(params) for example "lalr(1)". + * + * If the backend is one of the existing backends in the HBackend enum, + * HBackend will be populated in the result. + * + * TODO: actually do the below, also improve this comment to be more clear and concise. + * Otherwise the result will save the name for use in attempts later at + * loading the named module. + * + */ + +HAMMER_FN_DECL(HParserBackendWithParams *, h_get_backend_with_params_by_name, const char *name_with_params); + /** * Top-level function to call a parser that has been built over some * piece of input (of known size). @@ -881,6 +900,8 @@ void h_pprintln(FILE* stream, const HParsedToken* tok); * * Consult each backend for details. */ +HAMMER_FN_DECL(int, h_compile_for_named_backend, HParser* parser, HParserBackendWithParams *be_with_params); + HAMMER_FN_DECL(int, h_compile, HParser* parser, HParserBackend backend, const void* params); /** diff --git a/src/internal.h b/src/internal.h index 03d6c8adb3bee5c7a4ab7cf701eb2c89122bcd1f..467396eb69acd1ac42b3ba9b2c6557353c9e270d 100644 --- a/src/internal.h +++ b/src/internal.h @@ -262,6 +262,9 @@ typedef struct HParserBackendVTable_ { char * (*get_short_name_with_params)(HAllocator *mm__, HParserBackend be, void *params); + + /* extract params from the input string */ + int (*extract_params)(void** params, char *raw_params); } HParserBackendVTable;